diff --git a/.gitattributes b/.gitattributes index 6ef435cfe5..3c4605c943 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,14 +5,9 @@ docs/operator-manual/resource_actions_builtin.md linguist-generated=true docs/operator-manual/server-commands/argocd-*.md linguist-generated=true docs/user-guide/commands/argocd_*.md linguist-generated=true manifests/core-install.yaml linguist-generated=true -manifests/core-install-with-hydrator.yaml linguist-generated=true manifests/crds/*-crd.yaml linguist-generated=true manifests/ha/install.yaml linguist-generated=true -manifests/ha/install-with-hydrator.yaml linguist-generated=true manifests/ha/namespace-install.yaml linguist-generated=true -manifests/ha/namespace-install-with-hydrator.yaml linguist-generated=true manifests/install.yaml linguist-generated=true -manifests/install-with-hydrator.yaml linguist-generated=true manifests/namespace-install.yaml linguist-generated=true -manifests/namespace-install-with-hydrator.yaml linguist-generated=true pkg/apis/api-rules/violation_exceptions.list linguist-generated=true diff --git a/.github/workflows/bump-major-version.yaml b/.github/workflows/bump-major-version.yaml deleted file mode 100644 index b7fbf7101a..0000000000 --- a/.github/workflows/bump-major-version.yaml +++ /dev/null @@ -1,89 +0,0 @@ -name: Bump major version -on: - workflow_dispatch: {} - -permissions: {} - -jobs: - prepare-release: - permissions: - contents: write # for peter-evans/create-pull-request to create branch - pull-requests: write # for peter-evans/create-pull-request to create a PR - name: Automatically update major version - runs-on: ubuntu-22.04 - steps: - - name: Checkout code - uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - with: - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - - # Get the current major version from go.mod and save it as a variable. - - name: Get target version - id: get-target-version - run: | - set -ue - CURRENT_VERSION=$(grep 'module github.com/argoproj/argo-cd' go.mod | awk '{print $2}' | sed 's/.*\/v//') - echo "TARGET_VERSION=$((CURRENT_VERSION + 1))" >> $GITHUB_OUTPUT - - - name: Copy source code to GOPATH - run: | - mkdir -p ~/go/src/github.com/argoproj - cp -a ../argo-cd ~/go/src/github.com/argoproj - - - name: Run script to bump the version - run: | - hack/bump-major-version.sh - working-directory: /home/runner/go/src/github.com/argoproj/argo-cd - - - name: Setup Golang - uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 - with: - go-version: ${{ env.GOLANG_VERSION }} - - name: Add ~/go/bin to PATH - run: | - echo "/home/runner/go/bin" >> $GITHUB_PATH - - name: Add /usr/local/bin to PATH - run: | - echo "/usr/local/bin" >> $GITHUB_PATH - - name: Download & vendor dependencies - run: | - # We need to vendor go modules for codegen yet - go mod download - go mod vendor -v - working-directory: /home/runner/go/src/github.com/argoproj/argo-cd - - name: Install toolchain for codegen - run: | - make install-codegen-tools-local - make install-go-tools-local - working-directory: /home/runner/go/src/github.com/argoproj/argo-cd - # We install kustomize in the dist directory - - name: Add dist to PATH - run: | - echo "/home/runner/work/argo-cd/argo-cd/dist" >> $GITHUB_PATH - - name: Run codegen - run: | - set -x - export GOPATH=$(go env GOPATH) - make codegen-local - working-directory: /home/runner/go/src/github.com/argoproj/argo-cd - - - name: Copy changes back - run: | - # Copy the contents back, but skip the .git directory - rsync -a --exclude=.git /home/runner/go/src/github.com/argoproj/argo-cd/ ../argo-cd - - - name: Create pull request - uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 - with: - commit-message: "Bump major version to ${{ steps.get-target-version.outputs.TARGET_VERSION }}" - title: "Bump major version to ${{ steps.get-target-version.outputs.TARGET_VERSION }}" - body: | - Congrats! You've just bumped the major version to ${{ steps.get-target-version.outputs.TARGET_VERSION }}. - - Next steps: - - [ ] Merge this PR - - [ ] Add an upgrade guide to the docs for this version - branch: bump-major-version - branch-suffix: random - signoff: true \ No newline at end of file diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index e1afc4a76b..718b3b2f8a 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -14,7 +14,7 @@ on: env: # Golang version to use across CI steps # renovate: datasource=golang-version packageName=golang - GOLANG_VERSION: '1.24.3' + GOLANG_VERSION: '1.24.4' concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -39,7 +39,7 @@ jobs: files_yaml: | backend: - '!ui/**' - - '!**.md' + - '!**.md' - '!**/*.md' - '!docs/**' frontend: @@ -94,8 +94,8 @@ jobs: lint-go: permissions: - contents: read # for actions/checkout to fetch code - pull-requests: read # for golangci/golangci-lint-action to fetch pull requests + contents: read # for actions/checkout to fetch code + pull-requests: read # for golangci/golangci-lint-action to fetch pull requests name: Lint Go code if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-22.04 @@ -109,7 +109,7 @@ jobs: with: go-version: ${{ env.GOLANG_VERSION }} - name: Run golangci-lint - uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 + uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0 with: # renovate: datasource=go packageName=github.com/golangci/golangci-lint versioning=regex:^v(?\d+)\.(?\d+)\.(?\d+)?$ version: v2.1.6 @@ -174,7 +174,7 @@ jobs: - name: Run all unit tests run: make test-local - name: Generate test results artifacts - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: test-results path: test-results @@ -238,7 +238,7 @@ jobs: - name: Run all unit tests run: make test-race-local - name: Generate test results artifacts - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: race-results path: test-results/ @@ -333,15 +333,6 @@ jobs: run: yarn lint working-directory: ui/ - shellcheck: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - - run: | - sudo apt-get install shellcheck - shellcheck -e SC2086 -e SC2046 -e SC2068 -e SC2206 -e SC2048 -e SC2059 -e SC2154 -e SC2034 -e SC2016 -e SC2128 -e SC1091 -e SC2207 $(find . -type f -name '*.sh') | tee sc.log - test ! -s sc.log - analyze: name: Process & analyze test artifacts if: ${{ needs.changes.outputs.backend == 'true' || needs.changes.outputs.frontend == 'true' }} @@ -385,9 +376,9 @@ jobs: run: | go tool covdata percent -i=test-results,e2e-code-coverage/applicationset-controller,e2e-code-coverage/repo-server,e2e-code-coverage/app-controller,e2e-code-coverage/commit-server -o test-results/full-coverage.out - name: Upload code coverage information to codecov.io - uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3 + uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0 with: - files: test-results/full-coverage.out + file: test-results/full-coverage.out fail_ci_if_error: true env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} @@ -411,31 +402,30 @@ jobs: strategy: fail-fast: false matrix: - # latest: true means that this version mush upload the coverage report to codecov.io - # We designate the latest version because we only collect code coverage for that version. k3s: - - version: v1.32.1 - latest: true - version: v1.31.0 - latest: false + # We designate the latest version because we only collect code coverage for that version. + latest: true - version: v1.30.4 latest: false - version: v1.29.8 latest: false + - version: v1.28.13 + latest: false needs: - build-go - changes env: GOPATH: /home/runner/go - ARGOCD_FAKE_IN_CLUSTER: 'true' - ARGOCD_SSH_DATA_PATH: '/tmp/argo-e2e/app/config/ssh' - ARGOCD_TLS_DATA_PATH: '/tmp/argo-e2e/app/config/tls' - ARGOCD_E2E_SSH_KNOWN_HOSTS: '../fixture/certs/ssh_known_hosts' - ARGOCD_E2E_K3S: 'true' - ARGOCD_IN_CI: 'true' - ARGOCD_E2E_APISERVER_PORT: '8088' - ARGOCD_APPLICATION_NAMESPACES: 'argocd-e2e-external,argocd-e2e-external-2' - ARGOCD_SERVER: '127.0.0.1:8088' + ARGOCD_FAKE_IN_CLUSTER: "true" + ARGOCD_SSH_DATA_PATH: "/tmp/argo-e2e/app/config/ssh" + ARGOCD_TLS_DATA_PATH: "/tmp/argo-e2e/app/config/tls" + ARGOCD_E2E_SSH_KNOWN_HOSTS: "../fixture/certs/ssh_known_hosts" + ARGOCD_E2E_K3S: "true" + ARGOCD_IN_CI: "true" + ARGOCD_E2E_APISERVER_PORT: "8088" + ARGOCD_APPLICATION_NAMESPACES: "argocd-e2e-external,argocd-e2e-external-2" + ARGOCD_SERVER: "127.0.0.1:8088" GITHUB_TOKEN: ${{ secrets.E2E_TEST_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} GITLAB_TOKEN: ${{ secrets.E2E_TEST_GITLAB_TOKEN }} steps: @@ -494,9 +484,9 @@ jobs: git config --global user.email "john.doe@example.com" - name: Pull Docker image required for tests run: | - docker pull ghcr.io/dexidp/dex:v2.43.0 + docker pull ghcr.io/dexidp/dex:v2.41.1 docker pull argoproj/argo-cd-ci-builder:v1.0.0 - docker pull redis:7.2.7-alpine + docker pull redis:7.0.15-alpine - name: Create target directory for binaries in the build-process run: | mkdir -p dist @@ -526,13 +516,13 @@ jobs: goreman run stop-all || echo "goreman trouble" sleep 30 - name: Upload e2e coverage report - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + 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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + 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/image-reuse.yaml b/.github/workflows/image-reuse.yaml index 5c37240d04..426d2cbaa8 100644 --- a/.github/workflows/image-reuse.yaml +++ b/.github/workflows/image-reuse.yaml @@ -70,13 +70,12 @@ jobs: uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ inputs.go-version }} - cache: false - name: Install cosign uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 - uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 - - uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 + - uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 - name: Setup tags for container image as a CSV type run: | diff --git a/.github/workflows/image.yaml b/.github/workflows/image.yaml index e2ef286b4e..cbdaef5ef1 100644 --- a/.github/workflows/image.yaml +++ b/.github/workflows/image.yaml @@ -7,7 +7,7 @@ on: pull_request: branches: - master - types: [labeled, unlabeled, opened, synchronize, reopened] + types: [ labeled, unlabeled, opened, synchronize, reopened ] concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -46,14 +46,14 @@ jobs: needs: [set-vars] permissions: contents: read - packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags + packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags id-token: write # for creating OIDC tokens for signing. if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name != 'push' }} 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) # renovate: datasource=golang-version packageName=golang - go-version: 1.24.3 + go-version: 1.24.4 platforms: ${{ needs.set-vars.outputs.platforms }} push: false @@ -61,7 +61,7 @@ jobs: needs: [set-vars] permissions: contents: read - packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags + packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags id-token: write # for creating OIDC tokens for signing. if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name == 'push' }} uses: ./.github/workflows/image-reuse.yaml @@ -70,7 +70,7 @@ jobs: 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) # renovate: datasource=golang-version packageName=golang - go-version: 1.24.3 + go-version: 1.24.4 platforms: ${{ needs.set-vars.outputs.platforms }} push: true secrets: @@ -101,8 +101,8 @@ jobs: - build-and-publish - set-vars permissions: - contents: write # for git to push upgrade commit if not already deployed - packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags + contents: write # for git to push upgrade commit if not already deployed + packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name == 'push' }} runs-on: ubuntu-22.04 steps: @@ -116,3 +116,4 @@ jobs: git config --global user.name 'CI' git diff --exit-code && echo 'Already deployed' || (git commit -am 'Upgrade argocd to ${{ needs.set-vars.outputs.image-tag }}' && git push) working-directory: argoproj-deployments/argocd + diff --git a/.github/workflows/pr-title-check.yml b/.github/workflows/pr-title-check.yml index 81c1981923..5c19a36a48 100644 --- a/.github/workflows/pr-title-check.yml +++ b/.github/workflows/pr-title-check.yml @@ -12,8 +12,8 @@ permissions: {} # workflow being trigger a number of times. This limits it # to one run per PR. concurrency: - group: ${{ github.workflow }}-${{ github.head_ref }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.ref }} + jobs: validate: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index b9b7d56439..04351e92d2 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -11,7 +11,7 @@ permissions: {} env: # renovate: datasource=golang-version packageName=golang - GOLANG_VERSION: '1.24.3' # Note: go-version must also be set in job argocd-image.with.go-version + GOLANG_VERSION: '1.24.4' # Note: go-version must also be set in job argocd-image.with.go-version jobs: argocd-image: @@ -25,7 +25,7 @@ jobs: 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) # renovate: datasource=golang-version packageName=golang - go-version: 1.24.3 + go-version: 1.24.4 platforms: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le push: true secrets: @@ -33,20 +33,20 @@ jobs: quay_password: ${{ secrets.RELEASE_QUAY_TOKEN }} argocd-image-provenance: - needs: [argocd-image] - permissions: - actions: read # for detecting the Github Actions environment. - id-token: write # for creating OIDC tokens for signing. - packages: write # for uploading attestations. (https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#known-issues) - # 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 - if: github.repository == 'argoproj/argo-cd' - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0 - with: - image: quay.io/argoproj/argocd - digest: ${{ needs.argocd-image.outputs.image-digest }} - secrets: - registry-username: ${{ secrets.RELEASE_QUAY_USERNAME }} - registry-password: ${{ secrets.RELEASE_QUAY_TOKEN }} + needs: [argocd-image] + permissions: + actions: read # for detecting the Github Actions environment. + id-token: write # for creating OIDC tokens for signing. + packages: write # for uploading attestations. (https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#known-issues) + # 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 + if: github.repository == 'argoproj/argo-cd' + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0 + with: + image: quay.io/argoproj/argocd + digest: ${{ needs.argocd-image.outputs.image-digest }} + secrets: + registry-username: ${{ secrets.RELEASE_QUAY_USERNAME }} + registry-password: ${{ secrets.RELEASE_QUAY_TOKEN }} goreleaser: needs: @@ -73,13 +73,11 @@ jobs: uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ env.GOLANG_VERSION }} - cache: false - 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 - GORELEASER_PREVIOUS_TAG=$(go run hack/get-previous-release/get-previous-version-for-release-notes.go ${{ github.ref_name }}) || exit 1 - echo "GORELEASER_PREVIOUS_TAG=$GORELEASER_PREVIOUS_TAG" >> $GITHUB_ENV + 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 @@ -109,7 +107,7 @@ jobs: - name: Generate subject for provenance id: hash env: - ARTIFACTS: '${{ steps.run-goreleaser.outputs.artifacts }}' + ARTIFACTS: "${{ steps.run-goreleaser.outputs.artifacts }}" run: | set -euo pipefail @@ -130,8 +128,8 @@ jobs: # 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 uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0 with: - base64-subjects: '${{ needs.goreleaser.outputs.hashes }}' - provenance-name: 'argocd-cli.intoto.jsonl' + base64-subjects: "${{ needs.goreleaser.outputs.hashes }}" + provenance-name: "argocd-cli.intoto.jsonl" upload-assets: true generate-sbom: @@ -156,7 +154,6 @@ jobs: uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ env.GOLANG_VERSION }} - cache: false - name: Generate SBOM (spdx) id: spdx-builder @@ -167,7 +164,7 @@ jobs: SIGS_BOM_VERSION: v0.2.1 # comma delimited list of project relative folders to inspect for package # managers (gomod, yarn, npm). - PROJECT_FOLDERS: '.,./ui' + PROJECT_FOLDERS: ".,./ui" # full qualified name of the docker image to be inspected DOCKER_IMAGE: quay.io/argoproj/argocd:${{ github.ref_name }} run: | @@ -215,8 +212,8 @@ jobs: # 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' + base64-subjects: "${{ needs.generate-sbom.outputs.hashes }}" + provenance-name: "argocd-sbom.intoto.jsonl" upload-assets: true post-release: @@ -299,7 +296,7 @@ jobs: uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 with: commit-message: Bump version in master - title: 'chore: Bump version in master' + title: "chore: Bump version in master" body: All images built from master should indicate which version we are on track for. signoff: true branch: update-version diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml index 64650e5619..0403b1e2d8 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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: SARIF file path: results.sarif diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile index fa4f1691b0..ec47f2553d 100644 --- a/.gitpod.Dockerfile +++ b/.gitpod.Dockerfile @@ -1,4 +1,4 @@ -FROM gitpod/workspace-full@sha256:a47a68ee7f9da10cd889ccce4661bc73f2c0d5a98d3d087e8bdfc0230b27964c +FROM gitpod/workspace-full@sha256:230285e0b949e6d728d384b2029a4111db7b9c87c182f22f32a0be9e36b225df USER root diff --git a/.golangci.yaml b/.golangci.yaml index 38783894c5..4f01cf66d8 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,229 +1,101 @@ -formatters: - enable: - - gofumpt - - goimports - - settings: - goimports: - local-prefixes: - - github.com/argoproj/argo-cd/v3 - -issues: - max-issues-per-linter: 0 - - max-same-issues: 0 - +version: "2" +run: + timeout: 50m linters: + default: none enable: + - errcheck - errorlint - gocritic - - gomodguard - - importas + - govet + - ineffassign - misspell - perfsprint - - revive - staticcheck - testifylint - thelper - unparam + - unused - usestdlibvars - - usetesting - whitespace - - exclusions: - rules: - - linters: - - unparam - path: (.+)_test\.go - - presets: - - comments - - common-false-positives - - legacy - - std-error-handling - - warn-unused: true - settings: gocritic: disabled-checks: - appendAssign - assignOp + - badCond + - commentFormatting - exitAfterDefer + - ifElseChain - mapKey + - singleCaseSwitch - typeSwitchVar - - gomodguard: - blocked: - modules: - - github.com/golang-jwt/jwt/v4: - recommendations: - - github.com/golang-jwt/jwt/v5 - - - github.com/imdario/mergo: - recommendations: - - dario.cat/mergo - reason: '`github.com/imdario/mergo` has been renamed.' - - - github.com/pkg/errors: - recommendations: - - errors - - importas: - alias: - - pkg: github.com/golang-jwt/jwt/v5 - alias: jwtgo - - - pkg: k8s.io/api/apps/v1 - alias: appsv1 - - - pkg: k8s.io/api/core/v1 - alias: corev1 - - - pkg: k8s.io/api/rbac/v1 - alias: rbacv1 - - - pkg: k8s.io/apimachinery/pkg/api/errors - alias: apierrors - - - pkg: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 - alias: apiextensionsv1 - - - pkg: k8s.io/apimachinery/pkg/apis/meta/v1 - alias: metav1 - - - pkg: k8s.io/client-go/informers/core/v1 - alias: informersv1 - - - pkg: errors - alias: stderrors - - - pkg: github.com/argoproj/argo-cd/v3/util/io - alias: utilio - - nolintlint: - require-specific: true - perfsprint: - # Optimizes even if it requires an int or uint type cast. int-conversion: true - # Optimizes into `err.Error()` even if it is only equivalent for non-nil errors. - err-error: true - # Optimizes `fmt.Errorf`. - errorf: true - # Optimizes `fmt.Sprintf` with only one argument. + err-error: false + errorf: false sprintf1: true - # Optimizes into strings concatenation. - strconcat: true - - revive: - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md - rules: - - name: bool-literal-in-expr - - - name: blank-imports - disabled: true - - - name: context-as-argument - arguments: - - allowTypesBefore: '*testing.T,testing.TB' - - - name: context-keys-type - disabled: true - - - name: dot-imports - disabled: true - - - name: duplicated-imports - - - name: early-return - arguments: - - preserveScope - - - name: empty-block - disabled: true - - - name: error-naming - disabled: true - - - name: error-return - - - name: error-strings - disabled: true - - - name: errorf - - - name: identical-branches - - - name: if-return - - - name: increment-decrement - - - name: indent-error-flow - arguments: - - preserveScope - - - name: modifies-parameter - - - name: optimize-operands-order - - - name: range - - - name: receiver-naming - - - name: redefines-builtin-id - disabled: true - - - name: redundant-import-alias - - - name: superfluous-else - arguments: - - preserveScope - - - name: time-equal - - - name: time-naming - disabled: true - - - name: unexported-return - disabled: true - - - name: unnecessary-stmt - - - name: unreachable-code - - - name: unused-parameter - - - name: use-any - - - name: useless-break - - - name: var-declaration - - - name: var-naming - arguments: - - - ID - - - VM - - - skipPackageNameChecks: true - upperCaseConst: true - + strconcat: false staticcheck: checks: - - all - - -SA5011 - - -ST1003 - - -ST1016 - + - "all" + - "-ST1001" # dot imports are discouraged + - "-ST1003" # poorly chosen identifier + - "-ST1005" # incorrectly formatted error string + - "-ST1011" # poorly chosen name for variable of type time.Duration + - "-ST1012" # poorly chosen name for an error variable + - "-ST1016" # use consistent method receiver names + - "-ST1017" # don't use Yoda conditions + - "-ST1019" # importing the same package multiple times + - "-ST1023" # redundant type in variable declaration + - "-QF1001" # apply De Morgan’s law + - "-QF1003" # convert if/else-if chain to tagged switch + - "-QF1006" # lift if+break into loop condition + - "-QF1007" # merge conditional assignment into variable declaration + - "-QF1008" # omit embedded fields from selector expression + - "-QF1009" # use time.Time.Equal instead of == operator + - "-QF1011" # omit redundant type from variable declaration + - "-QF1012" # use fmt.Fprintf(x, ...) instead of x.Write(fmt.Sprintf(...)) testifylint: enable-all: true - disable: - go-require - - usetesting: - os-mkdir-temp: false - -output: - show-stats: false - -version: "2" + - equal-values + - empty + - len + - expected-actual + - formatter + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - linters: + - unparam + path: (.+)_test\.go + - path: (.+)\.go$ + text: SA5011 + paths: + - third_party$ + - builtin$ + - examples$ +issues: + max-issues-per-linter: 0 + max-same-issues: 0 +formatters: + enable: + - gofumpt + - goimports + settings: + goimports: + local-prefixes: + - github.com/argoproj/argo-cd/v2 + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/.goreleaser.yaml b/.goreleaser.yaml index baa7b1f5fa..ad23b85259 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -16,11 +16,11 @@ builds: flags: - -v ldflags: - - -X github.com/argoproj/argo-cd/v3/common.version={{ .Version }} - - -X github.com/argoproj/argo-cd/v3/common.buildDate={{ .Date }} - - -X github.com/argoproj/argo-cd/v3/common.gitCommit={{ .FullCommit }} - - -X github.com/argoproj/argo-cd/v3/common.gitTreeState={{ .Env.GIT_TREE_STATE }} - - -X github.com/argoproj/argo-cd/v3/common.kubectlVersion={{ .Env.KUBECTL_VERSION }} + - -X github.com/argoproj/argo-cd/v2/common.version={{ .Version }} + - -X github.com/argoproj/argo-cd/v2/common.buildDate={{ .Date }} + - -X github.com/argoproj/argo-cd/v2/common.gitCommit={{ .FullCommit }} + - -X github.com/argoproj/argo-cd/v2/common.gitTreeState={{ .Env.GIT_TREE_STATE }} + - -X github.com/argoproj/argo-cd/v2/common.kubectlVersion={{ .Env.KUBECTL_VERSION }} - -extldflags="-static" goos: - linux @@ -45,11 +45,11 @@ builds: archives: - id: argocd-archive - ids: - - argocd-cli + builds: + - argocd-cli name_template: |- {{ .ProjectName }}-{{ .Os }}-{{ .Arch }} - formats: [binary] + format: binary checksum: name_template: 'cli_checksums.txt' @@ -79,28 +79,25 @@ release: All Argo CD container images are signed by cosign. A Provenance is generated for container images and CLI binaries which meet the SLSA Level 3 specifications. See the [documentation](https://argo-cd.readthedocs.io/en/stable/operator-manual/signed-release-assets) on how to verify. - ## Release Notes Blog Post - For a detailed breakdown of the key changes and improvements in this release, check out the [official blog post](https://blog.argoproj.io/argo-cd-v2-14-release-candidate-57a664791e2a) ## Upgrading If upgrading from a different minor version, be sure to read the [upgrading](https://argo-cd.readthedocs.io/en/stable/operator-manual/upgrading/overview/) documentation. footer: | **Full Changelog**: https://github.com/argoproj/argo-cd/compare/{{ .PreviousTag }}...{{ .Tag }} - + + snapshot: #### To be removed for PR - version_template: '2.6.0' + name_template: "2.6.0" changelog: - use: github + use: + github sort: asc abbrev: 0 groups: # Regex use RE2 syntax as defined here: https://github.com/google/re2/wiki/Syntax. - - title: 'Breaking Changes' - regexp: '^.*?(\([[:word:]]+\))??!:.+$' - order: 0 - title: 'Features' regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$' order: 100 @@ -120,4 +117,7 @@ changelog: - '^test:' - '^.*?Bump(\([[:word:]]+\))?.+$' - '^.*?\[Bot\](\([[:word:]]+\))?.+$' + + # yaml-language-server: $schema=https://goreleaser.com/static/schema.json + diff --git a/.mockery.yaml b/.mockery.yaml index ca4a28b745..de7e1266f4 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -1,82 +1,79 @@ -dir: '{{.InterfaceDir}}/mocks' -structname: '{{.InterfaceName}}' -filename: '{{.InterfaceName}}.go' -pkgname: mocks - -template-data: - unroll-variadic: true - +# global config +filename: "{{.InterfaceName}}.go" +dir: "{{.InterfaceDir}}/mocks" +outpkg: "mocks" +mockname: "{{.InterfaceName}}" +with-expecter: false +# individual interface config packages: - github.com/argoproj/argo-cd/v3/applicationset/generators: + github.com/argoproj/argo-cd/v2/applicationset/generators: interfaces: - Generator: {} - github.com/argoproj/argo-cd/v3/applicationset/services: + Generator: + github.com/argoproj/argo-cd/v2/applicationset/services: interfaces: - Repos: {} - github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider: + Repos: + github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider: config: - dir: applicationset/services/scm_provider/aws_codecommit/mocks + dir: "applicationset/services/scm_provider/aws_codecommit/mocks" interfaces: - AWSCodeCommitClient: {} - AWSTaggingClient: {} - github.com/argoproj/argo-cd/v3/applicationset/utils: - interfaces: - Renderer: {} - github.com/argoproj/argo-cd/v3/commitserver/apiclient: - interfaces: - Clientset: {} - CommitServiceClient: {} - github.com/argoproj/argo-cd/v3/commitserver/commit: - interfaces: - RepoClientFactory: {} - github.com/argoproj/argo-cd/v3/controller/cache: - interfaces: - LiveStateCache: {} - github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster: - interfaces: - ClusterServiceServer: {} - github.com/argoproj/argo-cd/v3/pkg/apiclient/session: - interfaces: - SessionServiceClient: {} - SessionServiceServer: {} - github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1: - interfaces: - AppProjectInterface: {} - github.com/argoproj/argo-cd/v3/reposerver/apiclient: - interfaces: - RepoServerService_GenerateManifestWithFilesClient: {} - RepoServerServiceClient: {} - github.com/argoproj/argo-cd/v3/server/application: - interfaces: - Broadcaster: {} - github.com/argoproj/argo-cd/v3/server/extension: - interfaces: - ApplicationGetter: {} - ExtensionMetricsRegistry: {} - ProjectGetter: {} - RbacEnforcer: {} - SettingsGetter: {} - UserGetter: {} - github.com/argoproj/argo-cd/v3/util/db: - interfaces: - ArgoDB: {} - github.com/argoproj/argo-cd/v3/util/git: - interfaces: - Client: {} - github.com/argoproj/argo-cd/v3/util/helm: - interfaces: - Client: {} - github.com/argoproj/argo-cd/v3/util/io: - interfaces: - TempPaths: {} - github.com/argoproj/argo-cd/v3/util/notification/argocd: - interfaces: - Service: {} - github.com/argoproj/argo-cd/v3/util/workloadidentity: - interfaces: - TokenProvider: {} - github.com/microsoft/azure-devops-go-api/azuredevops/v7/git: + AWSCodeCommitClient: + AWSTaggingClient: + github.com/microsoft/azure-devops-go-api/azuredevops/git: config: - dir: applicationset/services/scm_provider/azure_devops/git/mocks + dir: "applicationset/services/scm_provider/azure_devops/git/mocks" interfaces: - Client: {} + Client: + github.com/argoproj/argo-cd/v2/applicationset/utils: + interfaces: + Renderer: + github.com/argoproj/argo-cd/v2/commitserver/commit: + interfaces: + RepoClientFactory: + github.com/argoproj/argo-cd/v2/commitserver/apiclient: + interfaces: + CommitServiceClient: + Clientset: + github.com/argoproj/argo-cd/v2/controller/cache: + interfaces: + LiveStateCache: + github.com/argoproj/argo-cd/v2/reposerver/apiclient: + interfaces: + RepoServerServiceClient: + RepoServerService_GenerateManifestWithFilesClient: + github.com/argoproj/argo-cd/v2/server/application: + interfaces: + Broadcaster: + github.com/argoproj/argo-cd/v2/server/extension: + interfaces: + ApplicationGetter: + ExtensionMetricsRegistry: + ProjectGetter: + RbacEnforcer: + SettingsGetter: + UserGetter: + github.com/argoproj/argo-cd/v2/util/db: + interfaces: + ArgoDB: + github.com/argoproj/argo-cd/v2/util/git: + interfaces: + Client: + github.com/argoproj/argo-cd/v2/util/helm: + interfaces: + Client: + github.com/argoproj/argo-cd/v2/util/io: + interfaces: + TempPaths: + github.com/argoproj/argo-cd/v2/util/notification/argocd: + interfaces: + Service: + # These mocks are not currently used, but they are part of the public API of this package. + github.com/argoproj/argo-cd/v2/pkg/apiclient/session: + interfaces: + SessionServiceServer: + SessionServiceClient: + github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster: + interfaces: + ClusterServiceServer: + github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1: + interfaces: + AppProjectInterface: diff --git a/Dockerfile b/Dockerfile index 789283a40f..d2b3eedc5d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,10 @@ -ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:80dd3c3b9c6cecb9f1667e9290b3bc61b78c2678c02cbdae5f0fea92cc6734ab +ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:3f85b7caad41a95462cf5b787d8a04604c8262cdcdf9a472b8c52ef83375fe15 #################################################################################################### # Builder image # Initial stage which pulls prepares build dependencies and CLI tooling we need for our final image # Also used as the image in CI jobs so needs all dependencies #################################################################################################### -FROM docker.io/library/golang:1.24.3@sha256:86b4cff66e04d41821a17cea30c1031ed53e2635e2be99ae0b4a7d69336b5063 AS builder - -WORKDIR /tmp +FROM docker.io/library/golang:1.24.4@sha256:db5d0afbfb4ab648af2393b92e87eaae9ad5e01132803d80caef91b5752d289c AS builder RUN echo 'deb http://archive.debian.org/debian buster-backports main' >> /etc/apt/sources.list @@ -25,6 +23,8 @@ RUN apt-get update && apt-get install --no-install-recommends -y \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +WORKDIR /tmp + COPY hack/install.sh hack/tool-versions.sh ./ COPY hack/installers installers @@ -40,8 +40,8 @@ LABEL org.opencontainers.image.source="https://github.com/argoproj/argo-cd" USER root -ENV ARGOCD_USER_ID=999 \ - DEBIAN_FRONTEND=noninteractive +ENV ARGOCD_USER_ID=999 +ENV DEBIAN_FRONTEND=noninteractive RUN groupadd -g $ARGOCD_USER_ID argocd && \ useradd -r -u $ARGOCD_USER_ID -g argocd argocd && \ @@ -55,13 +55,11 @@ RUN groupadd -g $ARGOCD_USER_ID argocd && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -COPY hack/gpg-wrapper.sh \ - hack/git-verify-wrapper.sh \ - entrypoint.sh \ - /usr/local/bin/ +COPY hack/gpg-wrapper.sh /usr/local/bin/gpg-wrapper.sh +COPY hack/git-verify-wrapper.sh /usr/local/bin/git-verify-wrapper.sh COPY --from=builder /usr/local/bin/helm /usr/local/bin/helm COPY --from=builder /usr/local/bin/kustomize /usr/local/bin/kustomize - +COPY entrypoint.sh /usr/local/bin/entrypoint.sh # keep uid_entrypoint.sh for backward compatibility RUN ln -s /usr/local/bin/entrypoint.sh /usr/local/bin/uid_entrypoint.sh @@ -103,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.24.3@sha256:86b4cff66e04d41821a17cea30c1031ed53e2635e2be99ae0b4a7d69336b5063 AS argocd-build +FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.24.4@sha256:db5d0afbfb4ab648af2393b92e87eaae9ad5e01132803d80caef91b5752d289c AS argocd-build WORKDIR /go/src/github.com/argoproj/argo-cd @@ -113,13 +111,13 @@ RUN go mod download # Perform the build COPY . . COPY --from=argocd-ui /src/dist/app /go/src/github.com/argoproj/argo-cd/ui/dist/app -ARG TARGETOS \ - TARGETARCH +ARG TARGETOS +ARG TARGETARCH # These build args are optional; if not specified the defaults will be taken from the Makefile -ARG GIT_TAG \ - BUILD_DATE \ - GIT_TREE_STATE \ - GIT_COMMIT +ARG GIT_TAG +ARG BUILD_DATE +ARG GIT_TREE_STATE +ARG GIT_COMMIT RUN GIT_COMMIT=$GIT_COMMIT \ GIT_TREE_STATE=$GIT_TREE_STATE \ GIT_TAG=$GIT_TAG \ @@ -132,7 +130,6 @@ RUN GIT_COMMIT=$GIT_COMMIT \ # Final image #################################################################################################### FROM argocd-base -ENTRYPOINT ["/usr/bin/tini", "--"] COPY --from=argocd-build /go/src/github.com/argoproj/argo-cd/dist/argocd* /usr/local/bin/ USER root @@ -147,3 +144,4 @@ RUN ln -s /usr/local/bin/argocd /usr/local/bin/argocd-server && \ ln -s /usr/local/bin/argocd /usr/local/bin/argocd-commit-server USER $ARGOCD_USER_ID +ENTRYPOINT ["/usr/bin/tini", "--"] diff --git a/Makefile b/Makefile index 7fe09815f1..8cc1b928da 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,9 @@ -PACKAGE=github.com/argoproj/argo-cd/v3/common +PACKAGE=github.com/argoproj/argo-cd/v2/common CURRENT_DIR=$(shell pwd) DIST_DIR=${CURRENT_DIR}/dist CLI_NAME=argocd BIN_NAME=argocd - -# When using OSX/Darwin, you might need to enable CGO for local builds -CGO_FLAG?=0 +CGO_FLAG=0 GEN_RESOURCES_CLI_NAME=argocd-resources-gen @@ -357,6 +355,11 @@ mod-vendor: test-tools-image mod-vendor-local: mod-download-local go mod vendor +# Deprecated - replace by install-tools-local +.PHONY: install-lint-tools +install-lint-tools: + ./hack/install.sh lint-tools + # Run linter on the code .PHONY: lint lint: test-tools-image @@ -432,7 +435,7 @@ test-e2e: test-e2e-local: cli-local # NO_PROXY ensures all tests don't go out through a proxy if one is configured on the test system export GO111MODULE=off - DIST_DIR=${DIST_DIR} RERUN_FAILS=5 PACKAGES="./test/e2e" ARGOCD_E2E_RECORD=${ARGOCD_E2E_RECORD} ARGOCD_CONFIG_DIR=$(HOME)/.config/argocd-e2e ARGOCD_GPG_ENABLED=true NO_PROXY=* ./hack/test.sh -timeout $(ARGOCD_E2E_TEST_TIMEOUT) -v -args -test.gocoverdir="$(PWD)/test-results" + DIST_DIR=${DIST_DIR} RERUN_FAILS=5 PACKAGES="./test/e2e" ARGOCD_E2E_RECORD=${ARGOCD_E2E_RECORD} ARGOCD_GPG_ENABLED=true NO_PROXY=* ./hack/test.sh -timeout $(ARGOCD_E2E_TEST_TIMEOUT) -v -args -test.gocoverdir="$(PWD)/test-results" # Spawns a shell in the test server container for debugging purposes debug-test-server: test-tools-image @@ -488,7 +491,6 @@ start-e2e-local: mod-vendor-local dep-ui-local cli-local ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS=http://127.0.0.1:8341,http://127.0.0.1:8342,http://127.0.0.1:8343,http://127.0.0.1:8344 \ ARGOCD_E2E_TEST=true \ ARGOCD_HYDRATOR_ENABLED=true \ - ARGOCD_CLUSTER_CACHE_EVENTS_PROCESSING_INTERVAL=1ms \ goreman -f $(ARGOCD_PROCFILE) start ${ARGOCD_START} ls -lrt /tmp/coverage @@ -597,7 +599,6 @@ install-codegen-tools-local: .PHONY: install-go-tools-local install-go-tools-local: ./hack/install.sh codegen-go-tools - ./hack/install.sh lint-tools .PHONY: dep-ui dep-ui: test-tools-image @@ -678,6 +679,7 @@ help: @echo 'debug:' @echo ' list -- list all make targets' @echo ' install-tools-local -- install all the tools below' + @echo ' install-lint-tools(-local)' @echo @echo 'codegen:' @echo ' codegen(-local) -- if using -local, run the following targets first' diff --git a/Procfile b/Procfile index e748770659..9ff5e67236 100644 --- a/Procfile +++ b/Procfile @@ -1,6 +1,6 @@ controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/app-controller} HOSTNAME=testappcontroller-1 FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --commit-server localhost:${ARGOCD_E2E_COMMITSERVER_PORT:-8086} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} --server-side-diff-enabled=${ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF:-'false'} --hydrator-enabled=${ARGOCD_HYDRATOR_ENABLED:='false'}" api-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/api-server} FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-server $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} --hydrator-enabled=${ARGOCD_HYDRATOR_ENABLED:='false'}" -dex: sh -c "ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/v3/cmd gendexcfg -o `pwd`/dist/dex.yaml && (test -f dist/dex.yaml || { echo 'Failed to generate dex configuration'; exit 1; }) && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:$(grep "image: ghcr.io/dexidp/dex" manifests/base/dex/argocd-dex-server-deployment.yaml | cut -d':' -f3) dex serve /dex.yaml" +dex: sh -c "ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/v2/cmd gendexcfg -o `pwd`/dist/dex.yaml && (test -f dist/dex.yaml || { echo 'Failed to generate dex configuration'; exit 1; }) && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:$(grep "image: ghcr.io/dexidp/dex" manifests/base/dex/argocd-dex-server-deployment.yaml | cut -d':' -f3) dex serve /dex.yaml" redis: hack/start-redis-with-password.sh repo-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/repo-server} FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-repo-server ARGOCD_GPG_ENABLED=${ARGOCD_GPG_ENABLED:-false} $COMMAND --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --otlp-address=${ARGOCD_OTLP_ADDRESS}" cmp-server: [ "$ARGOCD_E2E_TEST" = 'true' ] && exit 0 || [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_BINARY_NAME=argocd-cmp-server ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} $COMMAND --config-dir-path ./test/cmp --loglevel debug --otlp-address=${ARGOCD_OTLP_ADDRESS}" diff --git a/SECURITY-INSIGHTS.yml b/SECURITY-INSIGHTS.yml index 9af8b173d7..74236df3b1 100644 --- a/SECURITY-INSIGHTS.yml +++ b/SECURITY-INSIGHTS.yml @@ -3,9 +3,9 @@ header: expiration-date: '2024-10-31T00:00:00.000Z' # One year from initial release. last-updated: '2023-10-27' last-reviewed: '2023-10-27' - commit-hash: 226a670fe6b3c6769ff6d18e6839298a58e4577d + commit-hash: 74a367d10e7110209610ba3ec225539ebe5f7522 project-url: https://github.com/argoproj/argo-cd - project-release: v3.1.0 + project-release: v2.14.0 changelog: https://github.com/argoproj/argo-cd/releases license: https://github.com/argoproj/argo-cd/blob/master/LICENSE project-lifecycle: diff --git a/USERS.md b/USERS.md index 9ef7bced2d..ef200ecb3a 100644 --- a/USERS.md +++ b/USERS.md @@ -30,8 +30,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Ant Group](https://www.antgroup.com/) 1. [AppDirect](https://www.appdirect.com) 1. [Arctiq Inc.](https://www.arctiq.ca) -1. [Artemis Health by Nomi Health] (https://www.artemishealth.com/) -1. [Arturia](https://www.arturia.com) +2. [Arturia](https://www.arturia.com) 1. [ARZ Allgemeines Rechenzentrum GmbH](https://www.arz.at/) 1. [Augury](https://www.augury.com/) 1. [Autodesk](https://www.autodesk.com) @@ -46,7 +45,6 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Bedag Informatik AG](https://www.bedag.ch/) 1. [Beleza Na Web](https://www.belezanaweb.com.br/) 1. [Believable Bots](https://believablebots.io) -1. [Bayer AG](https://bayer.com) 1. [BigPanda](https://bigpanda.io) 1. [BioBox Analytics](https://biobox.io) 1. [BMW Group](https://www.bmwgroup.com/) @@ -69,7 +67,6 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Chainnodes](https://chainnodes.org) 1. [Chargetrip](https://chargetrip.com) 1. [Chime](https://www.chime.com) -1. [Chronicle Labs](https://chroniclelabs.org) 1. [Cisco ET&I](https://eti.cisco.com/) 1. [Cloud Posse](https://www.cloudposse.com/) 1. [Cloud Scale](https://cloudscaleinc.com/) @@ -95,15 +92,11 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Daydream](https://daydream.ing) 1. [Deloitte](https://www.deloitte.com/) 1. [Deutsche Telekom AG](https://telekom.com) -1. [Deutsche Bank AG](https://www.deutsche-bank.de/) 1. [Devopsi - Poland Software/DevOps Consulting](https://devopsi.pl/) 1. [Devtron Labs](https://github.com/devtron-labs/devtron) -1. [DigitalEd](https://www.digitaled.com) 1. [DigitalOcean](https://www.digitalocean.com) -1. [Divar](https://divar.ir) 1. [Divistant](https://divistant.com) 1. [Dott](https://ridedott.com) -1. [Doubble](https://www.doubble.app) 1. [Doximity](https://www.doximity.com/) 1. [EDF Renewables](https://www.edf-re.com/) 1. [edX](https://edx.org) @@ -153,7 +146,6 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Hazelcast](https://hazelcast.com/) 1. [Healy](https://www.healyworld.net) 1. [Helio](https://helio.exchange) -1. [hetao101](https://www.hetao101.com/) 1. [Hetki](https://hetki.ai) 1. [hipages](https://hipages.com.au/) 1. [Hiya](https://hiya.com) @@ -162,7 +154,6 @@ Currently, the following organizations are **officially** using Argo CD: 1. [IABAI](https://www.iab.ai) 1. [IBM](https://www.ibm.com/) 1. [Ibotta](https://home.ibotta.com) -1. [Icelandair](https://www.icelandair.com) 1. [IFS](https://www.ifs.com) 1. [IITS-Consulting](https://iits-consulting.de) 1. [IllumiDesk](https://www.illumidesk.com) @@ -200,10 +191,10 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Lian Chu Securities](https://lczq.com) 1. [Liatrio](https://www.liatrio.com) 1. [Lightricks](https://www.lightricks.com/) +1. [LINE](https://linecorp.com/en/) 1. [Loom](https://www.loom.com/) 1. [Lucid Motors](https://www.lucidmotors.com/) 1. [Lytt](https://www.lytt.co/) -1. [LY Corporation](https://www.lycorp.co.jp/en/) 1. [Magic Leap](https://www.magicleap.com/) 1. [Majid Al Futtaim](https://www.majidalfuttaim.com/) 1. [Major League Baseball](https://mlb.com) @@ -266,7 +257,6 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Patreon](https://www.patreon.com/) 1. [PayIt](https://payitgov.com/) 1. [PayPay](https://paypay.ne.jp/) -1. [Paystack](https://paystack.com/) 1. [Peloton Interactive](https://www.onepeloton.com/) 1. [Percona](https://percona.com/) 1. [PGS](https://www.pgs.com) @@ -278,7 +268,6 @@ Currently, the following organizations are **officially** using Argo CD: 1. [PITS Globale Datenrettungsdienste](https://www.pitsdatenrettung.de/) 1. [Platform9 Systems](https://platform9.com/) 1. [Polarpoint.io](https://polarpoint.io) -1. [Pollinate](https://www.pollinate.global) 1. [PostFinance](https://github.com/postfinance) 1. [Preferred Networks](https://preferred.jp/en/) 1. [Previder BV](https://previder.nl) @@ -313,7 +302,6 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Saloodo! GmbH](https://www.saloodo.com) 1. [Sap Labs](http://sap.com) 1. [Sauce Labs](https://saucelabs.com/) -1. [Schneider Electric](https://www.se.com) 1. [Schwarz IT](https://jobs.schwarz/it-mission) 1. [SCRM Lidl International Hub](https://scrm.lidl) 1. [SEEK](https://seek.com.au) @@ -323,7 +311,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [SI Analytics](https://si-analytics.ai) 1. [Sidewalk Entertainment](https://sidewalkplay.com/) 1. [Skit](https://skit.ai/) -1. [Skribble](https://skribble.com) +1. [Skribble](https://skribble.com) 1. [Skyscanner](https://www.skyscanner.net/) 1. [Smart Pension](https://www.smartpension.co.uk/) 1. [Smilee.io](https://smilee.io) @@ -344,13 +332,11 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Sumo Logic](https://sumologic.com/) 1. [Sutpc](http://www.sutpc.com/) 1. [Swiss Post](https://github.com/swisspost) -1. [Swissblock Technologies](https://swissblock.net/) 1. [Swisscom](https://www.swisscom.ch) 1. [Swissquote](https://github.com/swissquote) 1. [Syncier](https://syncier.com/) 1. [Synergy](https://synergy.net.au) 1. [Syself](https://syself.com) -1. [T-ROC Global](https://trocglobal.com/) 1. [TableCheck](https://tablecheck.com/) 1. [Tailor Brands](https://www.tailorbrands.com) 1. [Tamkeen Technologies](https://tamkeentech.sa/) @@ -388,11 +374,9 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Vinted](https://vinted.com/) 1. [Virtuo](https://www.govirtuo.com/) 1. [VISITS Technologies](https://visits.world/en) -1. [Viya](https://viya.me) 1. [Volvo Cars](https://www.volvocars.com/) 1. [Voyager Digital](https://www.investvoyager.com/) 1. [VSHN - The DevOps Company](https://vshn.ch/) -1. [Wakacje.pl](https://www.wakacje.pl/) 1. [Walkbase](https://www.walkbase.com/) 1. [Webstores](https://www.webstores.nl) 1. [Wehkamp](https://www.wehkamp.nl/) @@ -404,12 +388,10 @@ Currently, the following organizations are **officially** using Argo CD: 1. [WooliesX](https://wooliesx.com.au/) 1. [Woolworths Group](https://www.woolworthsgroup.com.au/) 1. [WSpot](https://www.wspot.com.br/) -1. [X3M ads](https://x3mads.com) 1. [Yieldlab](https://www.yieldlab.de/) 1. [Youverify](https://youverify.co/) 1. [Yubo](https://www.yubo.live/) -1. [Yuno](https://y.uno/) 1. [ZDF](https://www.zdf.de/) 1. [Zimpler](https://www.zimpler.com/) -1. [ZipRecruiter](https://www.ziprecruiter.com/) +1. [ZipRecuiter](https://www.ziprecruiter.com/) 1. [ZOZO](https://corp.zozo.com/) diff --git a/VERSION b/VERSION index fd2a01863f..ecbbf82074 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.1.0 +2.14.15 diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index 9d6184cea8..ac5b1975b0 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -28,7 +28,7 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" log "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" @@ -45,20 +45,19 @@ import ( "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/predicate" - "github.com/argoproj/argo-cd/v3/applicationset/controllers/template" - "github.com/argoproj/argo-cd/v3/applicationset/generators" - "github.com/argoproj/argo-cd/v3/applicationset/metrics" - "github.com/argoproj/argo-cd/v3/applicationset/status" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - "github.com/argoproj/argo-cd/v3/common" - applog "github.com/argoproj/argo-cd/v3/util/app/log" - "github.com/argoproj/argo-cd/v3/util/db" + "github.com/argoproj/argo-cd/v2/applicationset/controllers/template" + "github.com/argoproj/argo-cd/v2/applicationset/generators" + "github.com/argoproj/argo-cd/v2/applicationset/metrics" + "github.com/argoproj/argo-cd/v2/applicationset/status" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/db" - argov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - argoutil "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" + argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + argoutil "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) const ( @@ -468,7 +467,7 @@ func (r *ApplicationSetReconciler) setApplicationSetStatusCondition(ctx context. updatedAppset.DeepCopyInto(applicationSet) return nil }) - if err != nil && !apierrors.IsNotFound(err) { + if err != nil && !apierr.IsNotFound(err) { return fmt.Errorf("unable to set application set condition: %w", err) } } @@ -482,23 +481,24 @@ func (r *ApplicationSetReconciler) validateGeneratedApplications(ctx context.Con errorsByIndex := map[int]error{} namesSet := map[string]bool{} for i, app := range desiredApplications { - if namesSet[app.Name] { + if !namesSet[app.Name] { + namesSet[app.Name] = true + } else { errorsByIndex[i] = fmt.Errorf("ApplicationSet %s contains applications with duplicate name: %s", applicationSetInfo.Name, app.Name) continue } - namesSet[app.Name] = true appProject := &argov1alpha1.AppProject{} err := r.Get(ctx, types.NamespacedName{Name: app.Spec.Project, Namespace: r.ArgoCDNamespace}, appProject) if err != nil { - if apierrors.IsNotFound(err) { + if apierr.IsNotFound(err) { errorsByIndex[i] = fmt.Errorf("application references project %s which does not exist", app.Spec.Project) continue } return nil, err } - if _, err = argoutil.GetDestinationCluster(ctx, app.Spec.Destination, r.ArgoDB); err != nil { + if err := utils.ValidateDestination(ctx, &app.Spec.Destination, r.KubeClientset, r.ArgoCDNamespace); err != nil { errorsByIndex[i] = fmt.Errorf("application destination spec is invalid: %s", err.Error()) continue } @@ -578,7 +578,7 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context, var firstError error // Creates or updates the application in appList for _, generatedApp := range desiredApplications { - appLog := logCtx.WithFields(applog.GetAppLogFields(&generatedApp)) + appLog := logCtx.WithFields(log.Fields{"app": generatedApp.QualifiedName()}) // Normalize to avoid fighting with the application controller. generatedApp.Spec = *argoutil.NormalizeApplicationSpec(&generatedApp.Spec) @@ -741,7 +741,7 @@ func (r *ApplicationSetReconciler) deleteInCluster(ctx context.Context, logCtx * // Delete apps that are not in m[string]bool var firstError error for _, app := range current { - logCtx = logCtx.WithFields(applog.GetAppLogFields(&app)) + logCtx = logCtx.WithField("app", app.QualifiedName()) _, exists := m[app.Name] if !exists { @@ -771,7 +771,7 @@ func (r *ApplicationSetReconciler) deleteInCluster(ctx context.Context, logCtx * } // removeFinalizerOnInvalidDestination removes the Argo CD resources finalizer if the application contains an invalid target (eg missing cluster) -func (r *ApplicationSetReconciler) removeFinalizerOnInvalidDestination(ctx context.Context, applicationSet argov1alpha1.ApplicationSet, app *argov1alpha1.Application, clusterList []utils.ClusterSpecifier, appLog *log.Entry) error { +func (r *ApplicationSetReconciler) removeFinalizerOnInvalidDestination(ctx context.Context, applicationSet argov1alpha1.ApplicationSet, app *argov1alpha1.Application, clusterList *argov1alpha1.ClusterList, appLog *log.Entry) error { // Only check if the finalizers need to be removed IF there are finalizers to remove if len(app.Finalizers) == 0 { return nil @@ -780,18 +780,21 @@ func (r *ApplicationSetReconciler) removeFinalizerOnInvalidDestination(ctx conte var validDestination bool // Detect if the destination is invalid (name doesn't correspond to a matching cluster) - if destCluster, err := argoutil.GetDestinationCluster(ctx, app.Spec.Destination, r.ArgoDB); err != nil { + if err := utils.ValidateDestination(ctx, &app.Spec.Destination, r.KubeClientset, r.ArgoCDNamespace); err != nil { appLog.Warnf("The destination cluster for %s couldn't be found: %v", app.Name, err) validDestination = false } else { // Detect if the destination's server field does not match an existing cluster + matchingCluster := false - for _, cluster := range clusterList { - if destCluster.Server != cluster.Server { + for _, cluster := range clusterList.Items { + // Server fields must match. Note that ValidateDestination ensures that the server field is set, if applicable. + if app.Spec.Destination.Server != cluster.Server { continue } - if destCluster.Name != cluster.Name { + // The name must match, if it is not empty + if app.Spec.Destination.Name != "" && cluster.Name != app.Spec.Destination.Name { continue } @@ -976,16 +979,17 @@ func (r *ApplicationSetReconciler) buildAppSyncMap(applicationSet argov1alpha1.A } appStatus := applicationSet.Status.ApplicationStatus[idx] - app, ok := appMap[appName] - if !ok { + + if app, ok := appMap[appName]; ok { + syncEnabled = appSyncEnabledForNextStep(&applicationSet, app, appStatus) + if !syncEnabled { + break + } + } else { // application name not found in the list of applications managed by this ApplicationSet, maybe because it's being deleted syncEnabled = false break } - syncEnabled = appSyncEnabledForNextStep(&applicationSet, app, appStatus) - if !syncEnabled { - break - } } } @@ -1152,10 +1156,10 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress // populate updateCountMap with counts of existing Pending and Progressing Applications for _, appStatus := range applicationSet.Status.ApplicationStatus { - totalCountMap[appStepMap[appStatus.Application]]++ + totalCountMap[appStepMap[appStatus.Application]] += 1 if appStatus.Status == "Pending" || appStatus.Status == "Progressing" { - updateCountMap[appStepMap[appStatus.Application]]++ + updateCountMap[appStepMap[appStatus.Application]] += 1 } } @@ -1191,7 +1195,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress appStatus.Message = "Application moved to Pending status, watching for the Application resource to start Progressing." appStatus.Step = strconv.Itoa(getAppStep(appStatus.Application, appStepMap)) - updateCountMap[appStepMap[appStatus.Application]]++ + updateCountMap[appStepMap[appStatus.Application]] += 1 } appStatuses = append(appStatuses, appStatus) @@ -1292,7 +1296,7 @@ func (r *ApplicationSetReconciler) migrateStatus(ctx context.Context, appset *ar updatedAppset.DeepCopyInto(appset) return nil }) - if err != nil && !apierrors.IsNotFound(err) { + if err != nil && !apierr.IsNotFound(err) { return fmt.Errorf("unable to set application set condition: %w", err) } } @@ -1405,7 +1409,7 @@ func (r *ApplicationSetReconciler) syncValidApplications(logCtx *log.Entry, appl pruneEnabled := false // ensure that Applications generated with RollingSync do not have an automated sync policy, since the AppSet controller will handle triggering the sync operation instead - if validApps[i].Spec.SyncPolicy != nil && validApps[i].Spec.SyncPolicy.IsAutomatedSyncEnabled() { + if validApps[i].Spec.SyncPolicy != nil && validApps[i].Spec.SyncPolicy.Automated != nil { pruneEnabled = validApps[i].Spec.SyncPolicy.Automated.Prune validApps[i].Spec.SyncPolicy.Automated = nil } @@ -1463,23 +1467,23 @@ func getApplicationOwnsHandler(enableProgressiveSyncs bool) predicate.Funcs { // if we are the owner and there is a create event, we most likely created it and do not need to // re-reconcile if log.IsLevelEnabled(log.DebugLevel) { - logFields := log.Fields{"app": ""} + var appName string app, isApp := e.Object.(*argov1alpha1.Application) if isApp { - logFields = applog.GetAppLogFields(app) + appName = app.QualifiedName() } - log.WithFields(logFields).Debugln("received create event from owning an application") + log.WithField("app", appName).Debugln("received create event from owning an application") } return false }, DeleteFunc: func(e event.DeleteEvent) bool { if log.IsLevelEnabled(log.DebugLevel) { - logFields := log.Fields{"app": ""} + var appName string app, isApp := e.Object.(*argov1alpha1.Application) if isApp { - logFields = applog.GetAppLogFields(app) + appName = app.QualifiedName() } - log.WithFields(logFields).Debugln("received delete event from owning an application") + log.WithField("app", appName).Debugln("received delete event from owning an application") } return true }, @@ -1488,7 +1492,7 @@ func getApplicationOwnsHandler(enableProgressiveSyncs bool) predicate.Funcs { if !isApp { return false } - logCtx := log.WithFields(applog.GetAppLogFields(appOld)) + logCtx := log.WithField("app", appOld.QualifiedName()) logCtx.Debugln("received update event from owning an application") appNew, isApp := e.ObjectNew.(*argov1alpha1.Application) if !isApp { @@ -1500,12 +1504,12 @@ func getApplicationOwnsHandler(enableProgressiveSyncs bool) predicate.Funcs { }, GenericFunc: func(e event.GenericEvent) bool { if log.IsLevelEnabled(log.DebugLevel) { - logFields := log.Fields{} + var appName string app, isApp := e.Object.(*argov1alpha1.Application) if isApp { - logFields = applog.GetAppLogFields(app) + appName = app.QualifiedName() } - log.WithFields(logFields).Debugln("received generic event from owning an application") + log.WithField("app", appName).Debugln("received generic event from owning an application") } return true }, diff --git a/applicationset/controllers/applicationset_controller_test.go b/applicationset/controllers/applicationset_controller_test.go index 544a881f46..e0974bd8ce 100644 --- a/applicationset/controllers/applicationset_controller_test.go +++ b/applicationset/controllers/applicationset_controller_test.go @@ -1,10 +1,12 @@ package controllers import ( + "context" "encoding/json" - "errors" "fmt" + "reflect" "strconv" + "strings" "testing" "time" @@ -29,51 +31,18 @@ import ( "github.com/argoproj/gitops-engine/pkg/health" "github.com/argoproj/gitops-engine/pkg/sync/common" - "github.com/argoproj/argo-cd/v3/applicationset/generators" - "github.com/argoproj/argo-cd/v3/applicationset/generators/mocks" - appsetmetrics "github.com/argoproj/argo-cd/v3/applicationset/metrics" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - argocommon "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - applog "github.com/argoproj/argo-cd/v3/util/app/log" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/applicationset/generators" + "github.com/argoproj/argo-cd/v2/applicationset/generators/mocks" + "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" + dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) -// getDefaultTestClientSet creates a Clientset with the default argo objects -// and objects specified in parameters -func getDefaultTestClientSet(obj ...runtime.Object) *kubefake.Clientset { - argoCDSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: argocommon.ArgoCDSecretName, - Namespace: "argocd", - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string][]byte{ - "admin.password": nil, - "server.secretkey": nil, - }, - } - - emptyArgoCDConfigMap := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: argocommon.ArgoCDConfigMapName, - Namespace: "argocd", - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string]string{}, - } - - objects := append(obj, emptyArgoCDConfigMap, argoCDSecret) - kubeclientset := kubefake.NewClientset(objects...) - return kubeclientset -} - func TestCreateOrUpdateInCluster(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) @@ -1088,7 +1057,7 @@ func TestCreateOrUpdateInCluster(t *testing.T) { } client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -1097,12 +1066,12 @@ func TestCreateOrUpdateInCluster(t *testing.T) { Metrics: metrics, } - err = r.createOrUpdateInCluster(t.Context(), log.NewEntry(log.StandardLogger()), c.appSet, c.desiredApps) + err = r.createOrUpdateInCluster(context.TODO(), log.NewEntry(log.StandardLogger()), c.appSet, c.desiredApps) require.NoError(t, err) for _, obj := range c.expected { got := &v1alpha1.Application{} - _ = client.Get(t.Context(), crtclient.ObjectKey{ + _ = client.Get(context.Background(), crtclient.ObjectKey{ Namespace: obj.Namespace, Name: obj.Name, }, got) @@ -1196,9 +1165,7 @@ func TestRemoveFinalizerOnInvalidDestination_FinalizerTypes(t *testing.T) { objects := append([]runtime.Object{}, secret) kubeclientset := kubefake.NewSimpleClientset(objects...) - metrics := appsetmetrics.NewFakeAppsetMetrics() - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -1206,20 +1173,22 @@ func TestRemoveFinalizerOnInvalidDestination_FinalizerTypes(t *testing.T) { Recorder: record.NewFakeRecorder(10), KubeClientset: kubeclientset, Metrics: metrics, - ArgoDB: argodb, } - clusterList, err := utils.ListClusters(t.Context(), kubeclientset, "namespace") + // settingsMgr := settings.NewSettingsManager(context.TODO(), kubeclientset, "namespace") + // argoDB := db.NewDB("namespace", settingsMgr, r.KubeClientset) + // clusterList, err := argoDB.ListClusters(context.Background()) + clusterList, err := utils.ListClusters(context.Background(), kubeclientset, "namespace") require.NoError(t, err) - appLog := log.WithFields(applog.GetAppLogFields(&app)).WithField("appSet", "") + appLog := log.WithFields(log.Fields{"app": app.Name, "appSet": ""}) appInputParam := app.DeepCopy() - err = r.removeFinalizerOnInvalidDestination(t.Context(), appSet, appInputParam, clusterList, appLog) + err = r.removeFinalizerOnInvalidDestination(context.Background(), appSet, appInputParam, clusterList, appLog) require.NoError(t, err) retrievedApp := v1alpha1.Application{} - err = client.Get(t.Context(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) + err = client.Get(context.Background(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) require.NoError(t, err) // App on the cluster should have the expected finalizers @@ -1336,7 +1305,7 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) { secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "my-secret", - Namespace: "argocd", + Namespace: "namespace", Labels: map[string]string{ argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, @@ -1350,10 +1319,9 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) { }, } - kubeclientset := getDefaultTestClientSet(secret) - metrics := appsetmetrics.NewFakeAppsetMetrics() - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + objects := append([]runtime.Object{}, secret) + kubeclientset := kubefake.NewSimpleClientset(objects...) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -1361,21 +1329,22 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) { Recorder: record.NewFakeRecorder(10), KubeClientset: kubeclientset, Metrics: metrics, - ArgoDB: argodb, } - - clusterList, err := utils.ListClusters(t.Context(), kubeclientset, "argocd") + // settingsMgr := settings.NewSettingsManager(context.TODO(), kubeclientset, "argocd") + // argoDB := db.NewDB("argocd", settingsMgr, r.KubeClientset) + // clusterList, err := argoDB.ListClusters(context.Background()) + clusterList, err := utils.ListClusters(context.Background(), kubeclientset, "namespace") require.NoError(t, err) - appLog := log.WithFields(applog.GetAppLogFields(&app)).WithField("appSet", "") + appLog := log.WithFields(log.Fields{"app": app.Name, "appSet": ""}) appInputParam := app.DeepCopy() - err = r.removeFinalizerOnInvalidDestination(t.Context(), appSet, appInputParam, clusterList, appLog) + err = r.removeFinalizerOnInvalidDestination(context.Background(), appSet, appInputParam, clusterList, appLog) require.NoError(t, err) retrievedApp := v1alpha1.Application{} - err = client.Get(t.Context(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) + err = client.Get(context.Background(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) require.NoError(t, err) finalizerRemoved := len(retrievedApp.Finalizers) == 0 @@ -1438,7 +1407,7 @@ func TestRemoveOwnerReferencesOnDeleteAppSet(t *testing.T) { initObjs := []crtclient.Object{&app, &appSet} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -1448,11 +1417,11 @@ func TestRemoveOwnerReferencesOnDeleteAppSet(t *testing.T) { Metrics: metrics, } - err = r.removeOwnerReferencesOnDeleteAppSet(t.Context(), appSet) + err = r.removeOwnerReferencesOnDeleteAppSet(context.Background(), appSet) require.NoError(t, err) retrievedApp := v1alpha1.Application{} - err = client.Get(t.Context(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) + err = client.Get(context.Background(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) require.NoError(t, err) ownerReferencesRemoved := len(retrievedApp.OwnerReferences) == 0 @@ -1637,7 +1606,7 @@ func TestCreateApplications(t *testing.T) { } client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -1646,12 +1615,12 @@ func TestCreateApplications(t *testing.T) { Metrics: metrics, } - err = r.createInCluster(t.Context(), log.NewEntry(log.StandardLogger()), c.appSet, c.apps) + err = r.createInCluster(context.TODO(), log.NewEntry(log.StandardLogger()), c.appSet, c.apps) require.NoError(t, err) for _, obj := range c.expected { got := &v1alpha1.Application{} - _ = client.Get(t.Context(), crtclient.ObjectKey{ + _ = client.Get(context.Background(), crtclient.ObjectKey{ Namespace: obj.Namespace, Name: obj.Name, }, got) @@ -1779,7 +1748,7 @@ func TestDeleteInCluster(t *testing.T) { } client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -1789,13 +1758,13 @@ func TestDeleteInCluster(t *testing.T) { Metrics: metrics, } - err = r.deleteInCluster(t.Context(), log.NewEntry(log.StandardLogger()), c.appSet, c.desiredApps) + err = r.deleteInCluster(context.TODO(), log.NewEntry(log.StandardLogger()), c.appSet, c.desiredApps) require.NoError(t, err) // For each of the expected objects, verify they exist on the cluster for _, obj := range c.expected { got := &v1alpha1.Application{} - _ = client.Get(t.Context(), crtclient.ObjectKey{ + _ = client.Get(context.Background(), crtclient.ObjectKey{ Namespace: obj.Namespace, Name: obj.Name, }, got) @@ -1809,7 +1778,7 @@ func TestDeleteInCluster(t *testing.T) { // Verify each of the unexpected objs cannot be found for _, obj := range c.notExpected { got := &v1alpha1.Application{} - err := client.Get(t.Context(), crtclient.ObjectKey{ + err := client.Get(context.Background(), crtclient.ObjectKey{ Namespace: obj.Namespace, Name: obj.Name, }, got) @@ -1825,7 +1794,7 @@ func TestGetMinRequeueAfter(t *testing.T) { require.NoError(t, err) client := fake.NewClientBuilder().WithScheme(scheme).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) generator := v1alpha1.ApplicationSetGenerator{ List: &v1alpha1.ListGenerator{}, @@ -1894,9 +1863,9 @@ func TestRequeueGeneratorFails(t *testing.T) { generatorMock.On("GetTemplate", &generator). Return(&v1alpha1.ApplicationSetTemplate{}) generatorMock.On("GenerateParams", &generator, mock.AnythingOfType("*v1alpha1.ApplicationSet"), mock.Anything). - Return([]map[string]any{}, errors.New("Simulated error generating params that could be related to an external service/API call")) + Return([]map[string]interface{}{}, fmt.Errorf("Simulated error generating params that could be related to an external service/API call")) - metrics := appsetmetrics.NewFakeAppsetMetrics() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -1915,14 +1884,12 @@ func TestRequeueGeneratorFails(t *testing.T) { }, } - res, err := r.Reconcile(t.Context(), req) + res, err := r.Reconcile(context.Background(), req) require.NoError(t, err) assert.Equal(t, ReconcileRequeueOnValidationError, res.RequeueAfter) } func TestValidateGeneratedApplications(t *testing.T) { - t.Parallel() - scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) @@ -1948,12 +1915,13 @@ func TestValidateGeneratedApplications(t *testing.T) { } client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(myProject).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) // Test a subset of the validations that 'validateGeneratedApplications' performs for _, cc := range []struct { name string apps []v1alpha1.Application + expectedErrors []string validationErrors map[int]error }{ { @@ -1976,6 +1944,7 @@ func TestValidateGeneratedApplications(t *testing.T) { }, }, }, + expectedErrors: []string{}, validationErrors: map[int]error{}, }, { @@ -1999,7 +1968,8 @@ func TestValidateGeneratedApplications(t *testing.T) { }, }, }, - validationErrors: map[int]error{0: errors.New("application destination spec is invalid: application destination can't have both name and server defined: my-cluster my-server")}, + expectedErrors: []string{"application destination can't have both name and server defined"}, + validationErrors: map[int]error{0: fmt.Errorf("application destination spec is invalid: application destination can't have both name and server defined: my-cluster my-server")}, }, { name: "project mismatch should return error", @@ -2021,7 +1991,8 @@ func TestValidateGeneratedApplications(t *testing.T) { }, }, }, - validationErrors: map[int]error{0: errors.New("application references project DOES-NOT-EXIST which does not exist")}, + expectedErrors: []string{"application references project DOES-NOT-EXIST which does not exist"}, + validationErrors: map[int]error{0: fmt.Errorf("application references project DOES-NOT-EXIST which does not exist")}, }, { name: "valid app should return true", @@ -2043,6 +2014,7 @@ func TestValidateGeneratedApplications(t *testing.T) { }, }, }, + expectedErrors: []string{}, validationErrors: map[int]error{}, }, { @@ -2065,16 +2037,15 @@ func TestValidateGeneratedApplications(t *testing.T) { }, }, }, - validationErrors: map[int]error{0: errors.New("application destination spec is invalid: there are no clusters with this name: nonexistent-cluster")}, + expectedErrors: []string{"there are no clusters with this name: nonexistent-cluster"}, + validationErrors: map[int]error{0: fmt.Errorf("application destination spec is invalid: unable to find destination server: there are no clusters with this name: nonexistent-cluster")}, }, } { t.Run(cc.name, func(t *testing.T) { - t.Parallel() - secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "my-secret", - Namespace: "argocd", + Namespace: "namespace", Labels: map[string]string{ argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, @@ -2086,24 +2057,51 @@ func TestValidateGeneratedApplications(t *testing.T) { }, } - kubeclientset := getDefaultTestClientSet(secret) - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + objects := append([]runtime.Object{}, secret) + kubeclientset := kubefake.NewSimpleClientset(objects...) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), Generators: map[string]generators.Generator{}, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, ArgoCDNamespace: "namespace", KubeClientset: kubeclientset, Metrics: metrics, } appSetInfo := v1alpha1.ApplicationSet{} - validationErrors, _ := r.validateGeneratedApplications(t.Context(), cc.apps, appSetInfo) - assert.Equal(t, cc.validationErrors, validationErrors) + + validationErrors, _ := r.validateGeneratedApplications(context.TODO(), cc.apps, appSetInfo) + var errorMessages []string + for _, v := range validationErrors { + errorMessages = append(errorMessages, v.Error()) + } + + if len(errorMessages) == 0 { + assert.Empty(t, cc.expectedErrors, "Expected errors but none were seen") + } else { + // An error was returned: it should be expected + matched := false + for _, expectedErr := range cc.expectedErrors { + foundMatch := strings.Contains(strings.Join(errorMessages, ";"), expectedErr) + assert.True(t, foundMatch, "Unble to locate expected error: %s", cc.expectedErrors) + matched = matched || foundMatch + } + assert.True(t, matched, "An unexpected error occurrred: %v", err) + // validation message was returned: it should be expected + matched = false + foundMatch := reflect.DeepEqual(validationErrors, cc.validationErrors) + var message string + for _, v := range validationErrors { + message = v.Error() + break + } + assert.True(t, foundMatch, "Unble to locate validation message: %s", message) + matched = matched || foundMatch + assert.True(t, matched, "An unexpected error occurrred: %v", err) + } }) } } @@ -2148,12 +2146,10 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) { }, } - kubeclientset := getDefaultTestClientSet() + kubeclientset := kubefake.NewSimpleClientset() client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &project).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -2163,7 +2159,7 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) { Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, KubeClientset: kubeclientset, Policy: v1alpha1.ApplicationsSyncPolicySync, ArgoCDNamespace: "argocd", @@ -2178,19 +2174,19 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) { } // Verify that on validation error, no error is returned, but the object is requeued - res, err := r.Reconcile(t.Context(), req) + res, err := r.Reconcile(context.Background(), req) require.NoError(t, err) assert.Equal(t, ReconcileRequeueOnValidationError, res.RequeueAfter) var app v1alpha1.Application // make sure good app got created - err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "good-project"}, &app) + err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "good-project"}, &app) require.NoError(t, err) assert.Equal(t, "good-project", app.Name) // make sure bad app was not created - err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "bad-project"}, &app) + err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "bad-project"}, &app) require.Error(t, err) } @@ -2350,9 +2346,7 @@ func TestSetApplicationSetStatusCondition(t *testing.T) { for _, testCase := range testCases { client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&testCase.appset).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).WithStatusSubresource(&testCase.appset).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -2362,13 +2356,13 @@ func TestSetApplicationSetStatusCondition(t *testing.T) { Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, KubeClientset: kubeclientset, Metrics: metrics, } for _, condition := range testCase.conditions { - err = r.setApplicationSetStatusCondition(t.Context(), &testCase.appset, condition, true) + err = r.setApplicationSetStatusCondition(context.TODO(), &testCase.appset, condition, true) require.NoError(t, err) } @@ -2435,12 +2429,11 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp }, } - kubeclientset := getDefaultTestClientSet(secret) + objects := append([]runtime.Object{}, secret) + kubeclientset := kubefake.NewSimpleClientset(objects...) client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &defaultProject).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -2450,7 +2443,7 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, ArgoCDNamespace: "argocd", KubeClientset: kubeclientset, Policy: v1alpha1.ApplicationsSyncPolicySync, @@ -2466,20 +2459,20 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp } // Verify that on validation error, no error is returned, but the object is requeued - resCreate, err := r.Reconcile(t.Context(), req) - require.NoErrorf(t, err, "Reconcile failed with error: %v", err) + resCreate, err := r.Reconcile(context.Background(), req) + require.NoError(t, err) assert.Equal(t, time.Duration(0), resCreate.RequeueAfter) var app v1alpha1.Application // make sure good app got created - err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "good-cluster"}, &app) + err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "good-cluster"}, &app) require.NoError(t, err) assert.Equal(t, "good-cluster", app.Name) // Update resource var retrievedApplicationSet v1alpha1.ApplicationSet - err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "name"}, &retrievedApplicationSet) + err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "name"}, &retrievedApplicationSet) require.NoError(t, err) retrievedApplicationSet.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} @@ -2489,13 +2482,13 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp Values: "global.test: test", } - err = r.Update(t.Context(), &retrievedApplicationSet) + err = r.Client.Update(context.TODO(), &retrievedApplicationSet) require.NoError(t, err) - resUpdate, err := r.Reconcile(t.Context(), req) + resUpdate, err := r.Reconcile(context.Background(), req) require.NoError(t, err) - err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "good-cluster"}, &app) + err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "good-cluster"}, &app) require.NoError(t, err) assert.Equal(t, time.Duration(0), resUpdate.RequeueAfter) assert.Equal(t, "good-cluster", app.Name) @@ -2509,7 +2502,7 @@ func TestUpdateNotPerformedWithSyncPolicyCreateOnly(t *testing.T) { app := applicationsUpdateSyncPolicyTest(t, applicationsSyncPolicy, 1, true) assert.Nil(t, app.Spec.Source.Helm) - assert.Nil(t, app.Annotations) + assert.Nil(t, app.ObjectMeta.Annotations) } func TestUpdateNotPerformedWithSyncPolicyCreateDelete(t *testing.T) { @@ -2518,7 +2511,7 @@ func TestUpdateNotPerformedWithSyncPolicyCreateDelete(t *testing.T) { app := applicationsUpdateSyncPolicyTest(t, applicationsSyncPolicy, 1, true) assert.Nil(t, app.Spec.Source.Helm) - assert.Nil(t, app.Annotations) + assert.Nil(t, app.ObjectMeta.Annotations) } func TestUpdatePerformedWithSyncPolicyCreateUpdate(t *testing.T) { @@ -2527,8 +2520,8 @@ func TestUpdatePerformedWithSyncPolicyCreateUpdate(t *testing.T) { app := applicationsUpdateSyncPolicyTest(t, applicationsSyncPolicy, 2, true) assert.Equal(t, "global.test: test", app.Spec.Source.Helm.Values) - assert.Equal(t, map[string]string{"annotation-key": "annotation-value"}, app.Annotations) - assert.Equal(t, map[string]string{"label-key": "label-value"}, app.Labels) + assert.Equal(t, map[string]string{"annotation-key": "annotation-value"}, app.ObjectMeta.Annotations) + assert.Equal(t, map[string]string{"label-key": "label-value"}, app.ObjectMeta.Labels) } func TestUpdatePerformedWithSyncPolicySync(t *testing.T) { @@ -2537,8 +2530,8 @@ func TestUpdatePerformedWithSyncPolicySync(t *testing.T) { app := applicationsUpdateSyncPolicyTest(t, applicationsSyncPolicy, 2, true) assert.Equal(t, "global.test: test", app.Spec.Source.Helm.Values) - assert.Equal(t, map[string]string{"annotation-key": "annotation-value"}, app.Annotations) - assert.Equal(t, map[string]string{"label-key": "label-value"}, app.Labels) + assert.Equal(t, map[string]string{"annotation-key": "annotation-value"}, app.ObjectMeta.Annotations) + assert.Equal(t, map[string]string{"label-key": "label-value"}, app.ObjectMeta.Labels) } func TestUpdatePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *testing.T) { @@ -2547,8 +2540,8 @@ func TestUpdatePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *t app := applicationsUpdateSyncPolicyTest(t, applicationsSyncPolicy, 2, false) assert.Equal(t, "global.test: test", app.Spec.Source.Helm.Values) - assert.Equal(t, map[string]string{"annotation-key": "annotation-value"}, app.Annotations) - assert.Equal(t, map[string]string{"label-key": "label-value"}, app.Labels) + assert.Equal(t, map[string]string{"annotation-key": "annotation-value"}, app.ObjectMeta.Annotations) + assert.Equal(t, map[string]string{"label-key": "label-value"}, app.ObjectMeta.Labels) } func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alpha1.ApplicationsSyncPolicy, recordBuffer int, allowPolicyOverride bool) v1alpha1.ApplicationList { @@ -2610,12 +2603,11 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp }, } - kubeclientset := getDefaultTestClientSet(secret) + objects := append([]runtime.Object{}, secret) + kubeclientset := kubefake.NewSimpleClientset(objects...) client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &defaultProject).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -2625,7 +2617,7 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, ArgoCDNamespace: "argocd", KubeClientset: kubeclientset, Policy: v1alpha1.ApplicationsSyncPolicySync, @@ -2641,20 +2633,20 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp } // Verify that on validation error, no error is returned, but the object is requeued - resCreate, err := r.Reconcile(t.Context(), req) + resCreate, err := r.Reconcile(context.Background(), req) require.NoError(t, err) assert.Equal(t, time.Duration(0), resCreate.RequeueAfter) var app v1alpha1.Application // make sure good app got created - err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "good-cluster"}, &app) + err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "good-cluster"}, &app) require.NoError(t, err) assert.Equal(t, "good-cluster", app.Name) // Update resource var retrievedApplicationSet v1alpha1.ApplicationSet - err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "name"}, &retrievedApplicationSet) + err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "name"}, &retrievedApplicationSet) require.NoError(t, err) retrievedApplicationSet.Spec.Generators = []v1alpha1.ApplicationSetGenerator{ { @@ -2664,15 +2656,15 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp }, } - err = r.Update(t.Context(), &retrievedApplicationSet) + err = r.Client.Update(context.TODO(), &retrievedApplicationSet) require.NoError(t, err) - resUpdate, err := r.Reconcile(t.Context(), req) + resUpdate, err := r.Reconcile(context.Background(), req) require.NoError(t, err) var apps v1alpha1.ApplicationList - err = r.List(t.Context(), &apps) + err = r.Client.List(context.TODO(), &apps) require.NoError(t, err) assert.Equal(t, time.Duration(0), resUpdate.RequeueAfter) @@ -2729,7 +2721,7 @@ func TestPolicies(t *testing.T) { Spec: v1alpha1.AppProjectSpec{SourceRepos: []string{"*"}, Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "https://kubernetes.default.svc"}}}, } - kubeclientset := getDefaultTestClientSet() + kubeclientset := kubefake.NewSimpleClientset() for _, c := range []struct { name string @@ -2802,9 +2794,7 @@ func TestPolicies(t *testing.T) { } client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &defaultProject).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -2814,7 +2804,7 @@ func TestPolicies(t *testing.T) { Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, ArgoCDNamespace: "argocd", KubeClientset: kubeclientset, Policy: policy, @@ -2829,25 +2819,25 @@ func TestPolicies(t *testing.T) { } // Check if Application is created - res, err := r.Reconcile(t.Context(), req) + res, err := r.Reconcile(context.Background(), req) require.NoError(t, err) assert.Equal(t, time.Duration(0), res.RequeueAfter) var app v1alpha1.Application - err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "my-app"}, &app) + err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "my-app"}, &app) require.NoError(t, err) assert.Equal(t, "value", app.Annotations["key"]) // Check if Application is updated app.Annotations["key"] = "edited" - err = r.Update(t.Context(), &app) + err = r.Client.Update(context.TODO(), &app) require.NoError(t, err) - res, err = r.Reconcile(t.Context(), req) + res, err = r.Reconcile(context.Background(), req) require.NoError(t, err) assert.Equal(t, time.Duration(0), res.RequeueAfter) - err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "my-app"}, &app) + err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "my-app"}, &app) require.NoError(t, err) if c.allowedUpdate { @@ -2857,21 +2847,21 @@ func TestPolicies(t *testing.T) { } // Check if Application is deleted - err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "name"}, &appSet) + err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "name"}, &appSet) require.NoError(t, err) appSet.Spec.Generators[0] = v1alpha1.ApplicationSetGenerator{ List: &v1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{}, }, } - err = r.Update(t.Context(), &appSet) + err = r.Client.Update(context.TODO(), &appSet) require.NoError(t, err) - res, err = r.Reconcile(t.Context(), req) + res, err = r.Reconcile(context.Background(), req) require.NoError(t, err) assert.Equal(t, time.Duration(0), res.RequeueAfter) - err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "my-app"}, &app) + err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "my-app"}, &app) require.NoError(t, err) if c.allowedDelete { assert.NotNil(t, app.DeletionTimestamp) @@ -2961,9 +2951,7 @@ func TestSetApplicationSetApplicationStatus(t *testing.T) { } { t.Run(cc.name, func(t *testing.T) { client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&cc.appSet).WithStatusSubresource(&cc.appSet).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, @@ -2973,12 +2961,12 @@ func TestSetApplicationSetApplicationStatus(t *testing.T) { Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, KubeClientset: kubeclientset, Metrics: metrics, } - err = r.setAppSetApplicationStatus(t.Context(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appStatuses) + err = r.setAppSetApplicationStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appStatuses) require.NoError(t, err) assert.Equal(t, cc.expectedAppStatuses, cc.appSet.Status.ApplicationStatus) @@ -2992,7 +2980,7 @@ func TestBuildAppDependencyList(t *testing.T) { require.NoError(t, err) client := fake.NewClientBuilder().WithScheme(scheme).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) for _, cc := range []struct { name string @@ -3723,14 +3711,12 @@ func TestBuildAppDependencyList(t *testing.T) { t.Run(cc.name, func(t *testing.T) { kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) - r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), Generators: map[string]generators.Generator{}, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, KubeClientset: kubeclientset, Metrics: metrics, } @@ -3748,7 +3734,7 @@ func TestBuildAppSyncMap(t *testing.T) { require.NoError(t, err) client := fake.NewClientBuilder().WithScheme(scheme).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) for _, cc := range []struct { name string @@ -3888,7 +3874,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -3904,7 +3890,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app2", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -3966,7 +3952,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -3982,7 +3968,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app2", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4044,7 +4030,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4060,7 +4046,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app2", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4122,7 +4108,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusDegraded, }, OperationState: &v1alpha1.OperationState{ @@ -4138,7 +4124,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app2", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusDegraded, }, OperationState: &v1alpha1.OperationState{ @@ -4204,7 +4190,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4220,7 +4206,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app2", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4294,7 +4280,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4310,7 +4296,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app2", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4326,7 +4312,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app3", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4342,7 +4328,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app5", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4358,7 +4344,7 @@ func TestBuildAppSyncMap(t *testing.T) { Name: "app6", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusDegraded, }, OperationState: &v1alpha1.OperationState{ @@ -4391,14 +4377,12 @@ func TestBuildAppSyncMap(t *testing.T) { t.Run(cc.name, func(t *testing.T) { kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) - r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), Generators: map[string]generators.Generator{}, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, KubeClientset: kubeclientset, Metrics: metrics, } @@ -4476,7 +4460,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4531,7 +4515,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4595,7 +4579,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4746,7 +4730,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusProgressing, }, Sync: v1alpha1.SyncStatus{ @@ -4808,7 +4792,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4874,7 +4858,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4940,7 +4924,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -4995,7 +4979,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -5068,7 +5052,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusDegraded, }, OperationState: &v1alpha1.OperationState{ @@ -5149,7 +5133,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusDegraded, }, OperationState: &v1alpha1.OperationState{ @@ -5234,7 +5218,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -5300,7 +5284,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Name: "app1", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: health.HealthStatusHealthy, }, OperationState: &v1alpha1.OperationState{ @@ -5334,21 +5318,19 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&cc.appSet).WithStatusSubresource(&cc.appSet).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), Generators: map[string]generators.Generator{}, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, KubeClientset: kubeclientset, Metrics: metrics, } - appStatuses, err := r.updateApplicationSetApplicationStatus(t.Context(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps, cc.appStepMap) + appStatuses, err := r.updateApplicationSetApplicationStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps, cc.appStepMap) // opt out of testing the LastTransitionTime is accurate for i := range appStatuses { @@ -6084,21 +6066,19 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) { kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&cc.appSet).WithStatusSubresource(&cc.appSet).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), Generators: map[string]generators.Generator{}, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, KubeClientset: kubeclientset, Metrics: metrics, } - appStatuses, err := r.updateApplicationSetApplicationStatusProgress(t.Context(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appSyncMap, cc.appStepMap) + appStatuses, err := r.updateApplicationSetApplicationStatusProgress(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appSyncMap, cc.appStepMap) // opt out of testing the LastTransitionTime is accurate for i := range appStatuses { @@ -6156,8 +6136,9 @@ func TestUpdateResourceStatus(t *testing.T) { Sync: v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeSynced, }, - Health: v1alpha1.AppHealthStatus{ - Status: health.HealthStatusHealthy, + Health: v1alpha1.HealthStatus{ + Status: health.HealthStatusHealthy, + Message: "OK", }, }, }, @@ -6167,7 +6148,8 @@ func TestUpdateResourceStatus(t *testing.T) { Name: "app1", Status: v1alpha1.SyncStatusCodeSynced, Health: &v1alpha1.HealthStatus{ - Status: health.HealthStatusHealthy, + Status: health.HealthStatusHealthy, + Message: "OK", }, }, }, @@ -6185,7 +6167,8 @@ func TestUpdateResourceStatus(t *testing.T) { Name: "app1", Status: v1alpha1.SyncStatusCodeSynced, Health: &v1alpha1.HealthStatus{ - Status: health.HealthStatusHealthy, + Status: health.HealthStatusHealthy, + Message: "OK", }, }, }, @@ -6200,8 +6183,9 @@ func TestUpdateResourceStatus(t *testing.T) { Sync: v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeSynced, }, - Health: v1alpha1.AppHealthStatus{ - Status: health.HealthStatusHealthy, + Health: v1alpha1.HealthStatus{ + Status: health.HealthStatusHealthy, + Message: "OK", }, }, }, @@ -6211,7 +6195,8 @@ func TestUpdateResourceStatus(t *testing.T) { Name: "app1", Status: v1alpha1.SyncStatusCodeSynced, Health: &v1alpha1.HealthStatus{ - Status: health.HealthStatusHealthy, + Status: health.HealthStatusHealthy, + Message: "OK", }, }, }, @@ -6245,8 +6230,9 @@ func TestUpdateResourceStatus(t *testing.T) { Sync: v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeSynced, }, - Health: v1alpha1.AppHealthStatus{ - Status: health.HealthStatusHealthy, + Health: v1alpha1.HealthStatus{ + Status: health.HealthStatusHealthy, + Message: "OK", }, }, }, @@ -6256,7 +6242,8 @@ func TestUpdateResourceStatus(t *testing.T) { Name: "app1", Status: v1alpha1.SyncStatusCodeSynced, Health: &v1alpha1.HealthStatus{ - Status: health.HealthStatusHealthy, + Status: health.HealthStatusHealthy, + Message: "OK", }, }, }, @@ -6289,21 +6276,19 @@ func TestUpdateResourceStatus(t *testing.T) { kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) client := fake.NewClientBuilder().WithScheme(scheme).WithStatusSubresource(&cc.appSet).WithObjects(&cc.appSet).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), Generators: map[string]generators.Generator{}, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, KubeClientset: kubeclientset, Metrics: metrics, } - err := r.updateResourcesStatus(t.Context(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) + err := r.updateResourcesStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) require.NoError(t, err, "expected no errors, but errors occurred") assert.Equal(t, cc.expectedResources, cc.appSet.Status.Resources, "expected resources did not match actual") @@ -6318,7 +6303,8 @@ func generateNAppResourceStatuses(n int) []v1alpha1.ResourceStatus { Name: "app" + strconv.Itoa(i), Status: v1alpha1.SyncStatusCodeSynced, Health: &v1alpha1.HealthStatus{ - Status: health.HealthStatusHealthy, + Status: health.HealthStatusHealthy, + Message: "OK", }, }, ) @@ -6337,8 +6323,9 @@ func generateNHealthyApps(n int) []v1alpha1.Application { Sync: v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeSynced, }, - Health: v1alpha1.AppHealthStatus{ - Status: health.HealthStatusHealthy, + Health: v1alpha1.HealthStatus{ + Status: health.HealthStatusHealthy, + Message: "OK", }, }, }) @@ -6378,27 +6365,25 @@ func TestResourceStatusAreOrdered(t *testing.T) { kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) client := fake.NewClientBuilder().WithScheme(scheme).WithStatusSubresource(&cc.appSet).WithObjects(&cc.appSet).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() - - argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), Generators: map[string]generators.Generator{}, - ArgoDB: argodb, + ArgoDB: &dbmocks.ArgoDB{}, KubeClientset: kubeclientset, Metrics: metrics, } - err := r.updateResourcesStatus(t.Context(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) + err := r.updateResourcesStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) require.NoError(t, err, "expected no errors, but errors occurred") - err = r.updateResourcesStatus(t.Context(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) + err = r.updateResourcesStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) require.NoError(t, err, "expected no errors, but errors occurred") - err = r.updateResourcesStatus(t.Context(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) + err = r.updateResourcesStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) require.NoError(t, err, "expected no errors, but errors occurred") assert.Equal(t, cc.expectedResources, cc.appSet.Status.Resources, "expected resources did not match actual") @@ -6406,7 +6391,7 @@ func TestResourceStatusAreOrdered(t *testing.T) { } } -func TestApplicationOwnsHandler(t *testing.T) { +func TestOwnsHandler(t *testing.T) { // progressive syncs do not affect create, delete, or generic ownsHandler := getApplicationOwnsHandler(true) assert.False(t, ownsHandler.CreateFunc(event.CreateEvent{})) @@ -6442,12 +6427,12 @@ func TestApplicationOwnsHandler(t *testing.T) { {name: "ApplicationHealthStatusDiff", args: args{ e: event.UpdateEvent{ ObjectOld: &v1alpha1.Application{Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: "Unknown", }, }}, ObjectNew: &v1alpha1.Application{Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: "Healthy", }, }}, @@ -6662,7 +6647,7 @@ func TestMigrateStatus(t *testing.T) { Client: client, } - err := r.migrateStatus(t.Context(), &tc.appset) + err := r.migrateStatus(context.Background(), &tc.appset) require.NoError(t, err) assert.Equal(t, tc.expectedStatus, tc.appset.Status) }) diff --git a/applicationset/controllers/clustereventhandler.go b/applicationset/controllers/clustereventhandler.go index dd71e9b8c7..363fc03f16 100644 --- a/applicationset/controllers/clustereventhandler.go +++ b/applicationset/controllers/clustereventhandler.go @@ -14,8 +14,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" - "github.com/argoproj/argo-cd/v3/common" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/common" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) // clusterSecretEventHandler is used when watching Secrets to check if they are ArgoCD Cluster Secrets, and if so diff --git a/applicationset/controllers/clustereventhandler_test.go b/applicationset/controllers/clustereventhandler_test.go index 02b17551f6..8af4b1c17d 100644 --- a/applicationset/controllers/clustereventhandler_test.go +++ b/applicationset/controllers/clustereventhandler_test.go @@ -1,23 +1,24 @@ package controllers import ( + "context" "testing" - argocommon "github.com/argoproj/argo-cd/v3/common" + argocommon "github.com/argoproj/argo-cd/v2/common" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/reconcile" - argov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestClusterEventHandler(t *testing.T) { @@ -38,7 +39,7 @@ func TestClusterEventHandler(t *testing.T) { name: "no application sets should mean no requests", items: []argov1alpha1.ApplicationSet{}, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ @@ -52,7 +53,7 @@ func TestClusterEventHandler(t *testing.T) { name: "a cluster generator should produce a request", items: []argov1alpha1.ApplicationSet{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set", Namespace: "argocd", }, @@ -66,7 +67,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ @@ -82,7 +83,7 @@ func TestClusterEventHandler(t *testing.T) { name: "multiple cluster generators should produce multiple requests", items: []argov1alpha1.ApplicationSet{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set", Namespace: "argocd", }, @@ -95,7 +96,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set2", Namespace: "argocd", }, @@ -109,7 +110,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ @@ -126,7 +127,7 @@ func TestClusterEventHandler(t *testing.T) { name: "non-cluster generator should not match", items: []argov1alpha1.ApplicationSet{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set", Namespace: "another-namespace", }, @@ -139,7 +140,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "app-set-non-cluster", Namespace: "argocd", }, @@ -153,7 +154,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ @@ -169,7 +170,7 @@ func TestClusterEventHandler(t *testing.T) { name: "non-argo cd secret should not match", items: []argov1alpha1.ApplicationSet{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set", Namespace: "another-namespace", }, @@ -183,7 +184,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-non-argocd-secret", }, @@ -194,7 +195,7 @@ func TestClusterEventHandler(t *testing.T) { name: "a matrix generator with a cluster generator should produce a request", items: []argov1alpha1.ApplicationSet{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set", Namespace: "argocd", }, @@ -214,7 +215,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ @@ -230,7 +231,7 @@ func TestClusterEventHandler(t *testing.T) { name: "a matrix generator with non cluster generator should not match", items: []argov1alpha1.ApplicationSet{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set", Namespace: "argocd", }, @@ -250,7 +251,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ @@ -264,7 +265,7 @@ func TestClusterEventHandler(t *testing.T) { name: "a matrix generator with a nested matrix generator containing a cluster generator should produce a request", items: []argov1alpha1.ApplicationSet{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set", Namespace: "argocd", }, @@ -300,7 +301,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ @@ -316,7 +317,7 @@ func TestClusterEventHandler(t *testing.T) { name: "a matrix generator with a nested matrix generator containing non cluster generator should not match", items: []argov1alpha1.ApplicationSet{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set", Namespace: "argocd", }, @@ -351,7 +352,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ @@ -365,7 +366,7 @@ func TestClusterEventHandler(t *testing.T) { name: "a merge generator with a cluster generator should produce a request", items: []argov1alpha1.ApplicationSet{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set", Namespace: "argocd", }, @@ -385,7 +386,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ @@ -401,7 +402,7 @@ func TestClusterEventHandler(t *testing.T) { name: "a matrix generator with non cluster generator should not match", items: []argov1alpha1.ApplicationSet{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set", Namespace: "argocd", }, @@ -421,7 +422,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ @@ -435,7 +436,7 @@ func TestClusterEventHandler(t *testing.T) { name: "a merge generator with a nested merge generator containing a cluster generator should produce a request", items: []argov1alpha1.ApplicationSet{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set", Namespace: "argocd", }, @@ -471,7 +472,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ @@ -487,7 +488,7 @@ func TestClusterEventHandler(t *testing.T) { name: "a merge generator with a nested merge generator containing non cluster generator should not match", items: []argov1alpha1.ApplicationSet{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "my-app-set", Namespace: "argocd", }, @@ -522,7 +523,7 @@ func TestClusterEventHandler(t *testing.T) { }, }, secret: corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ @@ -549,7 +550,7 @@ func TestClusterEventHandler(t *testing.T) { mockAddRateLimitingInterface := mockAddRateLimitingInterface{} - handler.queueRelatedAppGenerators(t.Context(), &mockAddRateLimitingInterface, &test.secret) + handler.queueRelatedAppGenerators(context.Background(), &mockAddRateLimitingInterface, &test.secret) assert.ElementsMatch(t, mockAddRateLimitingInterface.addedItems, test.expectedRequests) }) diff --git a/applicationset/controllers/requeue_after_test.go b/applicationset/controllers/requeue_after_test.go index 5a2e033973..c0c039b88f 100644 --- a/applicationset/controllers/requeue_after_test.go +++ b/applicationset/controllers/requeue_after_test.go @@ -1,6 +1,7 @@ package controllers import ( + "context" "testing" "time" @@ -15,15 +16,15 @@ import ( "k8s.io/client-go/tools/record" "sigs.k8s.io/controller-runtime/pkg/client/fake" - "github.com/argoproj/argo-cd/v3/applicationset/generators" - appsetmetrics "github.com/argoproj/argo-cd/v3/applicationset/metrics" - "github.com/argoproj/argo-cd/v3/applicationset/services/mocks" - argov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/generators" + appsetmetrics "github.com/argoproj/argo-cd/v2/applicationset/metrics" + "github.com/argoproj/argo-cd/v2/applicationset/services/mocks" + argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestRequeueAfter(t *testing.T) { mockServer := &mocks.Repos{} - ctx := t.Context() + ctx := context.Background() scheme := runtime.NewScheme() err := argov1alpha1.AddToScheme(scheme) require.NoError(t, err) @@ -35,20 +36,20 @@ func TestRequeueAfter(t *testing.T) { appClientset := kubefake.NewSimpleClientset() k8sClient := fake.NewClientBuilder().Build() duckType := &unstructured.Unstructured{ - Object: map[string]any{ + Object: map[string]interface{}{ "apiVersion": "v2quack", "kind": "Duck", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "name": "mightyduck", "namespace": "namespace", - "labels": map[string]any{"duck": "all-species"}, + "labels": map[string]interface{}{"duck": "all-species"}, }, - "status": map[string]any{ - "decisions": []any{ - map[string]any{ + "status": map[string]interface{}{ + "decisions": []interface{}{ + map[string]interface{}{ "clusterName": "staging-01", }, - map[string]any{ + map[string]interface{}{ "clusterName": "production-01", }, }, @@ -59,7 +60,7 @@ func TestRequeueAfter(t *testing.T) { scmConfig := generators.NewSCMConfig("", []string{""}, true, nil, true) terminalGenerators := map[string]generators.Generator{ "List": generators.NewListGenerator(), - "Clusters": generators.NewClusterGenerator(ctx, k8sClient, appClientset, "argocd"), + "Clusters": generators.NewClusterGenerator(k8sClient, ctx, appClientset, "argocd"), "Git": generators.NewGitGenerator(mockServer, "namespace"), "SCMProvider": generators.NewSCMProviderGenerator(fake.NewClientBuilder().WithObjects(&corev1.Secret{}).Build(), scmConfig), "ClusterDecisionResource": generators.NewDuckTypeGenerator(ctx, fakeDynClient, appClientset, "argocd"), @@ -89,7 +90,7 @@ func TestRequeueAfter(t *testing.T) { } client := fake.NewClientBuilder().WithScheme(scheme).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, @@ -129,7 +130,7 @@ func TestRequeueAfter(t *testing.T) { }}, }, }, - }, ""}, want: generators.DefaultRequeueAfter, wantErr: assert.NoError}, + }, ""}, want: generators.DefaultRequeueAfterSeconds, wantErr: assert.NoError}, {name: "ClusterMatrixNested", args: args{&argov1alpha1.ApplicationSet{ Spec: argov1alpha1.ApplicationSetSpec{ Generators: []argov1alpha1.ApplicationSetGenerator{ @@ -144,7 +145,7 @@ func TestRequeueAfter(t *testing.T) { }}, }, }, - }, ""}, want: generators.DefaultRequeueAfter, 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{}}}, @@ -154,7 +155,7 @@ func TestRequeueAfter(t *testing.T) { Spec: argov1alpha1.ApplicationSetSpec{ Generators: []argov1alpha1.ApplicationSetGenerator{{ClusterDecisionResource: &argov1alpha1.DuckTypeGenerator{}}}, }, - }}, want: generators.DefaultRequeueAfter, wantErr: assert.NoError}, + }}, want: generators.DefaultRequeueAfterSeconds, wantErr: assert.NoError}, {name: "OverrideRequeueDuck", args: args{ appset: &argov1alpha1.ApplicationSet{ Spec: argov1alpha1.ApplicationSetSpec{ diff --git a/applicationset/controllers/template/patch.go b/applicationset/controllers/template/patch.go index 0449815dbe..b9d1166f1f 100644 --- a/applicationset/controllers/template/patch.go +++ b/applicationset/controllers/template/patch.go @@ -6,8 +6,8 @@ import ( "k8s.io/apimachinery/pkg/util/strategicpatch" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func applyTemplatePatch(app *appv1.Application, templatePatch string) (*appv1.Application, error) { diff --git a/applicationset/controllers/template/patch_test.go b/applicationset/controllers/template/patch_test.go index 35c88fe650..456fe44599 100644 --- a/applicationset/controllers/template/patch_test.go +++ b/applicationset/controllers/template/patch_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func Test_ApplyTemplatePatch(t *testing.T) { diff --git a/applicationset/controllers/template/template.go b/applicationset/controllers/template/template.go index 4706402cb5..616b7ef9a7 100644 --- a/applicationset/controllers/template/template.go +++ b/applicationset/controllers/template/template.go @@ -7,10 +7,10 @@ import ( log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/applicationset/generators" - "github.com/argoproj/argo-cd/v3/applicationset/utils" + "github.com/argoproj/argo-cd/v2/applicationset/generators" + "github.com/argoproj/argo-cd/v2/applicationset/utils" - argov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func GenerateApplications(logCtx *log.Entry, applicationSetInfo argov1alpha1.ApplicationSet, g map[string]generators.Generator, renderer utils.Renderer, client client.Client) ([]argov1alpha1.Application, argov1alpha1.ApplicationSetReasonType, error) { @@ -20,7 +20,7 @@ func GenerateApplications(logCtx *log.Entry, applicationSetInfo argov1alpha1.App var applicationSetReason argov1alpha1.ApplicationSetReasonType for _, requestedGenerator := range applicationSetInfo.Spec.Generators { - t, err := generators.Transform(requestedGenerator, g, applicationSetInfo.Spec.Template, &applicationSetInfo, map[string]any{}, client) + t, err := generators.Transform(requestedGenerator, g, applicationSetInfo.Spec.Template, &applicationSetInfo, map[string]interface{}{}, client) if err != nil { logCtx.WithError(err).WithField("generator", requestedGenerator). Error("error generating application from params") @@ -79,7 +79,7 @@ func GenerateApplications(logCtx *log.Entry, applicationSetInfo argov1alpha1.App return res, applicationSetReason, firstError } -func renderTemplatePatch(r utils.Renderer, app *argov1alpha1.Application, applicationSetInfo argov1alpha1.ApplicationSet, params map[string]any) (*argov1alpha1.Application, error) { +func renderTemplatePatch(r utils.Renderer, app *argov1alpha1.Application, applicationSetInfo argov1alpha1.ApplicationSet, params map[string]interface{}) (*argov1alpha1.Application, error) { replacedTemplate, err := r.Replace(*applicationSetInfo.Spec.TemplatePatch, params, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions) if err != nil { return nil, fmt.Errorf("error replacing values in templatePatch: %w", err) diff --git a/applicationset/controllers/template/template_test.go b/applicationset/controllers/template/template_test.go index e3e7ffaa8e..27e2c17f10 100644 --- a/applicationset/controllers/template/template_test.go +++ b/applicationset/controllers/template/template_test.go @@ -1,7 +1,7 @@ package template import ( - "errors" + "fmt" "maps" "testing" @@ -13,12 +13,12 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "github.com/argoproj/argo-cd/v3/applicationset/generators" - genmock "github.com/argoproj/argo-cd/v3/applicationset/generators/mocks" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - rendmock "github.com/argoproj/argo-cd/v3/applicationset/utils/mocks" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/generators" + genmock "github.com/argoproj/argo-cd/v2/applicationset/generators/mocks" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + 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" ) func TestGenerateApplications(t *testing.T) { @@ -31,7 +31,7 @@ func TestGenerateApplications(t *testing.T) { for _, c := range []struct { name string - params []map[string]any + params []map[string]interface{} template v1alpha1.ApplicationSetTemplate generateParamsError error rendererError error @@ -40,7 +40,7 @@ func TestGenerateApplications(t *testing.T) { }{ { name: "Generate two applications", - params: []map[string]any{{"name": "app1"}, {"name": "app2"}}, + params: []map[string]interface{}{{"name": "app1"}, {"name": "app2"}}, template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ Name: "name", @@ -53,13 +53,13 @@ func TestGenerateApplications(t *testing.T) { }, { name: "Handles error from the generator", - generateParamsError: errors.New("error"), + generateParamsError: fmt.Errorf("error"), expectErr: true, expectedReason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, }, { name: "Handles error from the render", - params: []map[string]any{{"name": "app1"}, {"name": "app2"}}, + params: []map[string]interface{}{{"name": "app1"}, {"name": "app2"}}, template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ Name: "name", @@ -68,7 +68,7 @@ func TestGenerateApplications(t *testing.T) { }, Spec: v1alpha1.ApplicationSpec{}, }, - rendererError: errors.New("error"), + rendererError: fmt.Errorf("error"), expectErr: true, expectedReason: v1alpha1.ApplicationSetReasonRenderTemplateParamsError, }, @@ -153,7 +153,7 @@ func TestGenerateApplications(t *testing.T) { func TestMergeTemplateApplications(t *testing.T) { for _, c := range []struct { name string - params []map[string]any + params []map[string]interface{} template v1alpha1.ApplicationSetTemplate overrideTemplate v1alpha1.ApplicationSetTemplate expectedMerged v1alpha1.ApplicationSetTemplate @@ -161,7 +161,7 @@ func TestMergeTemplateApplications(t *testing.T) { }{ { name: "Generate app", - params: []map[string]any{{"name": "app1"}}, + params: []map[string]interface{}{{"name": "app1"}}, template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ Name: "name", @@ -245,13 +245,13 @@ func TestMergeTemplateApplications(t *testing.T) { func TestGenerateAppsUsingPullRequestGenerator(t *testing.T) { for _, cases := range []struct { name string - params []map[string]any + params []map[string]interface{} template v1alpha1.ApplicationSetTemplate expectedApp []v1alpha1.Application }{ { name: "Generate an application from a go template application set manifest using a pull request generator", - params: []map[string]any{ + params: []map[string]interface{}{ { "number": "1", "title": "title1", @@ -341,10 +341,10 @@ func TestGenerateAppsUsingPullRequestGenerator(t *testing.T) { renderer, nil, ) - assert.Equal(t, cases.expectedApp[0].Name, gotApp[0].Name) - assert.Equal(t, cases.expectedApp[0].Spec.Source.TargetRevision, gotApp[0].Spec.Source.TargetRevision) - assert.Equal(t, cases.expectedApp[0].Spec.Destination.Namespace, gotApp[0].Spec.Destination.Namespace) - assert.True(t, maps.Equal(cases.expectedApp[0].Labels, gotApp[0].Labels)) + 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, maps.Equal(cases.expectedApp[0].ObjectMeta.Labels, gotApp[0].ObjectMeta.Labels)) }) } } diff --git a/applicationset/examples/applications-sync-policies/guestbook/engineering-dev/guestbook-ui-deployment.yaml b/applicationset/examples/applications-sync-policies/guestbook/engineering-dev/guestbook-ui-deployment.yaml index d0591f0831..8a0975e363 100644 --- a/applicationset/examples/applications-sync-policies/guestbook/engineering-dev/guestbook-ui-deployment.yaml +++ b/applicationset/examples/applications-sync-policies/guestbook/engineering-dev/guestbook-ui-deployment.yaml @@ -14,7 +14,7 @@ spec: app: guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook-ui ports: - containerPort: 80 diff --git a/applicationset/examples/applications-sync-policies/guestbook/engineering-prod/guestbook-ui-deployment.yaml b/applicationset/examples/applications-sync-policies/guestbook/engineering-prod/guestbook-ui-deployment.yaml index d0591f0831..8a0975e363 100644 --- a/applicationset/examples/applications-sync-policies/guestbook/engineering-prod/guestbook-ui-deployment.yaml +++ b/applicationset/examples/applications-sync-policies/guestbook/engineering-prod/guestbook-ui-deployment.yaml @@ -14,7 +14,7 @@ spec: app: guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook-ui ports: - containerPort: 80 diff --git a/applicationset/examples/git-generator-directory/excludes/cluster-addons/exclude-helm-guestbook/values.yaml b/applicationset/examples/git-generator-directory/excludes/cluster-addons/exclude-helm-guestbook/values.yaml index d0f2bf589b..3666712aec 100644 --- a/applicationset/examples/git-generator-directory/excludes/cluster-addons/exclude-helm-guestbook/values.yaml +++ b/applicationset/examples/git-generator-directory/excludes/cluster-addons/exclude-helm-guestbook/values.yaml @@ -5,7 +5,7 @@ replicaCount: 1 image: - repository: quay.io/argoprojlabs/argocd-e2e-container + repository: gcr.io/heptio-images/ks-guestbook-demo tag: 0.1 pullPolicy: IfNotPresent diff --git a/applicationset/examples/git-generator-files-discovery/apps/guestbook/guestbook-ui-deployment.yaml b/applicationset/examples/git-generator-files-discovery/apps/guestbook/guestbook-ui-deployment.yaml index d0591f0831..8a0975e363 100644 --- a/applicationset/examples/git-generator-files-discovery/apps/guestbook/guestbook-ui-deployment.yaml +++ b/applicationset/examples/git-generator-files-discovery/apps/guestbook/guestbook-ui-deployment.yaml @@ -14,7 +14,7 @@ spec: app: guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook-ui ports: - containerPort: 80 diff --git a/applicationset/examples/git-generator-files-discovery/excludes/git-files-exclude-example-fasttemplate.yaml b/applicationset/examples/git-generator-files-discovery/excludes/git-files-exclude-example-fasttemplate.yaml deleted file mode 100644 index 97b2cd3ad2..0000000000 --- a/applicationset/examples/git-generator-files-discovery/excludes/git-files-exclude-example-fasttemplate.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: ApplicationSet -metadata: - name: guestbook -spec: - generators: - - git: - repoURL: https://github.com/argoproj/argo-cd.git - revision: HEAD - files: - - path: "applicationset/examples/git-generator-files-discovery/cluster-config/**/config.json" - - path: "applicationset/examples/git-generator-files-discovery/cluster-config/*/dev/config.json" - exclude: true - template: - metadata: - name: '{{cluster.name}}-guestbook' - spec: - project: default - source: - repoURL: https://github.com/argoproj/argo-cd.git - targetRevision: HEAD - path: "applicationset/examples/git-generator-files-discovery/apps/guestbook" - destination: - server: https://kubernetes.default.svc - #server: '{{cluster.address}}' - namespace: guestbook \ No newline at end of file diff --git a/applicationset/examples/git-generator-files-discovery/excludes/git-files-exclude-example.yaml b/applicationset/examples/git-generator-files-discovery/excludes/git-files-exclude-example.yaml deleted file mode 100644 index 0a17e42fa6..0000000000 --- a/applicationset/examples/git-generator-files-discovery/excludes/git-files-exclude-example.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: ApplicationSet -metadata: - name: guestbook -spec: - goTemplate: true - goTemplateOptions: ["missingkey=error"] - generators: - - git: - repoURL: https://github.com/argoproj/argo-cd.git - revision: HEAD - files: - - path: "applicationset/examples/git-generator-files-discovery/cluster-config/**/config.json" - - path: "applicationset/examples/git-generator-files-discovery/cluster-config/*/dev/config.json" - exclude: true - template: - metadata: - name: '{{.cluster.name}}-guestbook' - spec: - project: default - source: - repoURL: https://github.com/argoproj/argo-cd.git - targetRevision: HEAD - path: "applicationset/examples/git-generator-files-discovery/apps/guestbook" - destination: - server: https://kubernetes.default.svc - namespace: guestbook \ No newline at end of file diff --git a/applicationset/examples/list-generator/guestbook/engineering-dev/guestbook-ui-deployment.yaml b/applicationset/examples/list-generator/guestbook/engineering-dev/guestbook-ui-deployment.yaml index d0591f0831..8a0975e363 100644 --- a/applicationset/examples/list-generator/guestbook/engineering-dev/guestbook-ui-deployment.yaml +++ b/applicationset/examples/list-generator/guestbook/engineering-dev/guestbook-ui-deployment.yaml @@ -14,7 +14,7 @@ spec: app: guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook-ui ports: - containerPort: 80 diff --git a/applicationset/examples/list-generator/guestbook/engineering-prod/guestbook-ui-deployment.yaml b/applicationset/examples/list-generator/guestbook/engineering-prod/guestbook-ui-deployment.yaml index d0591f0831..8a0975e363 100644 --- a/applicationset/examples/list-generator/guestbook/engineering-prod/guestbook-ui-deployment.yaml +++ b/applicationset/examples/list-generator/guestbook/engineering-prod/guestbook-ui-deployment.yaml @@ -14,7 +14,7 @@ spec: app: guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook-ui ports: - containerPort: 80 diff --git a/applicationset/examples/template-override/default/guestbook-ui-deployment.yaml b/applicationset/examples/template-override/default/guestbook-ui-deployment.yaml index d0591f0831..8a0975e363 100644 --- a/applicationset/examples/template-override/default/guestbook-ui-deployment.yaml +++ b/applicationset/examples/template-override/default/guestbook-ui-deployment.yaml @@ -14,7 +14,7 @@ spec: app: guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook-ui ports: - containerPort: 80 diff --git a/applicationset/examples/template-override/engineering-dev-override/guestbook-ui-deployment.yaml b/applicationset/examples/template-override/engineering-dev-override/guestbook-ui-deployment.yaml index d0591f0831..8a0975e363 100644 --- a/applicationset/examples/template-override/engineering-dev-override/guestbook-ui-deployment.yaml +++ b/applicationset/examples/template-override/engineering-dev-override/guestbook-ui-deployment.yaml @@ -14,7 +14,7 @@ spec: app: guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook-ui ports: - containerPort: 80 diff --git a/applicationset/generators/cluster.go b/applicationset/generators/cluster.go index db9d8f0716..79765f7bb3 100644 --- a/applicationset/generators/cluster.go +++ b/applicationset/generators/cluster.go @@ -7,16 +7,16 @@ import ( log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/util/settings" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - "github.com/argoproj/argo-cd/v3/common" - argoappsetv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "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" ) var _ Generator = (*ClusterGenerator)(nil) @@ -33,7 +33,7 @@ type ClusterGenerator struct { var render = &utils.Render{} -func NewClusterGenerator(ctx context.Context, c client.Client, clientset kubernetes.Interface, namespace string) Generator { +func NewClusterGenerator(c client.Client, ctx context.Context, clientset kubernetes.Interface, namespace string) Generator { settingsManager := settings.NewSettingsManager(ctx, clientset, namespace) g := &ClusterGenerator{ @@ -56,21 +56,21 @@ func (g *ClusterGenerator) GetTemplate(appSetGenerator *argoappsetv1alpha1.Appli return &appSetGenerator.Clusters.Template } -func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.ApplicationSetGenerator, appSet *argoappsetv1alpha1.ApplicationSet, _ client.Client) ([]map[string]any, error) { +func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.ApplicationSetGenerator, appSet *argoappsetv1alpha1.ApplicationSet, _ client.Client) ([]map[string]interface{}, error) { logCtx := log.WithField("applicationset", appSet.GetName()).WithField("namespace", appSet.GetNamespace()) if appSetGenerator == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } if appSetGenerator.Clusters == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } // Do not include the local cluster in the cluster parameters IF there is a non-empty selector // - Since local clusters do not have secrets, they do not have labels to match against ignoreLocalClusters := len(appSetGenerator.Clusters.Selector.MatchExpressions) > 0 || len(appSetGenerator.Clusters.Selector.MatchLabels) > 0 - // ListCluster will include the local cluster in the list of clusters + // ListCluster from Argo CD's util/db package will include the local cluster in the list of clusters clustersFromArgoCD, err := utils.ListClusters(g.ctx, g.clientset, g.namespace) if err != nil { return nil, fmt.Errorf("error listing clusters: %w", err) @@ -85,22 +85,22 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap return nil, fmt.Errorf("error getting cluster secrets: %w", err) } - res := []map[string]any{} + res := []map[string]interface{}{} secretsFound := []corev1.Secret{} isFlatMode := appSetGenerator.Clusters.FlatList logCtx.Debugf("Using flat mode = %t for cluster generator", isFlatMode) - clustersParams := make([]map[string]any, 0) + clustersParams := make([]map[string]interface{}, 0) - for _, cluster := range clustersFromArgoCD { + 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. if secretForCluster, exists := clusterSecrets[cluster.Name]; exists { secretsFound = append(secretsFound, secretForCluster) } else if !ignoreLocalClusters { // If there is no secret for the cluster, it's the local cluster, so handle it here. - params := map[string]any{} + params := map[string]interface{}{} params["name"] = cluster.Name params["nameNormalized"] = cluster.Name params["server"] = cluster.Server @@ -123,7 +123,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap // For each matching cluster secret (non-local clusters only) for _, cluster := range secretsFound { - params := map[string]any{} + params := map[string]interface{}{} params["name"] = string(cluster.Data["name"]) params["nameNormalized"] = utils.SanitizeName(string(cluster.Data["name"])) @@ -137,23 +137,23 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap } if appSet.Spec.GoTemplate { - meta := map[string]any{} + meta := map[string]interface{}{} - if len(cluster.Annotations) > 0 { - meta["annotations"] = cluster.Annotations + if len(cluster.ObjectMeta.Annotations) > 0 { + meta["annotations"] = cluster.ObjectMeta.Annotations } - if len(cluster.Labels) > 0 { - meta["labels"] = cluster.Labels + if len(cluster.ObjectMeta.Labels) > 0 { + meta["labels"] = cluster.ObjectMeta.Labels } params["metadata"] = meta } else { - for key, value := range cluster.Annotations { - params["metadata.annotations."+key] = value + for key, value := range cluster.ObjectMeta.Annotations { + params[fmt.Sprintf("metadata.annotations.%s", key)] = value } - for key, value := range cluster.Labels { - params["metadata.labels."+key] = value + for key, value := range cluster.ObjectMeta.Labels { + params[fmt.Sprintf("metadata.labels.%s", key)] = value } } @@ -172,7 +172,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap } if isFlatMode { - res = append(res, map[string]any{ + res = append(res, map[string]interface{}{ "clusters": clustersParams, }) } @@ -188,7 +188,7 @@ func (g *ClusterGenerator) getSecretsByClusterName(log *log.Entry, appSetGenerat return nil, fmt.Errorf("error converting label selector: %w", err) } - if err := g.List(context.Background(), clusterSecretList, client.MatchingLabelsSelector{Selector: secretSelector}); err != nil { + if err := g.Client.List(context.Background(), clusterSecretList, client.MatchingLabelsSelector{Selector: secretSelector}); err != nil { return nil, err } log.Debugf("clusters matching labels: %d", len(clusterSecretList.Items)) diff --git a/applicationset/generators/cluster_test.go b/applicationset/generators/cluster_test.go index e774c84c1a..30d8cf0347 100644 --- a/applicationset/generators/cluster_test.go +++ b/applicationset/generators/cluster_test.go @@ -2,7 +2,7 @@ package generators import ( "context" - "errors" + "fmt" "testing" corev1 "k8s.io/api/core/v1" @@ -13,8 +13,8 @@ import ( kubefake "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -27,7 +27,7 @@ type possiblyErroringFakeCtrlRuntimeClient struct { func (p *possiblyErroringFakeCtrlRuntimeClient) List(ctx context.Context, secretList client.ObjectList, opts ...client.ListOption) error { if p.shouldError { - return errors.New("could not list Secrets") + return fmt.Errorf("could not list Secrets") } return p.Client.List(ctx, secretList, opts...) } @@ -89,7 +89,7 @@ func TestGenerateParams(t *testing.T) { selector metav1.LabelSelector isFlatMode bool values map[string]string - expected []map[string]any + expected []map[string]interface{} // clientError is true if a k8s client error should be simulated clientError bool expectedError error @@ -106,7 +106,7 @@ func TestGenerateParams(t *testing.T) { "bat": "{{ metadata.labels.environment }}", "aaa": "{{ server }}", "no-op": "{{ this-does-not-exist }}", - }, expected: []map[string]any{ + }, 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", @@ -129,7 +129,7 @@ func TestGenerateParams(t *testing.T) { }, }, values: nil, - expected: []map[string]any{ + 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", "project": "prod-project", @@ -153,7 +153,7 @@ func TestGenerateParams(t *testing.T) { values: map[string]string{ "foo": "bar", }, - expected: []map[string]any{ + 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", "project": "prod-project", @@ -179,7 +179,7 @@ func TestGenerateParams(t *testing.T) { values: map[string]string{ "foo": "bar", }, - expected: []map[string]any{ + 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", "project": "", @@ -212,7 +212,7 @@ func TestGenerateParams(t *testing.T) { values: map[string]string{ "name": "baz", }, - expected: []map[string]any{ + 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", "project": "", @@ -227,7 +227,7 @@ func TestGenerateParams(t *testing.T) { values: nil, expected: nil, clientError: true, - expectedError: errors.New("error getting cluster secrets: could not list Secrets"), + expectedError: fmt.Errorf("error getting cluster secrets: could not list Secrets"), }, { name: "flat mode without selectors", @@ -242,9 +242,9 @@ func TestGenerateParams(t *testing.T) { "aaa": "{{ server }}", "no-op": "{{ this-does-not-exist }}", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "clusters": []map[string]any{ + "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", @@ -280,9 +280,9 @@ func TestGenerateParams(t *testing.T) { values: map[string]string{ "foo": "bar", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "clusters": []map[string]any{ + "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", @@ -315,7 +315,7 @@ func TestGenerateParams(t *testing.T) { testCase.clientError, } - clusterGenerator := NewClusterGenerator(t.Context(), cl, appClientset, "namespace") + clusterGenerator := NewClusterGenerator(cl, context.Background(), appClientset, "namespace") applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ @@ -398,7 +398,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { selector metav1.LabelSelector values map[string]string isFlatMode bool - expected []map[string]any + expected []map[string]interface{} // clientError is true if a k8s client error should be simulated clientError bool expectedError error @@ -415,13 +415,13 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "bat": "{{ if not (empty .metadata) }}{{.metadata.labels.environment}}{{ end }}", "aaa": "{{ .server }}", "no-op": "{{ .thisDoesNotExist }}", - }, expected: []map[string]any{ + }, expected: []map[string]interface{}{ { "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", "environment": "production", @@ -447,7 +447,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "nameNormalized": "staging-01", "server": "https://staging-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", "environment": "staging", @@ -496,13 +496,13 @@ func TestGenerateParamsGoTemplate(t *testing.T) { }, }, values: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", "environment": "production", @@ -518,7 +518,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "nameNormalized": "staging-01", "server": "https://staging-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", "environment": "staging", @@ -543,13 +543,13 @@ func TestGenerateParamsGoTemplate(t *testing.T) { values: map[string]string{ "foo": "bar", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", "environment": "production", @@ -584,13 +584,13 @@ func TestGenerateParamsGoTemplate(t *testing.T) { values: map[string]string{ "foo": "bar", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", "environment": "production", @@ -609,7 +609,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "nameNormalized": "staging-01", "server": "https://staging-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", "environment": "staging", @@ -647,13 +647,13 @@ func TestGenerateParamsGoTemplate(t *testing.T) { values: map[string]string{ "name": "baz", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "name": "staging-01", "nameNormalized": "staging-01", "server": "https://staging-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", "environment": "staging", @@ -677,7 +677,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { values: nil, expected: nil, clientError: true, - expectedError: errors.New("error getting cluster secrets: could not list Secrets"), + expectedError: fmt.Errorf("error getting cluster secrets: could not list Secrets"), }, { name: "Clusters with flat list mode and no selector", @@ -693,9 +693,9 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "aaa": "{{ .server }}", "no-op": "{{ .thisDoesNotExist }}", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "clusters": []map[string]any{ + "clusters": []map[string]interface{}{ { "nameNormalized": "in-cluster", "name": "in-cluster", @@ -717,7 +717,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "nameNormalized": "production-01-west", "server": "https://production-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", "environment": "production", @@ -743,7 +743,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "nameNormalized": "staging-01", "server": "https://staging-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", "environment": "staging", @@ -788,15 +788,15 @@ func TestGenerateParamsGoTemplate(t *testing.T) { values: map[string]string{ "foo": "bar", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "clusters": []map[string]any{ + "clusters": []map[string]interface{}{ { "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", "environment": "production", @@ -815,7 +815,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "nameNormalized": "staging-01", "server": "https://staging-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", "environment": "staging", @@ -853,7 +853,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { testCase.clientError, } - clusterGenerator := NewClusterGenerator(t.Context(), cl, appClientset, "namespace") + clusterGenerator := NewClusterGenerator(cl, context.Background(), appClientset, "namespace") applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ diff --git a/applicationset/generators/duck_type.go b/applicationset/generators/duck_type.go index 64b7b55eca..7bd78a0714 100644 --- a/applicationset/generators/duck_type.go +++ b/applicationset/generators/duck_type.go @@ -2,7 +2,6 @@ package generators import ( "context" - "errors" "fmt" "strings" "time" @@ -10,7 +9,7 @@ import ( log "github.com/sirupsen/logrus" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/util/settings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" @@ -18,8 +17,8 @@ import ( "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) var _ Generator = (*DuckTypeGenerator)(nil) @@ -60,14 +59,14 @@ func (g *DuckTypeGenerator) GetTemplate(appSetGenerator *argoprojiov1alpha1.Appl return &appSetGenerator.ClusterDecisionResource.Template } -func (g *DuckTypeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, _ client.Client) ([]map[string]any, error) { +func (g *DuckTypeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, _ client.Client) ([]map[string]interface{}, error) { if appSetGenerator == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } // Not likely to happen if appSetGenerator.ClusterDecisionResource == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } // ListCluster from Argo CD's util/db package will include the local cluster in the list of clusters @@ -97,13 +96,13 @@ func (g *DuckTypeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.A // Validate the fields if kind == "" || versionIdx < 1 { log.Warningf("kind=%v, resourceName=%v, versionIdx=%v", kind, resourceName, versionIdx) - return nil, errors.New("there is a problem with the apiVersion, kind or resourceName provided") + return nil, fmt.Errorf("There is a problem with the apiVersion, kind or resourceName provided") } if (resourceName == "" && labelSelector.MatchLabels == nil && labelSelector.MatchExpressions == nil) || (resourceName != "" && (labelSelector.MatchExpressions != nil || labelSelector.MatchLabels != nil)) { log.Warningf("You must choose either resourceName=%v, labelSelector.matchLabels=%v or labelSelect.matchExpressions=%v", resourceName, labelSelector.MatchLabels, labelSelector.MatchExpressions) - return nil, errors.New("there is a problem with the definition of the ClusterDecisionResource generator") + return nil, fmt.Errorf("There is a problem with the definition of the ClusterDecisionResource generator") } // Split up the apiVersion @@ -131,7 +130,7 @@ func (g *DuckTypeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.A if len(duckResources.Items) == 0 { log.Warning("no resource found, make sure you clusterDecisionResource is defined correctly") - return nil, errors.New("no clusterDecisionResources found") + return nil, fmt.Errorf("no clusterDecisionResources found") } // Override the duck type in the status of the resource @@ -147,77 +146,81 @@ func (g *DuckTypeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.A return nil, nil } - res := []map[string]any{} - clusterDecisions := []any{} + res := []map[string]interface{}{} + clusterDecisions := []interface{}{} // Build the decision slice for _, duckResource := range duckResources.Items { log.WithField("duckResourceName", duckResource.GetName()).Debug("found resource") - if duckResource.Object["status"] == nil || len(duckResource.Object["status"].(map[string]any)) == 0 { + if duckResource.Object["status"] == nil || len(duckResource.Object["status"].(map[string]interface{})) == 0 { log.Warningf("clusterDecisionResource: %s, has no status", duckResource.GetName()) continue } log.WithField("duckResourceStatus", duckResource.Object["status"]).Debug("found resource") - clusterDecisions = append(clusterDecisions, duckResource.Object["status"].(map[string]any)[statusListKey].([]any)...) + clusterDecisions = append(clusterDecisions, duckResource.Object["status"].(map[string]interface{})[statusListKey].([]interface{})...) } log.Infof("Number of decisions found: %v", len(clusterDecisions)) - if len(clusterDecisions) == 0 { + // Read this outside the loop to improve performance + argoClusters := clustersFromArgoCD.Items + + if len(clusterDecisions) > 0 { + for _, cluster := range clusterDecisions { + // generated instance of cluster params + params := map[string]interface{}{} + + log.Infof("cluster: %v", cluster) + matchValue := cluster.(map[string]interface{})[matchKey] + if matchValue == nil || matchValue.(string) == "" { + log.Warningf("matchKey=%v not found in \"%v\" list: %v\n", matchKey, statusListKey, cluster.(map[string]interface{})) + continue + } + + strMatchValue := matchValue.(string) + log.WithField(matchKey, strMatchValue).Debug("validate against ArgoCD") + + found := false + + for _, argoCluster := range argoClusters { + if argoCluster.Name == strMatchValue { + log.WithField(matchKey, argoCluster.Name).Info("matched cluster in ArgoCD") + params["name"] = argoCluster.Name + params["server"] = argoCluster.Server + + found = true + break // Stop looking + } + } + + if !found { + log.WithField(matchKey, strMatchValue).Warning("unmatched cluster in ArgoCD") + continue + } + + for key, value := range cluster.(map[string]interface{}) { + params[key] = value.(string) + } + + for key, value := range appSetGenerator.ClusterDecisionResource.Values { + if appSet.Spec.GoTemplate { + if params["values"] == nil { + params["values"] = map[string]string{} + } + params["values"].(map[string]string)[key] = value + } else { + params[fmt.Sprintf("values.%s", key)] = value + } + } + + res = append(res, params) + } + } else { log.Warningf("clusterDecisionResource status.%s missing", statusListKey) return nil, nil } - for _, cluster := range clusterDecisions { - // generated instance of cluster params - params := map[string]any{} - - log.Infof("cluster: %v", cluster) - matchValue := cluster.(map[string]any)[matchKey] - if matchValue == nil || matchValue.(string) == "" { - log.Warningf("matchKey=%v not found in \"%v\" list: %v\n", matchKey, statusListKey, cluster.(map[string]any)) - continue - } - - strMatchValue := matchValue.(string) - log.WithField(matchKey, strMatchValue).Debug("validate against ArgoCD") - - found := false - - for _, argoCluster := range clustersFromArgoCD { - if argoCluster.Name == strMatchValue { - log.WithField(matchKey, argoCluster.Name).Info("matched cluster in ArgoCD") - params["name"] = argoCluster.Name - params["server"] = argoCluster.Server - - found = true - break // Stop looking - } - } - - if !found { - log.WithField(matchKey, strMatchValue).Warning("unmatched cluster in ArgoCD") - continue - } - - for key, value := range cluster.(map[string]any) { - params[key] = value.(string) - } - - for key, value := range appSetGenerator.ClusterDecisionResource.Values { - if appSet.Spec.GoTemplate { - if params["values"] == nil { - params["values"] = map[string]string{} - } - params["values"].(map[string]string)[key] = value - } else { - params["values."+key] = value - } - } - - res = append(res, params) - } return res, nil } diff --git a/applicationset/generators/duck_type_test.go b/applicationset/generators/duck_type_test.go index 3d52d7fe0f..d2cfdbc59d 100644 --- a/applicationset/generators/duck_type_test.go +++ b/applicationset/generators/duck_type_test.go @@ -1,7 +1,8 @@ package generators import ( - "errors" + "context" + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -15,11 +16,11 @@ import ( kubefake "k8s.io/client-go/kubernetes/fake" "sigs.k8s.io/controller-runtime/pkg/client" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) const ( - resourceAPIVersion = "mallard.io/v1" + resourceApiVersion = "mallard.io/v1" resourceKind = "ducks" resourceName = "quak" ) @@ -77,20 +78,20 @@ func TestGenerateParamsForDuckType(t *testing.T) { } duckType := &unstructured.Unstructured{ - Object: map[string]any{ - "apiVersion": resourceAPIVersion, + Object: map[string]interface{}{ + "apiVersion": resourceApiVersion, "kind": "Duck", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "name": resourceName, "namespace": "namespace", - "labels": map[string]any{"duck": "all-species"}, + "labels": map[string]interface{}{"duck": "all-species"}, }, - "status": map[string]any{ - "decisions": []any{ - map[string]any{ + "status": map[string]interface{}{ + "decisions": []interface{}{ + map[string]interface{}{ "clusterName": "staging-01", }, - map[string]any{ + map[string]interface{}{ "clusterName": "production-01", }, }, @@ -99,17 +100,17 @@ func TestGenerateParamsForDuckType(t *testing.T) { } duckTypeProdOnly := &unstructured.Unstructured{ - Object: map[string]any{ - "apiVersion": resourceAPIVersion, + Object: map[string]interface{}{ + "apiVersion": resourceApiVersion, "kind": "Duck", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "name": resourceName, "namespace": "namespace", - "labels": map[string]any{"duck": "spotted"}, + "labels": map[string]interface{}{"duck": "spotted"}, }, - "status": map[string]any{ - "decisions": []any{ - map[string]any{ + "status": map[string]interface{}{ + "decisions": []interface{}{ + map[string]interface{}{ "clusterName": "production-01", }, }, @@ -118,15 +119,15 @@ func TestGenerateParamsForDuckType(t *testing.T) { } duckTypeEmpty := &unstructured.Unstructured{ - Object: map[string]any{ - "apiVersion": resourceAPIVersion, + Object: map[string]interface{}{ + "apiVersion": resourceApiVersion, "kind": "Duck", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "name": resourceName, "namespace": "namespace", - "labels": map[string]any{"duck": "canvasback"}, + "labels": map[string]interface{}{"duck": "canvasback"}, }, - "status": map[string]any{}, + "status": map[string]interface{}{}, }, } @@ -136,7 +137,7 @@ func TestGenerateParamsForDuckType(t *testing.T) { Namespace: "namespace", }, Data: map[string]string{ - "apiVersion": resourceAPIVersion, + "apiVersion": resourceApiVersion, "kind": resourceKind, "statusListKey": "decisions", "matchKey": "clusterName", @@ -150,7 +151,7 @@ func TestGenerateParamsForDuckType(t *testing.T) { labelSelector metav1.LabelSelector resource *unstructured.Unstructured values map[string]string - expected []map[string]any + expected []map[string]interface{} expectedError error }{ { @@ -158,8 +159,8 @@ func TestGenerateParamsForDuckType(t *testing.T) { resourceName: "", resource: duckType, values: nil, - expected: []map[string]any{}, - expectedError: errors.New("there is a problem with the definition of the ClusterDecisionResource generator"), + expected: []map[string]interface{}{}, + expectedError: fmt.Errorf("There is a problem with the definition of the ClusterDecisionResource generator"), }, /*** This does not work with the FAKE runtime client, fieldSelectors are broken. { @@ -176,7 +177,7 @@ func TestGenerateParamsForDuckType(t *testing.T) { resourceName: resourceName, resource: duckType, values: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"clusterName": "production-01", "name": "production-01", "server": "https://production-01.example.com"}, {"clusterName": "staging-01", "name": "staging-01", "server": "https://staging-01.example.com"}, @@ -190,7 +191,7 @@ func TestGenerateParamsForDuckType(t *testing.T) { values: map[string]string{ "foo": "bar", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"clusterName": "production-01", "values.foo": "bar", "name": "production-01", "server": "https://production-01.example.com"}, }, expectedError: nil, @@ -218,7 +219,7 @@ func TestGenerateParamsForDuckType(t *testing.T) { labelSelector: metav1.LabelSelector{MatchLabels: map[string]string{"duck": "all-species"}}, resource: duckType, values: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"clusterName": "production-01", "name": "production-01", "server": "https://production-01.example.com"}, {"clusterName": "staging-01", "name": "staging-01", "server": "https://staging-01.example.com"}, @@ -233,7 +234,7 @@ func TestGenerateParamsForDuckType(t *testing.T) { values: map[string]string{ "foo": "bar", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"clusterName": "production-01", "values.foo": "bar", "name": "production-01", "server": "https://production-01.example.com"}, }, expectedError: nil, @@ -250,7 +251,7 @@ func TestGenerateParamsForDuckType(t *testing.T) { }}, resource: duckType, values: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"clusterName": "production-01", "name": "production-01", "server": "https://production-01.example.com"}, {"clusterName": "staging-01", "name": "staging-01", "server": "https://staging-01.example.com"}, @@ -270,7 +271,7 @@ func TestGenerateParamsForDuckType(t *testing.T) { resource: duckType, values: nil, expected: nil, - expectedError: errors.New("there is a problem with the definition of the ClusterDecisionResource generator"), + expectedError: fmt.Errorf("There is a problem with the definition of the ClusterDecisionResource generator"), }, } @@ -292,7 +293,7 @@ func TestGenerateParamsForDuckType(t *testing.T) { fakeDynClient := dynfake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), gvrToListKind, testCase.resource) - duckTypeGenerator := NewDuckTypeGenerator(t.Context(), fakeDynClient, appClientset, "namespace") + duckTypeGenerator := NewDuckTypeGenerator(context.Background(), fakeDynClient, appClientset, "namespace") applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ @@ -373,20 +374,20 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { } duckType := &unstructured.Unstructured{ - Object: map[string]any{ - "apiVersion": resourceAPIVersion, + Object: map[string]interface{}{ + "apiVersion": resourceApiVersion, "kind": "Duck", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "name": resourceName, "namespace": "namespace", - "labels": map[string]any{"duck": "all-species"}, + "labels": map[string]interface{}{"duck": "all-species"}, }, - "status": map[string]any{ - "decisions": []any{ - map[string]any{ + "status": map[string]interface{}{ + "decisions": []interface{}{ + map[string]interface{}{ "clusterName": "staging-01", }, - map[string]any{ + map[string]interface{}{ "clusterName": "production-01", }, }, @@ -395,17 +396,17 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { } duckTypeProdOnly := &unstructured.Unstructured{ - Object: map[string]any{ - "apiVersion": resourceAPIVersion, + Object: map[string]interface{}{ + "apiVersion": resourceApiVersion, "kind": "Duck", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "name": resourceName, "namespace": "namespace", - "labels": map[string]any{"duck": "spotted"}, + "labels": map[string]interface{}{"duck": "spotted"}, }, - "status": map[string]any{ - "decisions": []any{ - map[string]any{ + "status": map[string]interface{}{ + "decisions": []interface{}{ + map[string]interface{}{ "clusterName": "production-01", }, }, @@ -414,15 +415,15 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { } duckTypeEmpty := &unstructured.Unstructured{ - Object: map[string]any{ - "apiVersion": resourceAPIVersion, + Object: map[string]interface{}{ + "apiVersion": resourceApiVersion, "kind": "Duck", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "name": resourceName, "namespace": "namespace", - "labels": map[string]any{"duck": "canvasback"}, + "labels": map[string]interface{}{"duck": "canvasback"}, }, - "status": map[string]any{}, + "status": map[string]interface{}{}, }, } @@ -432,7 +433,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { Namespace: "namespace", }, Data: map[string]string{ - "apiVersion": resourceAPIVersion, + "apiVersion": resourceApiVersion, "kind": resourceKind, "statusListKey": "decisions", "matchKey": "clusterName", @@ -446,7 +447,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { labelSelector metav1.LabelSelector resource *unstructured.Unstructured values map[string]string - expected []map[string]any + expected []map[string]interface{} expectedError error }{ { @@ -454,8 +455,8 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { resourceName: "", resource: duckType, values: nil, - expected: []map[string]any{}, - expectedError: errors.New("there is a problem with the definition of the ClusterDecisionResource generator"), + expected: []map[string]interface{}{}, + expectedError: fmt.Errorf("There is a problem with the definition of the ClusterDecisionResource generator"), }, /*** This does not work with the FAKE runtime client, fieldSelectors are broken. { @@ -472,7 +473,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { resourceName: resourceName, resource: duckType, values: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"clusterName": "production-01", "name": "production-01", "server": "https://production-01.example.com"}, {"clusterName": "staging-01", "name": "staging-01", "server": "https://staging-01.example.com"}, @@ -486,7 +487,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { values: map[string]string{ "foo": "bar", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"clusterName": "production-01", "values": map[string]string{"foo": "bar"}, "name": "production-01", "server": "https://production-01.example.com"}, }, expectedError: nil, @@ -514,7 +515,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { labelSelector: metav1.LabelSelector{MatchLabels: map[string]string{"duck": "all-species"}}, resource: duckType, values: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"clusterName": "production-01", "name": "production-01", "server": "https://production-01.example.com"}, {"clusterName": "staging-01", "name": "staging-01", "server": "https://staging-01.example.com"}, @@ -529,7 +530,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { values: map[string]string{ "foo": "bar", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"clusterName": "production-01", "values": map[string]string{"foo": "bar"}, "name": "production-01", "server": "https://production-01.example.com"}, }, expectedError: nil, @@ -546,7 +547,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { }}, resource: duckType, values: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"clusterName": "production-01", "name": "production-01", "server": "https://production-01.example.com"}, {"clusterName": "staging-01", "name": "staging-01", "server": "https://staging-01.example.com"}, @@ -566,7 +567,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { resource: duckType, values: nil, expected: nil, - expectedError: errors.New("there is a problem with the definition of the ClusterDecisionResource generator"), + expectedError: fmt.Errorf("There is a problem with the definition of the ClusterDecisionResource generator"), }, } @@ -588,7 +589,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { fakeDynClient := dynfake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), gvrToListKind, testCase.resource) - duckTypeGenerator := NewDuckTypeGenerator(t.Context(), fakeDynClient, appClientset, "namespace") + duckTypeGenerator := NewDuckTypeGenerator(context.Background(), fakeDynClient, appClientset, "namespace") applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ diff --git a/applicationset/generators/generator_spec_processor.go b/applicationset/generators/generator_spec_processor.go index 392fd4b85f..25e6b138da 100644 --- a/applicationset/generators/generator_spec_processor.go +++ b/applicationset/generators/generator_spec_processor.go @@ -7,13 +7,13 @@ import ( "github.com/jeremywohl/flatten" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/argoproj/argo-cd/v3/applicationset/utils" + "github.com/argoproj/argo-cd/v2/applicationset/utils" "k8s.io/apimachinery/pkg/labels" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - "dario.cat/mergo" + "github.com/imdario/mergo" log "github.com/sirupsen/logrus" ) @@ -22,12 +22,12 @@ const ( ) type TransformResult struct { - Params []map[string]any + Params []map[string]interface{} Template argoprojiov1alpha1.ApplicationSetTemplate } // Transform a spec generator to list of paramSets and a template -func Transform(requestedGenerator argoprojiov1alpha1.ApplicationSetGenerator, allGenerators map[string]Generator, baseTemplate argoprojiov1alpha1.ApplicationSetTemplate, appSet *argoprojiov1alpha1.ApplicationSet, genParams map[string]any, client client.Client) ([]TransformResult, error) { +func Transform(requestedGenerator argoprojiov1alpha1.ApplicationSetGenerator, allGenerators map[string]Generator, baseTemplate argoprojiov1alpha1.ApplicationSetTemplate, appSet *argoprojiov1alpha1.ApplicationSet, genParams map[string]interface{}, client client.Client) ([]TransformResult, error) { // This is a custom version of the `LabelSelectorAsSelector` that is in k8s.io/apimachinery. This has been copied // verbatim from that package, with the difference that we do not have any restrictions on label values. This is done // so that, among other things, we can match on cluster urls. @@ -52,7 +52,7 @@ func Transform(requestedGenerator argoprojiov1alpha1.ApplicationSetGenerator, al } continue } - var params []map[string]any + var params []map[string]interface{} if len(genParams) != 0 { tempInterpolatedGenerator, err := InterpolateGenerator(&requestedGenerator, genParams, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) interpolatedGenerator = &tempInterpolatedGenerator @@ -74,7 +74,7 @@ func Transform(requestedGenerator argoprojiov1alpha1.ApplicationSetGenerator, al } continue } - var filterParams []map[string]any + var filterParams []map[string]interface{} for _, param := range params { flatParam, err := flattenParameters(param) if err != nil { @@ -123,7 +123,7 @@ func GetRelevantGenerators(requestedGenerator *argoprojiov1alpha1.ApplicationSet return res } -func flattenParameters(in map[string]any) (map[string]string, error) { +func flattenParameters(in map[string]interface{}) (map[string]string, error) { flat, err := flatten.Flatten(in, "", flatten.DotStyle) if err != nil { return nil, fmt.Errorf("error flatenning parameters: %w", err) @@ -149,7 +149,7 @@ func mergeGeneratorTemplate(g Generator, requestedGenerator *argoprojiov1alpha1. // InterpolateGenerator allows interpolating the matrix's 2nd child generator with values from the 1st child generator // "params" parameter is an array, where each index corresponds to a generator. Each index contains a map w/ that generator's parameters. -func InterpolateGenerator(requestedGenerator *argoprojiov1alpha1.ApplicationSetGenerator, params map[string]any, useGoTemplate bool, goTemplateOptions []string) (argoprojiov1alpha1.ApplicationSetGenerator, error) { +func InterpolateGenerator(requestedGenerator *argoprojiov1alpha1.ApplicationSetGenerator, params map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (argoprojiov1alpha1.ApplicationSetGenerator, error) { render := utils.Render{} interpolatedGenerator, err := render.RenderGeneratorParams(requestedGenerator, params, useGoTemplate, goTemplateOptions) if err != nil { @@ -159,3 +159,16 @@ func InterpolateGenerator(requestedGenerator *argoprojiov1alpha1.ApplicationSetG return *interpolatedGenerator, nil } + +// Fixes https://github.com/argoproj/argo-cd/issues/11982 while ensuring backwards compatibility. +// This is only a short-term solution and should be removed in a future major version. +func dropDisabledNestedSelectors(generators []argoprojiov1alpha1.ApplicationSetNestedGenerator) bool { + var foundSelector bool + for i := range generators { + if generators[i].Selector != nil { + foundSelector = true + generators[i].Selector = nil + } + } + return foundSelector +} diff --git a/applicationset/generators/generator_spec_processor_test.go b/applicationset/generators/generator_spec_processor_test.go index 4f4be79fae..2c55fecad5 100644 --- a/applicationset/generators/generator_spec_processor_test.go +++ b/applicationset/generators/generator_spec_processor_test.go @@ -10,9 +10,9 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/applicationset/services/mocks" + "github.com/argoproj/argo-cd/v2/applicationset/services/mocks" - argov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/stretchr/testify/mock" corev1 "k8s.io/api/core/v1" @@ -27,19 +27,19 @@ func TestMatchValues(t *testing.T) { name string elements []apiextensionsv1.JSON selector *metav1.LabelSelector - expected []map[string]any + expected []map[string]interface{} }{ { name: "no filter", elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url"}`)}}, selector: &metav1.LabelSelector{}, - expected: []map[string]any{{"cluster": "cluster", "url": "url"}}, + expected: []map[string]interface{}{{"cluster": "cluster", "url": "url"}}, }, { name: "nil", elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url"}`)}}, selector: nil, - expected: []map[string]any{{"cluster": "cluster", "url": "url"}}, + expected: []map[string]interface{}{{"cluster": "cluster", "url": "url"}}, }, { name: "values.foo should be foo but is ignore element", @@ -49,7 +49,7 @@ func TestMatchValues(t *testing.T) { "values.foo": "foo", }, }, - expected: []map[string]any{}, + expected: []map[string]interface{}{}, }, { name: "values.foo should be bar", @@ -59,7 +59,7 @@ func TestMatchValues(t *testing.T) { "values.foo": "bar", }, }, - expected: []map[string]any{{"cluster": "cluster", "url": "url", "values.foo": "bar"}}, + expected: []map[string]interface{}{{"cluster": "cluster", "url": "url", "values.foo": "bar"}}, }, } @@ -101,19 +101,19 @@ func TestMatchValuesGoTemplate(t *testing.T) { name string elements []apiextensionsv1.JSON selector *metav1.LabelSelector - expected []map[string]any + expected []map[string]interface{} }{ { name: "no filter", elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url"}`)}}, selector: &metav1.LabelSelector{}, - expected: []map[string]any{{"cluster": "cluster", "url": "url"}}, + expected: []map[string]interface{}{{"cluster": "cluster", "url": "url"}}, }, { name: "nil", elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url"}`)}}, selector: nil, - expected: []map[string]any{{"cluster": "cluster", "url": "url"}}, + expected: []map[string]interface{}{{"cluster": "cluster", "url": "url"}}, }, { name: "values.foo should be foo but is ignore element", @@ -123,7 +123,7 @@ func TestMatchValuesGoTemplate(t *testing.T) { "values.foo": "foo", }, }, - expected: []map[string]any{}, + expected: []map[string]interface{}{}, }, { name: "values.foo should be bar", @@ -133,7 +133,7 @@ func TestMatchValuesGoTemplate(t *testing.T) { "values.foo": "bar", }, }, - expected: []map[string]any{{"cluster": "cluster", "url": "url", "values": map[string]any{"foo": "bar"}}}, + expected: []map[string]interface{}{{"cluster": "cluster", "url": "url", "values": map[string]interface{}{"foo": "bar"}}}, }, { name: "values.0 should be bar", @@ -143,7 +143,7 @@ func TestMatchValuesGoTemplate(t *testing.T) { "values.0": "bar", }, }, - expected: []map[string]any{{"cluster": "cluster", "url": "url", "values": []any{"bar"}}}, + expected: []map[string]interface{}{{"cluster": "cluster", "url": "url", "values": []interface{}{"bar"}}}, }, } @@ -184,14 +184,14 @@ func TestTransForm(t *testing.T) { testCases := []struct { name string selector *metav1.LabelSelector - expected []map[string]any + expected []map[string]interface{} }{ { name: "server filter", selector: &metav1.LabelSelector{ MatchLabels: map[string]string{"server": "https://production-01.example.com"}, }, - expected: []map[string]any{{ + expected: []map[string]interface{}{{ "metadata.annotations.foo.argoproj.io": "production", "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.labels.environment": "production", @@ -207,7 +207,7 @@ func TestTransForm(t *testing.T) { selector: &metav1.LabelSelector{ MatchLabels: map[string]string{"server": "https://some-really-long-url-that-will-exceed-63-characters.com"}, }, - expected: []map[string]any{{ + expected: []map[string]interface{}{{ "metadata.annotations.foo.argoproj.io": "production", "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.labels.environment": "production", @@ -342,7 +342,7 @@ func getMockClusterGenerator() Generator { appClientset := kubefake.NewSimpleClientset(runtimeClusters...) fakeClient := fake.NewClientBuilder().WithObjects(clusters...).Build() - return NewClusterGenerator(context.Background(), fakeClient, appClientset, "namespace") + return NewClusterGenerator(fakeClient, context.Background(), appClientset, "namespace") } func getMockGitGenerator() Generator { @@ -413,7 +413,7 @@ func TestInterpolateGenerator(t *testing.T) { }, }, } - gitGeneratorParams := map[string]any{ + gitGeneratorParams := map[string]interface{}{ "path": "p1/p2/app3", "path.basename": "app3", "path[0]": "p1", @@ -442,7 +442,7 @@ func TestInterpolateGenerator(t *testing.T) { Template: argov1alpha1.ApplicationSetTemplate{}, }, } - clusterGeneratorParams := map[string]any{ + clusterGeneratorParams := map[string]interface{}{ "name": "production_01/west", "server": "https://production-01.example.com", } interpolatedGenerator, err = InterpolateGenerator(requestedGenerator, clusterGeneratorParams, false, nil) @@ -468,8 +468,8 @@ func TestInterpolateGenerator_go(t *testing.T) { }, }, } - gitGeneratorParams := map[string]any{ - "path": map[string]any{ + gitGeneratorParams := map[string]interface{}{ + "path": map[string]interface{}{ "path": "p1/p2/app3", "segments": []string{"p1", "p2", "app3"}, }, @@ -497,7 +497,7 @@ func TestInterpolateGenerator_go(t *testing.T) { Template: argov1alpha1.ApplicationSetTemplate{}, }, } - clusterGeneratorParams := map[string]any{ + clusterGeneratorParams := map[string]interface{}{ "name": "production_01/west", "server": "https://production-01.example.com", } interpolatedGenerator, err = InterpolateGenerator(requestedGenerator, clusterGeneratorParams, true, nil) @@ -512,7 +512,7 @@ func TestInterpolateGenerator_go(t *testing.T) { func TestInterpolateGeneratorError(t *testing.T) { type args struct { requestedGenerator *argov1alpha1.ApplicationSetGenerator - params map[string]any + params map[string]interface{} useGoTemplate bool goTemplateOptions []string } @@ -530,7 +530,7 @@ func TestInterpolateGeneratorError(t *testing.T) { }, want: argov1alpha1.ApplicationSetGenerator{}, expectedErrStr: "generator is empty"}, {name: "No Params", args: args{ requestedGenerator: &argov1alpha1.ApplicationSetGenerator{}, - params: map[string]any{}, + params: map[string]interface{}{}, useGoTemplate: false, goTemplateOptions: nil, }, want: argov1alpha1.ApplicationSetGenerator{}, expectedErrStr: ""}, @@ -545,7 +545,7 @@ func TestInterpolateGeneratorError(t *testing.T) { "resolved": "{{ index .rmap (default .override .test) }}", }, }}, - params: map[string]any{ + params: map[string]interface{}{ "name": "in-cluster", "override": "foo", }, diff --git a/applicationset/generators/git.go b/applicationset/generators/git.go index 4afadec31b..d119824f40 100644 --- a/applicationset/generators/git.go +++ b/applicationset/generators/git.go @@ -15,10 +15,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/applicationset/services" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/gpg" + "github.com/argoproj/argo-cd/v2/applicationset/services" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/gpg" ) var _ Generator = (*GitGenerator)(nil) @@ -28,7 +28,6 @@ type GitGenerator struct { namespace string } -// NewGitGenerator creates a new instance of Git Generator func NewGitGenerator(repos services.Repos, namespace string) Generator { g := &GitGenerator{ repos: repos, @@ -38,17 +37,13 @@ func NewGitGenerator(repos services.Repos, namespace string) Generator { return g } -// GetTemplate returns the ApplicationSetTemplate associated with the Git generator -// from the provided ApplicationSetGenerator. This template defines how each -// generated Argo CD Application should be rendered. func (g *GitGenerator) GetTemplate(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) *argoprojiov1alpha1.ApplicationSetTemplate { return &appSetGenerator.Git.Template } -// GetRequeueAfter returns the duration after which the Git generator should be -// requeued for reconciliation. If RequeueAfterSeconds is set in the generator spec, -// it uses that value. Otherwise, it falls back to a default requeue interval (3 minutes). func (g *GitGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) time.Duration { + // Return a requeue default of 3 minutes, if no default is specified. + if appSetGenerator.Git.RequeueAfterSeconds != nil { return time.Duration(*appSetGenerator.Git.RequeueAfterSeconds) * time.Second } @@ -56,15 +51,13 @@ func (g *GitGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.Appli return getDefaultRequeueAfter() } -// GenerateParams generates a list of parameter maps for the ApplicationSet by evaluating the Git generator's configuration. -// It supports both directory-based and file-based Git generators. -func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, client client.Client) ([]map[string]any, error) { +func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, client client.Client) ([]map[string]interface{}, error) { if appSetGenerator == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } if appSetGenerator.Git == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } noRevisionCache := appSet.RefreshRequired() @@ -74,7 +67,6 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic // When the project field is templated, the contents of the git repo are required to run the git generator and get the templated value, // but git generator cannot be called without verifying the commit signature. // In this case, we skip the signature verification. - // If the project is templated, we skip the commit verification if !strings.Contains(appSet.Spec.Template.Spec.Project, "{{") { project := appSet.Spec.Template.Spec.Project appProject := &argoprojiov1alpha1.AppProject{} @@ -89,19 +81,14 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic verifyCommit = len(appProject.Spec.SignatureKeys) > 0 && gpg.IsGPGEnabled() } - // If the project field is templated, we cannot resolve the project name, so we pass an empty string to the repo-server. - // This means only "globally-scoped" repo credentials can be used for such appsets. - project := resolveProjectName(appSet.Spec.Template.Spec.Project) - var err error - var res []map[string]any - switch { - case len(appSetGenerator.Git.Directories) != 0: - res, err = g.generateParamsForGitDirectories(appSetGenerator, noRevisionCache, verifyCommit, appSet.Spec.GoTemplate, project, appSet.Spec.GoTemplateOptions) - case len(appSetGenerator.Git.Files) != 0: - res, err = g.generateParamsForGitFiles(appSetGenerator, noRevisionCache, verifyCommit, appSet.Spec.GoTemplate, project, appSet.Spec.GoTemplateOptions) - default: - return nil, ErrEmptyAppSetGenerator + var res []map[string]interface{} + if len(appSetGenerator.Git.Directories) != 0 { + res, err = g.generateParamsForGitDirectories(appSetGenerator, noRevisionCache, verifyCommit, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) + } else if len(appSetGenerator.Git.Files) != 0 { + res, err = g.generateParamsForGitFiles(appSetGenerator, noRevisionCache, verifyCommit, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) + } else { + return nil, EmptyAppSetGeneratorError } if err != nil { return nil, fmt.Errorf("error generating params from git: %w", err) @@ -110,11 +97,9 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic return res, nil } -// generateParamsForGitDirectories generates parameters for an ApplicationSet using a directory-based Git generator. -// It fetches all directories from the given Git repository and revision, optionally using a revision cache and verifying commits. -// It then filters the directories based on the generator's configuration and renders parameters for the resulting applications -func (g *GitGenerator) generateParamsForGitDirectories(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, noRevisionCache, verifyCommit, useGoTemplate bool, project string, goTemplateOptions []string) ([]map[string]any, error) { - allPaths, err := g.repos.GetDirectories(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, project, noRevisionCache, verifyCommit) +func (g *GitGenerator) generateParamsForGitDirectories(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, noRevisionCache, verifyCommit bool, useGoTemplate bool, goTemplateOptions []string) ([]map[string]interface{}, error) { + // Directories, not files + allPaths, err := g.repos.GetDirectories(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, noRevisionCache, verifyCommit) if err != nil { return nil, fmt.Errorf("error getting directories from repo: %w", err) } @@ -137,96 +122,49 @@ func (g *GitGenerator) generateParamsForGitDirectories(appSetGenerator *argoproj return res, nil } -// generateParamsForGitFiles generates parameters for an ApplicationSet using a file-based Git generator. -// It retrieves and processes specified files from the Git repository, supporting both YAML and JSON formats, -// and returns a list of parameter maps extracted from the content. -func (g *GitGenerator) generateParamsForGitFiles(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, noRevisionCache, verifyCommit, useGoTemplate bool, project string, goTemplateOptions []string) ([]map[string]any, error) { - // fileContentMap maps absolute file paths to their byte content - fileContentMap := make(map[string][]byte) - var includePatterns []string - var excludePatterns []string - - for _, req := range appSetGenerator.Git.Files { - if req.Exclude { - excludePatterns = append(excludePatterns, req.Path) - } else { - includePatterns = append(includePatterns, req.Path) - } - } - - // Fetch all files from include patterns - for _, includePattern := range includePatterns { - retrievedFiles, err := g.repos.GetFiles( - context.TODO(), - appSetGenerator.Git.RepoURL, - appSetGenerator.Git.Revision, - project, - includePattern, - noRevisionCache, - verifyCommit, - ) +func (g *GitGenerator) generateParamsForGitFiles(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, noRevisionCache, verifyCommit bool, useGoTemplate bool, goTemplateOptions []string) ([]map[string]interface{}, error) { + // Get all files that match the requested path string, removing duplicates + allFiles := make(map[string][]byte) + for _, requestedPath := range appSetGenerator.Git.Files { + files, err := g.repos.GetFiles(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, requestedPath.Path, noRevisionCache, verifyCommit) if err != nil { return nil, err } - for absPath, content := range retrievedFiles { - fileContentMap[absPath] = content + for filePath, content := range files { + allFiles[filePath] = content } } - // Now remove files matching any exclude pattern - for _, excludePattern := range excludePatterns { - matchingFiles, err := g.repos.GetFiles( - context.TODO(), - appSetGenerator.Git.RepoURL, - appSetGenerator.Git.Revision, - project, - excludePattern, - noRevisionCache, - verifyCommit, - ) - if err != nil { - return nil, err - } - for absPath := range matchingFiles { - // if the file doesn't exist already and you try to delete it from the map - // the operation is a no-op. It’s safe and doesn't return an error or panic. - // Hence, we can simply try to delete the file from the path without checking - // if that file already exists in the map. - delete(fileContentMap, absPath) - } + // Extract the unduplicated map into a list, and sort by path to ensure a deterministic + // processing order in the subsequent step + allPaths := []string{} + for path := range allFiles { + allPaths = append(allPaths, path) } + sort.Strings(allPaths) - // Get a sorted list of file paths to ensure deterministic processing order - var filePaths []string - for path := range fileContentMap { - filePaths = append(filePaths, path) - } - sort.Strings(filePaths) - - var allParams []map[string]any - for _, filePath := range filePaths { + // Generate params from each path, and return + res := []map[string]interface{}{} + for _, path := range allPaths { // A JSON / YAML file path can contain multiple sets of parameters (ie it is an array) - paramsFromFileArray, err := g.generateParamsFromGitFile(filePath, fileContentMap[filePath], appSetGenerator.Git.Values, useGoTemplate, goTemplateOptions, appSetGenerator.Git.PathParamPrefix) + paramsArray, err := g.generateParamsFromGitFile(path, allFiles[path], appSetGenerator.Git.Values, useGoTemplate, goTemplateOptions, appSetGenerator.Git.PathParamPrefix) if err != nil { - return nil, fmt.Errorf("unable to process file '%s': %w", filePath, err) + return nil, fmt.Errorf("unable to process file '%s': %w", path, err) } - allParams = append(allParams, paramsFromFileArray...) - } - return allParams, nil + res = append(res, paramsArray...) + } + return res, nil } -// generateParamsFromGitFile parses the content of a Git-tracked file and generates a slice of parameter maps. -// The file can contain a single YAML/JSON object or an array of such objects. Depending on the useGoTemplate flag, -// it either preserves structure for Go templating or flattens the objects for use as plain key-value parameters. -func (g *GitGenerator) generateParamsFromGitFile(filePath string, fileContent []byte, values map[string]string, useGoTemplate bool, goTemplateOptions []string, pathParamPrefix string) ([]map[string]any, error) { - objectsFound := []map[string]any{} +func (g *GitGenerator) generateParamsFromGitFile(filePath string, fileContent []byte, values map[string]string, useGoTemplate bool, goTemplateOptions []string, pathParamPrefix string) ([]map[string]interface{}, error) { + objectsFound := []map[string]interface{}{} // First, we attempt to parse as an array err := yaml.Unmarshal(fileContent, &objectsFound) if err != nil { // If unable to parse as an array, attempt to parse as a single object - singleObj := make(map[string]any) + singleObj := make(map[string]interface{}) err = yaml.Unmarshal(fileContent, &singleObj) if err != nil { return nil, fmt.Errorf("unable to parse file: %w", err) @@ -234,20 +172,20 @@ func (g *GitGenerator) generateParamsFromGitFile(filePath string, fileContent [] objectsFound = append(objectsFound, singleObj) } else if len(objectsFound) == 0 { // If file is valid but empty, add a default empty item - objectsFound = append(objectsFound, map[string]any{}) + objectsFound = append(objectsFound, map[string]interface{}{}) } - res := []map[string]any{} + res := []map[string]interface{}{} for _, objectFound := range objectsFound { - params := map[string]any{} + params := map[string]interface{}{} if useGoTemplate { for k, v := range objectFound { params[k] = v } - paramPath := map[string]any{} + paramPath := map[string]interface{}{} paramPath["path"] = path.Dir(filePath) paramPath["basename"] = path.Base(paramPath["path"].(string)) @@ -256,7 +194,7 @@ func (g *GitGenerator) generateParamsFromGitFile(filePath string, fileContent [] paramPath["filenameNormalized"] = utils.SanitizeName(path.Base(paramPath["filename"].(string))) paramPath["segments"] = strings.Split(paramPath["path"].(string), "/") if pathParamPrefix != "" { - params[pathParamPrefix] = map[string]any{"path": paramPath} + params[pathParamPrefix] = map[string]interface{}{"path": paramPath} } else { params["path"] = paramPath } @@ -295,10 +233,8 @@ func (g *GitGenerator) generateParamsFromGitFile(filePath string, fileContent [] return res, nil } -// filterApps filters the list of all application paths based on inclusion and exclusion rules -// defined in GitDirectoryGeneratorItems. Each item can either include or exclude matching paths. func (g *GitGenerator) filterApps(directories []argoprojiov1alpha1.GitDirectoryGeneratorItem, allPaths []string) []string { - var res []string + res := []string{} for _, appPath := range allPaths { appInclude := false appExclude := false @@ -325,22 +261,19 @@ func (g *GitGenerator) filterApps(directories []argoprojiov1alpha1.GitDirectoryG return res } -// generateParamsFromApps generates a list of parameter maps based on the given app paths. -// Each app path is converted into a parameter object with path metadata (basename, segments, etc.). -// It supports both Go templates and flat key-value parameters. -func (g *GitGenerator) generateParamsFromApps(requestedApps []string, appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, useGoTemplate bool, goTemplateOptions []string) ([]map[string]any, error) { - res := make([]map[string]any, len(requestedApps)) +func (g *GitGenerator) generateParamsFromApps(requestedApps []string, appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, useGoTemplate bool, goTemplateOptions []string) ([]map[string]interface{}, error) { + res := make([]map[string]interface{}, len(requestedApps)) for i, a := range requestedApps { - params := make(map[string]any, 5) + params := make(map[string]interface{}, 5) if useGoTemplate { - paramPath := map[string]any{} + paramPath := map[string]interface{}{} paramPath["path"] = a paramPath["basename"] = path.Base(a) paramPath["basenameNormalized"] = utils.SanitizeName(path.Base(a)) paramPath["segments"] = strings.Split(paramPath["path"].(string), "/") if appSetGenerator.Git.PathParamPrefix != "" { - params[appSetGenerator.Git.PathParamPrefix] = map[string]any{"path": paramPath} + params[appSetGenerator.Git.PathParamPrefix] = map[string]interface{}{"path": paramPath} } else { params["path"] = paramPath } @@ -369,12 +302,3 @@ func (g *GitGenerator) generateParamsFromApps(requestedApps []string, appSetGene return res, nil } - -// resolveProjectName resolves a project name whether templated or not -func resolveProjectName(project string) string { - if strings.Contains(project, "{{") { - return "" - } - - return project -} diff --git a/applicationset/generators/git_test.go b/applicationset/generators/git_test.go index b1b01c9e2a..cd0c14d844 100644 --- a/applicationset/generators/git_test.go +++ b/applicationset/generators/git_test.go @@ -1,7 +1,7 @@ package generators import ( - "errors" + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -9,11 +9,11 @@ import ( "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client/fake" - "github.com/argoproj/argo-cd/v3/applicationset/services/mocks" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/services/mocks" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func Test_generateParamsFromGitFile(t *testing.T) { @@ -32,7 +32,7 @@ foo: tests := []struct { name string args args - want []map[string]any + want []map[string]interface{} wantErr bool }{ { @@ -43,7 +43,7 @@ foo: values: map[string]string{}, useGoTemplate: false, }, - want: []map[string]any{ + want: []map[string]interface{}{ { "path": "path/dir", "path.basename": "dir", @@ -73,7 +73,7 @@ foo: values: map[string]string{}, useGoTemplate: false, }, - want: []map[string]any{ + want: []map[string]interface{}{ { "foo.bar": "baz", "path": "path/dir", @@ -95,7 +95,7 @@ foo: useGoTemplate: false, pathParamPrefix: "myRepo", }, - want: []map[string]any{ + want: []map[string]interface{}{ { "foo.bar": "baz", "myRepo.path": "path/dir", @@ -116,12 +116,12 @@ foo: values: map[string]string{}, useGoTemplate: true, }, - want: []map[string]any{ + want: []map[string]interface{}{ { - "foo": map[string]any{ + "foo": map[string]interface{}{ "bar": "baz", }, - "path": map[string]any{ + "path": map[string]interface{}{ "path": "path/dir", "basename": "dir", "filename": "file_name.yaml", @@ -144,13 +144,13 @@ foo: useGoTemplate: true, pathParamPrefix: "myRepo", }, - want: []map[string]any{ + want: []map[string]interface{}{ { - "foo": map[string]any{ + "foo": map[string]interface{}{ "bar": "baz", }, - "myRepo": map[string]any{ - "path": map[string]any{ + "myRepo": map[string]interface{}{ + "path": map[string]interface{}{ "path": "path/dir", "basename": "dir", "filename": "file_name.yaml", @@ -169,12 +169,11 @@ foo: for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { params, err := (*GitGenerator)(nil).generateParamsFromGitFile(tt.args.filePath, tt.args.fileContent, tt.args.values, tt.args.useGoTemplate, tt.args.goTemplateOptions, tt.args.pathParamPrefix) - if tt.wantErr { - assert.Error(t, err, "GitGenerator.generateParamsFromGitFile()") - } else { - require.NoError(t, err) - assert.Equal(t, tt.want, params) + if (err != nil) != tt.wantErr { + t.Errorf("GitGenerator.generateParamsFromGitFile() error = %v, wantErr %v", err, tt.wantErr) + return } + assert.Equal(t, tt.want, params) }) } } @@ -182,24 +181,25 @@ foo: func TestGitGenerateParamsFromDirectories(t *testing.T) { cases := []struct { name string - directories []v1alpha1.GitDirectoryGeneratorItem + directories []argoprojiov1alpha1.GitDirectoryGeneratorItem pathParamPrefix string repoApps []string repoError error values map[string]string - expected []map[string]any + expected []map[string]interface{} expectedError error }{ { name: "happy flow - created apps", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, repoApps: []string{ "app1", "app2", "app_3", "p1/app4", }, - expected: []map[string]any{ + repoError: nil, + expected: []map[string]interface{}{ {"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1"}, {"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2", "path[0]": "app2"}, {"path": "app_3", "path.basename": "app_3", "path.basenameNormalized": "app-3", "path[0]": "app_3"}, @@ -208,7 +208,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { }, { name: "It prefixes path parameters with PathParamPrefix", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, pathParamPrefix: "myRepo", repoApps: []string{ "app1", @@ -217,7 +217,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { "p1/app4", }, repoError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"myRepo.path": "app1", "myRepo.path.basename": "app1", "myRepo.path.basenameNormalized": "app1", "myRepo.path[0]": "app1"}, {"myRepo.path": "app2", "myRepo.path.basename": "app2", "myRepo.path.basenameNormalized": "app2", "myRepo.path[0]": "app2"}, {"myRepo.path": "app_3", "myRepo.path.basename": "app_3", "myRepo.path.basenameNormalized": "app-3", "myRepo.path[0]": "app_3"}, @@ -226,14 +226,15 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { }, { name: "It filters application according to the paths", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "p1/*"}, {Path: "p1/*/*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "p1/*"}, {Path: "p1/*/*"}}, repoApps: []string{ "app1", "p1/app2", "p1/p2/app3", "p1/p2/p3/app4", }, - expected: []map[string]any{ + repoError: nil, + expected: []map[string]interface{}{ {"path": "p1/app2", "path.basename": "app2", "path[0]": "p1", "path[1]": "app2", "path.basenameNormalized": "app2"}, {"path": "p1/p2/app3", "path.basename": "app3", "path[0]": "p1", "path[1]": "p2", "path[2]": "app3", "path.basenameNormalized": "app3"}, }, @@ -241,7 +242,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { }, { name: "It filters application according to the paths with Exclude", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "p1/*", Exclude: true}, {Path: "*"}, {Path: "*/*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "p1/*", Exclude: true}, {Path: "*"}, {Path: "*/*"}}, repoApps: []string{ "app1", "app2", @@ -250,7 +251,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { "p2/app3", }, repoError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"path": "app1", "path.basename": "app1", "path[0]": "app1", "path.basenameNormalized": "app1"}, {"path": "app2", "path.basename": "app2", "path[0]": "app2", "path.basenameNormalized": "app2"}, {"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path[1]": "app3", "path.basenameNormalized": "app3"}, @@ -259,7 +260,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { }, { name: "Expecting same exclude behavior with different order", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}, {Path: "*/*"}, {Path: "p1/*", Exclude: true}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}, {Path: "*/*"}, {Path: "p1/*", Exclude: true}}, repoApps: []string{ "app1", "app2", @@ -268,7 +269,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { "p2/app3", }, repoError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"path": "app1", "path.basename": "app1", "path[0]": "app1", "path.basenameNormalized": "app1"}, {"path": "app2", "path.basename": "app2", "path[0]": "app2", "path.basenameNormalized": "app2"}, {"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path[1]": "app3", "path.basenameNormalized": "app3"}, @@ -277,7 +278,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { }, { name: "Value variable interpolation", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}, {Path: "*/*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}, {Path: "*/*"}}, repoApps: []string{ "app1", "p1/app2", @@ -288,7 +289,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { "aaa": "{{ path[0] }}", "no-op": "{{ this-does-not-exist }}", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"values.foo": "bar", "values.no-op": "{{ this-does-not-exist }}", "values.aaa": "app1", "path": "app1", "path.basename": "app1", "path[0]": "app1", "path.basenameNormalized": "app1"}, {"values.foo": "bar", "values.no-op": "{{ this-does-not-exist }}", "values.aaa": "p1", "path": "p1/app2", "path.basename": "app2", "path[0]": "p1", "path[1]": "app2", "path.basenameNormalized": "app2"}, }, @@ -296,19 +297,19 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { }, { name: "handles empty response from repo server", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, repoApps: []string{}, repoError: nil, - expected: []map[string]any{}, + expected: []map[string]interface{}{}, expectedError: nil, }, { name: "handles error from repo server", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, repoApps: []string{}, - repoError: errors.New("error"), - expected: []map[string]any{}, - expectedError: errors.New("error generating params from git: error getting directories from repo: error"), + repoError: fmt.Errorf("error"), + expected: []map[string]interface{}{}, + expectedError: fmt.Errorf("error generating params from git: error getting directories from repo: error"), }, } @@ -320,16 +321,16 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { argoCDServiceMock := mocks.Repos{} - argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) + argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) gitGenerator := NewGitGenerator(&argoCDServiceMock, "") - applicationSetInfo := v1alpha1.ApplicationSet{ + applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", }, - Spec: v1alpha1.ApplicationSetSpec{ - Generators: []v1alpha1.ApplicationSetGenerator{{ - Git: &v1alpha1.GitGenerator{ + Spec: argoprojiov1alpha1.ApplicationSetSpec{ + Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{ + Git: &argoprojiov1alpha1.GitGenerator{ RepoURL: "RepoURL", Revision: "Revision", Directories: testCaseCopy.directories, @@ -343,7 +344,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - appProject := v1alpha1.AppProject{} + appProject := argoprojiov1alpha1.AppProject{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() @@ -364,16 +365,16 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { cases := []struct { name string - directories []v1alpha1.GitDirectoryGeneratorItem + directories []argoprojiov1alpha1.GitDirectoryGeneratorItem pathParamPrefix string repoApps []string repoError error - expected []map[string]any + expected []map[string]interface{} expectedError error }{ { name: "happy flow - created apps", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, repoApps: []string{ "app1", "app2", @@ -381,9 +382,9 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { "p1/app4", }, repoError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "path": map[string]any{ + "path": map[string]interface{}{ "path": "app1", "basename": "app1", "basenameNormalized": "app1", @@ -393,7 +394,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, }, { - "path": map[string]any{ + "path": map[string]interface{}{ "path": "app2", "basename": "app2", "basenameNormalized": "app2", @@ -403,7 +404,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, }, { - "path": map[string]any{ + "path": map[string]interface{}{ "path": "app_3", "basename": "app_3", "basenameNormalized": "app-3", @@ -417,7 +418,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, { name: "It prefixes path parameters with PathParamPrefix", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, pathParamPrefix: "myRepo", repoApps: []string{ "app1", @@ -426,10 +427,10 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { "p1/app4", }, repoError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "myRepo": map[string]any{ - "path": map[string]any{ + "myRepo": map[string]interface{}{ + "path": map[string]interface{}{ "path": "app1", "basename": "app1", "basenameNormalized": "app1", @@ -440,8 +441,8 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, }, { - "myRepo": map[string]any{ - "path": map[string]any{ + "myRepo": map[string]interface{}{ + "path": map[string]interface{}{ "path": "app2", "basename": "app2", "basenameNormalized": "app2", @@ -452,8 +453,8 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, }, { - "myRepo": map[string]any{ - "path": map[string]any{ + "myRepo": map[string]interface{}{ + "path": map[string]interface{}{ "path": "app_3", "basename": "app_3", "basenameNormalized": "app-3", @@ -468,7 +469,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, { name: "It filters application according to the paths", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "p1/*"}, {Path: "p1/*/*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "p1/*"}, {Path: "p1/*/*"}}, repoApps: []string{ "app1", "p1/app2", @@ -476,9 +477,9 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { "p1/p2/p3/app4", }, repoError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "path": map[string]any{ + "path": map[string]interface{}{ "path": "p1/app2", "basename": "app2", "basenameNormalized": "app2", @@ -489,7 +490,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, }, { - "path": map[string]any{ + "path": map[string]interface{}{ "path": "p1/p2/app3", "basename": "app3", "basenameNormalized": "app3", @@ -505,7 +506,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, { name: "It filters application according to the paths with Exclude", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "p1/*", Exclude: true}, {Path: "*"}, {Path: "*/*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "p1/*", Exclude: true}, {Path: "*"}, {Path: "*/*"}}, repoApps: []string{ "app1", "app2", @@ -514,9 +515,9 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { "p2/app3", }, repoError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "path": map[string]any{ + "path": map[string]interface{}{ "path": "app1", "basename": "app1", "basenameNormalized": "app1", @@ -526,7 +527,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, }, { - "path": map[string]any{ + "path": map[string]interface{}{ "path": "app2", "basename": "app2", "basenameNormalized": "app2", @@ -536,7 +537,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, }, { - "path": map[string]any{ + "path": map[string]interface{}{ "path": "p2/app3", "basename": "app3", "basenameNormalized": "app3", @@ -551,7 +552,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, { name: "Expecting same exclude behavior with different order", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}, {Path: "*/*"}, {Path: "p1/*", Exclude: true}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}, {Path: "*/*"}, {Path: "p1/*", Exclude: true}}, repoApps: []string{ "app1", "app2", @@ -560,9 +561,9 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { "p2/app3", }, repoError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "path": map[string]any{ + "path": map[string]interface{}{ "path": "app1", "basename": "app1", "basenameNormalized": "app1", @@ -572,7 +573,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, }, { - "path": map[string]any{ + "path": map[string]interface{}{ "path": "app2", "basename": "app2", "basenameNormalized": "app2", @@ -582,7 +583,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, }, { - "path": map[string]any{ + "path": map[string]interface{}{ "path": "p2/app3", "basename": "app3", "basenameNormalized": "app3", @@ -597,19 +598,19 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { }, { name: "handles empty response from repo server", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, repoApps: []string{}, repoError: nil, - expected: []map[string]any{}, + expected: []map[string]interface{}{}, expectedError: nil, }, { name: "handles error from repo server", - directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, repoApps: []string{}, - repoError: errors.New("error"), - expected: []map[string]any{}, - expectedError: errors.New("error generating params from git: error getting directories from repo: error"), + repoError: fmt.Errorf("error"), + expected: []map[string]interface{}{}, + expectedError: fmt.Errorf("error generating params from git: error getting directories from repo: error"), }, } @@ -621,17 +622,17 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { argoCDServiceMock := mocks.Repos{} - argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) + argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) gitGenerator := NewGitGenerator(&argoCDServiceMock, "") - applicationSetInfo := v1alpha1.ApplicationSet{ + applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", }, - Spec: v1alpha1.ApplicationSetSpec{ + Spec: argoprojiov1alpha1.ApplicationSetSpec{ GoTemplate: true, - Generators: []v1alpha1.ApplicationSetGenerator{{ - Git: &v1alpha1.GitGenerator{ + Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{ + Git: &argoprojiov1alpha1.GitGenerator{ RepoURL: "RepoURL", Revision: "Revision", Directories: testCaseCopy.directories, @@ -644,7 +645,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - appProject := v1alpha1.AppProject{} + appProject := argoprojiov1alpha1.AppProject{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() @@ -666,18 +667,18 @@ func TestGitGenerateParamsFromFiles(t *testing.T) { cases := []struct { name string // files is the list of paths/globs to match - files []v1alpha1.GitFileGeneratorItem + files []argoprojiov1alpha1.GitFileGeneratorItem // repoFileContents maps repo path to the literal contents of that path repoFileContents map[string][]byte // if repoPathsError is non-nil, the call to GetPaths(...) will return this error value repoPathsError error values map[string]string - expected []map[string]any + expected []map[string]interface{} expectedError error }{ { name: "happy flow: create params from git files", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, repoFileContents: map[string][]byte{ "cluster-config/production/config.json": []byte(`{ "cluster": { @@ -703,7 +704,7 @@ func TestGitGenerateParamsFromFiles(t *testing.T) { }`), }, repoPathsError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "cluster.owner": "john.doe@example.com", "cluster.name": "production", @@ -737,7 +738,7 @@ func TestGitGenerateParamsFromFiles(t *testing.T) { }, { name: "Value variable interpolation", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, repoFileContents: map[string][]byte{ "cluster-config/production/config.json": []byte(`{ "cluster": { @@ -767,7 +768,7 @@ func TestGitGenerateParamsFromFiles(t *testing.T) { "aaa": "{{ cluster.owner }}", "no-op": "{{ this-does-not-exist }}", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "cluster.owner": "john.doe@example.com", "cluster.name": "production", @@ -805,25 +806,25 @@ func TestGitGenerateParamsFromFiles(t *testing.T) { }, { name: "handles error during getting repo paths", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, repoFileContents: map[string][]byte{}, - repoPathsError: errors.New("paths error"), - expected: []map[string]any{}, - expectedError: errors.New("error generating params from git: paths error"), + repoPathsError: fmt.Errorf("paths error"), + expected: []map[string]interface{}{}, + expectedError: fmt.Errorf("error generating params from git: paths error"), }, { name: "test invalid JSON file returns error", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, repoFileContents: map[string][]byte{ "cluster-config/production/config.json": []byte(`invalid json file`), }, repoPathsError: nil, - expected: []map[string]any{}, - expectedError: errors.New("error generating params from git: unable to process file 'cluster-config/production/config.json': unable to parse file: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type map[string]interface {}"), + expected: []map[string]interface{}{}, + expectedError: fmt.Errorf("error generating params from git: unable to process file 'cluster-config/production/config.json': unable to parse file: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type map[string]interface {}"), }, { name: "test JSON array", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, repoFileContents: map[string][]byte{ "cluster-config/production/config.json": []byte(` [ @@ -847,7 +848,7 @@ func TestGitGenerateParamsFromFiles(t *testing.T) { ]`), }, repoPathsError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "cluster.owner": "john.doe@example.com", "cluster.name": "production", @@ -878,7 +879,7 @@ func TestGitGenerateParamsFromFiles(t *testing.T) { }, { name: "Test YAML flow", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.yaml"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.yaml"}}, repoFileContents: map[string][]byte{ "cluster-config/production/config.yaml": []byte(` cluster: @@ -899,7 +900,7 @@ cluster: `), }, repoPathsError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "cluster.owner": "john.doe@example.com", "cluster.name": "production", @@ -932,7 +933,7 @@ cluster: }, { name: "test YAML array", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.yaml"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.yaml"}}, repoFileContents: map[string][]byte{ "cluster-config/production/config.yaml": []byte(` - cluster: @@ -947,7 +948,7 @@ cluster: address: https://kubernetes.default.svc`), }, repoPathsError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "cluster.owner": "john.doe@example.com", "cluster.name": "production", @@ -985,17 +986,17 @@ cluster: t.Parallel() argoCDServiceMock := mocks.Repos{} - argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(testCaseCopy.repoFileContents, testCaseCopy.repoPathsError) gitGenerator := NewGitGenerator(&argoCDServiceMock, "") - applicationSetInfo := v1alpha1.ApplicationSet{ + applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", }, - Spec: v1alpha1.ApplicationSetSpec{ - Generators: []v1alpha1.ApplicationSetGenerator{{ - Git: &v1alpha1.GitGenerator{ + Spec: argoprojiov1alpha1.ApplicationSetSpec{ + Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{ + Git: &argoprojiov1alpha1.GitGenerator{ RepoURL: "RepoURL", Revision: "Revision", Files: testCaseCopy.files, @@ -1008,927 +1009,12 @@ cluster: scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - appProject := v1alpha1.AppProject{} - - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() - - got, err := gitGenerator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo, client) - - if testCaseCopy.expectedError != nil { - require.EqualError(t, err, testCaseCopy.expectedError.Error()) - } else { - require.NoError(t, err) - assert.ElementsMatch(t, testCaseCopy.expected, got) - } - - argoCDServiceMock.AssertExpectations(t) - }) - } -} - -// TestGitGeneratorParamsFromFilesWithExcludeOptionWithNewGlobbing tests the params values generated by git file generator -// when exclude option is set to true. It gives the result files based on new globbing pattern - doublestar package -func TestGitGeneratorParamsFromFilesWithExcludeOptionWithNewGlobbing(t *testing.T) { - cases := []struct { - name string - // files is the list of paths/globs to match - files []v1alpha1.GitFileGeneratorItem - // includePattern contains a list of file patterns that needs to be included - includePattern []string - // excludePattern contains a list of file patterns that needs to be excluded - excludePattern []string - // includeFiles is a map with key as absolute path to file and value as the content in bytes that satisfies the includePattern - includeFiles map[string][]byte - // excludeFiles is a map with key as absolute path to file and value as the content in bytes that satisfies the excludePattern - // This means all the files should be excluded - excludeFiles map[string][]byte - // noMatchFiles contains all the files that neither match include pattern nor exclude pattern - // Instead of keeping those files in the excludeFiles map, it is better to keep those files separately - // in a separate field like 'noMatchFiles' to avoid confusion. - noMatchFiles map[string][]byte - // if repoPathsError is non-nil, the call to GetPaths(...) will return this error value - repoPathsError error - values map[string]string - expected []map[string]any - expectedError error - }{ - { - name: "filter files according to file-path with exclude", - files: []v1alpha1.GitFileGeneratorItem{ - { - Path: "**/config.json", - }, - { - Path: "p1/**/config.json", - Exclude: true, - }, - }, - includePattern: []string{"**/config.json"}, - excludePattern: []string{"p1/**/config.json"}, - includeFiles: map[string][]byte{ - "cluster-config/production/config.json": []byte(`{ - "cluster": { - "owner": "john.doe@example.com", - "name": "production", - "address": "https://kubernetes.default.svc" - }, - "key1": "val1", - "key2": { - "key2_1": "val2_1", - "key2_2": { - "key2_2_1": "val2_2_1" - } - }, - "key3": 123 - } -`), - "p1/config.json": []byte(`{ - "database": { - "admin": "db.admin@example.com", - "name": "user-data", - "host": "db.internal.local", - "settings": { - "replicas": 3, - "backup": "daily" - } - } - } -`), - "p1/p2/config.json": []byte(``), - }, - excludeFiles: map[string][]byte{ - "p1/config.json": []byte(`{ - "database": { - "admin": "db.admin@example.com", - "name": "user-data", - "host": "db.internal.local", - "settings": { - "replicas": 3, - "backup": "daily" - } - } - } -`), - "p1/p2/config.json": []byte(``), - }, - repoPathsError: nil, - expected: []map[string]any{ - { - "cluster.owner": "john.doe@example.com", - "cluster.name": "production", - "cluster.address": "https://kubernetes.default.svc", - "key1": "val1", - "key2.key2_1": "val2_1", - "key2.key2_2.key2_2_1": "val2_2_1", - "key3": "123", - "path": "cluster-config/production", - "path.basename": "production", - "path[0]": "cluster-config", - "path[1]": "production", - "path.basenameNormalized": "production", - "path.filename": "config.json", - "path.filenameNormalized": "config.json", - }, - }, - }, - { - name: "filter files according to multiple file-paths with exclude", - files: []v1alpha1.GitFileGeneratorItem{ - {Path: "**/config.json"}, - {Path: "p1/app2/config.json", Exclude: true}, - {Path: "p1/app3/config.json", Exclude: true}, - }, - includePattern: []string{"**/config.json"}, - excludePattern: []string{"p1/app2/config.json", "p1/app3/config.json"}, - includeFiles: map[string][]byte{ - "p1/config.json": []byte(`{ - "cluster": { - "owner": "john.doe@example.com", - "name": "production", - "address": "https://kubernetes.default.svc", - "inner": { - "one" : "two" - } - } -}`), - "p1/app2/config.json": []byte(`{}`), - "p1/app3/config.json": []byte(`{}`), - }, - excludeFiles: map[string][]byte{ - "p1/app2/config.json": []byte(`{}`), - "p1/app3/config.json": []byte(`{}`), - }, - repoPathsError: nil, - expected: []map[string]any{ - { - "cluster.owner": "john.doe@example.com", - "cluster.name": "production", - "cluster.address": "https://kubernetes.default.svc", - "cluster.inner.one": "two", - "path": "p1", - "path.basename": "p1", - "path[0]": "p1", - "path.basenameNormalized": "p1", - "path.filename": "config.json", - "path.filenameNormalized": "config.json", - }, - }, - }, - { - name: "docs example test case to filter files according to multiple file-paths with exclude", - files: []v1alpha1.GitFileGeneratorItem{{Path: "cluster-config/**/config.json"}, {Path: "cluster-config/*/dev/config.json", Exclude: true}}, - includePattern: []string{"cluster-config/**/config.json"}, - excludePattern: []string{"cluster-config/*/dev/config.json"}, - includeFiles: map[string][]byte{ - "cluster-config/engineering/prod/config.json": []byte(` -cluster: - owner: john.doe@example.com - name: production - address: https://kubernetes.default.svc -`), - "cluster-config/engineering/dev/config.json": []byte(` -cluster: - owner: foo.bar@example.com - name: staging - address: https://kubernetes.default.svc -`), - }, - excludeFiles: map[string][]byte{ - "cluster-config/engineering/dev/config.json": []byte(` -cluster: - owner: foo.bar@example.com - name: staging - address: https://kubernetes.default.svc -`), - }, - repoPathsError: nil, - expected: []map[string]any{ - { - "cluster.owner": "john.doe@example.com", - "cluster.name": "production", - "cluster.address": "https://kubernetes.default.svc", - "path": "cluster-config/engineering/prod", - "path.basename": "prod", - "path[0]": "cluster-config", - "path[1]": "engineering", - "path[2]": "prod", - "path.basenameNormalized": "prod", - "path.filename": "config.json", - "path.filenameNormalized": "config.json", - }, - }, - }, - { - name: "testcase to verify new globbing pattern without any exclude", - files: []v1alpha1.GitFileGeneratorItem{{Path: "some-path/*.yaml"}}, - includePattern: []string{"some-path/*.yaml"}, - excludePattern: nil, - includeFiles: map[string][]byte{ - "some-path/values.yaml": []byte(` -cluster: - owner: john.doe@example.com - name: production - address: https://kubernetes.default.svc -`), - }, - excludeFiles: map[string][]byte{}, - noMatchFiles: map[string][]byte{ - "some-path/staging/values.yaml": []byte(` -cluster: - owner: foo.bar@example.com - name: staging - address: https://kubernetes.default.svc -`), - }, - repoPathsError: nil, - expected: []map[string]any{ - { - "cluster.owner": "john.doe@example.com", - "cluster.name": "production", - "cluster.address": "https://kubernetes.default.svc", - "path": "some-path", - "path.basename": "some-path", - "path[0]": "some-path", - "path.basenameNormalized": "some-path", - "path.filename": "values.yaml", - "path.filenameNormalized": "values.yaml", - }, - }, - expectedError: nil, - }, - { - name: "test to verify the solution for Git File Generator Problem", // https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/applicationset/Generators-Git-File-Globbing.md#git-file-generator-globbing - files: []v1alpha1.GitFileGeneratorItem{{Path: "cluster-charts/*/*/values.yaml"}, {Path: "cluster-charts/*/values.yaml", Exclude: true}}, - includePattern: []string{"cluster-charts/*/*/values.yaml"}, - excludePattern: []string{"cluster-charts/*/values.yaml"}, - includeFiles: map[string][]byte{ - "cluster-charts/cluster1/mychart/values.yaml": []byte(` -env: staging -`), - "cluster-charts/cluster1/myotherchart/values.yaml": []byte(` -env: prod -`), - }, - excludeFiles: map[string][]byte{ - "cluster-charts/cluster2/values.yaml": []byte(` -env: dev -`), - }, - noMatchFiles: map[string][]byte{ - "cluster-charts/cluster1/mychart/charts/mysubchart/values.yaml": []byte(` -env: testing -`), - }, - repoPathsError: nil, - expected: []map[string]any{ - { - "env": "staging", - "path": "cluster-charts/cluster1/mychart", - "path.filenameNormalized": "values.yaml", - "path[0]": "cluster-charts", - "path[1]": "cluster1", - "path[2]": "mychart", - "path.basename": "mychart", - "path.filename": "values.yaml", - "path.basenameNormalized": "mychart", - }, - { - "env": "prod", - "path": "cluster-charts/cluster1/myotherchart", - "path.filenameNormalized": "values.yaml", - "path[0]": "cluster-charts", - "path[1]": "cluster1", - "path[2]": "myotherchart", - "path.basename": "myotherchart", - "path.filename": "values.yaml", - "path.basenameNormalized": "myotherchart", - }, - }, - expectedError: nil, - }, - } - for _, testCase := range cases { - testCaseCopy := testCase - - t.Run(testCaseCopy.name, func(t *testing.T) { - t.Parallel() - - argoCDServiceMock := mocks.Repos{} - - // IMPORTANT: we try to get the files from the repo server that matches the patterns - // If we find those files also satisfy the exclude pattern, we remove them from map - // This is generally done by the g.repos.GetFiles() function. - // With the below mock setup, we make sure that if the GetFiles() function gets called - // for a include or exclude pattern, it should always return the includeFiles or excludeFiles. - for _, pattern := range testCaseCopy.excludePattern { - argoCDServiceMock. - On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, pattern, mock.Anything, mock.Anything). - Return(testCaseCopy.excludeFiles, testCaseCopy.repoPathsError) - } - - for _, pattern := range testCaseCopy.includePattern { - argoCDServiceMock. - On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, pattern, mock.Anything, mock.Anything). - Return(testCaseCopy.includeFiles, testCaseCopy.repoPathsError) - } - - gitGenerator := NewGitGenerator(&argoCDServiceMock, "") - applicationSetInfo := v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "set", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Generators: []v1alpha1.ApplicationSetGenerator{{ - Git: &v1alpha1.GitGenerator{ - RepoURL: "RepoURL", - Revision: "Revision", - Files: testCaseCopy.files, - Values: testCaseCopy.values, - }, - }}, - }, - } - - scheme := runtime.NewScheme() - err := v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - appProject := v1alpha1.AppProject{} - - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() - - got, err := gitGenerator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo, client) - - if testCaseCopy.expectedError != nil { - require.EqualError(t, err, testCaseCopy.expectedError.Error()) - } else { - require.NoError(t, err) - assert.ElementsMatch(t, testCaseCopy.expected, got) - } - - argoCDServiceMock.AssertExpectations(t) - }) - } -} - -// TestGitGeneratorParamsFromFilesWithExcludeOptionWithOldGlobbing tests the params values generated by git file generator -// // when exclude option is set to true. It gives the result files based on old globbing pattern - git ls-files -func TestGitGeneratorParamsFromFilesWithExcludeOptionWithOldGlobbing(t *testing.T) { - cases := []struct { - name string - // files is the list of paths/globs to match - files []v1alpha1.GitFileGeneratorItem - // includePattern contains a list of file patterns that needs to be included - includePattern []string - // excludePattern contains a list of file patterns that needs to be excluded - excludePattern []string - // includeFiles is a map with key as absolute path to file and value as the content in bytes that satisfies the includePattern - includeFiles map[string][]byte - // excludeFiles is a map with key as absolute path to file and value as the content in bytes that satisfies the excludePattern - // This means all the files should be excluded - excludeFiles map[string][]byte - // noMatchFiles contains all the files that neither match include pattern nor exclude pattern - // Instead of keeping those files in the excludeFiles map, it is better to keep those files separately - // in a separate field like 'noMatchFiles' to avoid confusion. - noMatchFiles map[string][]byte - // if repoPathsError is non-nil, the call to GetPaths(...) will return this error value - repoPathsError error - values map[string]string - expected []map[string]any - expectedError error - }{ - { - name: "filter files according to file-path with exclude", - files: []v1alpha1.GitFileGeneratorItem{ - { - Path: "**/config.json", - }, - { - Path: "p1/**/config.json", - Exclude: true, - }, - }, - includePattern: []string{"**/config.json"}, - excludePattern: []string{"p1/**/config.json"}, - includeFiles: map[string][]byte{ - "cluster-config/production/config.json": []byte(`{ - "cluster": { - "owner": "john.doe@example.com", - "name": "production", - "address": "https://kubernetes.default.svc" - }, - "key1": "val1", - "key2": { - "key2_1": "val2_1", - "key2_2": { - "key2_2_1": "val2_2_1" - } - }, - "key3": 123 - } -`), - "p1/config.json": []byte(`{ - "database": { - "admin": "db.admin@example.com", - "name": "user-data", - "host": "db.internal.local", - "settings": { - "replicas": 3, - "backup": "daily" - } - } - } -`), - "p1/p2/config.json": []byte(``), - }, - excludeFiles: map[string][]byte{ - "p1/config.json": []byte(`{ - "database": { - "admin": "db.admin@example.com", - "name": "user-data", - "host": "db.internal.local", - "settings": { - "replicas": 3, - "backup": "daily" - } - } - } -`), - "p1/p2/config.json": []byte(``), - }, - repoPathsError: nil, - expected: []map[string]any{ - { - "cluster.owner": "john.doe@example.com", - "cluster.name": "production", - "cluster.address": "https://kubernetes.default.svc", - "key1": "val1", - "key2.key2_1": "val2_1", - "key2.key2_2.key2_2_1": "val2_2_1", - "key3": "123", - "path": "cluster-config/production", - "path.basename": "production", - "path[0]": "cluster-config", - "path[1]": "production", - "path.basenameNormalized": "production", - "path.filename": "config.json", - "path.filenameNormalized": "config.json", - }, - }, - }, - { - name: "filter files according to multiple file-paths with exclude", - files: []v1alpha1.GitFileGeneratorItem{ - {Path: "**/config.json"}, - {Path: "p1/app2/config.json", Exclude: true}, - {Path: "p1/app3/config.json", Exclude: true}, - }, - includePattern: []string{"**/config.json"}, - excludePattern: []string{"p1/app2/config.json", "p1/app3/config.json"}, - includeFiles: map[string][]byte{ - "p1/config.json": []byte(`{ - "cluster": { - "owner": "john.doe@example.com", - "name": "production", - "address": "https://kubernetes.default.svc", - "inner": { - "one" : "two" - } - } -}`), - "p1/app2/config.json": []byte(`{}`), - "p1/app3/config.json": []byte(`{}`), - }, - excludeFiles: map[string][]byte{ - "p1/app2/config.json": []byte(`{}`), - "p1/app3/config.json": []byte(`{}`), - }, - repoPathsError: nil, - expected: []map[string]any{ - { - "cluster.owner": "john.doe@example.com", - "cluster.name": "production", - "cluster.address": "https://kubernetes.default.svc", - "cluster.inner.one": "two", - "path": "p1", - "path.basename": "p1", - "path[0]": "p1", - "path.basenameNormalized": "p1", - "path.filename": "config.json", - "path.filenameNormalized": "config.json", - }, - }, - }, - { - name: "docs example test case to filter files according to multiple file-paths with exclude", - files: []v1alpha1.GitFileGeneratorItem{{Path: "cluster-config/**/config.json"}, {Path: "cluster-config/*/dev/config.json", Exclude: true}}, - includePattern: []string{"cluster-config/**/config.json"}, - excludePattern: []string{"cluster-config/*/dev/config.json"}, - includeFiles: map[string][]byte{ - "cluster-config/engineering/prod/config.json": []byte(` -cluster: - owner: john.doe@example.com - name: production - address: https://kubernetes.default.svc -`), - "cluster-config/engineering/dev/config.json": []byte(` -cluster: - owner: foo.bar@example.com - name: staging - address: https://kubernetes.default.svc -`), - }, - excludeFiles: map[string][]byte{ - "cluster-config/engineering/dev/config.json": []byte(` -cluster: - owner: foo.bar@example.com - name: staging - address: https://kubernetes.default.svc -`), - }, - repoPathsError: nil, - expected: []map[string]any{ - { - "cluster.owner": "john.doe@example.com", - "cluster.name": "production", - "cluster.address": "https://kubernetes.default.svc", - "path": "cluster-config/engineering/prod", - "path.basename": "prod", - "path[0]": "cluster-config", - "path[1]": "engineering", - "path[2]": "prod", - "path.basenameNormalized": "prod", - "path.filename": "config.json", - "path.filenameNormalized": "config.json", - }, - }, - }, - { - name: "testcase to verify new globbing pattern without any exclude", - files: []v1alpha1.GitFileGeneratorItem{{Path: "some-path/*.yaml"}}, - includePattern: []string{"some-path/*.yaml"}, - excludePattern: nil, - includeFiles: map[string][]byte{ - "some-path/values.yaml": []byte(` -cluster: - owner: john.doe@example.com - name: production - address: https://kubernetes.default.svc -`), - "some-path/staging/values.yaml": []byte(` -cluster: - owner: foo.bar@example.com - name: staging - address: https://kubernetes.default.svc -`), - }, - excludeFiles: map[string][]byte{}, - repoPathsError: nil, - expected: []map[string]any{ - { - "cluster.owner": "john.doe@example.com", - "cluster.name": "production", - "cluster.address": "https://kubernetes.default.svc", - "path": "some-path", - "path.basename": "some-path", - "path[0]": "some-path", - "path.basenameNormalized": "some-path", - "path.filename": "values.yaml", - "path.filenameNormalized": "values.yaml", - }, - { - "cluster.owner": "foo.bar@example.com", - "cluster.name": "staging", - "cluster.address": "https://kubernetes.default.svc", - "path": "some-path/staging", - "path.basename": "staging", - "path[0]": "some-path", - "path[1]": "staging", - "path.basenameNormalized": "staging", - "path.filename": "values.yaml", - "path.filenameNormalized": "values.yaml", - }, - }, - expectedError: nil, - }, - { - name: "test to verify the solution for Git File Generator Problem", - files: []v1alpha1.GitFileGeneratorItem{{Path: "cluster-charts/*/*/values.yaml"}, {Path: "cluster-charts/*/values.yaml", Exclude: true}}, - includePattern: []string{"cluster-charts/*/*/values.yaml"}, - excludePattern: []string{"cluster-charts/*/values.yaml"}, - includeFiles: map[string][]byte{ - "cluster-charts/cluster1/mychart/values.yaml": []byte(` -env: staging -`), - "cluster-charts/cluster1/myotherchart/values.yaml": []byte(` -env: prod -`), - "cluster-charts/cluster1/mychart/charts/mysubchart/values.yaml": []byte(``), - }, - excludeFiles: map[string][]byte{ - "cluster-charts/cluster2/values.yaml": []byte(` -env: dev -`), - "cluster-charts/cluster1/mychart/values.yaml": []byte(` -env: staging -`), - "cluster-charts/cluster1/myotherchart/values.yaml": []byte(` -env: prod -`), - "cluster-charts/cluster1/mychart/charts/mysubchart/values.yaml": []byte(``), - }, - noMatchFiles: map[string][]byte{ - "cluster-charts/cluster1/mychart/charts/mysubchart/values.yaml": []byte(` -env: testing -`), - }, - repoPathsError: nil, - expected: []map[string]any{}, - expectedError: nil, - }, - } - for _, testCase := range cases { - testCaseCopy := testCase - - t.Run(testCaseCopy.name, func(t *testing.T) { - t.Parallel() - - argoCDServiceMock := mocks.Repos{} - - // IMPORTANT: we try to get the files from the repo server that matches the patterns - // If we find those files also satisfy the exclude pattern, we remove them from map - // This is generally done by the g.repos.GetFiles() function. - // With the below mock setup, we make sure that if the GetFiles() function gets called - // for a include or exclude pattern, it should always return the includeFiles or excludeFiles. - for _, pattern := range testCaseCopy.excludePattern { - argoCDServiceMock. - On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, pattern, mock.Anything, mock.Anything). - Return(testCaseCopy.excludeFiles, testCaseCopy.repoPathsError) - } - - for _, pattern := range testCaseCopy.includePattern { - argoCDServiceMock. - On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, pattern, mock.Anything, mock.Anything). - Return(testCaseCopy.includeFiles, testCaseCopy.repoPathsError) - } - - gitGenerator := NewGitGenerator(&argoCDServiceMock, "") - applicationSetInfo := v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "set", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Generators: []v1alpha1.ApplicationSetGenerator{{ - Git: &v1alpha1.GitGenerator{ - RepoURL: "RepoURL", - Revision: "Revision", - Files: testCaseCopy.files, - Values: testCaseCopy.values, - }, - }}, - }, - } - - scheme := runtime.NewScheme() - err := v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - appProject := v1alpha1.AppProject{} - - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() - - got, err := gitGenerator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo, client) - - if testCaseCopy.expectedError != nil { - require.EqualError(t, err, testCaseCopy.expectedError.Error()) - } else { - require.NoError(t, err) - assert.ElementsMatch(t, testCaseCopy.expected, got) - } - - argoCDServiceMock.AssertExpectations(t) - }) - } -} - -// TestGitGeneratorParamsFromFilesWithExcludeOption tests the params values generated by git file generator -// when exclude option is set to true. It gives the result files based on new globbing pattern - doublestar package -func TestGitGeneratorParamsFromFilesWithExcludeOptionGoTemplate(t *testing.T) { - cases := []struct { - name string - // files is the list of paths/globs to match - files []v1alpha1.GitFileGeneratorItem - // includePattern contains a list of file patterns that needs to be included - includePattern []string - // excludePattern contains a list of file patterns that needs to be excluded - excludePattern []string - // includeFiles is a map with key as absolute path to file and value as the content in bytes that satisfies the includePattern - includeFiles map[string][]byte - // excludeFiles is a map with key as absolute path to file and value as the content in bytes that satisfies the excludePattern - // This means all the files should be excluded - excludeFiles map[string][]byte - // if repoPathsError is non-nil, the call to GetPaths(...) will return this error value - repoPathsError error - values map[string]string - expected []map[string]any - expectedError error - }{ - { - name: "filter files according to file-path with exclude", - files: []v1alpha1.GitFileGeneratorItem{ - { - Path: "**/config.json", - }, - { - Path: "p1/**/config.json", - Exclude: true, - }, - }, - includePattern: []string{"**/config.json"}, - excludePattern: []string{"p1/**/config.json"}, - includeFiles: map[string][]byte{ - "cluster-config/production/config.json": []byte(`{ - "cluster": { - "owner": "john.doe@example.com", - "name": "production", - "address": "https://kubernetes.default.svc" - }, - "key1": "val1", - "key2": { - "key2_1": "val2_1", - "key2_2": { - "key2_2_1": "val2_2_1" - } - }, - "key3": 123 -} -`), - }, - excludeFiles: map[string][]byte{ - "p1/p2/config.json": []byte(`{ - "service": { - "maintainer": "dev.team@example.com", - "serviceName": "auth-service", - "endpoint": "http://auth.internal.svc", - "config": { - "retries": 5, - "timeout": "30s" - } - } - } -`), - }, - repoPathsError: nil, - expected: []map[string]any{ - { - "cluster": map[string]any{ - "owner": "john.doe@example.com", - "name": "production", - "address": "https://kubernetes.default.svc", - }, - "key1": "val1", - "key2": map[string]any{ - "key2_1": "val2_1", - "key2_2": map[string]any{ - "key2_2_1": "val2_2_1", - }, - }, - "key3": float64(123), - "path": map[string]any{ - "path": "cluster-config/production", - "basename": "production", - "filename": "config.json", - "basenameNormalized": "production", - "filenameNormalized": "config.json", - "segments": []string{ - "cluster-config", - "production", - }, - }, - }, - }, - expectedError: nil, - }, - { - name: "filter files according to multiple file-paths with exclude", - files: []v1alpha1.GitFileGeneratorItem{ - {Path: "**/config.json"}, - {Path: "p1/app2/config.json", Exclude: true}, - {Path: "p1/app3/config.json", Exclude: true}, - }, - includePattern: []string{"**/config.json"}, - excludePattern: []string{"p1/app2/config.json", "p1/app3/config.json"}, - includeFiles: map[string][]byte{ - "p1/config.json": []byte(`{ - "cluster": { - "owner": "john.doe@example.com", - "name": "production", - "address": "https://kubernetes.default.svc", - "inner": { - "one" : "two" - } - } -}`), - }, - excludeFiles: map[string][]byte{ - "p1/app2/config.json": []byte(`{ - "database": { - "admin": "alice.smith@example.com", - "env": "staging", - "url": "postgres://db.internal.svc:5432", - "settings": { - "replicas": 3, - "backup": "enabled" - } - } - } -`), - "p1/app3/config.json": []byte(`{ - "storage": { - "owner": "charlie.brown@example.com", - "bucketName": "app-assets", - "region": "us-west-2", - "options": { - "versioning": true, - "encryption": "AES256" - } - } - } -`), - }, - repoPathsError: nil, - expected: []map[string]any{ - { - "cluster": map[string]any{ - "owner": "john.doe@example.com", - "name": "production", - "address": "https://kubernetes.default.svc", - "inner": map[string]any{ - "one": "two", - }, - }, - "path": map[string]any{ - "path": "p1", - "basename": "p1", - "filename": "config.json", - "basenameNormalized": "p1", - "filenameNormalized": "config.json", - "segments": []string{ - "p1", - }, - }, - }, - }, - expectedError: nil, - }, - } - for _, testCase := range cases { - testCaseCopy := testCase - - t.Run(testCaseCopy.name, func(t *testing.T) { - t.Parallel() - - argoCDServiceMock := mocks.Repos{} - // IMPORTANT: we try to get the files from the repo server that matches the patterns - // If we find those files also satisfy the exclude pattern, we remove them from map - // This is generally done by the g.repos.GetFiles() function. - // With the below mock setup, we make sure that if the GetFiles() function gets called - // for a include or exclude pattern, it should always return the includeFiles or excludeFiles. - for _, pattern := range testCaseCopy.excludePattern { - argoCDServiceMock. - On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, pattern, mock.Anything, mock.Anything). - Return(testCaseCopy.excludeFiles, testCaseCopy.repoPathsError) - } - - for _, pattern := range testCaseCopy.includePattern { - argoCDServiceMock. - On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, pattern, mock.Anything, mock.Anything). - Return(testCaseCopy.includeFiles, testCaseCopy.repoPathsError) - } - - gitGenerator := NewGitGenerator(&argoCDServiceMock, "") - applicationSetInfo := v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "set", - }, - Spec: v1alpha1.ApplicationSetSpec{ - GoTemplate: true, - Generators: []v1alpha1.ApplicationSetGenerator{{ - Git: &v1alpha1.GitGenerator{ - RepoURL: "RepoURL", - Revision: "Revision", - Files: testCaseCopy.files, - }, - }}, - }, - } - - scheme := runtime.NewScheme() - err := v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - appProject := v1alpha1.AppProject{} + appProject := argoprojiov1alpha1.AppProject{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() got, err := gitGenerator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo, client) + fmt.Println(got, err) if testCaseCopy.expectedError != nil { require.EqualError(t, err, testCaseCopy.expectedError.Error()) @@ -1946,17 +1032,17 @@ func TestGitGenerateParamsFromFilesGoTemplate(t *testing.T) { cases := []struct { name string // files is the list of paths/globs to match - files []v1alpha1.GitFileGeneratorItem + files []argoprojiov1alpha1.GitFileGeneratorItem // repoFileContents maps repo path to the literal contents of that path repoFileContents map[string][]byte // if repoPathsError is non-nil, the call to GetPaths(...) will return this error value repoPathsError error - expected []map[string]any + expected []map[string]interface{} expectedError error }{ { name: "happy flow: create params from git files", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, repoFileContents: map[string][]byte{ "cluster-config/production/config.json": []byte(`{ "cluster": { @@ -1982,22 +1068,22 @@ func TestGitGenerateParamsFromFilesGoTemplate(t *testing.T) { }`), }, repoPathsError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "cluster": map[string]any{ + "cluster": map[string]interface{}{ "owner": "john.doe@example.com", "name": "production", "address": "https://kubernetes.default.svc", }, "key1": "val1", - "key2": map[string]any{ + "key2": map[string]interface{}{ "key2_1": "val2_1", - "key2_2": map[string]any{ + "key2_2": map[string]interface{}{ "key2_2_1": "val2_2_1", }, }, "key3": float64(123), - "path": map[string]any{ + "path": map[string]interface{}{ "path": "cluster-config/production", "basename": "production", "filename": "config.json", @@ -2010,12 +1096,12 @@ func TestGitGenerateParamsFromFilesGoTemplate(t *testing.T) { }, }, { - "cluster": map[string]any{ + "cluster": map[string]interface{}{ "owner": "foo.bar@example.com", "name": "staging", "address": "https://kubernetes.default.svc", }, - "path": map[string]any{ + "path": map[string]interface{}{ "path": "cluster-config/staging", "basename": "staging", "filename": "config.json", @@ -2032,25 +1118,25 @@ func TestGitGenerateParamsFromFilesGoTemplate(t *testing.T) { }, { name: "handles error during getting repo paths", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, repoFileContents: map[string][]byte{}, - repoPathsError: errors.New("paths error"), - expected: []map[string]any{}, - expectedError: errors.New("error generating params from git: paths error"), + repoPathsError: fmt.Errorf("paths error"), + expected: []map[string]interface{}{}, + expectedError: fmt.Errorf("error generating params from git: paths error"), }, { name: "test invalid JSON file returns error", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, repoFileContents: map[string][]byte{ "cluster-config/production/config.json": []byte(`invalid json file`), }, repoPathsError: nil, - expected: []map[string]any{}, - expectedError: errors.New("error generating params from git: unable to process file 'cluster-config/production/config.json': unable to parse file: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type map[string]interface {}"), + expected: []map[string]interface{}{}, + expectedError: fmt.Errorf("error generating params from git: unable to process file 'cluster-config/production/config.json': unable to parse file: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type map[string]interface {}"), }, { name: "test JSON array", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.json"}}, repoFileContents: map[string][]byte{ "cluster-config/production/config.json": []byte(` [ @@ -2074,17 +1160,17 @@ func TestGitGenerateParamsFromFilesGoTemplate(t *testing.T) { ]`), }, repoPathsError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "cluster": map[string]any{ + "cluster": map[string]interface{}{ "owner": "john.doe@example.com", "name": "production", "address": "https://kubernetes.default.svc", - "inner": map[string]any{ + "inner": map[string]interface{}{ "one": "two", }, }, - "path": map[string]any{ + "path": map[string]interface{}{ "path": "cluster-config/production", "basename": "production", "filename": "config.json", @@ -2097,12 +1183,12 @@ func TestGitGenerateParamsFromFilesGoTemplate(t *testing.T) { }, }, { - "cluster": map[string]any{ + "cluster": map[string]interface{}{ "owner": "john.doe@example.com", "name": "staging", "address": "https://kubernetes.default.svc", }, - "path": map[string]any{ + "path": map[string]interface{}{ "path": "cluster-config/production", "basename": "production", "filename": "config.json", @@ -2119,7 +1205,7 @@ func TestGitGenerateParamsFromFilesGoTemplate(t *testing.T) { }, { name: "Test YAML flow", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.yaml"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.yaml"}}, repoFileContents: map[string][]byte{ "cluster-config/production/config.yaml": []byte(` cluster: @@ -2140,21 +1226,21 @@ cluster: `), }, repoPathsError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "cluster": map[string]any{ + "cluster": map[string]interface{}{ "owner": "john.doe@example.com", "name": "production", "address": "https://kubernetes.default.svc", }, "key1": "val1", - "key2": map[string]any{ + "key2": map[string]interface{}{ "key2_1": "val2_1", - "key2_2": map[string]any{ + "key2_2": map[string]interface{}{ "key2_2_1": "val2_2_1", }, }, - "path": map[string]any{ + "path": map[string]interface{}{ "path": "cluster-config/production", "basename": "production", "filename": "config.yaml", @@ -2167,12 +1253,12 @@ cluster: }, }, { - "cluster": map[string]any{ + "cluster": map[string]interface{}{ "owner": "foo.bar@example.com", "name": "staging", "address": "https://kubernetes.default.svc", }, - "path": map[string]any{ + "path": map[string]interface{}{ "path": "cluster-config/staging", "basename": "staging", "filename": "config.yaml", @@ -2189,7 +1275,7 @@ cluster: }, { name: "test YAML array", - files: []v1alpha1.GitFileGeneratorItem{{Path: "**/config.yaml"}}, + files: []argoprojiov1alpha1.GitFileGeneratorItem{{Path: "**/config.yaml"}}, repoFileContents: map[string][]byte{ "cluster-config/production/config.yaml": []byte(` - cluster: @@ -2204,17 +1290,17 @@ cluster: address: https://kubernetes.default.svc`), }, repoPathsError: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { - "cluster": map[string]any{ + "cluster": map[string]interface{}{ "owner": "john.doe@example.com", "name": "production", "address": "https://kubernetes.default.svc", - "inner": map[string]any{ + "inner": map[string]interface{}{ "one": "two", }, }, - "path": map[string]any{ + "path": map[string]interface{}{ "path": "cluster-config/production", "basename": "production", "filename": "config.yaml", @@ -2227,12 +1313,12 @@ cluster: }, }, { - "cluster": map[string]any{ + "cluster": map[string]interface{}{ "owner": "john.doe@example.com", "name": "staging", "address": "https://kubernetes.default.svc", }, - "path": map[string]any{ + "path": map[string]interface{}{ "path": "cluster-config/production", "basename": "production", "filename": "config.yaml", @@ -2256,18 +1342,18 @@ cluster: t.Parallel() argoCDServiceMock := mocks.Repos{} - argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(testCaseCopy.repoFileContents, testCaseCopy.repoPathsError) gitGenerator := NewGitGenerator(&argoCDServiceMock, "") - applicationSetInfo := v1alpha1.ApplicationSet{ + applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", }, - Spec: v1alpha1.ApplicationSetSpec{ + Spec: argoprojiov1alpha1.ApplicationSetSpec{ GoTemplate: true, - Generators: []v1alpha1.ApplicationSetGenerator{{ - Git: &v1alpha1.GitGenerator{ + Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{ + Git: &argoprojiov1alpha1.GitGenerator{ RepoURL: "RepoURL", Revision: "Revision", Files: testCaseCopy.files, @@ -2279,11 +1365,12 @@ cluster: scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - appProject := v1alpha1.AppProject{} + appProject := argoprojiov1alpha1.AppProject{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() got, err := gitGenerator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo, client) + fmt.Println(got, err) if testCaseCopy.expectedError != nil { require.EqualError(t, err, testCaseCopy.expectedError.Error()) @@ -2300,17 +1387,15 @@ cluster: func TestGitGenerator_GenerateParams(t *testing.T) { cases := []struct { name string - appProject v1alpha1.AppProject - directories []v1alpha1.GitDirectoryGeneratorItem + directories []argoprojiov1alpha1.GitDirectoryGeneratorItem pathParamPrefix string repoApps []string repoPathsError error repoFileContents map[string][]byte values map[string]string - expected []map[string]any + expected []map[string]interface{} expectedError error - expectedProject *string - appset v1alpha1.ApplicationSet + appset argoprojiov1alpha1.ApplicationSet callGetDirectories bool }{ { @@ -2319,32 +1404,32 @@ func TestGitGenerator_GenerateParams(t *testing.T) { "app1", }, repoPathsError: nil, - appset: v1alpha1.ApplicationSet{ + appset: argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", Namespace: "namespace", }, - Spec: v1alpha1.ApplicationSetSpec{ - Generators: []v1alpha1.ApplicationSetGenerator{{ - Git: &v1alpha1.GitGenerator{ + Spec: argoprojiov1alpha1.ApplicationSetSpec{ + Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{ + Git: &argoprojiov1alpha1.GitGenerator{ RepoURL: "RepoURL", Revision: "Revision", - Directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + Directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, PathParamPrefix: "", Values: map[string]string{ "foo": "bar", }, }, }}, - Template: v1alpha1.ApplicationSetTemplate{ - Spec: v1alpha1.ApplicationSpec{ + Template: argoprojiov1alpha1.ApplicationSetTemplate{ + Spec: argoprojiov1alpha1.ApplicationSpec{ Project: "{{.project}}", }, }, }, }, callGetDirectories: true, - expected: []map[string]any{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}}, + expected: []map[string]interface{}{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}}, expectedError: nil, }, { @@ -2353,130 +1438,49 @@ func TestGitGenerator_GenerateParams(t *testing.T) { "app1", }, repoPathsError: nil, - appset: v1alpha1.ApplicationSet{ + appset: argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", Namespace: "namespace", }, - Spec: v1alpha1.ApplicationSetSpec{ - Generators: []v1alpha1.ApplicationSetGenerator{{ - Git: &v1alpha1.GitGenerator{ + Spec: argoprojiov1alpha1.ApplicationSetSpec{ + Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{ + Git: &argoprojiov1alpha1.GitGenerator{ RepoURL: "RepoURL", Revision: "Revision", - Directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + Directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, PathParamPrefix: "", Values: map[string]string{ "foo": "bar", }, }, }}, - Template: v1alpha1.ApplicationSetTemplate{ - Spec: v1alpha1.ApplicationSpec{ + Template: argoprojiov1alpha1.ApplicationSetTemplate{ + Spec: argoprojiov1alpha1.ApplicationSpec{ Project: "project", }, }, }, }, callGetDirectories: false, - expected: []map[string]any{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}}, - expectedError: errors.New("error getting project project: appprojects.argoproj.io \"project\" not found"), - }, - { - name: "Project field is not templated - verify that project is passed through to repo-server as-is", - repoApps: []string{ - "app1", - }, - callGetDirectories: true, - appProject: v1alpha1.AppProject{ - TypeMeta: metav1.TypeMeta{}, - ObjectMeta: metav1.ObjectMeta{ - Name: "project", - Namespace: "argocd", - }, - }, - appset: v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "set", - Namespace: "namespace", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Generators: []v1alpha1.ApplicationSetGenerator{{ - Git: &v1alpha1.GitGenerator{ - RepoURL: "RepoURL", - Revision: "Revision", - Directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, - PathParamPrefix: "", - Values: map[string]string{ - "foo": "bar", - }, - }, - }}, - Template: v1alpha1.ApplicationSetTemplate{ - Spec: v1alpha1.ApplicationSpec{ - Project: "project", - }, - }, - }, - }, - expected: []map[string]any{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}}, - expectedProject: ptr.To("project"), - expectedError: nil, - }, - { - name: "Project field is templated - verify that project is passed through to repo-server as empty string", - repoApps: []string{ - "app1", - }, - callGetDirectories: true, - appset: v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "set", - Namespace: "namespace", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Generators: []v1alpha1.ApplicationSetGenerator{{ - Git: &v1alpha1.GitGenerator{ - RepoURL: "RepoURL", - Revision: "Revision", - Directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, - PathParamPrefix: "", - Values: map[string]string{ - "foo": "bar", - }, - }, - }}, - Template: v1alpha1.ApplicationSetTemplate{ - Spec: v1alpha1.ApplicationSpec{ - Project: "{{.project}}", - }, - }, - }, - }, - expected: []map[string]any{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}}, - expectedProject: ptr.To(""), - expectedError: nil, + expected: []map[string]interface{}{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}}, + expectedError: fmt.Errorf("error getting project project: appprojects.argoproj.io \"project\" not found"), }, } for _, testCase := range cases { argoCDServiceMock := mocks.Repos{} if testCase.callGetDirectories { - var project any - if testCase.expectedProject != nil { - project = *testCase.expectedProject - } else { - project = mock.Anything - } - - argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, project, mock.Anything, mock.Anything).Return(testCase.repoApps, testCase.repoPathsError) + argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCase.repoApps, testCase.repoPathsError) } - gitGenerator := NewGitGenerator(&argoCDServiceMock, "argocd") + gitGenerator := NewGitGenerator(&argoCDServiceMock, "namespace") scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) + appProject := argoprojiov1alpha1.AppProject{} - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&testCase.appProject).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() got, err := gitGenerator.GenerateParams(&testCase.appset.Spec.Generators[0], &testCase.appset, client) diff --git a/applicationset/generators/interface.go b/applicationset/generators/interface.go index 1928920023..88853c73b2 100644 --- a/applicationset/generators/interface.go +++ b/applicationset/generators/interface.go @@ -1,13 +1,13 @@ package generators import ( - "errors" + "fmt" "time" "sigs.k8s.io/controller-runtime/pkg/client" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/env" + 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. @@ -15,7 +15,7 @@ type Generator interface { // GenerateParams interprets the ApplicationSet and generates all relevant parameters for the application template. // The expected / desired list of parameters is returned, it then will be render and reconciled // against the current state of the Applications in the cluster. - GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, applicationSetInfo *argoprojiov1alpha1.ApplicationSet, client client.Client) ([]map[string]any, error) + GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, applicationSetInfo *argoprojiov1alpha1.ApplicationSet, client client.Client) ([]map[string]interface{}, error) // GetRequeueAfter is the generator can controller the next reconciled loop // In case there is more then one generator the time will be the minimum of the times. @@ -27,15 +27,15 @@ type Generator interface { } var ( - ErrEmptyAppSetGenerator = errors.New("ApplicationSet is empty") - NoRequeueAfter time.Duration + EmptyAppSetGeneratorError = fmt.Errorf("ApplicationSet is empty") + NoRequeueAfter time.Duration ) const ( - DefaultRequeueAfter = 3 * time.Minute + 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", DefaultRequeueAfter, 1*time.Second, 8760*time.Hour) + 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 index f85c7bf004..d27111bc14 100644 --- a/applicationset/generators/interface_test.go +++ b/applicationset/generators/interface_test.go @@ -13,12 +13,12 @@ func Test_getDefaultRequeueAfter(t *testing.T) { requeueAfterEnv string want time.Duration }{ - {name: "Default", requeueAfterEnv: "", want: DefaultRequeueAfter}, + {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: DefaultRequeueAfter}, - {name: "MoreThanMax", requeueAfterEnv: "8761h", want: DefaultRequeueAfter}, + {name: "LessThanMin", requeueAfterEnv: "1ms", want: DefaultRequeueAfterSeconds}, + {name: "MoreThanMax", requeueAfterEnv: "8761h", want: DefaultRequeueAfterSeconds}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/applicationset/generators/list.go b/applicationset/generators/list.go index 36b67a7bfa..fad6a6af5c 100644 --- a/applicationset/generators/list.go +++ b/applicationset/generators/list.go @@ -2,14 +2,13 @@ package generators import ( "encoding/json" - "errors" "fmt" "time" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/yaml" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) var _ Generator = (*ListGenerator)(nil) @@ -21,7 +20,7 @@ func NewListGenerator() Generator { return g } -func (g *ListGenerator) GetRequeueAfter(_ *argoprojiov1alpha1.ApplicationSetGenerator) time.Duration { +func (g *ListGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) time.Duration { return NoRequeueAfter } @@ -29,20 +28,20 @@ func (g *ListGenerator) GetTemplate(appSetGenerator *argoprojiov1alpha1.Applicat return &appSetGenerator.List.Template } -func (g *ListGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, _ client.Client) ([]map[string]any, error) { +func (g *ListGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, _ client.Client) ([]map[string]interface{}, error) { if appSetGenerator == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } if appSetGenerator.List == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } - res := make([]map[string]any, len(appSetGenerator.List.Elements)) + res := make([]map[string]interface{}, len(appSetGenerator.List.Elements)) for i, tmpItem := range appSetGenerator.List.Elements { - params := map[string]any{} - var element map[string]any + params := map[string]interface{}{} + var element map[string]interface{} err := json.Unmarshal(tmpItem.Raw, &element) if err != nil { return nil, fmt.Errorf("error unmarshling list element %w", err) @@ -53,16 +52,16 @@ func (g *ListGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Appli } else { for key, value := range element { if key == "values" { - values, ok := (value).(map[string]any) + values, ok := (value).(map[string]interface{}) if !ok { - return nil, errors.New("error parsing values map") + return nil, fmt.Errorf("error parsing values map") } for k, v := range values { value, ok := v.(string) if !ok { return nil, fmt.Errorf("error parsing value as string %w", err) } - params["values."+k] = value + params[fmt.Sprintf("values.%s", k)] = value } } else { v, ok := value.(string) @@ -78,7 +77,7 @@ func (g *ListGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Appli // Append elements from ElementsYaml to the response if len(appSetGenerator.List.ElementsYaml) > 0 { - var yamlElements []map[string]any + var yamlElements []map[string]interface{} err := yaml.Unmarshal([]byte(appSetGenerator.List.ElementsYaml), &yamlElements) if err != nil { return nil, fmt.Errorf("error unmarshling decoded ElementsYaml %w", err) diff --git a/applicationset/generators/list_test.go b/applicationset/generators/list_test.go index 2952878baf..5a3b1d88dd 100644 --- a/applicationset/generators/list_test.go +++ b/applicationset/generators/list_test.go @@ -8,20 +8,20 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestGenerateListParams(t *testing.T) { testCases := []struct { elements []apiextensionsv1.JSON - expected []map[string]any + expected []map[string]interface{} }{ { elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url"}`)}}, - expected: []map[string]any{{"cluster": "cluster", "url": "url"}}, + expected: []map[string]interface{}{{"cluster": "cluster", "url": "url"}}, }, { elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url","values":{"foo":"bar"}}`)}}, - expected: []map[string]any{{"cluster": "cluster", "url": "url", "values.foo": "bar"}}, + expected: []map[string]interface{}{{"cluster": "cluster", "url": "url", "values.foo": "bar"}}, }, } @@ -49,14 +49,14 @@ func TestGenerateListParams(t *testing.T) { func TestGenerateListParamsGoTemplate(t *testing.T) { testCases := []struct { elements []apiextensionsv1.JSON - expected []map[string]any + expected []map[string]interface{} }{ { elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url"}`)}}, - expected: []map[string]any{{"cluster": "cluster", "url": "url"}}, + expected: []map[string]interface{}{{"cluster": "cluster", "url": "url"}}, }, { elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url","values":{"foo":"bar"}}`)}}, - expected: []map[string]any{{"cluster": "cluster", "url": "url", "values": map[string]any{"foo": "bar"}}}, + expected: []map[string]interface{}{{"cluster": "cluster", "url": "url", "values": map[string]interface{}{"foo": "bar"}}}, }, } diff --git a/applicationset/generators/matrix.go b/applicationset/generators/matrix.go index 64d23b8760..2a44d97b71 100644 --- a/applicationset/generators/matrix.go +++ b/applicationset/generators/matrix.go @@ -1,23 +1,24 @@ package generators import ( - "errors" "fmt" "time" - "dario.cat/mergo" + "github.com/imdario/mergo" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + + log "github.com/sirupsen/logrus" ) var _ Generator = (*MatrixGenerator)(nil) var ( - ErrMoreThanTwoGenerators = errors.New("found more than two generators, Matrix support only two") - ErrLessThanTwoGenerators = errors.New("found less than two generators, Matrix support only two") - ErrMoreThenOneInnerGenerators = errors.New("found more than one generator in matrix.Generators") + ErrMoreThanTwoGenerators = fmt.Errorf("found more than two generators, Matrix support only two") + ErrLessThanTwoGenerators = fmt.Errorf("found less than two generators, Matrix support only two") + ErrMoreThenOneInnerGenerators = fmt.Errorf("found more than one generator in matrix.Generators") ) type MatrixGenerator struct { @@ -32,9 +33,9 @@ func NewMatrixGenerator(supportedGenerators map[string]Generator) Generator { return m } -func (m *MatrixGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, client client.Client) ([]map[string]any, error) { +func (m *MatrixGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, client client.Client) ([]map[string]interface{}, error) { if appSetGenerator.Matrix == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } if len(appSetGenerator.Matrix.Generators) < 2 { @@ -45,7 +46,7 @@ func (m *MatrixGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.App return nil, ErrMoreThanTwoGenerators } - res := []map[string]any{} + res := []map[string]interface{}{} g0, err := m.getParams(appSetGenerator.Matrix.Generators[0], appSet, nil, client) if err != nil { @@ -58,7 +59,7 @@ func (m *MatrixGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.App } for _, b := range g1 { if appSet.Spec.GoTemplate { - tmp := map[string]any{} + tmp := map[string]interface{}{} if err := mergo.Merge(&tmp, b, mergo.WithOverride); err != nil { return nil, fmt.Errorf("failed to merge params from the second generator in the matrix generator with temp map: %w", err) } @@ -79,15 +80,27 @@ func (m *MatrixGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.App return res, nil } -func (m *MatrixGenerator) getParams(appSetBaseGenerator argoprojiov1alpha1.ApplicationSetNestedGenerator, appSet *argoprojiov1alpha1.ApplicationSet, params map[string]any, client client.Client) ([]map[string]any, error) { +func (m *MatrixGenerator) getParams(appSetBaseGenerator argoprojiov1alpha1.ApplicationSetNestedGenerator, appSet *argoprojiov1alpha1.ApplicationSet, params map[string]interface{}, client client.Client) ([]map[string]interface{}, error) { matrixGen, err := getMatrixGenerator(appSetBaseGenerator) if err != nil { return nil, err } + if matrixGen != nil && !appSet.Spec.ApplyNestedSelectors { + foundSelector := dropDisabledNestedSelectors(matrixGen.Generators) + if foundSelector { + log.Warnf("AppSet '%v' defines selector on nested matrix generator's generator without enabling them via 'spec.applyNestedSelectors', ignoring nested selectors", appSet.Name) + } + } mergeGen, err := getMergeGenerator(appSetBaseGenerator) if err != nil { return nil, fmt.Errorf("error retrieving merge generator: %w", err) } + if mergeGen != nil && !appSet.Spec.ApplyNestedSelectors { + foundSelector := dropDisabledNestedSelectors(mergeGen.Generators) + if foundSelector { + log.Warnf("AppSet '%v' defines selector on nested merge generator's generator without enabling them via 'spec.applyNestedSelectors', ignoring nested selectors", appSet.Name) + } + } t, err := Transform( argoprojiov1alpha1.ApplicationSetGenerator{ @@ -112,7 +125,7 @@ func (m *MatrixGenerator) getParams(appSetBaseGenerator argoprojiov1alpha1.Appli } if len(t) == 0 { - return nil, errors.New("child generator generated no parameters") + return nil, fmt.Errorf("child generator generated no parameters") } if len(t) > 1 { @@ -155,8 +168,9 @@ func (m *MatrixGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.Ap if found { return res + } else { + return NoRequeueAfter } - return NoRequeueAfter } func getMatrixGenerator(r argoprojiov1alpha1.ApplicationSetNestedGenerator) (*argoprojiov1alpha1.MatrixGenerator, error) { diff --git a/applicationset/generators/matrix_test.go b/applicationset/generators/matrix_test.go index 00b6353a50..dec0ab96b4 100644 --- a/applicationset/generators/matrix_test.go +++ b/applicationset/generators/matrix_test.go @@ -1,6 +1,7 @@ package generators import ( + "context" "testing" "time" @@ -12,35 +13,36 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" - "github.com/argoproj/argo-cd/v3/applicationset/services/mocks" + "github.com/argoproj/argo-cd/v2/applicationset/services/mocks" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestMatrixGenerate(t *testing.T) { - gitGenerator := &v1alpha1.GitGenerator{ + gitGenerator := &argoprojiov1alpha1.GitGenerator{ RepoURL: "RepoURL", Revision: "Revision", - Directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + Directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, } - listGenerator := &v1alpha1.ListGenerator{ + listGenerator := &argoprojiov1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "Cluster","url": "Url", "templated": "test-{{path.basenameNormalized}}"}`)}}, } testCases := []struct { name string - baseGenerators []v1alpha1.ApplicationSetNestedGenerator + baseGenerators []argoprojiov1alpha1.ApplicationSetNestedGenerator expectedErr error - expected []map[string]any + expected []map[string]interface{} }{ { name: "happy flow - generate params", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, }, @@ -48,16 +50,16 @@ func TestMatrixGenerate(t *testing.T) { List: listGenerator, }, }, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "cluster": "Cluster", "url": "Url", "templated": "test-app1"}, {"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2", "cluster": "Cluster", "url": "Url", "templated": "test-app2"}, }, }, { name: "happy flow - generate params from two lists", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { - List: &v1alpha1.ListGenerator{ + List: &argoprojiov1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{ {Raw: []byte(`{"a": "1"}`)}, {Raw: []byte(`{"a": "2"}`)}, @@ -65,7 +67,7 @@ func TestMatrixGenerate(t *testing.T) { }, }, { - List: &v1alpha1.ListGenerator{ + List: &argoprojiov1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{ {Raw: []byte(`{"b": "1"}`)}, {Raw: []byte(`{"b": "2"}`)}, @@ -73,7 +75,7 @@ func TestMatrixGenerate(t *testing.T) { }, }, }, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"a": "1", "b": "1"}, {"a": "1", "b": "2"}, {"a": "2", "b": "1"}, @@ -82,7 +84,7 @@ func TestMatrixGenerate(t *testing.T) { }, { name: "returns error if there is less than two base generators", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, }, @@ -91,7 +93,7 @@ func TestMatrixGenerate(t *testing.T) { }, { name: "returns error if there is more than two base generators", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { List: listGenerator, }, @@ -106,7 +108,7 @@ func TestMatrixGenerate(t *testing.T) { }, { name: "returns error if there is more than one inner generator in the first base generator", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, List: listGenerator, @@ -119,7 +121,7 @@ func TestMatrixGenerate(t *testing.T) { }, { name: "returns error if there is more than one inner generator in the second base generator", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { List: listGenerator, }, @@ -137,19 +139,19 @@ func TestMatrixGenerate(t *testing.T) { t.Run(testCaseCopy.name, func(t *testing.T) { genMock := &generatorMock{} - appSet := &v1alpha1.ApplicationSet{ + appSet := &argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", }, - Spec: v1alpha1.ApplicationSetSpec{}, + Spec: argoprojiov1alpha1.ApplicationSetSpec{}, } for _, g := range testCaseCopy.baseGenerators { - gitGeneratorSpec := v1alpha1.ApplicationSetGenerator{ + gitGeneratorSpec := argoprojiov1alpha1.ApplicationSetGenerator{ Git: g.Git, List: g.List, } - genMock.On("GenerateParams", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator"), appSet, mock.Anything).Return([]map[string]any{ + genMock.On("GenerateParams", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator"), appSet, mock.Anything).Return([]map[string]interface{}{ { "path": "app1", "path.basename": "app1", @@ -163,7 +165,7 @@ func TestMatrixGenerate(t *testing.T) { }, nil) genMock.On("GetTemplate", &gitGeneratorSpec). - Return(&v1alpha1.ApplicationSetTemplate{}) + Return(&argoprojiov1alpha1.ApplicationSetTemplate{}) } matrixGenerator := NewMatrixGenerator( @@ -173,10 +175,10 @@ func TestMatrixGenerate(t *testing.T) { }, ) - got, err := matrixGenerator.GenerateParams(&v1alpha1.ApplicationSetGenerator{ - Matrix: &v1alpha1.MatrixGenerator{ + got, err := matrixGenerator.GenerateParams(&argoprojiov1alpha1.ApplicationSetGenerator{ + Matrix: &argoprojiov1alpha1.MatrixGenerator{ Generators: testCaseCopy.baseGenerators, - Template: v1alpha1.ApplicationSetTemplate{}, + Template: argoprojiov1alpha1.ApplicationSetTemplate{}, }, }, appSet, nil) @@ -191,25 +193,25 @@ func TestMatrixGenerate(t *testing.T) { } func TestMatrixGenerateGoTemplate(t *testing.T) { - gitGenerator := &v1alpha1.GitGenerator{ + gitGenerator := &argoprojiov1alpha1.GitGenerator{ RepoURL: "RepoURL", Revision: "Revision", - Directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + Directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, } - listGenerator := &v1alpha1.ListGenerator{ + listGenerator := &argoprojiov1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "Cluster","url": "Url"}`)}}, } testCases := []struct { name string - baseGenerators []v1alpha1.ApplicationSetNestedGenerator + baseGenerators []argoprojiov1alpha1.ApplicationSetNestedGenerator expectedErr error - expected []map[string]any + expected []map[string]interface{} }{ { name: "happy flow - generate params", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, }, @@ -217,7 +219,7 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { List: listGenerator, }, }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "path": map[string]string{ "path": "app1", @@ -240,9 +242,9 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { }, { name: "happy flow - generate params from two lists", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { - List: &v1alpha1.ListGenerator{ + List: &argoprojiov1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{ {Raw: []byte(`{"a": "1"}`)}, {Raw: []byte(`{"a": "2"}`)}, @@ -250,7 +252,7 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { }, }, { - List: &v1alpha1.ListGenerator{ + List: &argoprojiov1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{ {Raw: []byte(`{"b": "1"}`)}, {Raw: []byte(`{"b": "2"}`)}, @@ -258,7 +260,7 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { }, }, }, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"a": "1", "b": "1"}, {"a": "1", "b": "2"}, {"a": "2", "b": "1"}, @@ -267,29 +269,29 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { }, { name: "parameter override: first list elements take precedence", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { - List: &v1alpha1.ListGenerator{ + List: &argoprojiov1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{ {Raw: []byte(`{"booleanFalse": false, "booleanTrue": true, "stringFalse": "false", "stringTrue": "true"}`)}, }, }, }, { - List: &v1alpha1.ListGenerator{ + List: &argoprojiov1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{ {Raw: []byte(`{"booleanFalse": true, "booleanTrue": false, "stringFalse": "true", "stringTrue": "false"}`)}, }, }, }, }, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"booleanFalse": false, "booleanTrue": true, "stringFalse": "false", "stringTrue": "true"}, }, }, { name: "returns error if there is less than two base generators", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, }, @@ -298,7 +300,7 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { }, { name: "returns error if there is more than two base generators", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { List: listGenerator, }, @@ -313,7 +315,7 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { }, { name: "returns error if there is more than one inner generator in the first base generator", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, List: listGenerator, @@ -326,7 +328,7 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { }, { name: "returns error if there is more than one inner generator in the second base generator", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { List: listGenerator, }, @@ -344,21 +346,21 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { t.Run(testCaseCopy.name, func(t *testing.T) { genMock := &generatorMock{} - appSet := &v1alpha1.ApplicationSet{ + appSet := &argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", }, - Spec: v1alpha1.ApplicationSetSpec{ + Spec: argoprojiov1alpha1.ApplicationSetSpec{ GoTemplate: true, }, } for _, g := range testCaseCopy.baseGenerators { - gitGeneratorSpec := v1alpha1.ApplicationSetGenerator{ + gitGeneratorSpec := argoprojiov1alpha1.ApplicationSetGenerator{ Git: g.Git, List: g.List, } - genMock.On("GenerateParams", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator"), appSet, mock.Anything).Return([]map[string]any{ + genMock.On("GenerateParams", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator"), appSet, mock.Anything).Return([]map[string]interface{}{ { "path": map[string]string{ "path": "app1", @@ -376,7 +378,7 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { }, nil) genMock.On("GetTemplate", &gitGeneratorSpec). - Return(&v1alpha1.ApplicationSetTemplate{}) + Return(&argoprojiov1alpha1.ApplicationSetTemplate{}) } matrixGenerator := NewMatrixGenerator( @@ -386,10 +388,10 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { }, ) - got, err := matrixGenerator.GenerateParams(&v1alpha1.ApplicationSetGenerator{ - Matrix: &v1alpha1.MatrixGenerator{ + got, err := matrixGenerator.GenerateParams(&argoprojiov1alpha1.ApplicationSetGenerator{ + Matrix: &argoprojiov1alpha1.MatrixGenerator{ Generators: testCaseCopy.baseGenerators, - Template: v1alpha1.ApplicationSetTemplate{}, + Template: argoprojiov1alpha1.ApplicationSetTemplate{}, }, }, appSet, nil) @@ -404,31 +406,31 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { } func TestMatrixGetRequeueAfter(t *testing.T) { - gitGenerator := &v1alpha1.GitGenerator{ + gitGenerator := &argoprojiov1alpha1.GitGenerator{ RepoURL: "RepoURL", Revision: "Revision", - Directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + Directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, } - listGenerator := &v1alpha1.ListGenerator{ + listGenerator := &argoprojiov1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "Cluster","url": "Url"}`)}}, } - pullRequestGenerator := &v1alpha1.PullRequestGenerator{} + pullRequestGenerator := &argoprojiov1alpha1.PullRequestGenerator{} - scmGenerator := &v1alpha1.SCMProviderGenerator{} + scmGenerator := &argoprojiov1alpha1.SCMProviderGenerator{} - duckTypeGenerator := &v1alpha1.DuckTypeGenerator{} + duckTypeGenerator := &argoprojiov1alpha1.DuckTypeGenerator{} testCases := []struct { name string - baseGenerators []v1alpha1.ApplicationSetNestedGenerator + baseGenerators []argoprojiov1alpha1.ApplicationSetNestedGenerator gitGetRequeueAfter time.Duration expected time.Duration }{ { name: "return NoRequeueAfter if all the inner baseGenerators returns it", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, }, @@ -441,7 +443,7 @@ func TestMatrixGetRequeueAfter(t *testing.T) { }, { name: "returns the minimal time", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, }, @@ -454,7 +456,7 @@ func TestMatrixGetRequeueAfter(t *testing.T) { }, { name: "returns the minimal time for pull request", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, }, @@ -467,7 +469,7 @@ func TestMatrixGetRequeueAfter(t *testing.T) { }, { name: "returns the default time if no requeueAfterSeconds is provided", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, }, @@ -479,7 +481,7 @@ func TestMatrixGetRequeueAfter(t *testing.T) { }, { name: "returns the default time for duck type generator", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, }, @@ -491,7 +493,7 @@ func TestMatrixGetRequeueAfter(t *testing.T) { }, { name: "returns the default time for scm generator", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, }, @@ -510,7 +512,7 @@ func TestMatrixGetRequeueAfter(t *testing.T) { mock := &generatorMock{} for _, g := range testCaseCopy.baseGenerators { - gitGeneratorSpec := v1alpha1.ApplicationSetGenerator{ + gitGeneratorSpec := argoprojiov1alpha1.ApplicationSetGenerator{ Git: g.Git, List: g.List, PullRequest: g.PullRequest, @@ -530,10 +532,10 @@ func TestMatrixGetRequeueAfter(t *testing.T) { }, ) - got := matrixGenerator.GetRequeueAfter(&v1alpha1.ApplicationSetGenerator{ - Matrix: &v1alpha1.MatrixGenerator{ + got := matrixGenerator.GetRequeueAfter(&argoprojiov1alpha1.ApplicationSetGenerator{ + Matrix: &argoprojiov1alpha1.MatrixGenerator{ Generators: testCaseCopy.baseGenerators, - Template: v1alpha1.ApplicationSetTemplate{}, + Template: argoprojiov1alpha1.ApplicationSetTemplate{}, }, }) @@ -543,16 +545,16 @@ func TestMatrixGetRequeueAfter(t *testing.T) { } func TestInterpolatedMatrixGenerate(t *testing.T) { - interpolatedGitGenerator := &v1alpha1.GitGenerator{ + interpolatedGitGenerator := &argoprojiov1alpha1.GitGenerator{ RepoURL: "RepoURL", Revision: "Revision", - Files: []v1alpha1.GitFileGeneratorItem{ + Files: []argoprojiov1alpha1.GitFileGeneratorItem{ {Path: "examples/git-generator-files-discovery/cluster-config/dev/config.json"}, {Path: "examples/git-generator-files-discovery/cluster-config/prod/config.json"}, }, } - interpolatedClusterGenerator := &v1alpha1.ClusterGenerator{ + interpolatedClusterGenerator := &argoprojiov1alpha1.ClusterGenerator{ Selector: metav1.LabelSelector{ MatchLabels: map[string]string{"environment": "{{path.basename}}"}, MatchExpressions: nil, @@ -560,14 +562,14 @@ func TestInterpolatedMatrixGenerate(t *testing.T) { } testCases := []struct { name string - baseGenerators []v1alpha1.ApplicationSetNestedGenerator + baseGenerators []argoprojiov1alpha1.ApplicationSetNestedGenerator expectedErr error - expected []map[string]any + expected []map[string]interface{} clientError bool }{ { name: "happy flow - generate interpolated params", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: interpolatedGitGenerator, }, @@ -575,7 +577,7 @@ func TestInterpolatedMatrixGenerate(t *testing.T) { Clusters: interpolatedClusterGenerator, }, }, - expected: []map[string]any{ + 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", "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": ""}, }, @@ -635,7 +637,7 @@ func TestInterpolatedMatrixGenerate(t *testing.T) { t.Run(testCaseCopy.name, func(t *testing.T) { genMock := &generatorMock{} - appSet := &v1alpha1.ApplicationSet{} + appSet := &argoprojiov1alpha1.ApplicationSet{} appClientset := kubefake.NewSimpleClientset(runtimeClusters...) fakeClient := fake.NewClientBuilder().WithObjects(clusters...).Build() @@ -643,14 +645,14 @@ func TestInterpolatedMatrixGenerate(t *testing.T) { fakeClient, testCase.clientError, } - clusterGenerator := NewClusterGenerator(t.Context(), cl, appClientset, "namespace") + clusterGenerator := NewClusterGenerator(cl, context.Background(), appClientset, "namespace") for _, g := range testCaseCopy.baseGenerators { - gitGeneratorSpec := v1alpha1.ApplicationSetGenerator{ + gitGeneratorSpec := argoprojiov1alpha1.ApplicationSetGenerator{ Git: g.Git, Clusters: g.Clusters, } - genMock.On("GenerateParams", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator"), appSet).Return([]map[string]any{ + genMock.On("GenerateParams", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator"), appSet).Return([]map[string]interface{}{ { "path": "examples/git-generator-files-discovery/cluster-config/dev/config.json", "path.basename": "dev", @@ -663,7 +665,7 @@ func TestInterpolatedMatrixGenerate(t *testing.T) { }, }, nil) genMock.On("GetTemplate", &gitGeneratorSpec). - Return(&v1alpha1.ApplicationSetTemplate{}) + Return(&argoprojiov1alpha1.ApplicationSetTemplate{}) } matrixGenerator := NewMatrixGenerator( map[string]Generator{ @@ -672,10 +674,10 @@ func TestInterpolatedMatrixGenerate(t *testing.T) { }, ) - got, err := matrixGenerator.GenerateParams(&v1alpha1.ApplicationSetGenerator{ - Matrix: &v1alpha1.MatrixGenerator{ + got, err := matrixGenerator.GenerateParams(&argoprojiov1alpha1.ApplicationSetGenerator{ + Matrix: &argoprojiov1alpha1.MatrixGenerator{ Generators: testCaseCopy.baseGenerators, - Template: v1alpha1.ApplicationSetTemplate{}, + Template: argoprojiov1alpha1.ApplicationSetTemplate{}, }, }, appSet, nil) @@ -690,16 +692,16 @@ func TestInterpolatedMatrixGenerate(t *testing.T) { } func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { - interpolatedGitGenerator := &v1alpha1.GitGenerator{ + interpolatedGitGenerator := &argoprojiov1alpha1.GitGenerator{ RepoURL: "RepoURL", Revision: "Revision", - Files: []v1alpha1.GitFileGeneratorItem{ + Files: []argoprojiov1alpha1.GitFileGeneratorItem{ {Path: "examples/git-generator-files-discovery/cluster-config/dev/config.json"}, {Path: "examples/git-generator-files-discovery/cluster-config/prod/config.json"}, }, } - interpolatedClusterGenerator := &v1alpha1.ClusterGenerator{ + interpolatedClusterGenerator := &argoprojiov1alpha1.ClusterGenerator{ Selector: metav1.LabelSelector{ MatchLabels: map[string]string{"environment": "{{.path.basename}}"}, MatchExpressions: nil, @@ -707,14 +709,14 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { } testCases := []struct { name string - baseGenerators []v1alpha1.ApplicationSetNestedGenerator + baseGenerators []argoprojiov1alpha1.ApplicationSetNestedGenerator expectedErr error - expected []map[string]any + expected []map[string]interface{} clientError bool }{ { name: "happy flow - generate interpolated params", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: interpolatedGitGenerator, }, @@ -722,7 +724,7 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { Clusters: interpolatedClusterGenerator, }, }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "path": map[string]string{ "path": "examples/git-generator-files-discovery/cluster-config/dev/config.json", @@ -733,7 +735,7 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { "nameNormalized": "dev-01", "server": "https://dev-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "environment": "dev", "argocd.argoproj.io/secret-type": "cluster", @@ -750,7 +752,7 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { "nameNormalized": "prod-01", "server": "https://prod-01.example.com", "project": "", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "labels": map[string]string{ "environment": "prod", "argocd.argoproj.io/secret-type": "cluster", @@ -814,8 +816,8 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { t.Run(testCaseCopy.name, func(t *testing.T) { genMock := &generatorMock{} - appSet := &v1alpha1.ApplicationSet{ - Spec: v1alpha1.ApplicationSetSpec{ + appSet := &argoprojiov1alpha1.ApplicationSet{ + Spec: argoprojiov1alpha1.ApplicationSetSpec{ GoTemplate: true, }, } @@ -826,14 +828,14 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { fakeClient, testCase.clientError, } - clusterGenerator := NewClusterGenerator(t.Context(), cl, appClientset, "namespace") + clusterGenerator := NewClusterGenerator(cl, context.Background(), appClientset, "namespace") for _, g := range testCaseCopy.baseGenerators { - gitGeneratorSpec := v1alpha1.ApplicationSetGenerator{ + gitGeneratorSpec := argoprojiov1alpha1.ApplicationSetGenerator{ Git: g.Git, Clusters: g.Clusters, } - genMock.On("GenerateParams", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator"), appSet).Return([]map[string]any{ + genMock.On("GenerateParams", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator"), appSet).Return([]map[string]interface{}{ { "path": map[string]string{ "path": "examples/git-generator-files-discovery/cluster-config/dev/config.json", @@ -850,7 +852,7 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { }, }, nil) genMock.On("GetTemplate", &gitGeneratorSpec). - Return(&v1alpha1.ApplicationSetTemplate{}) + Return(&argoprojiov1alpha1.ApplicationSetTemplate{}) } matrixGenerator := NewMatrixGenerator( map[string]Generator{ @@ -859,10 +861,10 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { }, ) - got, err := matrixGenerator.GenerateParams(&v1alpha1.ApplicationSetGenerator{ - Matrix: &v1alpha1.MatrixGenerator{ + got, err := matrixGenerator.GenerateParams(&argoprojiov1alpha1.ApplicationSetGenerator{ + Matrix: &argoprojiov1alpha1.MatrixGenerator{ Generators: testCaseCopy.baseGenerators, - Template: v1alpha1.ApplicationSetTemplate{}, + Template: argoprojiov1alpha1.ApplicationSetTemplate{}, }, }, appSet, nil) @@ -877,28 +879,28 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { } func TestMatrixGenerateListElementsYaml(t *testing.T) { - gitGenerator := &v1alpha1.GitGenerator{ + gitGenerator := &argoprojiov1alpha1.GitGenerator{ RepoURL: "RepoURL", Revision: "Revision", - Files: []v1alpha1.GitFileGeneratorItem{ + Files: []argoprojiov1alpha1.GitFileGeneratorItem{ {Path: "config.yaml"}, }, } - listGenerator := &v1alpha1.ListGenerator{ + listGenerator := &argoprojiov1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{}, ElementsYaml: "{{ .foo.bar | toJson }}", } testCases := []struct { name string - baseGenerators []v1alpha1.ApplicationSetNestedGenerator + baseGenerators []argoprojiov1alpha1.ApplicationSetNestedGenerator expectedErr error - expected []map[string]any + expected []map[string]interface{} }{ { name: "happy flow - generate params", - baseGenerators: []v1alpha1.ApplicationSetNestedGenerator{ + baseGenerators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { Git: gitGenerator, }, @@ -906,23 +908,23 @@ func TestMatrixGenerateListElementsYaml(t *testing.T) { List: listGenerator, }, }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "chart": "a", "version": "1", - "foo": map[string]any{ - "bar": []any{ - map[string]any{ + "foo": map[string]interface{}{ + "bar": []interface{}{ + map[string]interface{}{ "chart": "a", "version": "1", }, - map[string]any{ + map[string]interface{}{ "chart": "b", "version": "2", }, }, }, - "path": map[string]any{ + "path": map[string]interface{}{ "basename": "dir", "basenameNormalized": "dir", "filename": "file_name.yaml", @@ -937,19 +939,19 @@ func TestMatrixGenerateListElementsYaml(t *testing.T) { { "chart": "b", "version": "2", - "foo": map[string]any{ - "bar": []any{ - map[string]any{ + "foo": map[string]interface{}{ + "bar": []interface{}{ + map[string]interface{}{ "chart": "a", "version": "1", }, - map[string]any{ + map[string]interface{}{ "chart": "b", "version": "2", }, }, }, - "path": map[string]any{ + "path": map[string]interface{}{ "basename": "dir", "basenameNormalized": "dir", "filename": "file_name.yaml", @@ -970,34 +972,34 @@ func TestMatrixGenerateListElementsYaml(t *testing.T) { t.Run(testCaseCopy.name, func(t *testing.T) { genMock := &generatorMock{} - appSet := &v1alpha1.ApplicationSet{ + appSet := &argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", }, - Spec: v1alpha1.ApplicationSetSpec{ + Spec: argoprojiov1alpha1.ApplicationSetSpec{ GoTemplate: true, }, } for _, g := range testCaseCopy.baseGenerators { - gitGeneratorSpec := v1alpha1.ApplicationSetGenerator{ + gitGeneratorSpec := argoprojiov1alpha1.ApplicationSetGenerator{ Git: g.Git, List: g.List, } genMock.On("GenerateParams", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator"), appSet).Return([]map[string]any{{ - "foo": map[string]any{ - "bar": []any{ - map[string]any{ + "foo": map[string]interface{}{ + "bar": []interface{}{ + map[string]interface{}{ "chart": "a", "version": "1", }, - map[string]any{ + map[string]interface{}{ "chart": "b", "version": "2", }, }, }, - "path": map[string]any{ + "path": map[string]interface{}{ "basename": "dir", "basenameNormalized": "dir", "filename": "file_name.yaml", @@ -1010,7 +1012,7 @@ func TestMatrixGenerateListElementsYaml(t *testing.T) { }, }}, nil) genMock.On("GetTemplate", &gitGeneratorSpec). - Return(&v1alpha1.ApplicationSetTemplate{}) + Return(&argoprojiov1alpha1.ApplicationSetTemplate{}) } matrixGenerator := NewMatrixGenerator( @@ -1020,10 +1022,10 @@ func TestMatrixGenerateListElementsYaml(t *testing.T) { }, ) - got, err := matrixGenerator.GenerateParams(&v1alpha1.ApplicationSetGenerator{ - Matrix: &v1alpha1.MatrixGenerator{ + got, err := matrixGenerator.GenerateParams(&argoprojiov1alpha1.ApplicationSetGenerator{ + Matrix: &argoprojiov1alpha1.MatrixGenerator{ Generators: testCaseCopy.baseGenerators, - Template: v1alpha1.ApplicationSetTemplate{}, + Template: argoprojiov1alpha1.ApplicationSetTemplate{}, }, }, appSet, nil) @@ -1041,19 +1043,19 @@ type generatorMock struct { mock.Mock } -func (g *generatorMock) GetTemplate(appSetGenerator *v1alpha1.ApplicationSetGenerator) *v1alpha1.ApplicationSetTemplate { +func (g *generatorMock) GetTemplate(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) *argoprojiov1alpha1.ApplicationSetTemplate { args := g.Called(appSetGenerator) - return args.Get(0).(*v1alpha1.ApplicationSetTemplate) + return args.Get(0).(*argoprojiov1alpha1.ApplicationSetTemplate) } -func (g *generatorMock) GenerateParams(appSetGenerator *v1alpha1.ApplicationSetGenerator, appSet *v1alpha1.ApplicationSet, _ client.Client) ([]map[string]any, error) { +func (g *generatorMock) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, _ client.Client) ([]map[string]interface{}, error) { args := g.Called(appSetGenerator, appSet) - return args.Get(0).([]map[string]any), args.Error(1) + return args.Get(0).([]map[string]interface{}), args.Error(1) } -func (g *generatorMock) GetRequeueAfter(appSetGenerator *v1alpha1.ApplicationSetGenerator) time.Duration { +func (g *generatorMock) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) time.Duration { args := g.Called(appSetGenerator) return args.Get(0).(time.Duration) @@ -1073,20 +1075,20 @@ func TestGitGenerator_GenerateParams_list_x_git_matrix_generator(t *testing.T) { // of that bug. listGeneratorMock := &generatorMock{} - listGeneratorMock.On("GenerateParams", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator"), mock.AnythingOfType("*v1alpha1.ApplicationSet"), mock.Anything).Return([]map[string]any{ + listGeneratorMock.On("GenerateParams", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator"), mock.AnythingOfType("*v1alpha1.ApplicationSet"), mock.Anything).Return([]map[string]interface{}{ {"some": "value"}, }, nil) - listGeneratorMock.On("GetTemplate", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator")).Return(&v1alpha1.ApplicationSetTemplate{}) + listGeneratorMock.On("GetTemplate", mock.AnythingOfType("*v1alpha1.ApplicationSetGenerator")).Return(&argoprojiov1alpha1.ApplicationSetTemplate{}) - gitGeneratorSpec := &v1alpha1.GitGenerator{ + gitGeneratorSpec := &argoprojiov1alpha1.GitGenerator{ RepoURL: "https://git.example.com", - Files: []v1alpha1.GitFileGeneratorItem{ + Files: []argoprojiov1alpha1.GitFileGeneratorItem{ {Path: "some/path.json"}, }, } repoServiceMock := &mocks.Repos{} - repoServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(map[string][]byte{ + repoServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(map[string][]byte{ "some/path.json": []byte("test: content"), }, nil) gitGenerator := NewGitGenerator(repoServiceMock, "") @@ -1096,10 +1098,10 @@ func TestGitGenerator_GenerateParams_list_x_git_matrix_generator(t *testing.T) { "Git": gitGenerator, }) - matrixGeneratorSpec := &v1alpha1.MatrixGenerator{ - Generators: []v1alpha1.ApplicationSetNestedGenerator{ + matrixGeneratorSpec := &argoprojiov1alpha1.MatrixGenerator{ + Generators: []argoprojiov1alpha1.ApplicationSetNestedGenerator{ { - List: &v1alpha1.ListGenerator{ + List: &argoprojiov1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{ { Raw: []byte(`{"some": "value"}`), @@ -1116,15 +1118,15 @@ func TestGitGenerator_GenerateParams_list_x_git_matrix_generator(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - appProject := v1alpha1.AppProject{} + appProject := argoprojiov1alpha1.AppProject{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() - params, err := matrixGenerator.GenerateParams(&v1alpha1.ApplicationSetGenerator{ + params, err := matrixGenerator.GenerateParams(&argoprojiov1alpha1.ApplicationSetGenerator{ Matrix: matrixGeneratorSpec, - }, &v1alpha1.ApplicationSet{}, client) + }, &argoprojiov1alpha1.ApplicationSet{}, client) require.NoError(t, err) - assert.Equal(t, []map[string]any{{ + assert.Equal(t, []map[string]interface{}{{ "path": "some", "path.basename": "some", "path.basenameNormalized": "some", diff --git a/applicationset/generators/merge.go b/applicationset/generators/merge.go index a88af3543a..e9af81fada 100644 --- a/applicationset/generators/merge.go +++ b/applicationset/generators/merge.go @@ -2,23 +2,24 @@ package generators import ( "encoding/json" - "errors" "fmt" "time" - "dario.cat/mergo" + "github.com/imdario/mergo" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + + log "github.com/sirupsen/logrus" ) var _ Generator = (*MergeGenerator)(nil) var ( - ErrLessThanTwoGeneratorsInMerge = errors.New("found less than two generators, Merge requires two or more") - ErrNoMergeKeys = errors.New("no merge keys were specified, Merge requires at least one") - ErrNonUniqueParamSets = errors.New("the parameters from a generator were not unique by the given mergeKeys, Merge requires all param sets to be unique") + ErrLessThanTwoGeneratorsInMerge = fmt.Errorf("found less than two generators, Merge requires two or more") + ErrNoMergeKeys = fmt.Errorf("no merge keys were specified, Merge requires at least one") + ErrNonUniqueParamSets = fmt.Errorf("the parameters from a generator were not unique by the given mergeKeys, Merge requires all param sets to be unique") ) type MergeGenerator struct { @@ -36,8 +37,8 @@ func NewMergeGenerator(supportedGenerators map[string]Generator) Generator { // getParamSetsForAllGenerators generates params for each child generator in a MergeGenerator. Param sets are returned // in slices ordered according to the order of the given generators. -func (m *MergeGenerator) getParamSetsForAllGenerators(generators []argoprojiov1alpha1.ApplicationSetNestedGenerator, appSet *argoprojiov1alpha1.ApplicationSet, client client.Client) ([][]map[string]any, error) { - var paramSets [][]map[string]any +func (m *MergeGenerator) getParamSetsForAllGenerators(generators []argoprojiov1alpha1.ApplicationSetNestedGenerator, appSet *argoprojiov1alpha1.ApplicationSet, client client.Client) ([][]map[string]interface{}, error) { + var paramSets [][]map[string]interface{} for i, generator := range generators { generatorParamSets, err := m.getParams(generator, appSet, client) if err != nil { @@ -50,9 +51,9 @@ func (m *MergeGenerator) getParamSetsForAllGenerators(generators []argoprojiov1a } // GenerateParams gets the params produced by the MergeGenerator. -func (m *MergeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, client client.Client) ([]map[string]any, error) { +func (m *MergeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, client client.Client) ([]map[string]interface{}, error) { if appSetGenerator.Merge == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } if len(appSetGenerator.Merge.Generators) < 2 { @@ -93,11 +94,11 @@ func (m *MergeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Appl } } - mergedParamSets := make([]map[string]any, len(baseParamSetsByMergeKey)) + mergedParamSets := make([]map[string]interface{}, len(baseParamSetsByMergeKey)) i := 0 for _, mergedParamSet := range baseParamSetsByMergeKey { mergedParamSets[i] = mergedParamSet - i++ + i += 1 } return mergedParamSets, nil @@ -106,7 +107,7 @@ func (m *MergeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Appl // getParamSetsByMergeKey converts the given list of parameter sets to a map of parameter sets where the key is the // unique key of the parameter set as determined by the given mergeKeys. If any two parameter sets share the same merge // key, getParamSetsByMergeKey will throw NonUniqueParamSets. -func getParamSetsByMergeKey(mergeKeys []string, paramSets []map[string]any) (map[string]map[string]any, error) { +func getParamSetsByMergeKey(mergeKeys []string, paramSets []map[string]interface{}) (map[string]map[string]interface{}, error) { if len(mergeKeys) < 1 { return nil, ErrNoMergeKeys } @@ -116,17 +117,17 @@ func getParamSetsByMergeKey(mergeKeys []string, paramSets []map[string]any) (map deDuplicatedMergeKeys[mergeKey] = false } - paramSetsByMergeKey := make(map[string]map[string]any, len(paramSets)) + paramSetsByMergeKey := make(map[string]map[string]interface{}, len(paramSets)) for _, paramSet := range paramSets { - paramSetKey := make(map[string]any) + paramSetKey := make(map[string]interface{}) for mergeKey := range deDuplicatedMergeKeys { paramSetKey[mergeKey] = paramSet[mergeKey] } - paramSetKeyJSON, err := json.Marshal(paramSetKey) + paramSetKeyJson, err := json.Marshal(paramSetKey) if err != nil { return nil, fmt.Errorf("error marshalling param set key json: %w", err) } - paramSetKeyString := string(paramSetKeyJSON) + paramSetKeyString := string(paramSetKeyJson) if _, exists := paramSetsByMergeKey[paramSetKeyString]; exists { return nil, fmt.Errorf("%w. Duplicate key was %s", ErrNonUniqueParamSets, paramSetKeyString) } @@ -137,15 +138,27 @@ func getParamSetsByMergeKey(mergeKeys []string, paramSets []map[string]any) (map } // getParams get the parameters generated by this generator. -func (m *MergeGenerator) getParams(appSetBaseGenerator argoprojiov1alpha1.ApplicationSetNestedGenerator, appSet *argoprojiov1alpha1.ApplicationSet, client client.Client) ([]map[string]any, error) { +func (m *MergeGenerator) getParams(appSetBaseGenerator argoprojiov1alpha1.ApplicationSetNestedGenerator, appSet *argoprojiov1alpha1.ApplicationSet, client client.Client) ([]map[string]interface{}, error) { matrixGen, err := getMatrixGenerator(appSetBaseGenerator) if err != nil { return nil, err } + if matrixGen != nil && !appSet.Spec.ApplyNestedSelectors { + foundSelector := dropDisabledNestedSelectors(matrixGen.Generators) + if foundSelector { + log.Warnf("AppSet '%v' defines selector on nested matrix generator's generator without enabling them via 'spec.applyNestedSelectors', ignoring nested selector", appSet.Name) + } + } mergeGen, err := getMergeGenerator(appSetBaseGenerator) if err != nil { return nil, err } + if mergeGen != nil && !appSet.Spec.ApplyNestedSelectors { + foundSelector := dropDisabledNestedSelectors(mergeGen.Generators) + if foundSelector { + log.Warnf("AppSet '%v' defines selector on nested merge generator's generator without enabling them via 'spec.applyNestedSelectors', ignoring nested selector", appSet.Name) + } + } t, err := Transform( argoprojiov1alpha1.ApplicationSetGenerator{ @@ -163,13 +176,13 @@ func (m *MergeGenerator) getParams(appSetBaseGenerator argoprojiov1alpha1.Applic m.supportedGenerators, argoprojiov1alpha1.ApplicationSetTemplate{}, appSet, - map[string]any{}, client) + map[string]interface{}{}, client) if err != nil { return nil, fmt.Errorf("child generator returned an error on parameter generation: %w", err) } if len(t) == 0 { - return nil, errors.New("child generator generated no parameters") + return nil, fmt.Errorf("child generator generated no parameters") } if len(t) > 1 { @@ -210,8 +223,9 @@ func (m *MergeGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.App if found { return res + } else { + return NoRequeueAfter } - return NoRequeueAfter } func getMergeGenerator(r argoprojiov1alpha1.ApplicationSetNestedGenerator) (*argoprojiov1alpha1.MergeGenerator, error) { diff --git a/applicationset/generators/merge_test.go b/applicationset/generators/merge_test.go index 0bb2bfbce7..ad54debb37 100644 --- a/applicationset/generators/merge_test.go +++ b/applicationset/generators/merge_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/require" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func getNestedListGenerator(json string) *argoprojiov1alpha1.ApplicationSetNestedGenerator { @@ -36,15 +36,15 @@ func getTerminalListGeneratorMultiple(jsons []string) argoprojiov1alpha1.Applica return generator } -func listOfMapsToSet(maps []map[string]any) (map[string]bool, error) { +func listOfMapsToSet(maps []map[string]interface{}) (map[string]bool, error) { set := make(map[string]bool, len(maps)) for _, paramMap := range maps { - paramMapAsJSON, err := json.Marshal(paramMap) + paramMapAsJson, err := json.Marshal(paramMap) if err != nil { return nil, err } - set[string(paramMapAsJSON)] = false + set[string(paramMapAsJson)] = false } return set, nil } @@ -55,7 +55,7 @@ func TestMergeGenerate(t *testing.T) { baseGenerators []argoprojiov1alpha1.ApplicationSetNestedGenerator mergeKeys []string expectedErr error - expected []map[string]any + expected []map[string]interface{} }{ { name: "no generators", @@ -79,7 +79,7 @@ func TestMergeGenerate(t *testing.T) { *getNestedListGenerator(`{"a": "3_1","b": "different","c": "3_3"}`), // gets ignored because its merge key value isn't in the base params set }, mergeKeys: []string{"b"}, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"a": "2_1", "b": "same", "c": "1_3"}, }, }, @@ -90,7 +90,7 @@ func TestMergeGenerate(t *testing.T) { *getNestedListGenerator(`{"a": "a"}`), }, mergeKeys: []string{"b"}, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"a": "a"}, }, }, @@ -101,7 +101,7 @@ func TestMergeGenerate(t *testing.T) { *getNestedListGenerator(`{"b": "b"}`), }, mergeKeys: []string{"b"}, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"a": "a"}, }, }, @@ -119,7 +119,7 @@ func TestMergeGenerate(t *testing.T) { *getNestedListGenerator(`{"a": "1", "b": "1", "c": "added"}`), }, mergeKeys: []string{"a", "b"}, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"a": "1", "b": "1", "c": "added"}, {"a": "1", "b": "2"}, {"a": "2", "b": "1"}, @@ -141,7 +141,7 @@ func TestMergeGenerate(t *testing.T) { *getNestedListGenerator(`{"a": "1", "b": "3", "d": "added"}`), }, mergeKeys: []string{"a", "b"}, - expected: []map[string]any{ + expected: []map[string]interface{}{ {"a": "1", "b": "3", "c": "added", "d": "added"}, {"a": "2", "b": "2"}, }, @@ -196,7 +196,7 @@ func TestMergeGenerate(t *testing.T) { } } -func toAPIExtensionsJSON(t *testing.T, g any) *apiextensionsv1.JSON { +func toAPIExtensionsJSON(t *testing.T, g interface{}) *apiextensionsv1.JSON { t.Helper() resVal, err := json.Marshal(g) if err != nil { @@ -213,9 +213,9 @@ func TestParamSetsAreUniqueByMergeKeys(t *testing.T) { testCases := []struct { name string mergeKeys []string - paramSets []map[string]any + paramSets []map[string]interface{} expectedErr error - expected map[string]map[string]any + expected map[string]map[string]interface{} }{ { name: "no merge keys", @@ -225,13 +225,13 @@ func TestParamSetsAreUniqueByMergeKeys(t *testing.T) { { name: "no paramSets", mergeKeys: []string{"key"}, - expected: make(map[string]map[string]any), + expected: make(map[string]map[string]interface{}), }, { name: "simple key, unique paramSets", mergeKeys: []string{"key"}, - paramSets: []map[string]any{{"key": "a"}, {"key": "b"}}, - expected: map[string]map[string]any{ + paramSets: []map[string]interface{}{{"key": "a"}, {"key": "b"}}, + expected: map[string]map[string]interface{}{ `{"key":"a"}`: {"key": "a"}, `{"key":"b"}`: {"key": "b"}, }, @@ -239,23 +239,23 @@ func TestParamSetsAreUniqueByMergeKeys(t *testing.T) { { name: "simple key object, unique paramSets", mergeKeys: []string{"key"}, - paramSets: []map[string]any{{"key": map[string]any{"hello": "world"}}, {"key": "b"}}, - expected: map[string]map[string]any{ - `{"key":{"hello":"world"}}`: {"key": map[string]any{"hello": "world"}}, + paramSets: []map[string]interface{}{{"key": map[string]interface{}{"hello": "world"}}, {"key": "b"}}, + expected: map[string]map[string]interface{}{ + `{"key":{"hello":"world"}}`: {"key": map[string]interface{}{"hello": "world"}}, `{"key":"b"}`: {"key": "b"}, }, }, { name: "simple key, non-unique paramSets", mergeKeys: []string{"key"}, - paramSets: []map[string]any{{"key": "a"}, {"key": "b"}, {"key": "b"}}, + paramSets: []map[string]interface{}{{"key": "a"}, {"key": "b"}, {"key": "b"}}, expectedErr: fmt.Errorf("%w. Duplicate key was %s", ErrNonUniqueParamSets, `{"key":"b"}`), }, { name: "simple key, duplicated key name, unique paramSets", mergeKeys: []string{"key", "key"}, - paramSets: []map[string]any{{"key": "a"}, {"key": "b"}}, - expected: map[string]map[string]any{ + paramSets: []map[string]interface{}{{"key": "a"}, {"key": "b"}}, + expected: map[string]map[string]interface{}{ `{"key":"a"}`: {"key": "a"}, `{"key":"b"}`: {"key": "b"}, }, @@ -263,18 +263,18 @@ func TestParamSetsAreUniqueByMergeKeys(t *testing.T) { { name: "simple key, duplicated key name, non-unique paramSets", mergeKeys: []string{"key", "key"}, - paramSets: []map[string]any{{"key": "a"}, {"key": "b"}, {"key": "b"}}, + paramSets: []map[string]interface{}{{"key": "a"}, {"key": "b"}, {"key": "b"}}, expectedErr: fmt.Errorf("%w. Duplicate key was %s", ErrNonUniqueParamSets, `{"key":"b"}`), }, { name: "compound key, unique paramSets", mergeKeys: []string{"key1", "key2"}, - paramSets: []map[string]any{ + paramSets: []map[string]interface{}{ {"key1": "a", "key2": "a"}, {"key1": "a", "key2": "b"}, {"key1": "b", "key2": "a"}, }, - expected: map[string]map[string]any{ + expected: map[string]map[string]interface{}{ `{"key1":"a","key2":"a"}`: {"key1": "a", "key2": "a"}, `{"key1":"a","key2":"b"}`: {"key1": "a", "key2": "b"}, `{"key1":"b","key2":"a"}`: {"key1": "b", "key2": "a"}, @@ -283,13 +283,13 @@ func TestParamSetsAreUniqueByMergeKeys(t *testing.T) { { name: "compound key object, unique paramSets", mergeKeys: []string{"key1", "key2"}, - paramSets: []map[string]any{ - {"key1": "a", "key2": map[string]any{"hello": "world"}}, + paramSets: []map[string]interface{}{ + {"key1": "a", "key2": map[string]interface{}{"hello": "world"}}, {"key1": "a", "key2": "b"}, {"key1": "b", "key2": "a"}, }, - expected: map[string]map[string]any{ - `{"key1":"a","key2":{"hello":"world"}}`: {"key1": "a", "key2": map[string]any{"hello": "world"}}, + expected: map[string]map[string]interface{}{ + `{"key1":"a","key2":{"hello":"world"}}`: {"key1": "a", "key2": map[string]interface{}{"hello": "world"}}, `{"key1":"a","key2":"b"}`: {"key1": "a", "key2": "b"}, `{"key1":"b","key2":"a"}`: {"key1": "b", "key2": "a"}, }, @@ -297,12 +297,12 @@ func TestParamSetsAreUniqueByMergeKeys(t *testing.T) { { name: "compound key, duplicate key names, unique paramSets", mergeKeys: []string{"key1", "key1", "key2"}, - paramSets: []map[string]any{ + paramSets: []map[string]interface{}{ {"key1": "a", "key2": "a"}, {"key1": "a", "key2": "b"}, {"key1": "b", "key2": "a"}, }, - expected: map[string]map[string]any{ + expected: map[string]map[string]interface{}{ `{"key1":"a","key2":"a"}`: {"key1": "a", "key2": "a"}, `{"key1":"a","key2":"b"}`: {"key1": "a", "key2": "b"}, `{"key1":"b","key2":"a"}`: {"key1": "b", "key2": "a"}, @@ -311,7 +311,7 @@ func TestParamSetsAreUniqueByMergeKeys(t *testing.T) { { name: "compound key, non-unique paramSets", mergeKeys: []string{"key1", "key2"}, - paramSets: []map[string]any{ + paramSets: []map[string]interface{}{ {"key1": "a", "key2": "a"}, {"key1": "a", "key2": "a"}, {"key1": "b", "key2": "a"}, @@ -321,7 +321,7 @@ func TestParamSetsAreUniqueByMergeKeys(t *testing.T) { { name: "compound key, duplicate key names, non-unique paramSets", mergeKeys: []string{"key1", "key1", "key2"}, - paramSets: []map[string]any{ + paramSets: []map[string]interface{}{ {"key1": "a", "key2": "a"}, {"key1": "a", "key2": "a"}, {"key1": "b", "key2": "a"}, diff --git a/applicationset/generators/mocks/Generator.go b/applicationset/generators/mocks/Generator.go index 712a9ed0ed..12c153985d 100644 --- a/applicationset/generators/mocks/Generator.go +++ b/applicationset/generators/mocks/Generator.go @@ -1,17 +1,90 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "time" + client "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" mock "github.com/stretchr/testify/mock" - "sigs.k8s.io/controller-runtime/pkg/client" + + time "time" + + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) +// Generator is an autogenerated mock type for the Generator type +type Generator struct { + mock.Mock +} + +// GenerateParams provides a mock function with given fields: appSetGenerator, applicationSetInfo, _a2 +func (_m *Generator) GenerateParams(appSetGenerator *v1alpha1.ApplicationSetGenerator, applicationSetInfo *v1alpha1.ApplicationSet, _a2 client.Client) ([]map[string]interface{}, error) { + ret := _m.Called(appSetGenerator, applicationSetInfo, _a2) + + if len(ret) == 0 { + panic("no return value specified for GenerateParams") + } + + var r0 []map[string]interface{} + var r1 error + if rf, ok := ret.Get(0).(func(*v1alpha1.ApplicationSetGenerator, *v1alpha1.ApplicationSet, client.Client) ([]map[string]interface{}, error)); ok { + return rf(appSetGenerator, applicationSetInfo, _a2) + } + if rf, ok := ret.Get(0).(func(*v1alpha1.ApplicationSetGenerator, *v1alpha1.ApplicationSet, client.Client) []map[string]interface{}); ok { + r0 = rf(appSetGenerator, applicationSetInfo, _a2) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]map[string]interface{}) + } + } + + if rf, ok := ret.Get(1).(func(*v1alpha1.ApplicationSetGenerator, *v1alpha1.ApplicationSet, client.Client) error); ok { + r1 = rf(appSetGenerator, applicationSetInfo, _a2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRequeueAfter provides a mock function with given fields: appSetGenerator +func (_m *Generator) GetRequeueAfter(appSetGenerator *v1alpha1.ApplicationSetGenerator) time.Duration { + ret := _m.Called(appSetGenerator) + + if len(ret) == 0 { + panic("no return value specified for GetRequeueAfter") + } + + var r0 time.Duration + if rf, ok := ret.Get(0).(func(*v1alpha1.ApplicationSetGenerator) time.Duration); ok { + r0 = rf(appSetGenerator) + } else { + r0 = ret.Get(0).(time.Duration) + } + + return r0 +} + +// GetTemplate provides a mock function with given fields: appSetGenerator +func (_m *Generator) GetTemplate(appSetGenerator *v1alpha1.ApplicationSetGenerator) *v1alpha1.ApplicationSetTemplate { + ret := _m.Called(appSetGenerator) + + if len(ret) == 0 { + panic("no return value specified for GetTemplate") + } + + var r0 *v1alpha1.ApplicationSetTemplate + if rf, ok := ret.Get(0).(func(*v1alpha1.ApplicationSetGenerator) *v1alpha1.ApplicationSetTemplate); ok { + r0 = rf(appSetGenerator) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.ApplicationSetTemplate) + } + } + + return r0 +} + // NewGenerator creates a new instance of Generator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewGenerator(t interface { @@ -25,166 +98,3 @@ func NewGenerator(t interface { return mock } - -// Generator is an autogenerated mock type for the Generator type -type Generator struct { - mock.Mock -} - -type Generator_Expecter struct { - mock *mock.Mock -} - -func (_m *Generator) EXPECT() *Generator_Expecter { - return &Generator_Expecter{mock: &_m.Mock} -} - -// GenerateParams provides a mock function for the type Generator -func (_mock *Generator) GenerateParams(appSetGenerator *v1alpha1.ApplicationSetGenerator, applicationSetInfo *v1alpha1.ApplicationSet, client1 client.Client) ([]map[string]any, error) { - ret := _mock.Called(appSetGenerator, applicationSetInfo, client1) - - if len(ret) == 0 { - panic("no return value specified for GenerateParams") - } - - var r0 []map[string]any - var r1 error - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.ApplicationSetGenerator, *v1alpha1.ApplicationSet, client.Client) ([]map[string]any, error)); ok { - return returnFunc(appSetGenerator, applicationSetInfo, client1) - } - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.ApplicationSetGenerator, *v1alpha1.ApplicationSet, client.Client) []map[string]any); ok { - r0 = returnFunc(appSetGenerator, applicationSetInfo, client1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]map[string]any) - } - } - if returnFunc, ok := ret.Get(1).(func(*v1alpha1.ApplicationSetGenerator, *v1alpha1.ApplicationSet, client.Client) error); ok { - r1 = returnFunc(appSetGenerator, applicationSetInfo, client1) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Generator_GenerateParams_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GenerateParams' -type Generator_GenerateParams_Call struct { - *mock.Call -} - -// GenerateParams is a helper method to define mock.On call -// - appSetGenerator -// - applicationSetInfo -// - client1 -func (_e *Generator_Expecter) GenerateParams(appSetGenerator interface{}, applicationSetInfo interface{}, client1 interface{}) *Generator_GenerateParams_Call { - return &Generator_GenerateParams_Call{Call: _e.mock.On("GenerateParams", appSetGenerator, applicationSetInfo, client1)} -} - -func (_c *Generator_GenerateParams_Call) Run(run func(appSetGenerator *v1alpha1.ApplicationSetGenerator, applicationSetInfo *v1alpha1.ApplicationSet, client1 client.Client)) *Generator_GenerateParams_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.ApplicationSetGenerator), args[1].(*v1alpha1.ApplicationSet), args[2].(client.Client)) - }) - return _c -} - -func (_c *Generator_GenerateParams_Call) Return(stringToVs []map[string]any, err error) *Generator_GenerateParams_Call { - _c.Call.Return(stringToVs, err) - return _c -} - -func (_c *Generator_GenerateParams_Call) RunAndReturn(run func(appSetGenerator *v1alpha1.ApplicationSetGenerator, applicationSetInfo *v1alpha1.ApplicationSet, client1 client.Client) ([]map[string]any, error)) *Generator_GenerateParams_Call { - _c.Call.Return(run) - return _c -} - -// GetRequeueAfter provides a mock function for the type Generator -func (_mock *Generator) GetRequeueAfter(appSetGenerator *v1alpha1.ApplicationSetGenerator) time.Duration { - ret := _mock.Called(appSetGenerator) - - if len(ret) == 0 { - panic("no return value specified for GetRequeueAfter") - } - - var r0 time.Duration - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.ApplicationSetGenerator) time.Duration); ok { - r0 = returnFunc(appSetGenerator) - } else { - r0 = ret.Get(0).(time.Duration) - } - return r0 -} - -// Generator_GetRequeueAfter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRequeueAfter' -type Generator_GetRequeueAfter_Call struct { - *mock.Call -} - -// GetRequeueAfter is a helper method to define mock.On call -// - appSetGenerator -func (_e *Generator_Expecter) GetRequeueAfter(appSetGenerator interface{}) *Generator_GetRequeueAfter_Call { - return &Generator_GetRequeueAfter_Call{Call: _e.mock.On("GetRequeueAfter", appSetGenerator)} -} - -func (_c *Generator_GetRequeueAfter_Call) Run(run func(appSetGenerator *v1alpha1.ApplicationSetGenerator)) *Generator_GetRequeueAfter_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.ApplicationSetGenerator)) - }) - return _c -} - -func (_c *Generator_GetRequeueAfter_Call) Return(duration time.Duration) *Generator_GetRequeueAfter_Call { - _c.Call.Return(duration) - return _c -} - -func (_c *Generator_GetRequeueAfter_Call) RunAndReturn(run func(appSetGenerator *v1alpha1.ApplicationSetGenerator) time.Duration) *Generator_GetRequeueAfter_Call { - _c.Call.Return(run) - return _c -} - -// GetTemplate provides a mock function for the type Generator -func (_mock *Generator) GetTemplate(appSetGenerator *v1alpha1.ApplicationSetGenerator) *v1alpha1.ApplicationSetTemplate { - ret := _mock.Called(appSetGenerator) - - if len(ret) == 0 { - panic("no return value specified for GetTemplate") - } - - var r0 *v1alpha1.ApplicationSetTemplate - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.ApplicationSetGenerator) *v1alpha1.ApplicationSetTemplate); ok { - r0 = returnFunc(appSetGenerator) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.ApplicationSetTemplate) - } - } - return r0 -} - -// Generator_GetTemplate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTemplate' -type Generator_GetTemplate_Call struct { - *mock.Call -} - -// GetTemplate is a helper method to define mock.On call -// - appSetGenerator -func (_e *Generator_Expecter) GetTemplate(appSetGenerator interface{}) *Generator_GetTemplate_Call { - return &Generator_GetTemplate_Call{Call: _e.mock.On("GetTemplate", appSetGenerator)} -} - -func (_c *Generator_GetTemplate_Call) Run(run func(appSetGenerator *v1alpha1.ApplicationSetGenerator)) *Generator_GetTemplate_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.ApplicationSetGenerator)) - }) - return _c -} - -func (_c *Generator_GetTemplate_Call) Return(applicationSetTemplate *v1alpha1.ApplicationSetTemplate) *Generator_GetTemplate_Call { - _c.Call.Return(applicationSetTemplate) - return _c -} - -func (_c *Generator_GetTemplate_Call) RunAndReturn(run func(appSetGenerator *v1alpha1.ApplicationSetGenerator) *v1alpha1.ApplicationSetTemplate) *Generator_GetTemplate_Call { - _c.Call.Return(run) - return _c -} diff --git a/applicationset/generators/plugin.go b/applicationset/generators/plugin.go index 5db22571c5..6b6ba1ec40 100644 --- a/applicationset/generators/plugin.go +++ b/applicationset/generators/plugin.go @@ -2,7 +2,6 @@ package generators import ( "context" - "errors" "fmt" "strconv" "strings" @@ -13,14 +12,14 @@ import ( "k8s.io/client-go/kubernetes" "sigs.k8s.io/controller-runtime/pkg/client" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/settings" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/settings" - "github.com/argoproj/argo-cd/v3/applicationset/services/plugin" + "github.com/argoproj/argo-cd/v2/applicationset/services/plugin" ) const ( - DefaultPluginRequeueAfter = 30 * time.Minute + DefaultPluginRequeueAfterSeconds = 30 * time.Minute ) var _ Generator = (*PluginGenerator)(nil) @@ -32,7 +31,7 @@ type PluginGenerator struct { namespace string } -func NewPluginGenerator(ctx context.Context, client client.Client, clientset kubernetes.Interface, namespace string) Generator { +func NewPluginGenerator(client client.Client, ctx context.Context, clientset kubernetes.Interface, namespace string) Generator { g := &PluginGenerator{ client: client, ctx: ctx, @@ -49,20 +48,20 @@ func (g *PluginGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.Ap return time.Duration(*appSetGenerator.Plugin.RequeueAfterSeconds) * time.Second } - return DefaultPluginRequeueAfter + return DefaultPluginRequeueAfterSeconds } func (g *PluginGenerator) GetTemplate(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) *argoprojiov1alpha1.ApplicationSetTemplate { return &appSetGenerator.Plugin.Template } -func (g *PluginGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, applicationSetInfo *argoprojiov1alpha1.ApplicationSet, _ client.Client) ([]map[string]any, error) { +func (g *PluginGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, applicationSetInfo *argoprojiov1alpha1.ApplicationSet, _ client.Client) ([]map[string]interface{}, error) { if appSetGenerator == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } if appSetGenerator.Plugin == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } ctx := context.Background() @@ -106,18 +105,18 @@ func (g *PluginGenerator) getPluginFromGenerator(ctx context.Context, appSetName } } - pluginClient, err := plugin.NewPluginService(appSetName, cm["baseUrl"], token, requestTimeout) + pluginClient, err := plugin.NewPluginService(ctx, appSetName, cm["baseUrl"], token, requestTimeout) if err != nil { return nil, fmt.Errorf("error initializing plugin client: %w", err) } return pluginClient, nil } -func (g *PluginGenerator) generateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, objectsFound []map[string]any, pluginParams argoprojiov1alpha1.PluginParameters, useGoTemplate bool) ([]map[string]any, error) { - res := []map[string]any{} +func (g *PluginGenerator) generateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, objectsFound []map[string]interface{}, pluginParams argoprojiov1alpha1.PluginParameters, useGoTemplate bool) ([]map[string]interface{}, error) { + res := []map[string]interface{}{} for _, objectFound := range objectsFound { - params := map[string]any{} + params := map[string]interface{}{} if useGoTemplate { for k, v := range objectFound { @@ -133,7 +132,7 @@ func (g *PluginGenerator) generateParams(appSetGenerator *argoprojiov1alpha1.App } } - params["generator"] = map[string]any{ + params["generator"] = map[string]interface{}{ "input": map[string]argoprojiov1alpha1.PluginParameters{ "parameters": pluginParams, }, @@ -193,14 +192,14 @@ func (g *PluginGenerator) getConfigMap(ctx context.Context, configMapRef string) return nil, err } - baseURL, ok := cm.Data["baseUrl"] - if !ok || baseURL == "" { - return nil, errors.New("baseUrl not found in ConfigMap") + baseUrl, ok := cm.Data["baseUrl"] + if !ok || baseUrl == "" { + return nil, fmt.Errorf("baseUrl not found in ConfigMap") } token, ok := cm.Data["token"] if !ok || token == "" { - return nil, errors.New("token not found in ConfigMap") + return nil, fmt.Errorf("token not found in ConfigMap") } return cm.Data, nil diff --git a/applicationset/generators/plugin_test.go b/applicationset/generators/plugin_test.go index 4940b64d44..0ade708ee5 100644 --- a/applicationset/generators/plugin_test.go +++ b/applicationset/generators/plugin_test.go @@ -1,8 +1,8 @@ package generators import ( + "context" "encoding/json" - "errors" "fmt" "net/http" "net/http/httptest" @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -19,25 +19,25 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" - "github.com/argoproj/argo-cd/v3/applicationset/services/plugin" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/services/plugin" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestPluginGenerateParams(t *testing.T) { testCases := []struct { name string - configmap *corev1.ConfigMap - secret *corev1.Secret + configmap *v1.ConfigMap + secret *v1.Secret inputParameters map[string]apiextensionsv1.JSON values map[string]string gotemplate bool - expected []map[string]any + expected []map[string]interface{} content []byte expectedError error }{ { name: "simple case", - configmap: &corev1.ConfigMap{ + configmap: &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "first-plugin-cm", Namespace: "default", @@ -47,7 +47,7 @@ func TestPluginGenerateParams(t *testing.T) { "token": "$plugin.token", }, }, - secret: &corev1.Secret{ + secret: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: "default", @@ -73,13 +73,13 @@ func TestPluginGenerateParams(t *testing.T) { "key3": 123 }] }}`), - expected: []map[string]any{ + expected: []map[string]interface{}{ { "key1": "val1", "key2.key2_1": "val2_1", "key2.key2_2.key2_2_1": "val2_2_1", "key3": "123", - "generator": map[string]any{ + "generator": map[string]interface{}{ "input": argoprojiov1alpha1.PluginInput{ Parameters: argoprojiov1alpha1.PluginParameters{ "pkey1": {Raw: []byte(`"val1"`)}, @@ -93,7 +93,7 @@ func TestPluginGenerateParams(t *testing.T) { }, { name: "simple case with values", - configmap: &corev1.ConfigMap{ + configmap: &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "first-plugin-cm", Namespace: "default", @@ -103,7 +103,7 @@ func TestPluginGenerateParams(t *testing.T) { "token": "$plugin.token", }, }, - secret: &corev1.Secret{ + secret: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: "default", @@ -133,7 +133,7 @@ func TestPluginGenerateParams(t *testing.T) { "key3": 123 }] }}`), - expected: []map[string]any{ + expected: []map[string]interface{}{ { "key1": "val1", "key2.key2_1": "val2_1", @@ -141,7 +141,7 @@ func TestPluginGenerateParams(t *testing.T) { "key3": "123", "values.valuekey1": "valuevalue1", "values.valuekey2": "templated-val1", - "generator": map[string]any{ + "generator": map[string]interface{}{ "input": argoprojiov1alpha1.PluginInput{ Parameters: argoprojiov1alpha1.PluginParameters{ "pkey1": {Raw: []byte(`"val1"`)}, @@ -155,7 +155,7 @@ func TestPluginGenerateParams(t *testing.T) { }, { name: "simple case with gotemplate", - configmap: &corev1.ConfigMap{ + configmap: &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "first-plugin-cm", Namespace: "default", @@ -165,7 +165,7 @@ func TestPluginGenerateParams(t *testing.T) { "token": "$plugin.token", }, }, - secret: &corev1.Secret{ + secret: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: "default", @@ -191,17 +191,17 @@ func TestPluginGenerateParams(t *testing.T) { "key3": 123 }] }}`), - expected: []map[string]any{ + expected: []map[string]interface{}{ { "key1": "val1", - "key2": map[string]any{ + "key2": map[string]interface{}{ "key2_1": "val2_1", - "key2_2": map[string]any{ + "key2_2": map[string]interface{}{ "key2_2_1": "val2_2_1", }, }, "key3": float64(123), - "generator": map[string]any{ + "generator": map[string]interface{}{ "input": argoprojiov1alpha1.PluginInput{ Parameters: argoprojiov1alpha1.PluginParameters{ "pkey1": {Raw: []byte(`"val1"`)}, @@ -215,7 +215,7 @@ func TestPluginGenerateParams(t *testing.T) { }, { name: "simple case with appended params", - configmap: &corev1.ConfigMap{ + configmap: &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "first-plugin-cm", Namespace: "default", @@ -225,7 +225,7 @@ func TestPluginGenerateParams(t *testing.T) { "token": "$plugin.token", }, }, - secret: &corev1.Secret{ + secret: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: "default", @@ -250,14 +250,14 @@ func TestPluginGenerateParams(t *testing.T) { "key3": 123, "pkey2": "valplugin" }]}}`), - expected: []map[string]any{ + expected: []map[string]interface{}{ { "key1": "val1", "key2.key2_1": "val2_1", "key2.key2_2.key2_2_1": "val2_2_1", "key3": "123", "pkey2": "valplugin", - "generator": map[string]any{ + "generator": map[string]interface{}{ "input": argoprojiov1alpha1.PluginInput{ Parameters: argoprojiov1alpha1.PluginParameters{ "pkey1": {Raw: []byte(`"val1"`)}, @@ -271,7 +271,7 @@ func TestPluginGenerateParams(t *testing.T) { }, { name: "no params", - configmap: &corev1.ConfigMap{ + configmap: &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "first-plugin-cm", Namespace: "default", @@ -281,7 +281,7 @@ func TestPluginGenerateParams(t *testing.T) { "token": "$plugin.token", }, }, - secret: &corev1.Secret{ + secret: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: "default", @@ -304,14 +304,14 @@ func TestPluginGenerateParams(t *testing.T) { "key3": 123 }] }}`), - expected: []map[string]any{ + expected: []map[string]interface{}{ { "key1": "val1", "key2.key2_1": "val2_1", "key2.key2_2.key2_2_1": "val2_2_1", "key3": "123", - "generator": map[string]any{ - "input": map[string]map[string]any{ + "generator": map[string]interface{}{ + "input": map[string]map[string]interface{}{ "parameters": {}, }, }, @@ -321,7 +321,7 @@ func TestPluginGenerateParams(t *testing.T) { }, { name: "empty return", - configmap: &corev1.ConfigMap{ + configmap: &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "first-plugin-cm", Namespace: "default", @@ -331,7 +331,7 @@ func TestPluginGenerateParams(t *testing.T) { "token": "$plugin.token", }, }, - secret: &corev1.Secret{ + secret: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: "default", @@ -343,12 +343,12 @@ func TestPluginGenerateParams(t *testing.T) { inputParameters: map[string]apiextensionsv1.JSON{}, gotemplate: false, content: []byte(`{"input": {"parameters": []}}`), - expected: []map[string]any{}, + expected: []map[string]interface{}{}, expectedError: nil, }, { name: "wrong return", - configmap: &corev1.ConfigMap{ + configmap: &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "first-plugin-cm", Namespace: "default", @@ -358,7 +358,7 @@ func TestPluginGenerateParams(t *testing.T) { "token": "$plugin.token", }, }, - secret: &corev1.Secret{ + secret: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: "default", @@ -370,12 +370,12 @@ func TestPluginGenerateParams(t *testing.T) { inputParameters: map[string]apiextensionsv1.JSON{}, gotemplate: false, content: []byte(`wrong body ...`), - expected: []map[string]any{}, - expectedError: errors.New("error listing params: error get api 'set': invalid character 'w' looking for beginning of value: wrong body ..."), + expected: []map[string]interface{}{}, + expectedError: fmt.Errorf("error listing params: error get api 'set': invalid character 'w' looking for beginning of value: wrong body ..."), }, { name: "external secret", - configmap: &corev1.ConfigMap{ + configmap: &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "first-plugin-cm", Namespace: "default", @@ -385,7 +385,7 @@ func TestPluginGenerateParams(t *testing.T) { "token": "$plugin-secret:plugin.token", }, }, - secret: &corev1.Secret{ + secret: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "plugin-secret", Namespace: "default", @@ -410,14 +410,14 @@ func TestPluginGenerateParams(t *testing.T) { "key3": 123, "pkey2": "valplugin" }]}}`), - expected: []map[string]any{ + expected: []map[string]interface{}{ { "key1": "val1", "key2.key2_1": "val2_1", "key2.key2_2.key2_2_1": "val2_2_1", "key3": "123", "pkey2": "valplugin", - "generator": map[string]any{ + "generator": map[string]interface{}{ "input": argoprojiov1alpha1.PluginInput{ Parameters: argoprojiov1alpha1.PluginParameters{ "pkey1": {Raw: []byte(`"val1"`)}, @@ -431,7 +431,7 @@ func TestPluginGenerateParams(t *testing.T) { }, { name: "no secret", - configmap: &corev1.ConfigMap{ + configmap: &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "first-plugin-cm", Namespace: "default", @@ -441,7 +441,7 @@ func TestPluginGenerateParams(t *testing.T) { "token": "$plugin.token", }, }, - secret: &corev1.Secret{}, + secret: &v1.Secret{}, inputParameters: map[string]apiextensionsv1.JSON{ "pkey1": {Raw: []byte(`"val1"`)}, "pkey2": {Raw: []byte(`"val2"`)}, @@ -459,13 +459,13 @@ func TestPluginGenerateParams(t *testing.T) { "key3": 123 }] }}`), - expected: []map[string]any{ + expected: []map[string]interface{}{ { "key1": "val1", "key2.key2_1": "val2_1", "key2.key2_2.key2_2_1": "val2_2_1", "key3": "123", - "generator": map[string]any{ + "generator": map[string]interface{}{ "input": argoprojiov1alpha1.PluginInput{ Parameters: argoprojiov1alpha1.PluginParameters{ "pkey1": {Raw: []byte(`"val1"`)}, @@ -475,12 +475,12 @@ func TestPluginGenerateParams(t *testing.T) { }, }, }, - expectedError: errors.New("error getting plugin from generator: error fetching Secret token: error fetching secret default/argocd-secret: secrets \"argocd-secret\" not found"), + expectedError: fmt.Errorf("error getting plugin from generator: error fetching Secret token: error fetching secret default/argocd-secret: secrets \"argocd-secret\" not found"), }, { name: "no configmap", - configmap: &corev1.ConfigMap{}, - secret: &corev1.Secret{ + configmap: &v1.ConfigMap{}, + secret: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: "default", @@ -506,13 +506,13 @@ func TestPluginGenerateParams(t *testing.T) { "key3": 123 }] }}`), - expected: []map[string]any{ + expected: []map[string]interface{}{ { "key1": "val1", "key2.key2_1": "val2_1", "key2.key2_2.key2_2_1": "val2_2_1", "key3": "123", - "generator": map[string]any{ + "generator": map[string]interface{}{ "input": argoprojiov1alpha1.PluginInput{ Parameters: argoprojiov1alpha1.PluginParameters{ "pkey1": {Raw: []byte(`"val1"`)}, @@ -522,11 +522,11 @@ func TestPluginGenerateParams(t *testing.T) { }, }, }, - expectedError: errors.New("error getting plugin from generator: error fetching ConfigMap: configmaps \"\" not found"), + expectedError: fmt.Errorf("error getting plugin from generator: error fetching ConfigMap: configmaps \"\" not found"), }, { name: "no baseUrl", - configmap: &corev1.ConfigMap{ + configmap: &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "first-plugin-cm", Namespace: "default", @@ -535,7 +535,7 @@ func TestPluginGenerateParams(t *testing.T) { "token": "$plugin.token", }, }, - secret: &corev1.Secret{ + secret: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: "default", @@ -561,13 +561,13 @@ func TestPluginGenerateParams(t *testing.T) { "key3": 123 }] }}`), - expected: []map[string]any{ + expected: []map[string]interface{}{ { "key1": "val1", "key2.key2_1": "val2_1", "key2.key2_2.key2_2_1": "val2_2_1", "key3": "123", - "generator": map[string]any{ + "generator": map[string]interface{}{ "input": argoprojiov1alpha1.PluginInput{ Parameters: argoprojiov1alpha1.PluginParameters{ "pkey1": {Raw: []byte(`"val1"`)}, @@ -577,11 +577,11 @@ func TestPluginGenerateParams(t *testing.T) { }, }, }, - expectedError: errors.New("error getting plugin from generator: error fetching ConfigMap: baseUrl not found in ConfigMap"), + expectedError: fmt.Errorf("error getting plugin from generator: error fetching ConfigMap: baseUrl not found in ConfigMap"), }, { name: "no token", - configmap: &corev1.ConfigMap{ + configmap: &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "first-plugin-cm", Namespace: "default", @@ -590,7 +590,7 @@ func TestPluginGenerateParams(t *testing.T) { "baseUrl": "http://127.0.0.1", }, }, - secret: &corev1.Secret{}, + secret: &v1.Secret{}, inputParameters: map[string]apiextensionsv1.JSON{ "pkey1": {Raw: []byte(`"val1"`)}, "pkey2": {Raw: []byte(`"val2"`)}, @@ -608,13 +608,13 @@ func TestPluginGenerateParams(t *testing.T) { "key3": 123 }] }}`), - expected: []map[string]any{ + expected: []map[string]interface{}{ { "key1": "val1", "key2.key2_1": "val2_1", "key2.key2_2.key2_2_1": "val2_2_1", "key3": "123", - "generator": map[string]any{ + "generator": map[string]interface{}{ "input": argoprojiov1alpha1.PluginInput{ Parameters: argoprojiov1alpha1.PluginParameters{ "pkey1": {Raw: []byte(`"val1"`)}, @@ -624,11 +624,11 @@ func TestPluginGenerateParams(t *testing.T) { }, }, }, - expectedError: errors.New("error getting plugin from generator: error fetching ConfigMap: token not found in ConfigMap"), + expectedError: fmt.Errorf("error getting plugin from generator: error fetching ConfigMap: token not found in ConfigMap"), }, } - ctx := t.Context() + ctx := context.Background() for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { @@ -670,7 +670,7 @@ func TestPluginGenerateParams(t *testing.T) { fakeClientWithCache := fake.NewClientBuilder().WithObjects([]client.Object{testCase.configmap, testCase.secret}...).Build() - pluginGenerator := NewPluginGenerator(ctx, fakeClientWithCache, fakeClient, "default") + pluginGenerator := NewPluginGenerator(fakeClientWithCache, ctx, fakeClient, "default") applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ @@ -690,11 +690,11 @@ func TestPluginGenerateParams(t *testing.T) { require.EqualError(t, err, testCase.expectedError.Error()) } else { require.NoError(t, err) - expectedJSON, err := json.Marshal(testCase.expected) + expectedJson, err := json.Marshal(testCase.expected) require.NoError(t, err) - gotJSON, err := json.Marshal(got) + gotJson, err := json.Marshal(got) require.NoError(t, err) - assert.JSONEq(t, string(expectedJSON), string(gotJSON)) + assert.JSONEq(t, string(expectedJson), string(gotJson)) } }) } diff --git a/applicationset/generators/pull_request.go b/applicationset/generators/pull_request.go index 0059f249b0..f0c2bfaacf 100644 --- a/applicationset/generators/pull_request.go +++ b/applicationset/generators/pull_request.go @@ -2,7 +2,6 @@ package generators import ( "context" - "errors" "fmt" "strconv" "time" @@ -11,15 +10,15 @@ import ( "github.com/gosimple/slug" - pullrequest "github.com/argoproj/argo-cd/v3/applicationset/services/pull_request" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + pullrequest "github.com/argoproj/argo-cd/v2/applicationset/services/pull_request" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) var _ Generator = (*PullRequestGenerator)(nil) const ( - DefaultPullRequestRequeueAfter = 30 * time.Minute + DefaultPullRequestRequeueAfterSeconds = 30 * time.Minute ) type PullRequestGenerator struct { @@ -44,20 +43,20 @@ func (g *PullRequestGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alph return time.Duration(*appSetGenerator.PullRequest.RequeueAfterSeconds) * time.Second } - return DefaultPullRequestRequeueAfter + return DefaultPullRequestRequeueAfterSeconds } func (g *PullRequestGenerator) GetTemplate(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) *argoprojiov1alpha1.ApplicationSetTemplate { return &appSetGenerator.PullRequest.Template } -func (g *PullRequestGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, applicationSetInfo *argoprojiov1alpha1.ApplicationSet, _ client.Client) ([]map[string]any, error) { +func (g *PullRequestGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, applicationSetInfo *argoprojiov1alpha1.ApplicationSet, _ client.Client) ([]map[string]interface{}, error) { if appSetGenerator == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } if appSetGenerator.PullRequest == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } ctx := context.Background() @@ -70,7 +69,7 @@ func (g *PullRequestGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha if err != nil { return nil, fmt.Errorf("error listing repos: %w", err) } - params := make([]map[string]any, 0, len(pulls)) + params := make([]map[string]interface{}, 0, len(pulls)) // In order to follow the DNS label standard as defined in RFC 1123, // we need to limit the 'branch' to 50 to give room to append/suffix-ing it @@ -96,7 +95,7 @@ func (g *PullRequestGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha shortSHALength7 = len(pull.HeadSHA) } - paramMap := map[string]any{ + paramMap := map[string]interface{}{ "number": strconv.Itoa(pull.Number), "title": pull.Title, "branch": pull.Branch, @@ -109,11 +108,6 @@ func (g *PullRequestGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha "author": pull.Author, } - err := appendTemplatedValues(appSetGenerator.PullRequest.Values, paramMap, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions) - if err != nil { - return nil, fmt.Errorf("failed to append templated values: %w", err) - } - // PR lables will only be supported for Go Template appsets, since fasttemplate will be deprecated. if applicationSetInfo != nil && applicationSetInfo.Spec.GoTemplate { paramMap["labels"] = pull.Labels @@ -149,7 +143,7 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } - return pullrequest.NewGitLabService(token, providerConfig.API, providerConfig.Project, providerConfig.Labels, providerConfig.PullRequestState, g.scmRootCAPath, providerConfig.Insecure, caCerts) + return pullrequest.NewGitLabService(ctx, token, providerConfig.API, providerConfig.Project, providerConfig.Labels, providerConfig.PullRequestState, g.scmRootCAPath, providerConfig.Insecure, caCerts) } if generatorConfig.Gitea != nil { providerConfig := generatorConfig.Gitea @@ -157,8 +151,7 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } - - return pullrequest.NewGiteaService(token, providerConfig.API, providerConfig.Owner, providerConfig.Repo, providerConfig.Labels, providerConfig.Insecure) + return pullrequest.NewGiteaService(ctx, token, providerConfig.API, providerConfig.Owner, providerConfig.Repo, providerConfig.Insecure) } if generatorConfig.BitbucketServer != nil { providerConfig := generatorConfig.BitbucketServer @@ -182,8 +175,9 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera return nil, fmt.Errorf("error fetching Secret token: %w", err) } return pullrequest.NewBitbucketServiceBasicAuth(ctx, providerConfig.BasicAuth.Username, password, providerConfig.API, providerConfig.Project, providerConfig.Repo, g.scmRootCAPath, providerConfig.Insecure, caCerts) + } else { + return pullrequest.NewBitbucketServiceNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.Repo, g.scmRootCAPath, providerConfig.Insecure, caCerts) } - return pullrequest.NewBitbucketServiceNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.Repo, g.scmRootCAPath, providerConfig.Insecure, caCerts) } if generatorConfig.Bitbucket != nil { providerConfig := generatorConfig.Bitbucket @@ -199,8 +193,9 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera return nil, fmt.Errorf("error fetching Secret token: %w", err) } return pullrequest.NewBitbucketCloudServiceBasicAuth(providerConfig.API, providerConfig.BasicAuth.Username, password, providerConfig.Owner, providerConfig.Repo) + } else { + return pullrequest.NewBitbucketCloudServiceNoAuth(providerConfig.API, providerConfig.Owner, providerConfig.Repo) } - return pullrequest.NewBitbucketCloudServiceNoAuth(providerConfig.API, providerConfig.Owner, providerConfig.Repo) } if generatorConfig.AzureDevOps != nil { providerConfig := generatorConfig.AzureDevOps @@ -208,9 +203,9 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } - return pullrequest.NewAzureDevOpsService(token, providerConfig.API, providerConfig.Organization, providerConfig.Project, providerConfig.Repo, providerConfig.Labels) + return pullrequest.NewAzureDevOpsService(ctx, token, providerConfig.API, providerConfig.Organization, providerConfig.Project, providerConfig.Repo, providerConfig.Labels) } - return nil, errors.New("no Pull Request provider implementation configured") + return nil, fmt.Errorf("no Pull Request provider implementation configured") } func (g *PullRequestGenerator) github(ctx context.Context, cfg *argoprojiov1alpha1.PullRequestGeneratorGithub, applicationSetInfo *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) { @@ -228,5 +223,5 @@ func (g *PullRequestGenerator) github(ctx context.Context, cfg *argoprojiov1alph if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } - return pullrequest.NewGithubService(token, cfg.API, cfg.Owner, cfg.Repo, cfg.Labels) + return pullrequest.NewGithubService(ctx, token, cfg.API, cfg.Owner, cfg.Repo, cfg.Labels) } diff --git a/applicationset/generators/pull_request_test.go b/applicationset/generators/pull_request_test.go index 8cfbf7920d..d4eae1602b 100644 --- a/applicationset/generators/pull_request_test.go +++ b/applicationset/generators/pull_request_test.go @@ -2,23 +2,22 @@ package generators import ( "context" - "errors" + "fmt" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - pullrequest "github.com/argoproj/argo-cd/v3/applicationset/services/pull_request" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + pullrequest "github.com/argoproj/argo-cd/v2/applicationset/services/pull_request" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestPullRequestGithubGenerateParams(t *testing.T) { - ctx := t.Context() + ctx := context.Background() cases := []struct { selectFunc func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) - values map[string]string - expected []map[string]any + expected []map[string]interface{} expectedErr error applicationSet argoprojiov1alpha1.ApplicationSet }{ @@ -39,7 +38,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { nil, ) }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "number": "1", "title": "title1", @@ -72,7 +71,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { nil, ) }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "number": "2", "title": "title2", @@ -105,7 +104,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { nil, ) }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "number": "1", "title": "title1", @@ -125,51 +124,12 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { selectFunc: func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) { return pullrequest.NewFakeService( ctx, - []*pullrequest.PullRequest{ - { - Number: 1, - Title: "title1", - Branch: "my_branch", - TargetBranch: "master", - HeadSHA: "abcd", - Author: "testName", - }, - }, nil, - ) - }, - values: map[string]string{ - "foo": "bar", - "pr_branch": "{{ branch }}", - }, - expected: []map[string]any{ - { - "number": "1", - "title": "title1", - "branch": "my_branch", - "branch_slug": "my-branch", - "target_branch": "master", - "target_branch_slug": "master", - "head_sha": "abcd", - "head_short_sha": "abcd", - "head_short_sha_7": "abcd", - "author": "testName", - "values.foo": "bar", - "values.pr_branch": "my_branch", - }, - }, - expectedErr: nil, - }, - { - selectFunc: func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) { - return pullrequest.NewFakeService( - ctx, - nil, - errors.New("fake error"), + fmt.Errorf("fake error"), ) }, expected: nil, - expectedErr: errors.New("error listing repos: fake error"), + expectedErr: fmt.Errorf("error listing repos: fake error"), }, { selectFunc: func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) { @@ -189,7 +149,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { nil, ) }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "number": "1", "title": "title1", @@ -230,7 +190,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { nil, ) }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "number": "1", "title": "title1", @@ -259,14 +219,12 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { selectServiceProviderFunc: c.selectFunc, } generatorConfig := argoprojiov1alpha1.ApplicationSetGenerator{ - PullRequest: &argoprojiov1alpha1.PullRequestGenerator{ - Values: c.values, - }, + PullRequest: &argoprojiov1alpha1.PullRequestGenerator{}, } got, gotErr := gen.GenerateParams(&generatorConfig, &c.applicationSet, nil) if c.expectedErr != nil { - require.EqualError(t, gotErr, c.expectedErr.Error()) + assert.Equal(t, c.expectedErr.Error(), gotErr.Error()) } else { require.NoError(t, gotErr) } diff --git a/applicationset/generators/scm_provider.go b/applicationset/generators/scm_provider.go index 560a37050d..417b682e50 100644 --- a/applicationset/generators/scm_provider.go +++ b/applicationset/generators/scm_provider.go @@ -11,17 +11,17 @@ import ( log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/applicationset/services/github_app_auth" - "github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - "github.com/argoproj/argo-cd/v3/common" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/services/github_app_auth" + "github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + "github.com/argoproj/argo-cd/v2/common" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) var _ Generator = (*SCMProviderGenerator)(nil) const ( - DefaultSCMProviderRequeueAfter = 30 * time.Minute + DefaultSCMProviderRequeueAfterSeconds = 30 * time.Minute ) type SCMProviderGenerator struct { @@ -69,7 +69,7 @@ func (g *SCMProviderGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alph return time.Duration(*appSetGenerator.SCMProvider.RequeueAfterSeconds) * time.Second } - return DefaultSCMProviderRequeueAfter + return DefaultSCMProviderRequeueAfterSeconds } func (g *SCMProviderGenerator) GetTemplate(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) *argoprojiov1alpha1.ApplicationSetTemplate { @@ -116,13 +116,13 @@ func ScmProviderAllowed(applicationSetInfo *argoprojiov1alpha1.ApplicationSet, g return NewErrDisallowedSCMProvider(url, allowedScmProviders) } -func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, applicationSetInfo *argoprojiov1alpha1.ApplicationSet, _ client.Client) ([]map[string]any, error) { +func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, applicationSetInfo *argoprojiov1alpha1.ApplicationSet, _ client.Client) ([]map[string]interface{}, error) { if appSetGenerator == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } if appSetGenerator.SCMProvider == nil { - return nil, ErrEmptyAppSetGenerator + return nil, EmptyAppSetGeneratorError } if !g.enableSCMProviders { @@ -138,16 +138,15 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha ctx := context.Background() var provider scm_provider.SCMProviderService - switch { - case g.overrideProvider != nil: + if g.overrideProvider != nil { provider = g.overrideProvider - case providerConfig.Github != nil: + } else if providerConfig.Github != nil { var err error provider, err = g.githubProvider(ctx, providerConfig.Github, applicationSetInfo) if err != nil { return nil, fmt.Errorf("scm provider: %w", err) } - case providerConfig.Gitlab != nil: + } else if providerConfig.Gitlab != nil { providerConfig := providerConfig.Gitlab var caCerts []byte var scmError error @@ -161,20 +160,20 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha if err != nil { return nil, fmt.Errorf("error fetching Gitlab token: %w", err) } - provider, err = scm_provider.NewGitlabProvider(providerConfig.Group, token, providerConfig.API, providerConfig.AllBranches, providerConfig.IncludeSubgroups, providerConfig.WillIncludeSharedProjects(), providerConfig.Insecure, g.scmRootCAPath, providerConfig.Topic, caCerts) + provider, err = scm_provider.NewGitlabProvider(ctx, providerConfig.Group, token, providerConfig.API, providerConfig.AllBranches, providerConfig.IncludeSubgroups, providerConfig.WillIncludeSharedProjects(), providerConfig.Insecure, g.scmRootCAPath, providerConfig.Topic, caCerts) if err != nil { return nil, fmt.Errorf("error initializing Gitlab service: %w", err) } - case providerConfig.Gitea != nil: + } else if providerConfig.Gitea != nil { 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) } - provider, err = scm_provider.NewGiteaProvider(providerConfig.Gitea.Owner, token, providerConfig.Gitea.API, providerConfig.Gitea.AllBranches, providerConfig.Gitea.Insecure) + provider, err = scm_provider.NewGiteaProvider(ctx, providerConfig.Gitea.Owner, token, providerConfig.Gitea.API, providerConfig.Gitea.AllBranches, providerConfig.Gitea.Insecure) if err != nil { return nil, fmt.Errorf("error initializing Gitea service: %w", err) } - case providerConfig.BitbucketServer != nil: + } else if providerConfig.BitbucketServer != nil { providerConfig := providerConfig.BitbucketServer var caCerts []byte var scmError error @@ -184,51 +183,50 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha return nil, fmt.Errorf("error fetching CA certificates from ConfigMap: %w", scmError) } } - switch { - case providerConfig.BearerToken != nil: + if providerConfig.BearerToken != nil { 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) - case providerConfig.BasicAuth != nil: + } else if providerConfig.BasicAuth != nil { 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) } provider, scmError = scm_provider.NewBitbucketServerProviderBasicAuth(ctx, providerConfig.BasicAuth.Username, password, providerConfig.API, providerConfig.Project, providerConfig.AllBranches, g.scmRootCAPath, providerConfig.Insecure, caCerts) - default: + } else { provider, scmError = scm_provider.NewBitbucketServerProviderNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.AllBranches, g.scmRootCAPath, providerConfig.Insecure, caCerts) } if scmError != nil { return nil, fmt.Errorf("error initializing Bitbucket Server service: %w", scmError) } - case providerConfig.AzureDevOps != nil: + } else if providerConfig.AzureDevOps != nil { 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) } - provider, err = scm_provider.NewAzureDevOpsProvider(token, providerConfig.AzureDevOps.Organization, providerConfig.AzureDevOps.API, providerConfig.AzureDevOps.TeamProject, providerConfig.AzureDevOps.AllBranches) + provider, err = scm_provider.NewAzureDevOpsProvider(ctx, token, providerConfig.AzureDevOps.Organization, providerConfig.AzureDevOps.API, providerConfig.AzureDevOps.TeamProject, providerConfig.AzureDevOps.AllBranches) if err != nil { return nil, fmt.Errorf("error initializing Azure Devops service: %w", err) } - case providerConfig.Bitbucket != nil: + } else if providerConfig.Bitbucket != nil { 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) } - provider, err = scm_provider.NewBitBucketCloudProvider(providerConfig.Bitbucket.Owner, providerConfig.Bitbucket.User, appPassword, providerConfig.Bitbucket.AllBranches) + provider, err = scm_provider.NewBitBucketCloudProvider(ctx, providerConfig.Bitbucket.Owner, providerConfig.Bitbucket.User, appPassword, providerConfig.Bitbucket.AllBranches) if err != nil { return nil, fmt.Errorf("error initializing Bitbucket cloud service: %w", err) } - case providerConfig.AWSCodeCommit != nil: + } else if providerConfig.AWSCodeCommit != nil { var awsErr error provider, awsErr = scm_provider.NewAWSCodeCommitProvider(ctx, providerConfig.AWSCodeCommit.TagFilters, providerConfig.AWSCodeCommit.Role, providerConfig.AWSCodeCommit.Region, providerConfig.AWSCodeCommit.AllBranches) if awsErr != nil { return nil, fmt.Errorf("error initializing AWS codecommit service: %w", awsErr) } - default: - return nil, errors.New("no SCM provider implementation configured") + } else { + return nil, fmt.Errorf("no SCM provider implementation configured") } // Find all the available repos. @@ -236,7 +234,7 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha if err != nil { return nil, fmt.Errorf("error listing repos: %w", err) } - paramsArray := make([]map[string]any, 0, len(repos)) + paramsArray := make([]map[string]interface{}, 0, len(repos)) var shortSHALength int var shortSHALength7 int for _, repo := range repos { @@ -250,10 +248,9 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha shortSHALength7 = len(repo.SHA) } - params := map[string]any{ + params := map[string]interface{}{ "organization": repo.Organization, "repository": repo.Repository, - "repository_id": repo.RepositoryId, "url": repo.URL, "branch": repo.Branch, "sha": repo.SHA, @@ -292,5 +289,5 @@ func (g *SCMProviderGenerator) githubProvider(ctx context.Context, github *argop if err != nil { return nil, fmt.Errorf("error fetching Github token: %w", err) } - return scm_provider.NewGithubProvider(github.Organization, token, github.API, github.AllBranches) + return scm_provider.NewGithubProvider(ctx, github.Organization, token, github.API, github.AllBranches) } diff --git a/applicationset/generators/scm_provider_test.go b/applicationset/generators/scm_provider_test.go index 9d7618c869..a52f7e8159 100644 --- a/applicationset/generators/scm_provider_test.go +++ b/applicationset/generators/scm_provider_test.go @@ -7,8 +7,8 @@ import ( "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestSCMProviderGenerateParams(t *testing.T) { @@ -16,7 +16,7 @@ func TestSCMProviderGenerateParams(t *testing.T) { name string repos []*scm_provider.Repository values map[string]string - expected []map[string]any + expected []map[string]interface{} expectedError error }{ { @@ -25,7 +25,6 @@ func TestSCMProviderGenerateParams(t *testing.T) { { Organization: "myorg", Repository: "repo1", - RepositoryId: 190320251, URL: "git@github.com:myorg/repo1.git", Branch: "main", SHA: "0bc57212c3cbbec69d20b34c507284bd300def5b", @@ -34,17 +33,15 @@ func TestSCMProviderGenerateParams(t *testing.T) { { Organization: "myorg", Repository: "repo2", - RepositoryId: 190320252, URL: "git@github.com:myorg/repo2.git", Branch: "main", SHA: "59d0", }, }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "organization": "myorg", "repository": "repo1", - "repository_id": 190320251, "url": "git@github.com:myorg/repo1.git", "branch": "main", "branchNormalized": "main", @@ -56,7 +53,6 @@ func TestSCMProviderGenerateParams(t *testing.T) { { "organization": "myorg", "repository": "repo2", - "repository_id": 190320252, "url": "git@github.com:myorg/repo2.git", "branch": "main", "branchNormalized": "main", @@ -73,7 +69,6 @@ func TestSCMProviderGenerateParams(t *testing.T) { { Organization: "myorg", Repository: "repo3", - RepositoryId: 190320253, URL: "git@github.com:myorg/repo3.git", Branch: "main", SHA: "0bc57212c3cbbec69d20b34c507284bd300def5b", @@ -84,11 +79,10 @@ func TestSCMProviderGenerateParams(t *testing.T) { "foo": "bar", "should_i_force_push_to": "{{ branch }}?", }, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "organization": "myorg", "repository": "repo3", - "repository_id": 190320253, "url": "git@github.com:myorg/repo3.git", "branch": "main", "branchNormalized": "main", @@ -101,52 +95,6 @@ func TestSCMProviderGenerateParams(t *testing.T) { }, }, }, - { - name: "Repos with and without id", - repos: []*scm_provider.Repository{ - { - Organization: "myorg", - Repository: "repo4", - RepositoryId: "idaz09", - URL: "git@github.com:myorg/repo4.git", - Branch: "main", - SHA: "0bc57212c3cbbec69d20b34c507284bd300def5b", - }, - { - Organization: "myorg", - Repository: "repo5", - URL: "git@github.com:myorg/repo5.git", - Branch: "main", - SHA: "0bc57212c3cbbec69d20b34c507284bd300def5b", - }, - }, - expected: []map[string]any{ - { - "organization": "myorg", - "repository": "repo4", - "repository_id": "idaz09", - "url": "git@github.com:myorg/repo4.git", - "branch": "main", - "branchNormalized": "main", - "sha": "0bc57212c3cbbec69d20b34c507284bd300def5b", - "short_sha": "0bc57212", - "short_sha_7": "0bc5721", - "labels": "", - }, - { - "organization": "myorg", - "repository": "repo5", - "repository_id": nil, - "url": "git@github.com:myorg/repo5.git", - "branch": "main", - "branchNormalized": "main", - "sha": "0bc57212c3cbbec69d20b34c507284bd300def5b", - "short_sha": "0bc57212", - "short_sha_7": "0bc5721", - "labels": "", - }, - }, - }, } for _, testCase := range cases { diff --git a/applicationset/generators/scm_utils.go b/applicationset/generators/scm_utils.go index 8fa6616a42..51ac99d9b7 100644 --- a/applicationset/generators/scm_utils.go +++ b/applicationset/generators/scm_utils.go @@ -1,5 +1,5 @@ package generators -type SCMGeneratorWithCustomApiUrl interface { //nolint:revive //FIXME(var-naming) +type SCMGeneratorWithCustomApiUrl interface { CustomApiUrl() string } diff --git a/applicationset/generators/utils.go b/applicationset/generators/utils.go index fe9e710179..84bdda6101 100644 --- a/applicationset/generators/utils.go +++ b/applicationset/generators/utils.go @@ -7,18 +7,18 @@ import ( "k8s.io/client-go/kubernetes" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/argoproj/argo-cd/v3/applicationset/services" + "github.com/argoproj/argo-cd/v2/applicationset/services" ) func GetGenerators(ctx context.Context, c client.Client, k8sClient kubernetes.Interface, namespace string, argoCDService services.Repos, dynamicClient dynamic.Interface, scmConfig SCMConfig) map[string]Generator { terminalGenerators := map[string]Generator{ "List": NewListGenerator(), - "Clusters": NewClusterGenerator(ctx, c, k8sClient, namespace), + "Clusters": NewClusterGenerator(c, ctx, k8sClient, namespace), "Git": NewGitGenerator(argoCDService, namespace), "SCMProvider": NewSCMProviderGenerator(c, scmConfig), "ClusterDecisionResource": NewDuckTypeGenerator(ctx, dynamicClient, k8sClient, namespace), "PullRequest": NewPullRequestGenerator(c, scmConfig), - "Plugin": NewPluginGenerator(ctx, c, k8sClient, namespace), + "Plugin": NewPluginGenerator(c, ctx, k8sClient, namespace), } nestedGenerators := map[string]Generator{ diff --git a/applicationset/generators/value_interpolation.go b/applicationset/generators/value_interpolation.go index a7b3f25b80..814843e3d8 100644 --- a/applicationset/generators/value_interpolation.go +++ b/applicationset/generators/value_interpolation.go @@ -4,11 +4,11 @@ import ( "fmt" ) -func appendTemplatedValues(values map[string]string, params map[string]any, useGoTemplate bool, goTemplateOptions []string) error { +func appendTemplatedValues(values map[string]string, params map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) error { // We create a local map to ensure that we do not fall victim to a billion-laughs attack. We iterate through the // cluster values map and only replace values in said map if it has already been allowlisted in the params map. // Once we iterate through all the cluster values we can then safely merge the `tmp` map into the main params map. - tmp := map[string]any{} + tmp := map[string]interface{}{} for key, value := range values { result, err := replaceTemplatedString(value, params, useGoTemplate, goTemplateOptions) @@ -22,7 +22,7 @@ func appendTemplatedValues(values map[string]string, params map[string]any, useG } tmp["values"].(map[string]string)[key] = result } else { - tmp["values."+key] = result + tmp[fmt.Sprintf("values.%s", key)] = result } } @@ -33,7 +33,7 @@ func appendTemplatedValues(values map[string]string, params map[string]any, useG return nil } -func replaceTemplatedString(value string, params map[string]any, useGoTemplate bool, goTemplateOptions []string) (string, error) { +func replaceTemplatedString(value string, params map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (string, error) { replacedTmplStr, err := render.Replace(value, params, useGoTemplate, goTemplateOptions) if err != nil { return "", fmt.Errorf("failed to replace templated string with rendered values: %w", err) diff --git a/applicationset/generators/value_interpolation_test.go b/applicationset/generators/value_interpolation_test.go index 38a4bfd167..5b490233d5 100644 --- a/applicationset/generators/value_interpolation_test.go +++ b/applicationset/generators/value_interpolation_test.go @@ -11,18 +11,18 @@ func TestValueInterpolation(t *testing.T) { testCases := []struct { name string values map[string]string - params map[string]any - expected map[string]any + params map[string]interface{} + expected map[string]interface{} }{ { name: "Simple interpolation", values: map[string]string{ "hello": "{{ world }}", }, - params: map[string]any{ + params: map[string]interface{}{ "world": "world!", }, - expected: map[string]any{ + expected: map[string]interface{}{ "world": "world!", "values.hello": "world!", }, @@ -32,8 +32,8 @@ func TestValueInterpolation(t *testing.T) { values: map[string]string{ "non-existent": "{{ non-existent }}", }, - params: map[string]any{}, - expected: map[string]any{ + params: map[string]interface{}{}, + expected: map[string]interface{}{ "values.non-existent": "{{ non-existent }}", }, }, @@ -44,8 +44,8 @@ func TestValueInterpolation(t *testing.T) { "lol2": "{{values.lol1}}{{values.lol1}}", "lol3": "{{values.lol2}}{{values.lol2}}{{values.lol2}}", }, - params: map[string]any{}, - expected: map[string]any{ + params: map[string]interface{}{}, + expected: map[string]interface{}{ "values.lol1": "lol", "values.lol2": "{{values.lol1}}{{values.lol1}}", "values.lol3": "{{values.lol2}}{{values.lol2}}{{values.lol2}}", @@ -57,7 +57,7 @@ func TestValueInterpolation(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { err := appendTemplatedValues(testCase.values, testCase.params, false, nil) require.NoError(t, err) - assert.Equal(t, testCase.expected, testCase.params) + assert.EqualValues(t, testCase.expected, testCase.params) }) } } @@ -66,18 +66,18 @@ func TestValueInterpolationWithGoTemplating(t *testing.T) { testCases := []struct { name string values map[string]string - params map[string]any - expected map[string]any + params map[string]interface{} + expected map[string]interface{} }{ { name: "Simple interpolation", values: map[string]string{ "hello": "{{ .world }}", }, - params: map[string]any{ + params: map[string]interface{}{ "world": "world!", }, - expected: map[string]any{ + expected: map[string]interface{}{ "world": "world!", "values": map[string]string{ "hello": "world!", @@ -89,8 +89,8 @@ func TestValueInterpolationWithGoTemplating(t *testing.T) { values: map[string]string{ "non_existent": "{{ default \"bar\" .non_existent }}", }, - params: map[string]any{}, - expected: map[string]any{ + params: map[string]interface{}{}, + expected: map[string]interface{}{ "values": map[string]string{ "non_existent": "bar", }, @@ -103,8 +103,8 @@ func TestValueInterpolationWithGoTemplating(t *testing.T) { "lol2": "{{.values.lol1}}{{.values.lol1}}", "lol3": "{{.values.lol2}}{{.values.lol2}}{{.values.lol2}}", }, - params: map[string]any{}, - expected: map[string]any{ + params: map[string]interface{}{}, + expected: map[string]interface{}{ "values": map[string]string{ "lol1": "lol", "lol2": "", @@ -118,7 +118,7 @@ func TestValueInterpolationWithGoTemplating(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { err := appendTemplatedValues(testCase.values, testCase.params, true, nil) require.NoError(t, err) - assert.Equal(t, testCase.expected, testCase.params) + assert.EqualValues(t, testCase.expected, testCase.params) }) } } diff --git a/applicationset/metrics/fake.go b/applicationset/metrics/fake.go index aebddde651..9c1d55d2f2 100644 --- a/applicationset/metrics/fake.go +++ b/applicationset/metrics/fake.go @@ -2,10 +2,11 @@ package metrics import ( "github.com/prometheus/client_golang/prometheus" + ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" ) // Fake implementation for testing -func NewFakeAppsetMetrics() *ApplicationsetMetrics { +func NewFakeAppsetMetrics(client ctrlclient.WithWatch) *ApplicationsetMetrics { reconcileHistogram := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "argocd_appset_reconcile", diff --git a/applicationset/metrics/metrics.go b/applicationset/metrics/metrics.go index b50e359f31..5b5c1cd82c 100644 --- a/applicationset/metrics/metrics.go +++ b/applicationset/metrics/metrics.go @@ -7,10 +7,9 @@ import ( "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/metrics" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - metricsutil "github.com/argoproj/argo-cd/v3/util/metrics" - "github.com/argoproj/argo-cd/v3/util/metrics/kubectl" + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + metricsutil "github.com/argoproj/argo-cd/v2/util/metrics" ) var ( @@ -58,10 +57,6 @@ func NewApplicationsetMetrics(appsetLister applisters.ApplicationSetLister, apps metrics.Registry.MustRegister(reconcileHistogram) metrics.Registry.MustRegister(appsetCollector) - kubectlMetricsServer := kubectl.NewKubectlMetrics() - kubectlMetricsServer.RegisterWithClientGo() - kubectl.RegisterWithPrometheus(metrics.Registry) - return ApplicationsetMetrics{ reconcileHistogram: reconcileHistogram, } diff --git a/applicationset/metrics/metrics_test.go b/applicationset/metrics/metrics_test.go index 1db5b3efbe..13457ca03d 100644 --- a/applicationset/metrics/metrics_test.go +++ b/applicationset/metrics/metrics_test.go @@ -7,19 +7,23 @@ import ( "testing" "time" - "github.com/prometheus/client_golang/prometheus" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/runtime" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - "sigs.k8s.io/controller-runtime/pkg/metrics" - "sigs.k8s.io/yaml" + fake "sigs.k8s.io/controller-runtime/pkg/client/fake" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - metricsutil "github.com/argoproj/argo-cd/v3/util/metrics" + prometheus "github.com/prometheus/client_golang/prometheus" + + metricsutil "github.com/argoproj/argo-cd/v2/util/metrics" + + "sigs.k8s.io/controller-runtime/pkg/metrics" + + "sigs.k8s.io/yaml" ) var ( diff --git a/applicationset/services/internal/github_app/client.go b/applicationset/services/internal/github_app/client.go index df96ba1731..7cdfd51554 100644 --- a/applicationset/services/internal/github_app/client.go +++ b/applicationset/services/internal/github_app/client.go @@ -5,9 +5,9 @@ import ( "net/http" "github.com/bradleyfalzon/ghinstallation/v2" - "github.com/google/go-github/v69/github" + "github.com/google/go-github/v66/github" - "github.com/argoproj/argo-cd/v3/applicationset/services/github_app_auth" + "github.com/argoproj/argo-cd/v2/applicationset/services/github_app_auth" ) // Client builds a github client for the given app authentication. diff --git a/applicationset/services/internal/http/client.go b/applicationset/services/internal/http/client.go index b16bd873e6..1a4a86285a 100644 --- a/applicationset/services/internal/http/client.go +++ b/applicationset/services/internal/http/client.go @@ -65,7 +65,7 @@ func newClient(baseURL string, options ...ClientOptionFunc) (*Client, error) { return c, nil } -func (c *Client) NewRequestWithContext(ctx context.Context, method, path string, body any) (*http.Request, error) { +func (c *Client) NewRequest(method, path string, body interface{}, options []ClientOptionFunc) (*http.Request, error) { // Make sure the given URL end with a slash if !strings.HasSuffix(c.baseURL, "/") { c.baseURL += "/" @@ -82,7 +82,7 @@ func (c *Client) NewRequestWithContext(ctx context.Context, method, path string, } } - req, err := http.NewRequestWithContext(ctx, method, c.baseURL+path, buf) + req, err := http.NewRequest(method, c.baseURL+path, buf) if err != nil { return nil, err } @@ -102,7 +102,7 @@ func (c *Client) NewRequestWithContext(ctx context.Context, method, path string, return req, nil } -func (c *Client) Do(req *http.Request, v any) (*http.Response, error) { +func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*http.Response, error) { resp, err := c.client.Do(req) if err != nil { return nil, err @@ -143,7 +143,7 @@ func CheckResponse(resp *http.Response) error { return fmt.Errorf("API error with status code %d: %w", resp.StatusCode, err) } - var raw map[string]any + var raw map[string]interface{} if err := json.Unmarshal(data, &raw); err != nil { return fmt.Errorf("API error with status code %d: %s", resp.StatusCode, string(data)) } diff --git a/applicationset/services/internal/http/client_test.go b/applicationset/services/internal/http/client_test.go index c0235cd74d..29c183b5b2 100644 --- a/applicationset/services/internal/http/client_test.go +++ b/applicationset/services/internal/http/client_test.go @@ -2,7 +2,7 @@ package http import ( "bytes" - "errors" + "context" "fmt" "io" "net/http" @@ -14,7 +14,7 @@ import ( ) func TestClient(t *testing.T) { - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) _, err := w.Write([]byte("Hello, World!")) if err != nil { @@ -29,13 +29,15 @@ func TestClient(t *testing.T) { } func TestClientDo(t *testing.T) { + ctx := context.Background() + for _, c := range []struct { name string params map[string]string content []byte fakeServer *httptest.Server clientOptionFns []ClientOptionFunc - expected []map[string]any + expected []map[string]interface{} expectedCode int expectedError error }{ @@ -45,7 +47,7 @@ func TestClientDo(t *testing.T) { "pkey1": "val1", "pkey2": "val2", }, - fakeServer: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + fakeServer: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) _, err := w.Write([]byte(`[{ "key1": "val1", @@ -62,12 +64,12 @@ func TestClientDo(t *testing.T) { } })), clientOptionFns: nil, - expected: []map[string]any{ + expected: []map[string]interface{}{ { "key1": "val1", - "key2": map[string]any{ + "key2": map[string]interface{}{ "key2_1": "val2_1", - "key2_2": map[string]any{ + "key2_2": map[string]interface{}{ "key2_2_1": "val2_2_1", }, }, @@ -105,9 +107,9 @@ func TestClientDo(t *testing.T) { } })), clientOptionFns: nil, - expected: []map[string]any(nil), + expected: []map[string]interface{}(nil), expectedCode: http.StatusUnauthorized, - expectedError: errors.New("API error with status code 401: "), + expectedError: fmt.Errorf("API error with status code 401: "), }, } { cc := c @@ -117,12 +119,12 @@ func TestClientDo(t *testing.T) { client, err := NewClient(cc.fakeServer.URL, cc.clientOptionFns...) require.NoError(t, err, "NewClient returned unexpected error") - req, err := client.NewRequestWithContext(t.Context(), http.MethodPost, "", cc.params) + req, err := client.NewRequest("POST", "", cc.params, nil) require.NoError(t, err, "NewRequest returned unexpected error") - var data []map[string]any + var data []map[string]interface{} - resp, err := client.Do(req, &data) + resp, err := client.Do(ctx, req, &data) if cc.expectedError != nil { assert.EqualError(t, err, cc.expectedError.Error()) diff --git a/applicationset/services/mocks/Repos.go b/applicationset/services/mocks/Repos.go index d493bf2da7..7d67fe4ab2 100644 --- a/applicationset/services/mocks/Repos.go +++ b/applicationset/services/mocks/Repos.go @@ -1,15 +1,78 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" + context "context" mock "github.com/stretchr/testify/mock" ) +// Repos is an autogenerated mock type for the Repos type +type Repos struct { + mock.Mock +} + +// GetDirectories provides a mock function with given fields: ctx, repoURL, revision, noRevisionCache, verifyCommit +func (_m *Repos) GetDirectories(ctx context.Context, repoURL string, revision string, noRevisionCache bool, verifyCommit bool) ([]string, error) { + ret := _m.Called(ctx, repoURL, revision, noRevisionCache, verifyCommit) + + if len(ret) == 0 { + panic("no return value specified for GetDirectories") + } + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string, bool, bool) ([]string, error)); ok { + return rf(ctx, repoURL, revision, noRevisionCache, verifyCommit) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string, bool, bool) []string); ok { + r0 = rf(ctx, repoURL, revision, noRevisionCache, verifyCommit) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string, bool, bool) error); ok { + r1 = rf(ctx, repoURL, revision, noRevisionCache, verifyCommit) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetFiles provides a mock function with given fields: ctx, repoURL, revision, pattern, noRevisionCache, verifyCommit +func (_m *Repos) GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache bool, verifyCommit bool) (map[string][]byte, error) { + ret := _m.Called(ctx, repoURL, revision, pattern, noRevisionCache, verifyCommit) + + if len(ret) == 0 { + panic("no return value specified for GetFiles") + } + + var r0 map[string][]byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string, string, bool, bool) (map[string][]byte, error)); ok { + return rf(ctx, repoURL, revision, pattern, noRevisionCache, verifyCommit) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string, string, bool, bool) map[string][]byte); ok { + r0 = rf(ctx, repoURL, revision, pattern, noRevisionCache, verifyCommit) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string][]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string, string, bool, bool) error); ok { + r1 = rf(ctx, repoURL, revision, pattern, noRevisionCache, verifyCommit) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewRepos creates a new instance of Repos. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewRepos(t interface { @@ -23,139 +86,3 @@ func NewRepos(t interface { return mock } - -// Repos is an autogenerated mock type for the Repos type -type Repos struct { - mock.Mock -} - -type Repos_Expecter struct { - mock *mock.Mock -} - -func (_m *Repos) EXPECT() *Repos_Expecter { - return &Repos_Expecter{mock: &_m.Mock} -} - -// GetDirectories provides a mock function for the type Repos -func (_mock *Repos) GetDirectories(ctx context.Context, repoURL string, revision string, project string, noRevisionCache bool, verifyCommit bool) ([]string, error) { - ret := _mock.Called(ctx, repoURL, revision, project, noRevisionCache, verifyCommit) - - if len(ret) == 0 { - panic("no return value specified for GetDirectories") - } - - var r0 []string - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string, string, bool, bool) ([]string, error)); ok { - return returnFunc(ctx, repoURL, revision, project, noRevisionCache, verifyCommit) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string, string, bool, bool) []string); ok { - r0 = returnFunc(ctx, repoURL, revision, project, noRevisionCache, verifyCommit) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string, string, string, bool, bool) error); ok { - r1 = returnFunc(ctx, repoURL, revision, project, noRevisionCache, verifyCommit) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Repos_GetDirectories_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDirectories' -type Repos_GetDirectories_Call struct { - *mock.Call -} - -// GetDirectories is a helper method to define mock.On call -// - ctx -// - repoURL -// - revision -// - project -// - noRevisionCache -// - verifyCommit -func (_e *Repos_Expecter) GetDirectories(ctx interface{}, repoURL interface{}, revision interface{}, project interface{}, noRevisionCache interface{}, verifyCommit interface{}) *Repos_GetDirectories_Call { - return &Repos_GetDirectories_Call{Call: _e.mock.On("GetDirectories", ctx, repoURL, revision, project, noRevisionCache, verifyCommit)} -} - -func (_c *Repos_GetDirectories_Call) Run(run func(ctx context.Context, repoURL string, revision string, project string, noRevisionCache bool, verifyCommit bool)) *Repos_GetDirectories_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(string), args[4].(bool), args[5].(bool)) - }) - return _c -} - -func (_c *Repos_GetDirectories_Call) Return(strings []string, err error) *Repos_GetDirectories_Call { - _c.Call.Return(strings, err) - return _c -} - -func (_c *Repos_GetDirectories_Call) RunAndReturn(run func(ctx context.Context, repoURL string, revision string, project string, noRevisionCache bool, verifyCommit bool) ([]string, error)) *Repos_GetDirectories_Call { - _c.Call.Return(run) - return _c -} - -// GetFiles provides a mock function for the type Repos -func (_mock *Repos) GetFiles(ctx context.Context, repoURL string, revision string, project string, pattern string, noRevisionCache bool, verifyCommit bool) (map[string][]byte, error) { - ret := _mock.Called(ctx, repoURL, revision, project, pattern, noRevisionCache, verifyCommit) - - if len(ret) == 0 { - panic("no return value specified for GetFiles") - } - - var r0 map[string][]byte - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string, string, string, bool, bool) (map[string][]byte, error)); ok { - return returnFunc(ctx, repoURL, revision, project, pattern, noRevisionCache, verifyCommit) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string, string, string, bool, bool) map[string][]byte); ok { - r0 = returnFunc(ctx, repoURL, revision, project, pattern, noRevisionCache, verifyCommit) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[string][]byte) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string, string, string, string, bool, bool) error); ok { - r1 = returnFunc(ctx, repoURL, revision, project, pattern, noRevisionCache, verifyCommit) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Repos_GetFiles_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFiles' -type Repos_GetFiles_Call struct { - *mock.Call -} - -// GetFiles is a helper method to define mock.On call -// - ctx -// - repoURL -// - revision -// - project -// - pattern -// - noRevisionCache -// - verifyCommit -func (_e *Repos_Expecter) GetFiles(ctx interface{}, repoURL interface{}, revision interface{}, project interface{}, pattern interface{}, noRevisionCache interface{}, verifyCommit interface{}) *Repos_GetFiles_Call { - return &Repos_GetFiles_Call{Call: _e.mock.On("GetFiles", ctx, repoURL, revision, project, pattern, noRevisionCache, verifyCommit)} -} - -func (_c *Repos_GetFiles_Call) Run(run func(ctx context.Context, repoURL string, revision string, project string, pattern string, noRevisionCache bool, verifyCommit bool)) *Repos_GetFiles_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(string), args[4].(string), args[5].(bool), args[6].(bool)) - }) - return _c -} - -func (_c *Repos_GetFiles_Call) Return(stringToBytes map[string][]byte, err error) *Repos_GetFiles_Call { - _c.Call.Return(stringToBytes, err) - return _c -} - -func (_c *Repos_GetFiles_Call) RunAndReturn(run func(ctx context.Context, repoURL string, revision string, project string, pattern string, noRevisionCache bool, verifyCommit bool) (map[string][]byte, error)) *Repos_GetFiles_Call { - _c.Call.Return(run) - return _c -} diff --git a/applicationset/services/plugin/plugin_service.go b/applicationset/services/plugin/plugin_service.go index b88e4ea30b..175683c434 100644 --- a/applicationset/services/plugin/plugin_service.go +++ b/applicationset/services/plugin/plugin_service.go @@ -5,8 +5,8 @@ import ( "fmt" "net/http" - internalhttp "github.com/argoproj/argo-cd/v3/applicationset/services/internal/http" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + internalhttp "github.com/argoproj/argo-cd/v2/applicationset/services/internal/http" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) // ServiceRequest is the request object sent to the plugin service. @@ -20,7 +20,7 @@ type ServiceRequest struct { type Output struct { // Parameters is the list of parameter sets returned by the plugin. - Parameters []map[string]any `json:"parameters"` + Parameters []map[string]interface{} `json:"parameters"` } // ServiceResponse is the response object returned by the plugin service. @@ -34,7 +34,7 @@ type Service struct { appSetName string } -func NewPluginService(appSetName string, baseURL string, token string, requestTimeout int) (*Service, error) { +func NewPluginService(ctx context.Context, appSetName string, baseURL string, token string, requestTimeout int) (*Service, error) { var clientOptionFns []internalhttp.ClientOptionFunc clientOptionFns = append(clientOptionFns, internalhttp.WithToken(token)) @@ -55,14 +55,14 @@ func NewPluginService(appSetName string, baseURL string, token string, requestTi } func (p *Service) List(ctx context.Context, parameters v1alpha1.PluginParameters) (*ServiceResponse, error) { - req, err := p.client.NewRequestWithContext(ctx, http.MethodPost, "api/v1/getparams.execute", ServiceRequest{ApplicationSetName: p.appSetName, Input: v1alpha1.PluginInput{Parameters: parameters}}) + req, err := p.client.NewRequest(http.MethodPost, "api/v1/getparams.execute", ServiceRequest{ApplicationSetName: p.appSetName, Input: v1alpha1.PluginInput{Parameters: parameters}}, nil) if err != nil { return nil, fmt.Errorf("NewRequest returned unexpected error: %w", err) } var data ServiceResponse - _, err = p.client.Do(req, &data) + _, err = p.client.Do(ctx, req, &data) if err != nil { return nil, fmt.Errorf("error get api '%s': %w", p.appSetName, err) } diff --git a/applicationset/services/plugin/plugin_service_test.go b/applicationset/services/plugin/plugin_service_test.go index a04841203f..c6e795c403 100644 --- a/applicationset/services/plugin/plugin_service_test.go +++ b/applicationset/services/plugin/plugin_service_test.go @@ -1,6 +1,7 @@ package plugin import ( + "context" "encoding/json" "fmt" "net/http" @@ -30,10 +31,10 @@ func TestPlugin(t *testing.T) { ts := httptest.NewServer(handler) defer ts.Close() - client, err := NewPluginService("plugin-test", ts.URL, token, 0) + client, err := NewPluginService(context.Background(), "plugin-test", ts.URL, token, 0) require.NoError(t, err) - data, err := client.List(t.Context(), nil) + data, err := client.List(context.Background(), nil) require.NoError(t, err) var expectedData ServiceResponse diff --git a/applicationset/services/plugin/utils.go b/applicationset/services/plugin/utils.go index 7130f748b6..26e38e4922 100644 --- a/applicationset/services/plugin/utils.go +++ b/applicationset/services/plugin/utils.go @@ -1,9 +1,10 @@ package plugin import ( + "fmt" "strings" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) // ParseSecretKey retrieves secret appSetName if different from common ArgoCDSecretName. @@ -11,7 +12,7 @@ func ParseSecretKey(key string) (secretName string, tokenKey string) { if strings.Contains(key, ":") { parts := strings.Split(key, ":") secretName = parts[0][1:] - tokenKey = "$" + parts[1] + tokenKey = fmt.Sprintf("$%s", parts[1]) } else { secretName = common.ArgoCDSecretName tokenKey = key diff --git a/applicationset/services/pull_request/azure_devops.go b/applicationset/services/pull_request/azure_devops.go index f70d2eda13..1d263212cd 100644 --- a/applicationset/services/pull_request/azure_devops.go +++ b/applicationset/services/pull_request/azure_devops.go @@ -5,9 +5,9 @@ import ( "fmt" "strings" - "github.com/microsoft/azure-devops-go-api/azuredevops/v7" - "github.com/microsoft/azure-devops-go-api/azuredevops/v7/core" - "github.com/microsoft/azure-devops-go-api/azuredevops/v7/git" + "github.com/microsoft/azure-devops-go-api/azuredevops" + core "github.com/microsoft/azure-devops-go-api/azuredevops/core" + git "github.com/microsoft/azure-devops-go-api/azuredevops/git" ) const AZURE_DEVOPS_DEFAULT_URL = "https://dev.azure.com" @@ -41,14 +41,14 @@ var ( _ AzureDevOpsClientFactory = &devopsFactoryImpl{} ) -func NewAzureDevOpsService(token, url, organization, project, repo string, labels []string) (PullRequestService, error) { - organizationURL := buildURL(url, organization) +func NewAzureDevOpsService(ctx context.Context, token, url, organization, project, repo string, labels []string) (PullRequestService, error) { + organizationUrl := buildURL(url, organization) var connection *azuredevops.Connection if token == "" { - connection = azuredevops.NewAnonymousConnection(organizationURL) + connection = azuredevops.NewAnonymousConnection(organizationUrl) } else { - connection = azuredevops.NewPatConnection(organizationURL, token) + connection = azuredevops.NewPatConnection(organizationUrl, token) } return &AzureDevOpsService{ diff --git a/applicationset/services/pull_request/azure_devops_test.go b/applicationset/services/pull_request/azure_devops_test.go index 29774ad08e..24453c93a2 100644 --- a/applicationset/services/pull_request/azure_devops_test.go +++ b/applicationset/services/pull_request/azure_devops_test.go @@ -4,14 +4,15 @@ import ( "context" "testing" - "github.com/microsoft/azure-devops-go-api/azuredevops/v7/core" - "github.com/microsoft/azure-devops-go-api/azuredevops/v7/git" - "github.com/microsoft/azure-devops-go-api/azuredevops/v7/webapi" + "github.com/microsoft/azure-devops-go-api/azuredevops/webapi" + + "github.com/microsoft/azure-devops-go-api/azuredevops/core" + git "github.com/microsoft/azure-devops-go-api/azuredevops/git" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - azureMock "github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider/azure_devops/git/mocks" + azureMock "github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider/azure_devops/git/mocks" ) func createBoolPtr(x bool) *bool { @@ -60,20 +61,20 @@ func (m *AzureClientFactoryMock) GetClient(ctx context.Context) (git.Client, err func TestListPullRequest(t *testing.T) { teamProject := "myorg_project" repoName := "myorg_project_repo" - prID := 123 - prTitle := "feat(123)" - prHeadSha := "cd4973d9d14a08ffe6b641a89a68891d6aac8056" - ctx := t.Context() + pr_id := 123 + pr_title := "feat(123)" + pr_head_sha := "cd4973d9d14a08ffe6b641a89a68891d6aac8056" + ctx := context.Background() uniqueName := "testName" pullRequestMock := []git.GitPullRequest{ { - PullRequestId: createIntPtr(prID), - Title: createStringPtr(prTitle), + PullRequestId: createIntPtr(pr_id), + Title: createStringPtr(pr_title), SourceRefName: createStringPtr("refs/heads/feature-branch"), TargetRefName: createStringPtr("refs/heads/main"), LastMergeSourceCommit: &git.GitCommitRef{ - CommitId: createStringPtr(prHeadSha), + CommitId: createStringPtr(pr_head_sha), }, Labels: &[]core.WebApiTagDefinition{}, Repository: &git.GitRepository{ @@ -107,9 +108,9 @@ func TestListPullRequest(t *testing.T) { assert.Len(t, list, 1) assert.Equal(t, "feature-branch", list[0].Branch) assert.Equal(t, "main", list[0].TargetBranch) - assert.Equal(t, prHeadSha, list[0].HeadSHA) + assert.Equal(t, pr_head_sha, list[0].HeadSHA) assert.Equal(t, "feat(123)", list[0].Title) - assert.Equal(t, prID, list[0].Number) + assert.Equal(t, pr_id, list[0].Number) assert.Equal(t, uniqueName, list[0].Author) } diff --git a/applicationset/services/pull_request/bitbucket_cloud.go b/applicationset/services/pull_request/bitbucket_cloud.go index 1d03bb0249..2ee79d2cfa 100644 --- a/applicationset/services/pull_request/bitbucket_cloud.go +++ b/applicationset/services/pull_request/bitbucket_cloud.go @@ -3,7 +3,6 @@ package pull_request import ( "context" "encoding/json" - "errors" "fmt" "net/url" @@ -17,19 +16,10 @@ type BitbucketCloudService struct { } type BitbucketCloudPullRequest struct { - ID int `json:"id"` - Title string `json:"title"` - Source BitbucketCloudPullRequestSource `json:"source"` - Author BitbucketCloudPullRequestAuthor `json:"author"` - Destination BitbucketCloudPullRequestDestination `json:"destination"` -} - -type BitbucketCloudPullRequestDestination struct { - Branch BitbucketCloudPullRequestDestinationBranch `json:"branch"` -} - -type BitbucketCloudPullRequestDestinationBranch struct { - Name string `json:"name"` + ID int `json:"id"` + Title string `json:"title"` + Source BitbucketCloudPullRequestSource `json:"source"` + Author BitbucketCloudPullRequestAuthor `json:"author"` } type BitbucketCloudPullRequestSource struct { @@ -61,7 +51,7 @@ type PullRequestResponse struct { var _ PullRequestService = (*BitbucketCloudService)(nil) -func parseURL(uri string) (*url.URL, error) { +func parseUrl(uri string) (*url.URL, error) { if uri == "" { uri = "https://api.bitbucket.org/2.0" } @@ -74,10 +64,10 @@ func parseURL(uri string) (*url.URL, error) { return url, nil } -func NewBitbucketCloudServiceBasicAuth(baseURL, username, password, owner, repositorySlug string) (PullRequestService, error) { - url, err := parseURL(baseURL) +func NewBitbucketCloudServiceBasicAuth(baseUrl, username, password, owner, repositorySlug string) (PullRequestService, error) { + url, err := parseUrl(baseUrl) if err != nil { - return nil, fmt.Errorf("error parsing base url of %s for %s/%s: %w", baseURL, owner, repositorySlug, err) + return nil, fmt.Errorf("error parsing base url of %s for %s/%s: %w", baseUrl, owner, repositorySlug, err) } bitbucketClient := bitbucket.NewBasicAuth(username, password) @@ -90,10 +80,10 @@ func NewBitbucketCloudServiceBasicAuth(baseURL, username, password, owner, repos }, nil } -func NewBitbucketCloudServiceBearerToken(baseURL, bearerToken, owner, repositorySlug string) (PullRequestService, error) { - url, err := parseURL(baseURL) +func NewBitbucketCloudServiceBearerToken(baseUrl, bearerToken, owner, repositorySlug string) (PullRequestService, error) { + url, err := parseUrl(baseUrl) if err != nil { - return nil, fmt.Errorf("error parsing base url of %s for %s/%s: %w", baseURL, owner, repositorySlug, err) + return nil, fmt.Errorf("error parsing base url of %s for %s/%s: %w", baseUrl, owner, repositorySlug, err) } bitbucketClient := bitbucket.NewOAuthbearerToken(bearerToken) @@ -106,9 +96,9 @@ func NewBitbucketCloudServiceBearerToken(baseURL, bearerToken, owner, repository }, nil } -func NewBitbucketCloudServiceNoAuth(baseURL, owner, repositorySlug string) (PullRequestService, error) { +func NewBitbucketCloudServiceNoAuth(baseUrl, owner, repositorySlug string) (PullRequestService, error) { // There is currently no method to explicitly not require auth - return NewBitbucketCloudServiceBearerToken(baseURL, "", owner, repositorySlug) + return NewBitbucketCloudServiceBearerToken(baseUrl, "", owner, repositorySlug) } func (b *BitbucketCloudService) List(_ context.Context) ([]*PullRequest, error) { @@ -122,14 +112,14 @@ func (b *BitbucketCloudService) List(_ context.Context) ([]*PullRequest, error) return nil, fmt.Errorf("error listing pull requests for %s/%s: %w", b.owner, b.repositorySlug, err) } - resp, ok := response.(map[string]any) + resp, ok := response.(map[string]interface{}) if !ok { - return nil, errors.New("unknown type returned from bitbucket pull requests") + return nil, fmt.Errorf("unknown type returned from bitbucket pull requests") } - repoArray, ok := resp["values"].([]any) + repoArray, ok := resp["values"].([]interface{}) if !ok { - return nil, errors.New("unknown type returned from response values") + return nil, fmt.Errorf("unknown type returned from response values") } jsonStr, err := json.Marshal(repoArray) @@ -145,12 +135,11 @@ func (b *BitbucketCloudService) List(_ context.Context) ([]*PullRequest, error) pullRequests := []*PullRequest{} for _, pull := range pulls { pullRequests = append(pullRequests, &PullRequest{ - Number: pull.ID, - Title: pull.Title, - Branch: pull.Source.Branch.Name, - TargetBranch: pull.Destination.Branch.Name, - HeadSHA: pull.Source.Commit.Hash, - Author: pull.Author.Nickname, + Number: pull.ID, + Title: pull.Title, + Branch: pull.Source.Branch.Name, + HeadSHA: pull.Source.Commit.Hash, + Author: pull.Author.Nickname, }) } diff --git a/applicationset/services/pull_request/bitbucket_cloud_test.go b/applicationset/services/pull_request/bitbucket_cloud_test.go index 62a949bf80..411f6148c8 100644 --- a/applicationset/services/pull_request/bitbucket_cloud_test.go +++ b/applicationset/services/pull_request/bitbucket_cloud_test.go @@ -1,6 +1,7 @@ package pull_request import ( + "context" "fmt" "io" "net/http" @@ -10,7 +11,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func defaultHandlerCloud(t *testing.T) func(http.ResponseWriter, *http.Request) { @@ -53,11 +54,11 @@ func defaultHandlerCloud(t *testing.T) func(http.ResponseWriter, *http.Request) } func TestParseUrlEmptyUrl(t *testing.T) { - url, err := parseURL("") - bitbucketURL, _ := url.Parse("https://api.bitbucket.org/2.0") + url, err := parseUrl("") + bitbucketUrl, _ := url.Parse("https://api.bitbucket.org/2.0") require.NoError(t, err) - assert.Equal(t, bitbucketURL, url) + assert.Equal(t, bitbucketUrl, url) } func TestInvalidBaseUrlBasicAuthCloud(t *testing.T) { @@ -86,7 +87,7 @@ func TestListPullRequestBearerTokenCloud(t *testing.T) { defer ts.Close() svc, err := NewBitbucketCloudServiceBearerToken(ts.URL, "TOKEN", "OWNER", "REPO") require.NoError(t, err) - pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, 101, pullRequests[0].Number) @@ -104,7 +105,7 @@ func TestListPullRequestNoAuthCloud(t *testing.T) { defer ts.Close() svc, err := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") require.NoError(t, err) - pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, 101, pullRequests[0].Number) @@ -122,7 +123,7 @@ func TestListPullRequestBasicAuthCloud(t *testing.T) { defer ts.Close() svc, err := NewBitbucketCloudServiceBasicAuth(ts.URL, "user", "password", "OWNER", "REPO") require.NoError(t, err) - pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, 101, pullRequests[0].Number) @@ -213,7 +214,7 @@ func TestListPullRequestPaginationCloud(t *testing.T) { defer ts.Close() svc, err := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") require.NoError(t, err) - pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.NoError(t, err) assert.Len(t, pullRequests, 3) assert.Equal(t, PullRequest{ @@ -240,12 +241,12 @@ func TestListPullRequestPaginationCloud(t *testing.T) { } func TestListResponseErrorCloud(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) })) defer ts.Close() svc, _ := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") - _, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + _, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.Error(t, err) } @@ -269,7 +270,7 @@ func TestListResponseMalformedCloud(t *testing.T) { })) defer ts.Close() svc, _ := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") - _, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + _, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.Error(t, err) } @@ -293,7 +294,7 @@ func TestListResponseMalformedValuesCloud(t *testing.T) { })) defer ts.Close() svc, _ := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") - _, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + _, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.Error(t, err) } @@ -318,7 +319,7 @@ func TestListResponseEmptyCloud(t *testing.T) { defer ts.Close() svc, err := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") require.NoError(t, err) - pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.NoError(t, err) assert.Empty(t, pullRequests) } @@ -349,11 +350,6 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { }, "author": { "nickname": "testName" - }, - "destination": { - "branch": { - "name": "master" - } } }, { @@ -370,11 +366,6 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { }, "author": { "nickname": "testName" - }, - "destination": { - "branch": { - "name": "branch-200" - } } } ] @@ -400,11 +391,6 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { }, "author": { "nickname": "testName" - }, - "destination": { - "branch": { - "name": "master" - } } } ] @@ -420,7 +406,7 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { regexp := `feature-1[\d]{2}` svc, err := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") require.NoError(t, err) - pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{ + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{ { BranchMatch: ®exp, }, @@ -428,26 +414,24 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { require.NoError(t, err) assert.Len(t, pullRequests, 2) assert.Equal(t, PullRequest{ - Number: 101, - Title: "feat(101)", - Branch: "feature-101", - HeadSHA: "1a8dd249c04a", - Author: "testName", - TargetBranch: "master", + Number: 101, + Title: "feat(101)", + Branch: "feature-101", + HeadSHA: "1a8dd249c04a", + Author: "testName", }, *pullRequests[0]) assert.Equal(t, PullRequest{ - Number: 102, - Title: "feat(102)", - Branch: "feature-102", - HeadSHA: "6344d9623e3b", - Author: "testName", - TargetBranch: "master", + Number: 102, + Title: "feat(102)", + Branch: "feature-102", + HeadSHA: "6344d9623e3b", + Author: "testName", }, *pullRequests[1]) regexp = `.*2$` svc, err = NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") require.NoError(t, err) - pullRequests, err = ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{ + pullRequests, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{ { BranchMatch: ®exp, }, @@ -455,40 +439,20 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, PullRequest{ - Number: 102, - Title: "feat(102)", - Branch: "feature-102", - HeadSHA: "6344d9623e3b", - Author: "testName", - TargetBranch: "master", + Number: 102, + Title: "feat(102)", + Branch: "feature-102", + HeadSHA: "6344d9623e3b", + Author: "testName", }, *pullRequests[0]) regexp = `[\d{2}` svc, err = NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") require.NoError(t, err) - _, err = ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{ + _, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{ { BranchMatch: ®exp, }, }) require.Error(t, err) - - regexp = `feature-2[\d]{2}` - targetRegexp := `branch.*` - pullRequests, err = ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{ - { - BranchMatch: ®exp, - TargetBranchMatch: &targetRegexp, - }, - }) - require.NoError(t, err) - assert.Len(t, pullRequests, 1) - assert.Equal(t, PullRequest{ - Number: 200, - Title: "feat(200)", - Branch: "feature-200", - HeadSHA: "4cf807e67a6d", - Author: "testName", - TargetBranch: "branch-200", - }, *pullRequests[0]) } diff --git a/applicationset/services/pull_request/bitbucket_server.go b/applicationset/services/pull_request/bitbucket_server.go index f016bba877..1f2be70edb 100644 --- a/applicationset/services/pull_request/bitbucket_server.go +++ b/applicationset/services/pull_request/bitbucket_server.go @@ -8,7 +8,7 @@ import ( bitbucketv1 "github.com/gfleury/go-bitbucket-v1" log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/applicationset/utils" + "github.com/argoproj/argo-cd/v2/applicationset/utils" ) type BitbucketService struct { @@ -64,7 +64,7 @@ func newBitbucketService(ctx context.Context, bitbucketConfig *bitbucketv1.Confi } func (b *BitbucketService) List(_ context.Context) ([]*PullRequest, error) { - paged := map[string]any{ + paged := map[string]interface{}{ "limit": 100, } diff --git a/applicationset/services/pull_request/bitbucket_server_test.go b/applicationset/services/pull_request/bitbucket_server_test.go index 745ac9f744..b9da370830 100644 --- a/applicationset/services/pull_request/bitbucket_server_test.go +++ b/applicationset/services/pull_request/bitbucket_server_test.go @@ -1,6 +1,7 @@ package pull_request import ( + "context" "crypto/x509" "encoding/pem" "io" @@ -11,7 +12,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func defaultHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { @@ -63,9 +64,9 @@ func TestListPullRequestNoAuth(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - svc, err := NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil) + svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) require.NoError(t, err) - pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, 101, pullRequests[0].Number) @@ -164,9 +165,9 @@ func TestListPullRequestPagination(t *testing.T) { } })) defer ts.Close() - svc, err := NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil) + svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) require.NoError(t, err) - pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.NoError(t, err) assert.Len(t, pullRequests, 3) assert.Equal(t, PullRequest{ @@ -206,9 +207,9 @@ func TestListPullRequestBasicAuth(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - svc, err := NewBitbucketServiceBasicAuth(t.Context(), "user", "password", ts.URL, "PROJECT", "REPO", "", false, nil) + svc, err := NewBitbucketServiceBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", "REPO", "", false, nil) require.NoError(t, err) - pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, 101, pullRequests[0].Number) @@ -223,9 +224,9 @@ func TestListPullRequestBearerAuth(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - svc, err := NewBitbucketServiceBearerToken(t.Context(), "tolkien", ts.URL, "PROJECT", "REPO", "", false, nil) + svc, err := NewBitbucketServiceBearerToken(context.Background(), "tolkien", ts.URL, "PROJECT", "REPO", "", false, nil) require.NoError(t, err) - pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, 101, pullRequests[0].Number) @@ -276,7 +277,7 @@ func TestListPullRequestTLS(t *testing.T) { defer ts.Close() var certs []byte - if test.passCerts { + if test.passCerts == true { for _, cert := range ts.TLS.Certificates { for _, c := range cert.Certificate { parsedCert, err := x509.ParseCertificate(c) @@ -289,9 +290,9 @@ func TestListPullRequestTLS(t *testing.T) { } } - svc, err := NewBitbucketServiceBasicAuth(t.Context(), "user", "password", ts.URL, "PROJECT", "REPO", "", test.tlsInsecure, certs) + svc, err := NewBitbucketServiceBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", "REPO", "", test.tlsInsecure, certs) require.NoError(t, err) - _, err = ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + _, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) if test.requireErr { require.Error(t, err) } else { @@ -302,12 +303,12 @@ func TestListPullRequestTLS(t *testing.T) { } func TestListResponseError(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) })) defer ts.Close() - svc, _ := NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil) - _, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + svc, _ := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) + _, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.Error(t, err) } @@ -331,8 +332,8 @@ func TestListResponseMalformed(t *testing.T) { } })) defer ts.Close() - svc, _ := NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil) - _, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + svc, _ := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) + _, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.Error(t, err) } @@ -356,9 +357,9 @@ func TestListResponseEmpty(t *testing.T) { } })) defer ts.Close() - svc, err := NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil) + svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) require.NoError(t, err) - pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) require.NoError(t, err) assert.Empty(t, pullRequests) } @@ -452,9 +453,9 @@ func TestListPullRequestBranchMatch(t *testing.T) { })) defer ts.Close() regexp := `feature-1[\d]{2}` - svc, err := NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil) + svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) require.NoError(t, err) - pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{ + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{ { BranchMatch: ®exp, }, @@ -481,9 +482,9 @@ func TestListPullRequestBranchMatch(t *testing.T) { }, *pullRequests[1]) regexp = `.*2$` - svc, err = NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil) + svc, err = NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) require.NoError(t, err) - pullRequests, err = ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{ + pullRequests, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{ { BranchMatch: ®exp, }, @@ -501,9 +502,9 @@ func TestListPullRequestBranchMatch(t *testing.T) { }, *pullRequests[0]) regexp = `[\d{2}` - svc, err = NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil) + svc, err = NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) require.NoError(t, err) - _, err = ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{ + _, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{ { BranchMatch: ®exp, }, diff --git a/applicationset/services/pull_request/fake.go b/applicationset/services/pull_request/fake.go index 50d4969e84..845df70d66 100644 --- a/applicationset/services/pull_request/fake.go +++ b/applicationset/services/pull_request/fake.go @@ -18,6 +18,6 @@ func NewFakeService(_ context.Context, listPullReuests []*PullRequest, listError }, nil } -func (g *FakeService) List(_ context.Context) ([]*PullRequest, error) { +func (g *FakeService) List(ctx context.Context) ([]*PullRequest, error) { return g.listPullReuests, g.listError } diff --git a/applicationset/services/pull_request/gitea.go b/applicationset/services/pull_request/gitea.go index d0e51c23aa..5f32e4dc30 100644 --- a/applicationset/services/pull_request/gitea.go +++ b/applicationset/services/pull_request/gitea.go @@ -14,12 +14,11 @@ type GiteaService struct { client *gitea.Client owner string repo string - labels []string } var _ PullRequestService = (*GiteaService)(nil) -func NewGiteaService(token, url, owner, repo string, labels []string, insecure bool) (PullRequestService, error) { +func NewGiteaService(ctx context.Context, token, url, owner, repo string, insecure bool) (PullRequestService, error) { if token == "" { token = os.Getenv("GITEA_TOKEN") } @@ -43,7 +42,6 @@ func NewGiteaService(token, url, owner, repo string, labels []string, insecure b client: client, owner: owner, repo: repo, - labels: labels, }, nil } @@ -51,16 +49,12 @@ func (g *GiteaService) List(ctx context.Context) ([]*PullRequest, error) { opts := gitea.ListPullRequestsOptions{ State: gitea.StateOpen, } - g.client.SetContext(ctx) prs, _, err := g.client.ListRepoPullRequests(g.owner, g.repo, opts) if err != nil { return nil, err } list := []*PullRequest{} for _, pr := range prs { - if !giteaContainLabels(g.labels, pr.Labels) { - continue - } list = append(list, &PullRequest{ Number: int(pr.Index), Title: pr.Title, @@ -74,21 +68,6 @@ func (g *GiteaService) List(ctx context.Context) ([]*PullRequest, error) { return list, nil } -// containLabels returns true if gotLabels contains expectedLabels -func giteaContainLabels(expectedLabels []string, gotLabels []*gitea.Label) bool { - gotLabelNamesMap := make(map[string]bool) - for i := 0; i < len(gotLabels); i++ { - gotLabelNamesMap[gotLabels[i].Name] = true - } - for _, expected := range expectedLabels { - v, ok := gotLabelNamesMap[expected] - if !v || !ok { - return false - } - } - return true -} - // Get the Gitea pull request label names. func getGiteaPRLabelNames(giteaLabels []*gitea.Label) []string { var labelNames []string diff --git a/applicationset/services/pull_request/gitea_test.go b/applicationset/services/pull_request/gitea_test.go index c2b1ec22b1..ab58a049e5 100644 --- a/applicationset/services/pull_request/gitea_test.go +++ b/applicationset/services/pull_request/gitea_test.go @@ -1,6 +1,7 @@ package pull_request import ( + "context" "fmt" "io" "net/http" @@ -52,7 +53,7 @@ func giteaMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { }, "title": "add an empty file", "body": "", - "labels": [{"id": 1, "name": "label1", "color": "00aabb", "description": "foo", "url": ""}], + "labels": [], "milestone": null, "assignee": null, "assignees": null, @@ -246,61 +247,13 @@ func giteaMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { } } -func TestGiteaContainLabels(t *testing.T) { - cases := []struct { - Name string - Labels []string - PullLabels []*gitea.Label - Expect bool - }{ - { - Name: "Match labels", - Labels: []string{"label1", "label2"}, - PullLabels: []*gitea.Label{ - {Name: "label1"}, - {Name: "label2"}, - {Name: "label3"}, - }, - Expect: true, - }, - { - Name: "Not match labels", - Labels: []string{"label1", "label4"}, - PullLabels: []*gitea.Label{ - {Name: "label1"}, - {Name: "label2"}, - {Name: "label3"}, - }, - Expect: false, - }, - { - Name: "No specify", - Labels: []string{}, - PullLabels: []*gitea.Label{ - {Name: "label1"}, - {Name: "label2"}, - {Name: "label3"}, - }, - Expect: true, - }, - } - - for _, c := range cases { - t.Run(c.Name, func(t *testing.T) { - if got := giteaContainLabels(c.Labels, c.PullLabels); got != c.Expect { - t.Errorf("expect: %v, got: %v", c.Expect, got) - } - }) - } -} - func TestGiteaList(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { giteaMockHandler(t)(w, r) })) - host, err := NewGiteaService("", ts.URL, "test-argocd", "pr-test", []string{"label1"}, false) + host, err := NewGiteaService(context.Background(), "", ts.URL, "test-argocd", "pr-test", false) require.NoError(t, err) - prs, err := host.List(t.Context()) + prs, err := host.List(context.Background()) require.NoError(t, err) assert.Len(t, prs, 1) assert.Equal(t, 1, prs[0].Number) diff --git a/applicationset/services/pull_request/github.go b/applicationset/services/pull_request/github.go index dd63a68105..eaee02ffb1 100644 --- a/applicationset/services/pull_request/github.go +++ b/applicationset/services/pull_request/github.go @@ -3,10 +3,10 @@ package pull_request import ( "context" "fmt" - "net/http" "os" - "github.com/google/go-github/v69/github" + "github.com/google/go-github/v66/github" + "golang.org/x/oauth2" ) type GithubService struct { @@ -18,19 +18,21 @@ type GithubService struct { var _ PullRequestService = (*GithubService)(nil) -func NewGithubService(token, url, owner, repo string, labels []string) (PullRequestService, error) { +func NewGithubService(ctx context.Context, token, url, owner, repo string, labels []string) (PullRequestService, error) { + var ts oauth2.TokenSource // Undocumented environment variable to set a default token, to be used in testing to dodge anonymous rate limits. if token == "" { token = os.Getenv("GITHUB_TOKEN") } - httpClient := &http.Client{} + if token != "" { + ts = oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: token}, + ) + } + httpClient := oauth2.NewClient(ctx, ts) var client *github.Client if url == "" { - if token == "" { - client = github.NewClient(httpClient) - } else { - client = github.NewClient(httpClient).WithAuthToken(token) - } + client = github.NewClient(httpClient) } else { var err error client, err = github.NewClient(httpClient).WithEnterpriseURLs(url, url) diff --git a/applicationset/services/pull_request/github_app.go b/applicationset/services/pull_request/github_app.go index 3eeea1853f..8879a777ad 100644 --- a/applicationset/services/pull_request/github_app.go +++ b/applicationset/services/pull_request/github_app.go @@ -1,8 +1,8 @@ package pull_request import ( - "github.com/argoproj/argo-cd/v3/applicationset/services/github_app_auth" - "github.com/argoproj/argo-cd/v3/applicationset/services/internal/github_app" + "github.com/argoproj/argo-cd/v2/applicationset/services/github_app_auth" + "github.com/argoproj/argo-cd/v2/applicationset/services/internal/github_app" ) func NewGithubAppService(g github_app_auth.Authentication, url, owner, repo string, labels []string) (PullRequestService, error) { diff --git a/applicationset/services/pull_request/github_test.go b/applicationset/services/pull_request/github_test.go index 0380891d07..fb35ad20b0 100644 --- a/applicationset/services/pull_request/github_test.go +++ b/applicationset/services/pull_request/github_test.go @@ -3,7 +3,7 @@ package pull_request import ( "testing" - "github.com/google/go-github/v69/github" + "github.com/google/go-github/v66/github" "github.com/stretchr/testify/require" ) diff --git a/applicationset/services/pull_request/gitlab.go b/applicationset/services/pull_request/gitlab.go index d6d94cf05e..c4e49881a4 100644 --- a/applicationset/services/pull_request/gitlab.go +++ b/applicationset/services/pull_request/gitlab.go @@ -7,9 +7,9 @@ import ( "os" "github.com/hashicorp/go-retryablehttp" - gitlab "gitlab.com/gitlab-org/api/client-go" + gitlab "github.com/xanzy/go-gitlab" - "github.com/argoproj/argo-cd/v3/applicationset/utils" + "github.com/argoproj/argo-cd/v2/applicationset/utils" ) type GitLabService struct { @@ -21,7 +21,7 @@ type GitLabService struct { var _ PullRequestService = (*GitLabService)(nil) -func NewGitLabService(token, url, project string, labels []string, pullRequestState string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) { +func NewGitLabService(ctx context.Context, token, url, project string, labels []string, pullRequestState string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) { var clientOptionFns []gitlab.ClientOptionFunc // Set a custom Gitlab base URL if one is provided @@ -74,7 +74,7 @@ func (g *GitLabService) List(ctx context.Context) ([]*PullRequest, error) { pullRequests := []*PullRequest{} for { - mrs, resp, err := g.client.MergeRequests.ListProjectMergeRequests(g.project, opts, gitlab.WithContext(ctx)) + mrs, resp, err := g.client.MergeRequests.ListProjectMergeRequests(g.project, opts) if err != nil { return nil, fmt.Errorf("error listing merge requests for project '%s': %w", g.project, err) } diff --git a/applicationset/services/pull_request/gitlab_test.go b/applicationset/services/pull_request/gitlab_test.go index ab8e99456a..18467fe088 100644 --- a/applicationset/services/pull_request/gitlab_test.go +++ b/applicationset/services/pull_request/gitlab_test.go @@ -1,6 +1,7 @@ package pull_request import ( + "context" "crypto/x509" "encoding/pem" "io" @@ -34,10 +35,10 @@ func TestGitLabServiceCustomBaseURL(t *testing.T) { writeMRListResponse(t, w) }) - svc, err := NewGitLabService("", server.URL, "278964", nil, "", "", false, nil) + svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", nil, "", "", false, nil) require.NoError(t, err) - _, err = svc.List(t.Context()) + _, err = svc.List(context.Background()) require.NoError(t, err) } @@ -53,10 +54,10 @@ func TestGitLabServiceToken(t *testing.T) { writeMRListResponse(t, w) }) - svc, err := NewGitLabService("token-123", server.URL, "278964", nil, "", "", false, nil) + svc, err := NewGitLabService(context.Background(), "token-123", server.URL, "278964", nil, "", "", false, nil) require.NoError(t, err) - _, err = svc.List(t.Context()) + _, err = svc.List(context.Background()) require.NoError(t, err) } @@ -72,10 +73,10 @@ func TestList(t *testing.T) { writeMRListResponse(t, w) }) - svc, err := NewGitLabService("", server.URL, "278964", []string{}, "", "", false, nil) + svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", []string{}, "", "", false, nil) require.NoError(t, err) - prs, err := svc.List(t.Context()) + prs, err := svc.List(context.Background()) require.NoError(t, err) assert.Len(t, prs, 1) assert.Equal(t, 15442, prs[0].Number) @@ -98,10 +99,10 @@ func TestListWithLabels(t *testing.T) { writeMRListResponse(t, w) }) - svc, err := NewGitLabService("", server.URL, "278964", []string{"feature", "ready"}, "", "", false, nil) + svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", []string{"feature", "ready"}, "", "", false, nil) require.NoError(t, err) - _, err = svc.List(t.Context()) + _, err = svc.List(context.Background()) require.NoError(t, err) } @@ -117,10 +118,10 @@ func TestListWithState(t *testing.T) { writeMRListResponse(t, w) }) - svc, err := NewGitLabService("", server.URL, "278964", []string{}, "opened", "", false, nil) + svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", []string{}, "opened", "", false, nil) require.NoError(t, err) - _, err = svc.List(t.Context()) + _, err = svc.List(context.Background()) require.NoError(t, err) } @@ -160,13 +161,13 @@ func TestListWithStateTLS(t *testing.T) { for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { writeMRListResponse(t, w) })) defer ts.Close() var certs []byte - if test.passCerts { + if test.passCerts == true { for _, cert := range ts.TLS.Certificates { for _, c := range cert.Certificate { parsedCert, err := x509.ParseCertificate(c) @@ -179,10 +180,10 @@ func TestListWithStateTLS(t *testing.T) { } } - svc, err := NewGitLabService("", ts.URL, "278964", []string{}, "opened", "", test.tlsInsecure, certs) + svc, err := NewGitLabService(context.Background(), "", ts.URL, "278964", []string{}, "opened", "", test.tlsInsecure, certs) require.NoError(t, err) - _, err = svc.List(t.Context()) + _, err = svc.List(context.Background()) if test.requireErr { require.Error(t, err) } else { diff --git a/applicationset/services/pull_request/utils.go b/applicationset/services/pull_request/utils.go index 100596fc3d..09b5b6ca10 100644 --- a/applicationset/services/pull_request/utils.go +++ b/applicationset/services/pull_request/utils.go @@ -5,7 +5,7 @@ import ( "fmt" "regexp" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func compileFilters(filters []argoprojiov1alpha1.PullRequestGeneratorFilter) ([]*Filter, error) { diff --git a/applicationset/services/pull_request/utils_test.go b/applicationset/services/pull_request/utils_test.go index d25b25ae83..1c74ae4b66 100644 --- a/applicationset/services/pull_request/utils_test.go +++ b/applicationset/services/pull_request/utils_test.go @@ -1,12 +1,13 @@ package pull_request import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func strp(s string) *string { @@ -15,7 +16,7 @@ func strp(s string) *string { func TestFilterBranchMatchBadRegexp(t *testing.T) { provider, _ := NewFakeService( - t.Context(), + context.Background(), []*PullRequest{ { Number: 1, @@ -33,13 +34,13 @@ func TestFilterBranchMatchBadRegexp(t *testing.T) { BranchMatch: strp("("), }, } - _, err := ListPullRequests(t.Context(), provider, filters) + _, err := ListPullRequests(context.Background(), provider, filters) require.Error(t, err) } func TestFilterBranchMatch(t *testing.T) { provider, _ := NewFakeService( - t.Context(), + context.Background(), []*PullRequest{ { Number: 1, @@ -81,7 +82,7 @@ func TestFilterBranchMatch(t *testing.T) { BranchMatch: strp("w"), }, } - pullRequests, err := ListPullRequests(t.Context(), provider, filters) + pullRequests, err := ListPullRequests(context.Background(), provider, filters) require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, "two", pullRequests[0].Branch) @@ -89,7 +90,7 @@ func TestFilterBranchMatch(t *testing.T) { func TestFilterTargetBranchMatch(t *testing.T) { provider, _ := NewFakeService( - t.Context(), + context.Background(), []*PullRequest{ { Number: 1, @@ -131,7 +132,7 @@ func TestFilterTargetBranchMatch(t *testing.T) { TargetBranchMatch: strp("1"), }, } - pullRequests, err := ListPullRequests(t.Context(), provider, filters) + pullRequests, err := ListPullRequests(context.Background(), provider, filters) require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, "two", pullRequests[0].Branch) @@ -139,7 +140,7 @@ func TestFilterTargetBranchMatch(t *testing.T) { func TestMultiFilterOr(t *testing.T) { provider, _ := NewFakeService( - t.Context(), + context.Background(), []*PullRequest{ { Number: 1, @@ -184,7 +185,7 @@ func TestMultiFilterOr(t *testing.T) { BranchMatch: strp("r"), }, } - pullRequests, err := ListPullRequests(t.Context(), provider, filters) + pullRequests, err := ListPullRequests(context.Background(), provider, filters) require.NoError(t, err) assert.Len(t, pullRequests, 3) assert.Equal(t, "two", pullRequests[0].Branch) @@ -194,7 +195,7 @@ func TestMultiFilterOr(t *testing.T) { func TestMultiFilterOrWithTargetBranchFilter(t *testing.T) { provider, _ := NewFakeService( - t.Context(), + context.Background(), []*PullRequest{ { Number: 1, @@ -241,7 +242,7 @@ func TestMultiFilterOrWithTargetBranchFilter(t *testing.T) { TargetBranchMatch: strp("3"), }, } - pullRequests, err := ListPullRequests(t.Context(), provider, filters) + pullRequests, err := ListPullRequests(context.Background(), provider, filters) require.NoError(t, err) assert.Len(t, pullRequests, 2) assert.Equal(t, "two", pullRequests[0].Branch) @@ -250,7 +251,7 @@ func TestMultiFilterOrWithTargetBranchFilter(t *testing.T) { func TestNoFilters(t *testing.T) { provider, _ := NewFakeService( - t.Context(), + context.Background(), []*PullRequest{ { Number: 1, @@ -272,7 +273,7 @@ func TestNoFilters(t *testing.T) { nil, ) filters := []argoprojiov1alpha1.PullRequestGeneratorFilter{} - repos, err := ListPullRequests(t.Context(), provider, filters) + repos, err := ListPullRequests(context.Background(), provider, filters) require.NoError(t, err) assert.Len(t, repos, 2) assert.Equal(t, "one", repos[0].Branch) diff --git a/applicationset/services/repo_service.go b/applicationset/services/repo_service.go index dd218f3092..f415a9a6d1 100644 --- a/applicationset/services/repo_service.go +++ b/applicationset/services/repo_service.go @@ -4,54 +4,39 @@ import ( "context" "fmt" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/db" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/io" ) type argoCDService struct { - getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) - submoduleEnabled bool - newFileGlobbingEnabled bool - getGitFilesFromRepoServer func(ctx context.Context, req *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error) - getGitDirectoriesFromRepoServer func(ctx context.Context, req *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error) + getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) + storecreds git.CredsStore + submoduleEnabled bool + repoServerClientSet apiclient.Clientset + newFileGlobbingEnabled bool } type Repos interface { // GetFiles returns content of files (not directories) within the target repo - GetFiles(ctx context.Context, repoURL, revision, project, pattern string, noRevisionCache, verifyCommit bool) (map[string][]byte, error) + GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache, verifyCommit bool) (map[string][]byte, error) // GetDirectories returns a list of directories (not files) within the target repo - GetDirectories(ctx context.Context, repoURL, revision, project string, noRevisionCache, verifyCommit bool) ([]string, error) + GetDirectories(ctx context.Context, repoURL string, revision string, noRevisionCache, verifyCommit bool) ([]string, error) } -func NewArgoCDService(db db.ArgoDB, submoduleEnabled bool, repoClientset apiclient.Clientset, newFileGlobbingEnabled bool) Repos { +func NewArgoCDService(getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error), submoduleEnabled bool, repoClientset apiclient.Clientset, newFileGlobbingEnabled bool) (Repos, error) { return &argoCDService{ - getRepository: db.GetRepository, + getRepository: getRepository, submoduleEnabled: submoduleEnabled, + repoServerClientSet: repoClientset, newFileGlobbingEnabled: newFileGlobbingEnabled, - getGitFilesFromRepoServer: func(ctx context.Context, fileRequest *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error) { - closer, client, err := repoClientset.NewRepoServerClient() - if err != nil { - return nil, fmt.Errorf("error initializing new repo server client: %w", err) - } - defer utilio.Close(closer) - return client.GetGitFiles(ctx, fileRequest) - }, - getGitDirectoriesFromRepoServer: func(ctx context.Context, dirRequest *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error) { - closer, client, err := repoClientset.NewRepoServerClient() - if err != nil { - return nil, fmt.Errorf("error initialising new repo server client: %w", err) - } - defer utilio.Close(closer) - return client.GetGitDirectories(ctx, dirRequest) - }, - } + }, nil } -func (a *argoCDService) GetFiles(ctx context.Context, repoURL, revision, project, pattern string, noRevisionCache, verifyCommit bool) (map[string][]byte, error) { - repo, err := a.getRepository(ctx, repoURL, project) +func (a *argoCDService) GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache, verifyCommit bool) (map[string][]byte, error) { + repo, err := a.getRepository(ctx, repoURL, "") if err != nil { return nil, fmt.Errorf("error in GetRepository: %w", err) } @@ -65,15 +50,21 @@ func (a *argoCDService) GetFiles(ctx context.Context, repoURL, revision, project NoRevisionCache: noRevisionCache, VerifyCommit: verifyCommit, } - fileResponse, err := a.getGitFilesFromRepoServer(ctx, fileRequest) + closer, client, err := a.repoServerClientSet.NewRepoServerClient() + if err != nil { + return nil, fmt.Errorf("error initialising new repo server client: %w", err) + } + defer io.Close(closer) + + fileResponse, err := client.GetGitFiles(ctx, fileRequest) if err != nil { return nil, fmt.Errorf("error retrieving Git files: %w", err) } return fileResponse.GetMap(), nil } -func (a *argoCDService) GetDirectories(ctx context.Context, repoURL, revision, project string, noRevisionCache, verifyCommit bool) ([]string, error) { - repo, err := a.getRepository(ctx, repoURL, project) +func (a *argoCDService) GetDirectories(ctx context.Context, repoURL string, revision string, noRevisionCache, verifyCommit bool) ([]string, error) { + repo, err := a.getRepository(ctx, repoURL, "") if err != nil { return nil, fmt.Errorf("error in GetRepository: %w", err) } @@ -86,7 +77,13 @@ func (a *argoCDService) GetDirectories(ctx context.Context, repoURL, revision, p VerifyCommit: verifyCommit, } - dirResponse, err := a.getGitDirectoriesFromRepoServer(ctx, dirRequest) + closer, client, err := a.repoServerClientSet.NewRepoServerClient() + if err != nil { + return nil, fmt.Errorf("error initialising new repo server client: %w", err) + } + defer io.Close(closer) + + dirResponse, err := client.GetGitDirectories(ctx, dirRequest) if err != nil { return nil, fmt.Errorf("error retrieving Git Directories: %w", err) } diff --git a/applicationset/services/repo_service_test.go b/applicationset/services/repo_service_test.go index 4762080edd..c621c317a9 100644 --- a/applicationset/services/repo_service_test.go +++ b/applicationset/services/repo_service_test.go @@ -2,26 +2,26 @@ package services import ( "context" - "errors" "fmt" "testing" "github.com/stretchr/testify/assert" - "k8s.io/client-go/kubernetes/fake" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - repo_mocks "github.com/argoproj/argo-cd/v3/reposerver/apiclient/mocks" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + repo_mocks "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" + "github.com/argoproj/argo-cd/v2/util/git" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestGetDirectories(t *testing.T) { type fields struct { - submoduleEnabled bool - getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) - getGitDirectories func(ctx context.Context, req *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error) + storecreds git.CredsStore + submoduleEnabled bool + getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) + repoServerClientFuncs []func(*repo_mocks.RepoServerServiceClient) } type args struct { ctx context.Context @@ -38,49 +38,58 @@ func TestGetDirectories(t *testing.T) { wantErr assert.ErrorAssertionFunc }{ {name: "ErrorGettingRepos", fields: fields{ - getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) { - return nil, errors.New("unable to get repos") + getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { + return nil, fmt.Errorf("unable to get repos") }, }, args: args{}, want: nil, wantErr: assert.Error}, {name: "ErrorGettingDirs", fields: fields{ - getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) { + getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { return &v1alpha1.Repository{}, nil }, - getGitDirectories: func(_ context.Context, _ *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error) { - return nil, errors.New("unable to get dirs") + repoServerClientFuncs: []func(*repo_mocks.RepoServerServiceClient){ + func(client *repo_mocks.RepoServerServiceClient) { + client.On("GetGitDirectories", mock.Anything, mock.Anything).Return(nil, fmt.Errorf("unable to get dirs")) + }, }, }, args: args{}, want: nil, wantErr: assert.Error}, {name: "HappyCase", fields: fields{ - getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) { - return &v1alpha1.Repository{ - Repo: "foo", - }, nil - }, - getGitDirectories: func(_ context.Context, _ *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error) { - return &apiclient.GitDirectoriesResponse{ - Paths: []string{"foo", "foo/bar", "bar/foo"}, - }, nil - }, - }, args: args{ - repoURL: "foo", - }, want: []string{"foo", "foo/bar", "bar/foo"}, wantErr: assert.NoError}, - {name: "ErrorVerifyingCommit", fields: fields{ - getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) { + getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { return &v1alpha1.Repository{}, nil }, - getGitDirectories: func(_ context.Context, _ *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error) { - return nil, errors.New("revision HEAD is not signed") + repoServerClientFuncs: []func(*repo_mocks.RepoServerServiceClient){ + func(client *repo_mocks.RepoServerServiceClient) { + client.On("GetGitDirectories", mock.Anything, mock.Anything).Return(&apiclient.GitDirectoriesResponse{ + Paths: []string{"foo", "foo/bar", "bar/foo"}, + }, nil) + }, + }, + }, args: args{}, want: []string{"foo", "foo/bar", "bar/foo"}, wantErr: assert.NoError}, + {name: "ErrorVerifyingCommit", fields: fields{ + getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { + return &v1alpha1.Repository{}, nil + }, + repoServerClientFuncs: []func(*repo_mocks.RepoServerServiceClient){ + func(client *repo_mocks.RepoServerServiceClient) { + client.On("GetGitDirectories", mock.Anything, mock.Anything).Return(nil, fmt.Errorf("revision HEAD is not signed")) + }, }, }, args: args{}, want: nil, wantErr: assert.Error}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - a := &argoCDService{ - getRepository: tt.fields.getRepository, - submoduleEnabled: tt.fields.submoduleEnabled, - getGitDirectoriesFromRepoServer: tt.fields.getGitDirectories, + mockRepoClient := &repo_mocks.RepoServerServiceClient{} + // decorate the mocks + for i := range tt.fields.repoServerClientFuncs { + tt.fields.repoServerClientFuncs[i](mockRepoClient) } - got, err := a.GetDirectories(tt.args.ctx, tt.args.repoURL, tt.args.revision, "", tt.args.noRevisionCache, tt.args.verifyCommit) + + a := &argoCDService{ + getRepository: tt.fields.getRepository, + storecreds: tt.fields.storecreds, + submoduleEnabled: tt.fields.submoduleEnabled, + repoServerClientSet: &repo_mocks.Clientset{RepoServerServiceClient: mockRepoClient}, + } + got, err := a.GetDirectories(tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.noRevisionCache, tt.args.verifyCommit) if !tt.wantErr(t, err, fmt.Sprintf("GetDirectories(%v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.noRevisionCache)) { return } @@ -91,9 +100,10 @@ func TestGetDirectories(t *testing.T) { func TestGetFiles(t *testing.T) { type fields struct { - submoduleEnabled bool - getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) - getGitFiles func(ctx context.Context, req *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error) + storecreds git.CredsStore + submoduleEnabled bool + repoServerClientFuncs []func(*repo_mocks.RepoServerServiceClient) + getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) } type args struct { ctx context.Context @@ -111,55 +121,64 @@ func TestGetFiles(t *testing.T) { wantErr assert.ErrorAssertionFunc }{ {name: "ErrorGettingRepos", fields: fields{ - getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) { - return nil, errors.New("unable to get repos") + getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { + return nil, fmt.Errorf("unable to get repos") }, }, args: args{}, want: nil, wantErr: assert.Error}, {name: "ErrorGettingFiles", fields: fields{ - getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) { + getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { return &v1alpha1.Repository{}, nil }, - getGitFiles: func(_ context.Context, _ *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error) { - return nil, errors.New("unable to get files") + repoServerClientFuncs: []func(*repo_mocks.RepoServerServiceClient){ + func(client *repo_mocks.RepoServerServiceClient) { + client.On("GetGitFiles", mock.Anything, mock.Anything).Return(nil, fmt.Errorf("unable to get files")) + }, }, }, args: args{}, want: nil, wantErr: assert.Error}, {name: "HappyCase", fields: fields{ - getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) { - return &v1alpha1.Repository{ - Repo: "foo", - }, nil + getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { + return &v1alpha1.Repository{}, nil }, - getGitFiles: func(_ context.Context, _ *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error) { - return &apiclient.GitFilesResponse{ - Map: map[string][]byte{ - "foo.json": []byte("hello: world!"), - "bar.yaml": []byte("yay: appsets"), - }, - }, nil + repoServerClientFuncs: []func(*repo_mocks.RepoServerServiceClient){ + func(client *repo_mocks.RepoServerServiceClient) { + client.On("GetGitFiles", mock.Anything, mock.Anything).Return(&apiclient.GitFilesResponse{ + Map: map[string][]byte{ + "foo.json": []byte("hello: world!"), + "bar.yaml": []byte("yay: appsets"), + }, + }, nil) + }, }, - }, args: args{ - repoURL: "foo", - }, want: map[string][]byte{ + }, args: args{}, want: map[string][]byte{ "foo.json": []byte("hello: world!"), "bar.yaml": []byte("yay: appsets"), }, wantErr: assert.NoError}, {name: "ErrorVerifyingCommit", fields: fields{ - getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) { + getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { return &v1alpha1.Repository{}, nil }, - getGitFiles: func(_ context.Context, _ *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error) { - return nil, errors.New("revision HEAD is not signed") + repoServerClientFuncs: []func(*repo_mocks.RepoServerServiceClient){ + func(client *repo_mocks.RepoServerServiceClient) { + client.On("GetGitFiles", mock.Anything, mock.Anything).Return(nil, fmt.Errorf("revision HEAD is not signed")) + }, }, }, args: args{}, want: nil, wantErr: assert.Error}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - a := &argoCDService{ - getRepository: tt.fields.getRepository, - submoduleEnabled: tt.fields.submoduleEnabled, - getGitFilesFromRepoServer: tt.fields.getGitFiles, + mockRepoClient := &repo_mocks.RepoServerServiceClient{} + // decorate the mocks + for i := range tt.fields.repoServerClientFuncs { + tt.fields.repoServerClientFuncs[i](mockRepoClient) } - got, err := a.GetFiles(tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern, "", tt.args.noRevisionCache, tt.args.verifyCommit) + + a := &argoCDService{ + getRepository: tt.fields.getRepository, + storecreds: tt.fields.storecreds, + submoduleEnabled: tt.fields.submoduleEnabled, + repoServerClientSet: &repo_mocks.Clientset{RepoServerServiceClient: mockRepoClient}, + } + got, err := a.GetFiles(tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern, tt.args.noRevisionCache, tt.args.verifyCommit) if !tt.wantErr(t, err, fmt.Sprintf("GetFiles(%v, %v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern, tt.args.noRevisionCache)) { return } @@ -169,9 +188,9 @@ func TestGetFiles(t *testing.T) { } func TestNewArgoCDService(t *testing.T) { - testNamespace := "test" - clientset := fake.NewClientset() - testDB := db.NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) - service := NewArgoCDService(testDB, false, &repo_mocks.Clientset{}, false) + service, err := NewArgoCDService(func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { + return &v1alpha1.Repository{}, nil + }, false, &repo_mocks.Clientset{}, false) + require.NoError(t, err) assert.NotNil(t, service) } diff --git a/applicationset/services/scm_provider/aws_codecommit.go b/applicationset/services/scm_provider/aws_codecommit.go index 481645454a..7732ff5361 100644 --- a/applicationset/services/scm_provider/aws_codecommit.go +++ b/applicationset/services/scm_provider/aws_codecommit.go @@ -21,13 +21,13 @@ import ( "golang.org/x/exp/maps" "k8s.io/utils/strings/slices" - application "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + application "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) const ( resourceTypeCodeCommitRepository = "codecommit:repository" - prefixGitURLHTTPS = "https://git-codecommit." - prefixGitURLHTTPSFIPS = "https://git-codecommit-fips." + prefixGitUrlHttps = "https://git-codecommit." + prefixGitUrlHttpsFIPS = "https://git-codecommit-fips." ) // AWSCodeCommitClient is a lean facade to the codecommitiface.CodeCommitAPI @@ -315,16 +315,16 @@ func getCodeCommitRepoName(repoArn string) (string, error) { // getCodeCommitFIPSEndpoint transforms provided https:// codecommit URL to a FIPS-compliant endpoint. // note that the specified region must support FIPS, otherwise the returned URL won't be reachable // see: https://docs.aws.amazon.com/codecommit/latest/userguide/regions.html#regions-git -func getCodeCommitFIPSEndpoint(repoURL string) (string, error) { - if strings.HasPrefix(repoURL, prefixGitURLHTTPSFIPS) { - log.Debugf("provided repoUrl %s is already a fips endpoint", repoURL) - return repoURL, nil +func getCodeCommitFIPSEndpoint(repoUrl string) (string, error) { + if strings.HasPrefix(repoUrl, prefixGitUrlHttpsFIPS) { + log.Debugf("provided repoUrl %s is already a fips endpoint", repoUrl) + return repoUrl, nil } - if !strings.HasPrefix(repoURL, prefixGitURLHTTPS) { - return "", fmt.Errorf("the provided https endpoint isn't recognized, cannot be transformed to FIPS endpoint: %s", repoURL) + if !strings.HasPrefix(repoUrl, prefixGitUrlHttps) { + return "", fmt.Errorf("the provided https endpoint isn't recognized, cannot be transformed to FIPS endpoint: %s", repoUrl) } // we already have the prefix, so we guarantee to replace exactly the prefix only. - return strings.Replace(repoURL, prefixGitURLHTTPS, prefixGitURLHTTPSFIPS, 1), nil + return strings.Replace(repoUrl, prefixGitUrlHttps, prefixGitUrlHttpsFIPS, 1), nil } func hasAwsError(err error, codes ...string) bool { diff --git a/applicationset/services/scm_provider/aws_codecommit/mocks/AWSCodeCommitClient.go b/applicationset/services/scm_provider/aws_codecommit/mocks/AWSCodeCommitClient.go index a410802bc2..822ca9b275 100644 --- a/applicationset/services/scm_provider/aws_codecommit/mocks/AWSCodeCommitClient.go +++ b/applicationset/services/scm_provider/aws_codecommit/mocks/AWSCodeCommitClient.go @@ -1,16 +1,170 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/service/codecommit" + context "context" + + codecommit "github.com/aws/aws-sdk-go/service/codecommit" + mock "github.com/stretchr/testify/mock" + + request "github.com/aws/aws-sdk-go/aws/request" ) +// AWSCodeCommitClient is an autogenerated mock type for the AWSCodeCommitClient type +type AWSCodeCommitClient struct { + mock.Mock +} + +// GetFolderWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *AWSCodeCommitClient) GetFolderWithContext(_a0 context.Context, _a1 *codecommit.GetFolderInput, _a2 ...request.Option) (*codecommit.GetFolderOutput, error) { + _va := make([]interface{}, len(_a2)) + for _i := range _a2 { + _va[_i] = _a2[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0, _a1) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetFolderWithContext") + } + + var r0 *codecommit.GetFolderOutput + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *codecommit.GetFolderInput, ...request.Option) (*codecommit.GetFolderOutput, error)); ok { + return rf(_a0, _a1, _a2...) + } + if rf, ok := ret.Get(0).(func(context.Context, *codecommit.GetFolderInput, ...request.Option) *codecommit.GetFolderOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*codecommit.GetFolderOutput) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *codecommit.GetFolderInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRepositoryWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *AWSCodeCommitClient) GetRepositoryWithContext(_a0 context.Context, _a1 *codecommit.GetRepositoryInput, _a2 ...request.Option) (*codecommit.GetRepositoryOutput, error) { + _va := make([]interface{}, len(_a2)) + for _i := range _a2 { + _va[_i] = _a2[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0, _a1) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetRepositoryWithContext") + } + + var r0 *codecommit.GetRepositoryOutput + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *codecommit.GetRepositoryInput, ...request.Option) (*codecommit.GetRepositoryOutput, error)); ok { + return rf(_a0, _a1, _a2...) + } + if rf, ok := ret.Get(0).(func(context.Context, *codecommit.GetRepositoryInput, ...request.Option) *codecommit.GetRepositoryOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*codecommit.GetRepositoryOutput) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *codecommit.GetRepositoryInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListBranchesWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *AWSCodeCommitClient) ListBranchesWithContext(_a0 context.Context, _a1 *codecommit.ListBranchesInput, _a2 ...request.Option) (*codecommit.ListBranchesOutput, error) { + _va := make([]interface{}, len(_a2)) + for _i := range _a2 { + _va[_i] = _a2[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0, _a1) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for ListBranchesWithContext") + } + + var r0 *codecommit.ListBranchesOutput + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *codecommit.ListBranchesInput, ...request.Option) (*codecommit.ListBranchesOutput, error)); ok { + return rf(_a0, _a1, _a2...) + } + if rf, ok := ret.Get(0).(func(context.Context, *codecommit.ListBranchesInput, ...request.Option) *codecommit.ListBranchesOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*codecommit.ListBranchesOutput) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *codecommit.ListBranchesInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListRepositoriesWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *AWSCodeCommitClient) ListRepositoriesWithContext(_a0 context.Context, _a1 *codecommit.ListRepositoriesInput, _a2 ...request.Option) (*codecommit.ListRepositoriesOutput, error) { + _va := make([]interface{}, len(_a2)) + for _i := range _a2 { + _va[_i] = _a2[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0, _a1) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for ListRepositoriesWithContext") + } + + var r0 *codecommit.ListRepositoriesOutput + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *codecommit.ListRepositoriesInput, ...request.Option) (*codecommit.ListRepositoriesOutput, error)); ok { + return rf(_a0, _a1, _a2...) + } + if rf, ok := ret.Get(0).(func(context.Context, *codecommit.ListRepositoriesInput, ...request.Option) *codecommit.ListRepositoriesOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*codecommit.ListRepositoriesOutput) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *codecommit.ListRepositoriesInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewAWSCodeCommitClient creates a new instance of AWSCodeCommitClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewAWSCodeCommitClient(t interface { @@ -24,308 +178,3 @@ func NewAWSCodeCommitClient(t interface { return mock } - -// AWSCodeCommitClient is an autogenerated mock type for the AWSCodeCommitClient type -type AWSCodeCommitClient struct { - mock.Mock -} - -type AWSCodeCommitClient_Expecter struct { - mock *mock.Mock -} - -func (_m *AWSCodeCommitClient) EXPECT() *AWSCodeCommitClient_Expecter { - return &AWSCodeCommitClient_Expecter{mock: &_m.Mock} -} - -// GetFolderWithContext provides a mock function for the type AWSCodeCommitClient -func (_mock *AWSCodeCommitClient) GetFolderWithContext(v aws.Context, getFolderInput *codecommit.GetFolderInput, options ...request.Option) (*codecommit.GetFolderOutput, error) { - // request.Option - _va := make([]interface{}, len(options)) - for _i := range options { - _va[_i] = options[_i] - } - var _ca []interface{} - _ca = append(_ca, v, getFolderInput) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GetFolderWithContext") - } - - var r0 *codecommit.GetFolderOutput - var r1 error - if returnFunc, ok := ret.Get(0).(func(aws.Context, *codecommit.GetFolderInput, ...request.Option) (*codecommit.GetFolderOutput, error)); ok { - return returnFunc(v, getFolderInput, options...) - } - if returnFunc, ok := ret.Get(0).(func(aws.Context, *codecommit.GetFolderInput, ...request.Option) *codecommit.GetFolderOutput); ok { - r0 = returnFunc(v, getFolderInput, options...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*codecommit.GetFolderOutput) - } - } - if returnFunc, ok := ret.Get(1).(func(aws.Context, *codecommit.GetFolderInput, ...request.Option) error); ok { - r1 = returnFunc(v, getFolderInput, options...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// AWSCodeCommitClient_GetFolderWithContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFolderWithContext' -type AWSCodeCommitClient_GetFolderWithContext_Call struct { - *mock.Call -} - -// GetFolderWithContext is a helper method to define mock.On call -// - v -// - getFolderInput -// - options -func (_e *AWSCodeCommitClient_Expecter) GetFolderWithContext(v interface{}, getFolderInput interface{}, options ...interface{}) *AWSCodeCommitClient_GetFolderWithContext_Call { - return &AWSCodeCommitClient_GetFolderWithContext_Call{Call: _e.mock.On("GetFolderWithContext", - append([]interface{}{v, getFolderInput}, options...)...)} -} - -func (_c *AWSCodeCommitClient_GetFolderWithContext_Call) Run(run func(v aws.Context, getFolderInput *codecommit.GetFolderInput, options ...request.Option)) *AWSCodeCommitClient_GetFolderWithContext_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]request.Option, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(request.Option) - } - } - run(args[0].(aws.Context), args[1].(*codecommit.GetFolderInput), variadicArgs...) - }) - return _c -} - -func (_c *AWSCodeCommitClient_GetFolderWithContext_Call) Return(getFolderOutput *codecommit.GetFolderOutput, err error) *AWSCodeCommitClient_GetFolderWithContext_Call { - _c.Call.Return(getFolderOutput, err) - return _c -} - -func (_c *AWSCodeCommitClient_GetFolderWithContext_Call) RunAndReturn(run func(v aws.Context, getFolderInput *codecommit.GetFolderInput, options ...request.Option) (*codecommit.GetFolderOutput, error)) *AWSCodeCommitClient_GetFolderWithContext_Call { - _c.Call.Return(run) - return _c -} - -// GetRepositoryWithContext provides a mock function for the type AWSCodeCommitClient -func (_mock *AWSCodeCommitClient) GetRepositoryWithContext(v aws.Context, getRepositoryInput *codecommit.GetRepositoryInput, options ...request.Option) (*codecommit.GetRepositoryOutput, error) { - // request.Option - _va := make([]interface{}, len(options)) - for _i := range options { - _va[_i] = options[_i] - } - var _ca []interface{} - _ca = append(_ca, v, getRepositoryInput) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GetRepositoryWithContext") - } - - var r0 *codecommit.GetRepositoryOutput - var r1 error - if returnFunc, ok := ret.Get(0).(func(aws.Context, *codecommit.GetRepositoryInput, ...request.Option) (*codecommit.GetRepositoryOutput, error)); ok { - return returnFunc(v, getRepositoryInput, options...) - } - if returnFunc, ok := ret.Get(0).(func(aws.Context, *codecommit.GetRepositoryInput, ...request.Option) *codecommit.GetRepositoryOutput); ok { - r0 = returnFunc(v, getRepositoryInput, options...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*codecommit.GetRepositoryOutput) - } - } - if returnFunc, ok := ret.Get(1).(func(aws.Context, *codecommit.GetRepositoryInput, ...request.Option) error); ok { - r1 = returnFunc(v, getRepositoryInput, options...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// AWSCodeCommitClient_GetRepositoryWithContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRepositoryWithContext' -type AWSCodeCommitClient_GetRepositoryWithContext_Call struct { - *mock.Call -} - -// GetRepositoryWithContext is a helper method to define mock.On call -// - v -// - getRepositoryInput -// - options -func (_e *AWSCodeCommitClient_Expecter) GetRepositoryWithContext(v interface{}, getRepositoryInput interface{}, options ...interface{}) *AWSCodeCommitClient_GetRepositoryWithContext_Call { - return &AWSCodeCommitClient_GetRepositoryWithContext_Call{Call: _e.mock.On("GetRepositoryWithContext", - append([]interface{}{v, getRepositoryInput}, options...)...)} -} - -func (_c *AWSCodeCommitClient_GetRepositoryWithContext_Call) Run(run func(v aws.Context, getRepositoryInput *codecommit.GetRepositoryInput, options ...request.Option)) *AWSCodeCommitClient_GetRepositoryWithContext_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]request.Option, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(request.Option) - } - } - run(args[0].(aws.Context), args[1].(*codecommit.GetRepositoryInput), variadicArgs...) - }) - return _c -} - -func (_c *AWSCodeCommitClient_GetRepositoryWithContext_Call) Return(getRepositoryOutput *codecommit.GetRepositoryOutput, err error) *AWSCodeCommitClient_GetRepositoryWithContext_Call { - _c.Call.Return(getRepositoryOutput, err) - return _c -} - -func (_c *AWSCodeCommitClient_GetRepositoryWithContext_Call) RunAndReturn(run func(v aws.Context, getRepositoryInput *codecommit.GetRepositoryInput, options ...request.Option) (*codecommit.GetRepositoryOutput, error)) *AWSCodeCommitClient_GetRepositoryWithContext_Call { - _c.Call.Return(run) - return _c -} - -// ListBranchesWithContext provides a mock function for the type AWSCodeCommitClient -func (_mock *AWSCodeCommitClient) ListBranchesWithContext(v aws.Context, listBranchesInput *codecommit.ListBranchesInput, options ...request.Option) (*codecommit.ListBranchesOutput, error) { - // request.Option - _va := make([]interface{}, len(options)) - for _i := range options { - _va[_i] = options[_i] - } - var _ca []interface{} - _ca = append(_ca, v, listBranchesInput) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for ListBranchesWithContext") - } - - var r0 *codecommit.ListBranchesOutput - var r1 error - if returnFunc, ok := ret.Get(0).(func(aws.Context, *codecommit.ListBranchesInput, ...request.Option) (*codecommit.ListBranchesOutput, error)); ok { - return returnFunc(v, listBranchesInput, options...) - } - if returnFunc, ok := ret.Get(0).(func(aws.Context, *codecommit.ListBranchesInput, ...request.Option) *codecommit.ListBranchesOutput); ok { - r0 = returnFunc(v, listBranchesInput, options...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*codecommit.ListBranchesOutput) - } - } - if returnFunc, ok := ret.Get(1).(func(aws.Context, *codecommit.ListBranchesInput, ...request.Option) error); ok { - r1 = returnFunc(v, listBranchesInput, options...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// AWSCodeCommitClient_ListBranchesWithContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListBranchesWithContext' -type AWSCodeCommitClient_ListBranchesWithContext_Call struct { - *mock.Call -} - -// ListBranchesWithContext is a helper method to define mock.On call -// - v -// - listBranchesInput -// - options -func (_e *AWSCodeCommitClient_Expecter) ListBranchesWithContext(v interface{}, listBranchesInput interface{}, options ...interface{}) *AWSCodeCommitClient_ListBranchesWithContext_Call { - return &AWSCodeCommitClient_ListBranchesWithContext_Call{Call: _e.mock.On("ListBranchesWithContext", - append([]interface{}{v, listBranchesInput}, options...)...)} -} - -func (_c *AWSCodeCommitClient_ListBranchesWithContext_Call) Run(run func(v aws.Context, listBranchesInput *codecommit.ListBranchesInput, options ...request.Option)) *AWSCodeCommitClient_ListBranchesWithContext_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]request.Option, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(request.Option) - } - } - run(args[0].(aws.Context), args[1].(*codecommit.ListBranchesInput), variadicArgs...) - }) - return _c -} - -func (_c *AWSCodeCommitClient_ListBranchesWithContext_Call) Return(listBranchesOutput *codecommit.ListBranchesOutput, err error) *AWSCodeCommitClient_ListBranchesWithContext_Call { - _c.Call.Return(listBranchesOutput, err) - return _c -} - -func (_c *AWSCodeCommitClient_ListBranchesWithContext_Call) RunAndReturn(run func(v aws.Context, listBranchesInput *codecommit.ListBranchesInput, options ...request.Option) (*codecommit.ListBranchesOutput, error)) *AWSCodeCommitClient_ListBranchesWithContext_Call { - _c.Call.Return(run) - return _c -} - -// ListRepositoriesWithContext provides a mock function for the type AWSCodeCommitClient -func (_mock *AWSCodeCommitClient) ListRepositoriesWithContext(v aws.Context, listRepositoriesInput *codecommit.ListRepositoriesInput, options ...request.Option) (*codecommit.ListRepositoriesOutput, error) { - // request.Option - _va := make([]interface{}, len(options)) - for _i := range options { - _va[_i] = options[_i] - } - var _ca []interface{} - _ca = append(_ca, v, listRepositoriesInput) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for ListRepositoriesWithContext") - } - - var r0 *codecommit.ListRepositoriesOutput - var r1 error - if returnFunc, ok := ret.Get(0).(func(aws.Context, *codecommit.ListRepositoriesInput, ...request.Option) (*codecommit.ListRepositoriesOutput, error)); ok { - return returnFunc(v, listRepositoriesInput, options...) - } - if returnFunc, ok := ret.Get(0).(func(aws.Context, *codecommit.ListRepositoriesInput, ...request.Option) *codecommit.ListRepositoriesOutput); ok { - r0 = returnFunc(v, listRepositoriesInput, options...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*codecommit.ListRepositoriesOutput) - } - } - if returnFunc, ok := ret.Get(1).(func(aws.Context, *codecommit.ListRepositoriesInput, ...request.Option) error); ok { - r1 = returnFunc(v, listRepositoriesInput, options...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// AWSCodeCommitClient_ListRepositoriesWithContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListRepositoriesWithContext' -type AWSCodeCommitClient_ListRepositoriesWithContext_Call struct { - *mock.Call -} - -// ListRepositoriesWithContext is a helper method to define mock.On call -// - v -// - listRepositoriesInput -// - options -func (_e *AWSCodeCommitClient_Expecter) ListRepositoriesWithContext(v interface{}, listRepositoriesInput interface{}, options ...interface{}) *AWSCodeCommitClient_ListRepositoriesWithContext_Call { - return &AWSCodeCommitClient_ListRepositoriesWithContext_Call{Call: _e.mock.On("ListRepositoriesWithContext", - append([]interface{}{v, listRepositoriesInput}, options...)...)} -} - -func (_c *AWSCodeCommitClient_ListRepositoriesWithContext_Call) Run(run func(v aws.Context, listRepositoriesInput *codecommit.ListRepositoriesInput, options ...request.Option)) *AWSCodeCommitClient_ListRepositoriesWithContext_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]request.Option, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(request.Option) - } - } - run(args[0].(aws.Context), args[1].(*codecommit.ListRepositoriesInput), variadicArgs...) - }) - return _c -} - -func (_c *AWSCodeCommitClient_ListRepositoriesWithContext_Call) Return(listRepositoriesOutput *codecommit.ListRepositoriesOutput, err error) *AWSCodeCommitClient_ListRepositoriesWithContext_Call { - _c.Call.Return(listRepositoriesOutput, err) - return _c -} - -func (_c *AWSCodeCommitClient_ListRepositoriesWithContext_Call) RunAndReturn(run func(v aws.Context, listRepositoriesInput *codecommit.ListRepositoriesInput, options ...request.Option) (*codecommit.ListRepositoriesOutput, error)) *AWSCodeCommitClient_ListRepositoriesWithContext_Call { - _c.Call.Return(run) - return _c -} diff --git a/applicationset/services/scm_provider/aws_codecommit/mocks/AWSTaggingClient.go b/applicationset/services/scm_provider/aws_codecommit/mocks/AWSTaggingClient.go index 5e9cbc714f..e454e2a9d9 100644 --- a/applicationset/services/scm_provider/aws_codecommit/mocks/AWSTaggingClient.go +++ b/applicationset/services/scm_provider/aws_codecommit/mocks/AWSTaggingClient.go @@ -1,16 +1,58 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi" + context "context" + + request "github.com/aws/aws-sdk-go/aws/request" mock "github.com/stretchr/testify/mock" + + resourcegroupstaggingapi "github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi" ) +// AWSTaggingClient is an autogenerated mock type for the AWSTaggingClient type +type AWSTaggingClient struct { + mock.Mock +} + +// GetResourcesWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *AWSTaggingClient) GetResourcesWithContext(_a0 context.Context, _a1 *resourcegroupstaggingapi.GetResourcesInput, _a2 ...request.Option) (*resourcegroupstaggingapi.GetResourcesOutput, error) { + _va := make([]interface{}, len(_a2)) + for _i := range _a2 { + _va[_i] = _a2[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0, _a1) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetResourcesWithContext") + } + + var r0 *resourcegroupstaggingapi.GetResourcesOutput + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *resourcegroupstaggingapi.GetResourcesInput, ...request.Option) (*resourcegroupstaggingapi.GetResourcesOutput, error)); ok { + return rf(_a0, _a1, _a2...) + } + if rf, ok := ret.Get(0).(func(context.Context, *resourcegroupstaggingapi.GetResourcesInput, ...request.Option) *resourcegroupstaggingapi.GetResourcesOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*resourcegroupstaggingapi.GetResourcesOutput) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *resourcegroupstaggingapi.GetResourcesInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewAWSTaggingClient creates a new instance of AWSTaggingClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewAWSTaggingClient(t interface { @@ -24,89 +66,3 @@ func NewAWSTaggingClient(t interface { return mock } - -// AWSTaggingClient is an autogenerated mock type for the AWSTaggingClient type -type AWSTaggingClient struct { - mock.Mock -} - -type AWSTaggingClient_Expecter struct { - mock *mock.Mock -} - -func (_m *AWSTaggingClient) EXPECT() *AWSTaggingClient_Expecter { - return &AWSTaggingClient_Expecter{mock: &_m.Mock} -} - -// GetResourcesWithContext provides a mock function for the type AWSTaggingClient -func (_mock *AWSTaggingClient) GetResourcesWithContext(v aws.Context, getResourcesInput *resourcegroupstaggingapi.GetResourcesInput, options ...request.Option) (*resourcegroupstaggingapi.GetResourcesOutput, error) { - // request.Option - _va := make([]interface{}, len(options)) - for _i := range options { - _va[_i] = options[_i] - } - var _ca []interface{} - _ca = append(_ca, v, getResourcesInput) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GetResourcesWithContext") - } - - var r0 *resourcegroupstaggingapi.GetResourcesOutput - var r1 error - if returnFunc, ok := ret.Get(0).(func(aws.Context, *resourcegroupstaggingapi.GetResourcesInput, ...request.Option) (*resourcegroupstaggingapi.GetResourcesOutput, error)); ok { - return returnFunc(v, getResourcesInput, options...) - } - if returnFunc, ok := ret.Get(0).(func(aws.Context, *resourcegroupstaggingapi.GetResourcesInput, ...request.Option) *resourcegroupstaggingapi.GetResourcesOutput); ok { - r0 = returnFunc(v, getResourcesInput, options...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*resourcegroupstaggingapi.GetResourcesOutput) - } - } - if returnFunc, ok := ret.Get(1).(func(aws.Context, *resourcegroupstaggingapi.GetResourcesInput, ...request.Option) error); ok { - r1 = returnFunc(v, getResourcesInput, options...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// AWSTaggingClient_GetResourcesWithContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetResourcesWithContext' -type AWSTaggingClient_GetResourcesWithContext_Call struct { - *mock.Call -} - -// GetResourcesWithContext is a helper method to define mock.On call -// - v -// - getResourcesInput -// - options -func (_e *AWSTaggingClient_Expecter) GetResourcesWithContext(v interface{}, getResourcesInput interface{}, options ...interface{}) *AWSTaggingClient_GetResourcesWithContext_Call { - return &AWSTaggingClient_GetResourcesWithContext_Call{Call: _e.mock.On("GetResourcesWithContext", - append([]interface{}{v, getResourcesInput}, options...)...)} -} - -func (_c *AWSTaggingClient_GetResourcesWithContext_Call) Run(run func(v aws.Context, getResourcesInput *resourcegroupstaggingapi.GetResourcesInput, options ...request.Option)) *AWSTaggingClient_GetResourcesWithContext_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]request.Option, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(request.Option) - } - } - run(args[0].(aws.Context), args[1].(*resourcegroupstaggingapi.GetResourcesInput), variadicArgs...) - }) - return _c -} - -func (_c *AWSTaggingClient_GetResourcesWithContext_Call) Return(getResourcesOutput *resourcegroupstaggingapi.GetResourcesOutput, err error) *AWSTaggingClient_GetResourcesWithContext_Call { - _c.Call.Return(getResourcesOutput, err) - return _c -} - -func (_c *AWSTaggingClient_GetResourcesWithContext_Call) RunAndReturn(run func(v aws.Context, getResourcesInput *resourcegroupstaggingapi.GetResourcesInput, options ...request.Option) (*resourcegroupstaggingapi.GetResourcesOutput, error)) *AWSTaggingClient_GetResourcesWithContext_Call { - _c.Call.Return(run) - return _c -} diff --git a/applicationset/services/scm_provider/aws_codecommit_test.go b/applicationset/services/scm_provider/aws_codecommit_test.go index fc5b7fa5d1..00d8240973 100644 --- a/applicationset/services/scm_provider/aws_codecommit_test.go +++ b/applicationset/services/scm_provider/aws_codecommit_test.go @@ -1,6 +1,7 @@ package scm_provider import ( + "context" "errors" "sort" "testing" @@ -12,8 +13,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider/aws_codecommit/mocks" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider/aws_codecommit/mocks" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) type awsCodeCommitTestRepository struct { @@ -22,7 +23,7 @@ type awsCodeCommitTestRepository struct { arn string accountId string defaultBranch string - expectedCloneURL string + expectedCloneUrl string getRepositoryError error getRepositoryNilMetadata bool valid bool @@ -48,7 +49,7 @@ func TestAWSCodeCommitListRepos(t *testing.T) { id: "8235624d-d248-4df9-a983-2558b01dbe83", arn: "arn:aws:codecommit:us-east-1:111111111111:repo1", defaultBranch: "main", - expectedCloneURL: "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo1", + expectedCloneUrl: "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo1", valid: true, }, }, @@ -73,7 +74,7 @@ func TestAWSCodeCommitListRepos(t *testing.T) { id: "8235624d-d248-4df9-a983-2558b01dbe83", arn: "arn:aws:codecommit:us-east-1:111111111111:repo1", defaultBranch: "main", - expectedCloneURL: "https://git-codecommit-fips.us-east-1.amazonaws.com/v1/repos/repo1", + expectedCloneUrl: "https://git-codecommit-fips.us-east-1.amazonaws.com/v1/repos/repo1", valid: true, }, }, @@ -95,7 +96,7 @@ func TestAWSCodeCommitListRepos(t *testing.T) { id: "8235624d-d248-4df9-a983-2558b01dbe83", arn: "arn:aws:codecommit:us-east-1:111111111111:repo1", defaultBranch: "main", - expectedCloneURL: "ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo1", + expectedCloneUrl: "ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo1", valid: true, }, { @@ -159,7 +160,7 @@ func TestAWSCodeCommitListRepos(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { codeCommitClient := mocks.NewAWSCodeCommitClient(t) taggingClient := mocks.NewAWSTaggingClient(t) - ctx := t.Context() + ctx := context.Background() codecommitRepoNameIdPairs := make([]*codecommit.RepositoryNameIdPair, 0) resourceTaggings := make([]*resourcegroupstaggingapi.ResourceTagMapping, 0) validRepositories := make([]*awsCodeCommitTestRepository, 0) @@ -225,7 +226,7 @@ func TestAWSCodeCommitListRepos(t *testing.T) { assert.Equal(t, originRepo.name, repo.Repository) assert.Equal(t, originRepo.id, repo.RepositoryId) assert.Equal(t, originRepo.defaultBranch, repo.Branch) - assert.Equal(t, originRepo.expectedCloneURL, repo.URL) + assert.Equal(t, originRepo.expectedCloneUrl, repo.URL) assert.Empty(t, repo.SHA, "SHA is always empty") } } @@ -348,7 +349,7 @@ func TestAWSCodeCommitRepoHasPath(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { codeCommitClient := mocks.NewAWSCodeCommitClient(t) taggingClient := mocks.NewAWSTaggingClient(t) - ctx := t.Context() + ctx := context.Background() if testCase.expectedGetFolderPath != "" { codeCommitClient. On("GetFolderWithContext", ctx, &codecommit.GetFolderInput{ @@ -381,7 +382,7 @@ func TestAWSCodeCommitGetBranches(t *testing.T) { id := "1a64adc4-2fb5-4abd-afe7-127984ba83c0" defaultBranch := "main" organization := "111111111111" - cloneURL := "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo1" + cloneUrl := "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo1" testCases := []struct { name string @@ -421,7 +422,7 @@ func TestAWSCodeCommitGetBranches(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { codeCommitClient := mocks.NewAWSCodeCommitClient(t) taggingClient := mocks.NewAWSTaggingClient(t) - ctx := t.Context() + ctx := context.Background() if testCase.allBranches { codeCommitClient. On("ListBranchesWithContext", ctx, &codecommit.ListBranchesInput{ @@ -444,7 +445,7 @@ func TestAWSCodeCommitGetBranches(t *testing.T) { actual, err := provider.GetBranches(ctx, &Repository{ Organization: organization, Repository: name, - URL: cloneURL, + URL: cloneUrl, RepositoryId: id, }) if testCase.expectOverallError { @@ -453,7 +454,7 @@ func TestAWSCodeCommitGetBranches(t *testing.T) { assertCopiedProperties := func(repo *Repository) { assert.Equal(t, id, repo.RepositoryId) assert.Equal(t, name, repo.Repository) - assert.Equal(t, cloneURL, repo.URL) + assert.Equal(t, cloneUrl, repo.URL) assert.Equal(t, organization, repo.Organization) assert.Empty(t, repo.SHA) } diff --git a/applicationset/services/scm_provider/azure_devops.go b/applicationset/services/scm_provider/azure_devops.go index afda2551ec..a4bb50a023 100644 --- a/applicationset/services/scm_provider/azure_devops.go +++ b/applicationset/services/scm_provider/azure_devops.go @@ -8,8 +8,8 @@ import ( "strings" "github.com/google/uuid" - "github.com/microsoft/azure-devops-go-api/azuredevops/v7" - azureGit "github.com/microsoft/azure-devops-go-api/azuredevops/v7/git" + "github.com/microsoft/azure-devops-go-api/azuredevops" + azureGit "github.com/microsoft/azure-devops-go-api/azuredevops/git" ) const AZURE_DEVOPS_DEFAULT_URL = "https://dev.azure.com" @@ -57,9 +57,9 @@ var ( _ AzureDevOpsClientFactory = &devopsFactoryImpl{} ) -func NewAzureDevOpsProvider(accessToken string, org string, url string, project string, allBranches bool) (*AzureDevOpsProvider, error) { +func NewAzureDevOpsProvider(ctx context.Context, accessToken string, org string, url string, project string, allBranches bool) (*AzureDevOpsProvider, error) { if accessToken == "" { - return nil, errors.New("no access token provided") + return nil, fmt.Errorf("no access token provided") } devOpsURL, err := getValidDevOpsURL(url, org) @@ -72,7 +72,7 @@ func NewAzureDevOpsProvider(accessToken string, org string, url string, project return &AzureDevOpsProvider{organization: org, teamProject: project, accessToken: accessToken, clientFactory: &devopsFactoryImpl{connection: connection}, allBranches: allBranches}, nil } -func (g *AzureDevOpsProvider) ListRepos(ctx context.Context, _ string) ([]*Repository, error) { +func (g *AzureDevOpsProvider) ListRepos(ctx context.Context, cloneProtocol string) ([]*Repository, error) { gitClient, err := g.clientFactory.GetClient(ctx) if err != nil { return nil, fmt.Errorf("failed to get Azure DevOps client: %w", err) @@ -107,7 +107,7 @@ func (g *AzureDevOpsProvider) RepoHasPath(ctx context.Context, repo *Repository, } var repoId string - if uuid, isUUID := repo.RepositoryId.(uuid.UUID); isUUID { // most likely an UUID, but do type-safe check anyway. Do %v fallback if not expected type. + if uuid, isUuid := repo.RepositoryId.(uuid.UUID); isUuid { // most likely an UUID, but do type-safe check anyway. Do %v fallback if not expected type. repoId = uuid.String() } else { repoId = fmt.Sprintf("%v", repo.RepositoryId) diff --git a/applicationset/services/scm_provider/azure_devops/git/mocks/Client.go b/applicationset/services/scm_provider/azure_devops/git/mocks/Client.go index 9bec031656..4fd54456ca 100644 --- a/applicationset/services/scm_provider/azure_devops/git/mocks/Client.go +++ b/applicationset/services/scm_provider/azure_devops/git/mocks/Client.go @@ -1,19 +1,3325 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" - "io" + context "context" + + core "github.com/microsoft/azure-devops-go-api/azuredevops/core" + git "github.com/microsoft/azure-devops-go-api/azuredevops/git" + + io "io" - "github.com/microsoft/azure-devops-go-api/azuredevops/v7/core" - "github.com/microsoft/azure-devops-go-api/azuredevops/v7/git" - "github.com/microsoft/azure-devops-go-api/azuredevops/v7/webapi" mock "github.com/stretchr/testify/mock" + + webapi "github.com/microsoft/azure-devops-go-api/azuredevops/webapi" ) +// Client is an autogenerated mock type for the Client type +type Client struct { + mock.Mock +} + +// CreateAnnotatedTag provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateAnnotatedTag(_a0 context.Context, _a1 git.CreateAnnotatedTagArgs) (*git.GitAnnotatedTag, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateAnnotatedTag") + } + + var r0 *git.GitAnnotatedTag + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateAnnotatedTagArgs) (*git.GitAnnotatedTag, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreateAnnotatedTagArgs) *git.GitAnnotatedTag); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitAnnotatedTag) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreateAnnotatedTagArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateAttachment provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateAttachment(_a0 context.Context, _a1 git.CreateAttachmentArgs) (*git.Attachment, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateAttachment") + } + + var r0 *git.Attachment + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateAttachmentArgs) (*git.Attachment, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreateAttachmentArgs) *git.Attachment); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.Attachment) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreateAttachmentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateCherryPick provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateCherryPick(_a0 context.Context, _a1 git.CreateCherryPickArgs) (*git.GitCherryPick, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateCherryPick") + } + + var r0 *git.GitCherryPick + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateCherryPickArgs) (*git.GitCherryPick, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreateCherryPickArgs) *git.GitCherryPick); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitCherryPick) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreateCherryPickArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateComment provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateComment(_a0 context.Context, _a1 git.CreateCommentArgs) (*git.Comment, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateComment") + } + + var r0 *git.Comment + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateCommentArgs) (*git.Comment, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreateCommentArgs) *git.Comment); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.Comment) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreateCommentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateCommitStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateCommitStatus(_a0 context.Context, _a1 git.CreateCommitStatusArgs) (*git.GitStatus, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateCommitStatus") + } + + var r0 *git.GitStatus + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateCommitStatusArgs) (*git.GitStatus, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreateCommitStatusArgs) *git.GitStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitStatus) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreateCommitStatusArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateFavorite provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateFavorite(_a0 context.Context, _a1 git.CreateFavoriteArgs) (*git.GitRefFavorite, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateFavorite") + } + + var r0 *git.GitRefFavorite + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateFavoriteArgs) (*git.GitRefFavorite, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreateFavoriteArgs) *git.GitRefFavorite); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRefFavorite) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreateFavoriteArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateForkSyncRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateForkSyncRequest(_a0 context.Context, _a1 git.CreateForkSyncRequestArgs) (*git.GitForkSyncRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateForkSyncRequest") + } + + var r0 *git.GitForkSyncRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateForkSyncRequestArgs) (*git.GitForkSyncRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreateForkSyncRequestArgs) *git.GitForkSyncRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitForkSyncRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreateForkSyncRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateImportRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateImportRequest(_a0 context.Context, _a1 git.CreateImportRequestArgs) (*git.GitImportRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateImportRequest") + } + + var r0 *git.GitImportRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateImportRequestArgs) (*git.GitImportRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreateImportRequestArgs) *git.GitImportRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitImportRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreateImportRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateLike provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateLike(_a0 context.Context, _a1 git.CreateLikeArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateLike") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateLikeArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CreateMergeRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateMergeRequest(_a0 context.Context, _a1 git.CreateMergeRequestArgs) (*git.GitMerge, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateMergeRequest") + } + + var r0 *git.GitMerge + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateMergeRequestArgs) (*git.GitMerge, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreateMergeRequestArgs) *git.GitMerge); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitMerge) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreateMergeRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePullRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePullRequest(_a0 context.Context, _a1 git.CreatePullRequestArgs) (*git.GitPullRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreatePullRequest") + } + + var r0 *git.GitPullRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestArgs) (*git.GitPullRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestArgs) *git.GitPullRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePullRequestIterationStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePullRequestIterationStatus(_a0 context.Context, _a1 git.CreatePullRequestIterationStatusArgs) (*git.GitPullRequestStatus, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreatePullRequestIterationStatus") + } + + var r0 *git.GitPullRequestStatus + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestIterationStatusArgs) (*git.GitPullRequestStatus, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestIterationStatusArgs) *git.GitPullRequestStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestStatus) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestIterationStatusArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePullRequestLabel provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePullRequestLabel(_a0 context.Context, _a1 git.CreatePullRequestLabelArgs) (*core.WebApiTagDefinition, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreatePullRequestLabel") + } + + var r0 *core.WebApiTagDefinition + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestLabelArgs) (*core.WebApiTagDefinition, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestLabelArgs) *core.WebApiTagDefinition); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*core.WebApiTagDefinition) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestLabelArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePullRequestReviewer provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePullRequestReviewer(_a0 context.Context, _a1 git.CreatePullRequestReviewerArgs) (*git.IdentityRefWithVote, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreatePullRequestReviewer") + } + + var r0 *git.IdentityRefWithVote + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestReviewerArgs) (*git.IdentityRefWithVote, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestReviewerArgs) *git.IdentityRefWithVote); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.IdentityRefWithVote) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestReviewerArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePullRequestReviewers provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePullRequestReviewers(_a0 context.Context, _a1 git.CreatePullRequestReviewersArgs) (*[]git.IdentityRefWithVote, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreatePullRequestReviewers") + } + + var r0 *[]git.IdentityRefWithVote + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestReviewersArgs) (*[]git.IdentityRefWithVote, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestReviewersArgs) *[]git.IdentityRefWithVote); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.IdentityRefWithVote) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestReviewersArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePullRequestStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePullRequestStatus(_a0 context.Context, _a1 git.CreatePullRequestStatusArgs) (*git.GitPullRequestStatus, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreatePullRequestStatus") + } + + var r0 *git.GitPullRequestStatus + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestStatusArgs) (*git.GitPullRequestStatus, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestStatusArgs) *git.GitPullRequestStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestStatus) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestStatusArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePush provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePush(_a0 context.Context, _a1 git.CreatePushArgs) (*git.GitPush, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreatePush") + } + + var r0 *git.GitPush + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePushArgs) (*git.GitPush, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePushArgs) *git.GitPush); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPush) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePushArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateRepository provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateRepository(_a0 context.Context, _a1 git.CreateRepositoryArgs) (*git.GitRepository, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateRepository") + } + + var r0 *git.GitRepository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateRepositoryArgs) (*git.GitRepository, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreateRepositoryArgs) *git.GitRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRepository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreateRepositoryArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateRevert provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateRevert(_a0 context.Context, _a1 git.CreateRevertArgs) (*git.GitRevert, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateRevert") + } + + var r0 *git.GitRevert + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateRevertArgs) (*git.GitRevert, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreateRevertArgs) *git.GitRevert); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRevert) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreateRevertArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateThread provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateThread(_a0 context.Context, _a1 git.CreateThreadArgs) (*git.GitPullRequestCommentThread, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CreateThread") + } + + var r0 *git.GitPullRequestCommentThread + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateThreadArgs) (*git.GitPullRequestCommentThread, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.CreateThreadArgs) *git.GitPullRequestCommentThread); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestCommentThread) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.CreateThreadArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteAttachment provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeleteAttachment(_a0 context.Context, _a1 git.DeleteAttachmentArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for DeleteAttachment") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeleteAttachmentArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteComment provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeleteComment(_a0 context.Context, _a1 git.DeleteCommentArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for DeleteComment") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeleteCommentArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteLike provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeleteLike(_a0 context.Context, _a1 git.DeleteLikeArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for DeleteLike") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeleteLikeArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeletePullRequestIterationStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeletePullRequestIterationStatus(_a0 context.Context, _a1 git.DeletePullRequestIterationStatusArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for DeletePullRequestIterationStatus") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeletePullRequestIterationStatusArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeletePullRequestLabels provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeletePullRequestLabels(_a0 context.Context, _a1 git.DeletePullRequestLabelsArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for DeletePullRequestLabels") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeletePullRequestLabelsArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeletePullRequestReviewer provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeletePullRequestReviewer(_a0 context.Context, _a1 git.DeletePullRequestReviewerArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for DeletePullRequestReviewer") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeletePullRequestReviewerArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeletePullRequestStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeletePullRequestStatus(_a0 context.Context, _a1 git.DeletePullRequestStatusArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for DeletePullRequestStatus") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeletePullRequestStatusArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteRefFavorite provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeleteRefFavorite(_a0 context.Context, _a1 git.DeleteRefFavoriteArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for DeleteRefFavorite") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeleteRefFavoriteArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteRepository provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeleteRepository(_a0 context.Context, _a1 git.DeleteRepositoryArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for DeleteRepository") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeleteRepositoryArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteRepositoryFromRecycleBin provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeleteRepositoryFromRecycleBin(_a0 context.Context, _a1 git.DeleteRepositoryFromRecycleBinArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for DeleteRepositoryFromRecycleBin") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeleteRepositoryFromRecycleBinArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GetAnnotatedTag provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetAnnotatedTag(_a0 context.Context, _a1 git.GetAnnotatedTagArgs) (*git.GitAnnotatedTag, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetAnnotatedTag") + } + + var r0 *git.GitAnnotatedTag + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetAnnotatedTagArgs) (*git.GitAnnotatedTag, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetAnnotatedTagArgs) *git.GitAnnotatedTag); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitAnnotatedTag) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetAnnotatedTagArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAttachmentContent provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetAttachmentContent(_a0 context.Context, _a1 git.GetAttachmentContentArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetAttachmentContent") + } + + var r0 io.ReadCloser + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetAttachmentContentArgs) (io.ReadCloser, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetAttachmentContentArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetAttachmentContentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAttachmentZip provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetAttachmentZip(_a0 context.Context, _a1 git.GetAttachmentZipArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetAttachmentZip") + } + + var r0 io.ReadCloser + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetAttachmentZipArgs) (io.ReadCloser, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetAttachmentZipArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetAttachmentZipArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAttachments provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetAttachments(_a0 context.Context, _a1 git.GetAttachmentsArgs) (*[]git.Attachment, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetAttachments") + } + + var r0 *[]git.Attachment + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetAttachmentsArgs) (*[]git.Attachment, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetAttachmentsArgs) *[]git.Attachment); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.Attachment) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetAttachmentsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBlob provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetBlob(_a0 context.Context, _a1 git.GetBlobArgs) (*git.GitBlobRef, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetBlob") + } + + var r0 *git.GitBlobRef + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetBlobArgs) (*git.GitBlobRef, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetBlobArgs) *git.GitBlobRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitBlobRef) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetBlobArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBlobContent provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetBlobContent(_a0 context.Context, _a1 git.GetBlobContentArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetBlobContent") + } + + var r0 io.ReadCloser + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetBlobContentArgs) (io.ReadCloser, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetBlobContentArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetBlobContentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBlobZip provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetBlobZip(_a0 context.Context, _a1 git.GetBlobZipArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetBlobZip") + } + + var r0 io.ReadCloser + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetBlobZipArgs) (io.ReadCloser, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetBlobZipArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetBlobZipArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBlobsZip provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetBlobsZip(_a0 context.Context, _a1 git.GetBlobsZipArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetBlobsZip") + } + + var r0 io.ReadCloser + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetBlobsZipArgs) (io.ReadCloser, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetBlobsZipArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetBlobsZipArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBranch provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetBranch(_a0 context.Context, _a1 git.GetBranchArgs) (*git.GitBranchStats, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetBranch") + } + + var r0 *git.GitBranchStats + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetBranchArgs) (*git.GitBranchStats, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetBranchArgs) *git.GitBranchStats); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitBranchStats) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetBranchArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBranches provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetBranches(_a0 context.Context, _a1 git.GetBranchesArgs) (*[]git.GitBranchStats, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetBranches") + } + + var r0 *[]git.GitBranchStats + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetBranchesArgs) (*[]git.GitBranchStats, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetBranchesArgs) *[]git.GitBranchStats); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitBranchStats) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetBranchesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetChanges provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetChanges(_a0 context.Context, _a1 git.GetChangesArgs) (*git.GitCommitChanges, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetChanges") + } + + var r0 *git.GitCommitChanges + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetChangesArgs) (*git.GitCommitChanges, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetChangesArgs) *git.GitCommitChanges); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitCommitChanges) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetChangesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCherryPick provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetCherryPick(_a0 context.Context, _a1 git.GetCherryPickArgs) (*git.GitCherryPick, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetCherryPick") + } + + var r0 *git.GitCherryPick + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetCherryPickArgs) (*git.GitCherryPick, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetCherryPickArgs) *git.GitCherryPick); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitCherryPick) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetCherryPickArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCherryPickForRefName provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetCherryPickForRefName(_a0 context.Context, _a1 git.GetCherryPickForRefNameArgs) (*git.GitCherryPick, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetCherryPickForRefName") + } + + var r0 *git.GitCherryPick + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetCherryPickForRefNameArgs) (*git.GitCherryPick, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetCherryPickForRefNameArgs) *git.GitCherryPick); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitCherryPick) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetCherryPickForRefNameArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetComment provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetComment(_a0 context.Context, _a1 git.GetCommentArgs) (*git.Comment, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetComment") + } + + var r0 *git.Comment + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommentArgs) (*git.Comment, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommentArgs) *git.Comment); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.Comment) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetCommentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetComments provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetComments(_a0 context.Context, _a1 git.GetCommentsArgs) (*[]git.Comment, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetComments") + } + + var r0 *[]git.Comment + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommentsArgs) (*[]git.Comment, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommentsArgs) *[]git.Comment); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.Comment) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetCommentsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCommit provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetCommit(_a0 context.Context, _a1 git.GetCommitArgs) (*git.GitCommit, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetCommit") + } + + var r0 *git.GitCommit + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommitArgs) (*git.GitCommit, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommitArgs) *git.GitCommit); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitCommit) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetCommitArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCommitDiffs provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetCommitDiffs(_a0 context.Context, _a1 git.GetCommitDiffsArgs) (*git.GitCommitDiffs, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetCommitDiffs") + } + + var r0 *git.GitCommitDiffs + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommitDiffsArgs) (*git.GitCommitDiffs, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommitDiffsArgs) *git.GitCommitDiffs); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitCommitDiffs) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetCommitDiffsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCommits provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetCommits(_a0 context.Context, _a1 git.GetCommitsArgs) (*[]git.GitCommitRef, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetCommits") + } + + var r0 *[]git.GitCommitRef + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommitsArgs) (*[]git.GitCommitRef, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommitsArgs) *[]git.GitCommitRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitCommitRef) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetCommitsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCommitsBatch provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetCommitsBatch(_a0 context.Context, _a1 git.GetCommitsBatchArgs) (*[]git.GitCommitRef, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetCommitsBatch") + } + + var r0 *[]git.GitCommitRef + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommitsBatchArgs) (*[]git.GitCommitRef, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommitsBatchArgs) *[]git.GitCommitRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitCommitRef) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetCommitsBatchArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetDeletedRepositories provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetDeletedRepositories(_a0 context.Context, _a1 git.GetDeletedRepositoriesArgs) (*[]git.GitDeletedRepository, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetDeletedRepositories") + } + + var r0 *[]git.GitDeletedRepository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetDeletedRepositoriesArgs) (*[]git.GitDeletedRepository, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetDeletedRepositoriesArgs) *[]git.GitDeletedRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitDeletedRepository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetDeletedRepositoriesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetForkSyncRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetForkSyncRequest(_a0 context.Context, _a1 git.GetForkSyncRequestArgs) (*git.GitForkSyncRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetForkSyncRequest") + } + + var r0 *git.GitForkSyncRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetForkSyncRequestArgs) (*git.GitForkSyncRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetForkSyncRequestArgs) *git.GitForkSyncRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitForkSyncRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetForkSyncRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetForkSyncRequests provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetForkSyncRequests(_a0 context.Context, _a1 git.GetForkSyncRequestsArgs) (*[]git.GitForkSyncRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetForkSyncRequests") + } + + var r0 *[]git.GitForkSyncRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetForkSyncRequestsArgs) (*[]git.GitForkSyncRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetForkSyncRequestsArgs) *[]git.GitForkSyncRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitForkSyncRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetForkSyncRequestsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetForks provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetForks(_a0 context.Context, _a1 git.GetForksArgs) (*[]git.GitRepositoryRef, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetForks") + } + + var r0 *[]git.GitRepositoryRef + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetForksArgs) (*[]git.GitRepositoryRef, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetForksArgs) *[]git.GitRepositoryRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitRepositoryRef) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetForksArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetImportRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetImportRequest(_a0 context.Context, _a1 git.GetImportRequestArgs) (*git.GitImportRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetImportRequest") + } + + var r0 *git.GitImportRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetImportRequestArgs) (*git.GitImportRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetImportRequestArgs) *git.GitImportRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitImportRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetImportRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetItem provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetItem(_a0 context.Context, _a1 git.GetItemArgs) (*git.GitItem, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetItem") + } + + var r0 *git.GitItem + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemArgs) (*git.GitItem, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemArgs) *git.GitItem); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitItem) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetItemArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetItemContent provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetItemContent(_a0 context.Context, _a1 git.GetItemContentArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetItemContent") + } + + var r0 io.ReadCloser + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemContentArgs) (io.ReadCloser, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemContentArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetItemContentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetItemText provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetItemText(_a0 context.Context, _a1 git.GetItemTextArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetItemText") + } + + var r0 io.ReadCloser + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemTextArgs) (io.ReadCloser, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemTextArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetItemTextArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetItemZip provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetItemZip(_a0 context.Context, _a1 git.GetItemZipArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetItemZip") + } + + var r0 io.ReadCloser + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemZipArgs) (io.ReadCloser, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemZipArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetItemZipArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetItems provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetItems(_a0 context.Context, _a1 git.GetItemsArgs) (*[]git.GitItem, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetItems") + } + + var r0 *[]git.GitItem + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemsArgs) (*[]git.GitItem, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemsArgs) *[]git.GitItem); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitItem) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetItemsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetItemsBatch provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetItemsBatch(_a0 context.Context, _a1 git.GetItemsBatchArgs) (*[][]git.GitItem, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetItemsBatch") + } + + var r0 *[][]git.GitItem + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemsBatchArgs) (*[][]git.GitItem, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemsBatchArgs) *[][]git.GitItem); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[][]git.GitItem) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetItemsBatchArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetLikes provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetLikes(_a0 context.Context, _a1 git.GetLikesArgs) (*[]webapi.IdentityRef, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetLikes") + } + + var r0 *[]webapi.IdentityRef + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetLikesArgs) (*[]webapi.IdentityRef, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetLikesArgs) *[]webapi.IdentityRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]webapi.IdentityRef) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetLikesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetMergeBases provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetMergeBases(_a0 context.Context, _a1 git.GetMergeBasesArgs) (*[]git.GitCommitRef, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetMergeBases") + } + + var r0 *[]git.GitCommitRef + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetMergeBasesArgs) (*[]git.GitCommitRef, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetMergeBasesArgs) *[]git.GitCommitRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitCommitRef) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetMergeBasesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetMergeRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetMergeRequest(_a0 context.Context, _a1 git.GetMergeRequestArgs) (*git.GitMerge, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetMergeRequest") + } + + var r0 *git.GitMerge + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetMergeRequestArgs) (*git.GitMerge, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetMergeRequestArgs) *git.GitMerge); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitMerge) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetMergeRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPolicyConfigurations provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPolicyConfigurations(_a0 context.Context, _a1 git.GetPolicyConfigurationsArgs) (*git.GitPolicyConfigurationResponse, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPolicyConfigurations") + } + + var r0 *git.GitPolicyConfigurationResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPolicyConfigurationsArgs) (*git.GitPolicyConfigurationResponse, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPolicyConfigurationsArgs) *git.GitPolicyConfigurationResponse); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPolicyConfigurationResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPolicyConfigurationsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequest(_a0 context.Context, _a1 git.GetPullRequestArgs) (*git.GitPullRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequest") + } + + var r0 *git.GitPullRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestArgs) (*git.GitPullRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestArgs) *git.GitPullRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestById provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestById(_a0 context.Context, _a1 git.GetPullRequestByIdArgs) (*git.GitPullRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestById") + } + + var r0 *git.GitPullRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestByIdArgs) (*git.GitPullRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestByIdArgs) *git.GitPullRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestByIdArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestCommits provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestCommits(_a0 context.Context, _a1 git.GetPullRequestCommitsArgs) (*git.GetPullRequestCommitsResponseValue, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestCommits") + } + + var r0 *git.GetPullRequestCommitsResponseValue + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestCommitsArgs) (*git.GetPullRequestCommitsResponseValue, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestCommitsArgs) *git.GetPullRequestCommitsResponseValue); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GetPullRequestCommitsResponseValue) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestCommitsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestIteration provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestIteration(_a0 context.Context, _a1 git.GetPullRequestIterationArgs) (*git.GitPullRequestIteration, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestIteration") + } + + var r0 *git.GitPullRequestIteration + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationArgs) (*git.GitPullRequestIteration, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationArgs) *git.GitPullRequestIteration); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestIteration) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestIterationChanges provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestIterationChanges(_a0 context.Context, _a1 git.GetPullRequestIterationChangesArgs) (*git.GitPullRequestIterationChanges, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestIterationChanges") + } + + var r0 *git.GitPullRequestIterationChanges + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationChangesArgs) (*git.GitPullRequestIterationChanges, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationChangesArgs) *git.GitPullRequestIterationChanges); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestIterationChanges) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationChangesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestIterationCommits provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestIterationCommits(_a0 context.Context, _a1 git.GetPullRequestIterationCommitsArgs) (*[]git.GitCommitRef, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestIterationCommits") + } + + var r0 *[]git.GitCommitRef + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationCommitsArgs) (*[]git.GitCommitRef, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationCommitsArgs) *[]git.GitCommitRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitCommitRef) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationCommitsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestIterationStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestIterationStatus(_a0 context.Context, _a1 git.GetPullRequestIterationStatusArgs) (*git.GitPullRequestStatus, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestIterationStatus") + } + + var r0 *git.GitPullRequestStatus + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationStatusArgs) (*git.GitPullRequestStatus, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationStatusArgs) *git.GitPullRequestStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestStatus) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationStatusArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestIterationStatuses provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestIterationStatuses(_a0 context.Context, _a1 git.GetPullRequestIterationStatusesArgs) (*[]git.GitPullRequestStatus, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestIterationStatuses") + } + + var r0 *[]git.GitPullRequestStatus + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationStatusesArgs) (*[]git.GitPullRequestStatus, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationStatusesArgs) *[]git.GitPullRequestStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPullRequestStatus) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationStatusesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestIterations provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestIterations(_a0 context.Context, _a1 git.GetPullRequestIterationsArgs) (*[]git.GitPullRequestIteration, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestIterations") + } + + var r0 *[]git.GitPullRequestIteration + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationsArgs) (*[]git.GitPullRequestIteration, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationsArgs) *[]git.GitPullRequestIteration); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPullRequestIteration) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestLabel provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestLabel(_a0 context.Context, _a1 git.GetPullRequestLabelArgs) (*core.WebApiTagDefinition, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestLabel") + } + + var r0 *core.WebApiTagDefinition + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestLabelArgs) (*core.WebApiTagDefinition, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestLabelArgs) *core.WebApiTagDefinition); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*core.WebApiTagDefinition) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestLabelArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestLabels provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestLabels(_a0 context.Context, _a1 git.GetPullRequestLabelsArgs) (*[]core.WebApiTagDefinition, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestLabels") + } + + var r0 *[]core.WebApiTagDefinition + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestLabelsArgs) (*[]core.WebApiTagDefinition, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestLabelsArgs) *[]core.WebApiTagDefinition); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]core.WebApiTagDefinition) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestLabelsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestProperties provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestProperties(_a0 context.Context, _a1 git.GetPullRequestPropertiesArgs) (interface{}, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestProperties") + } + + var r0 interface{} + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestPropertiesArgs) (interface{}, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestPropertiesArgs) interface{}); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(interface{}) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestPropertiesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestQuery provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestQuery(_a0 context.Context, _a1 git.GetPullRequestQueryArgs) (*git.GitPullRequestQuery, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestQuery") + } + + var r0 *git.GitPullRequestQuery + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestQueryArgs) (*git.GitPullRequestQuery, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestQueryArgs) *git.GitPullRequestQuery); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestQuery) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestQueryArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestReviewer provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestReviewer(_a0 context.Context, _a1 git.GetPullRequestReviewerArgs) (*git.IdentityRefWithVote, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestReviewer") + } + + var r0 *git.IdentityRefWithVote + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestReviewerArgs) (*git.IdentityRefWithVote, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestReviewerArgs) *git.IdentityRefWithVote); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.IdentityRefWithVote) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestReviewerArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestReviewers provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestReviewers(_a0 context.Context, _a1 git.GetPullRequestReviewersArgs) (*[]git.IdentityRefWithVote, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestReviewers") + } + + var r0 *[]git.IdentityRefWithVote + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestReviewersArgs) (*[]git.IdentityRefWithVote, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestReviewersArgs) *[]git.IdentityRefWithVote); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.IdentityRefWithVote) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestReviewersArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestStatus(_a0 context.Context, _a1 git.GetPullRequestStatusArgs) (*git.GitPullRequestStatus, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestStatus") + } + + var r0 *git.GitPullRequestStatus + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestStatusArgs) (*git.GitPullRequestStatus, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestStatusArgs) *git.GitPullRequestStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestStatus) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestStatusArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestStatuses provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestStatuses(_a0 context.Context, _a1 git.GetPullRequestStatusesArgs) (*[]git.GitPullRequestStatus, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestStatuses") + } + + var r0 *[]git.GitPullRequestStatus + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestStatusesArgs) (*[]git.GitPullRequestStatus, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestStatusesArgs) *[]git.GitPullRequestStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPullRequestStatus) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestStatusesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestThread provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestThread(_a0 context.Context, _a1 git.GetPullRequestThreadArgs) (*git.GitPullRequestCommentThread, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestThread") + } + + var r0 *git.GitPullRequestCommentThread + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestThreadArgs) (*git.GitPullRequestCommentThread, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestThreadArgs) *git.GitPullRequestCommentThread); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestCommentThread) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestThreadArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestWorkItemRefs provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestWorkItemRefs(_a0 context.Context, _a1 git.GetPullRequestWorkItemRefsArgs) (*[]webapi.ResourceRef, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestWorkItemRefs") + } + + var r0 *[]webapi.ResourceRef + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestWorkItemRefsArgs) (*[]webapi.ResourceRef, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestWorkItemRefsArgs) *[]webapi.ResourceRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]webapi.ResourceRef) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestWorkItemRefsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequests provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequests(_a0 context.Context, _a1 git.GetPullRequestsArgs) (*[]git.GitPullRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequests") + } + + var r0 *[]git.GitPullRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestsArgs) (*[]git.GitPullRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestsArgs) *[]git.GitPullRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPullRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestsByProject provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestsByProject(_a0 context.Context, _a1 git.GetPullRequestsByProjectArgs) (*[]git.GitPullRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPullRequestsByProject") + } + + var r0 *[]git.GitPullRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestsByProjectArgs) (*[]git.GitPullRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestsByProjectArgs) *[]git.GitPullRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPullRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestsByProjectArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPush provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPush(_a0 context.Context, _a1 git.GetPushArgs) (*git.GitPush, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPush") + } + + var r0 *git.GitPush + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPushArgs) (*git.GitPush, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPushArgs) *git.GitPush); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPush) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPushArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPushCommits provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPushCommits(_a0 context.Context, _a1 git.GetPushCommitsArgs) (*[]git.GitCommitRef, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPushCommits") + } + + var r0 *[]git.GitCommitRef + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPushCommitsArgs) (*[]git.GitCommitRef, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPushCommitsArgs) *[]git.GitCommitRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitCommitRef) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPushCommitsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPushes provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPushes(_a0 context.Context, _a1 git.GetPushesArgs) (*[]git.GitPush, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetPushes") + } + + var r0 *[]git.GitPush + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetPushesArgs) (*[]git.GitPush, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetPushesArgs) *[]git.GitPush); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPush) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetPushesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRecycleBinRepositories provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRecycleBinRepositories(_a0 context.Context, _a1 git.GetRecycleBinRepositoriesArgs) (*[]git.GitDeletedRepository, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetRecycleBinRepositories") + } + + var r0 *[]git.GitDeletedRepository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetRecycleBinRepositoriesArgs) (*[]git.GitDeletedRepository, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetRecycleBinRepositoriesArgs) *[]git.GitDeletedRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitDeletedRepository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetRecycleBinRepositoriesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRefFavorite provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRefFavorite(_a0 context.Context, _a1 git.GetRefFavoriteArgs) (*git.GitRefFavorite, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetRefFavorite") + } + + var r0 *git.GitRefFavorite + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetRefFavoriteArgs) (*git.GitRefFavorite, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetRefFavoriteArgs) *git.GitRefFavorite); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRefFavorite) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetRefFavoriteArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRefFavorites provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRefFavorites(_a0 context.Context, _a1 git.GetRefFavoritesArgs) (*[]git.GitRefFavorite, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetRefFavorites") + } + + var r0 *[]git.GitRefFavorite + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetRefFavoritesArgs) (*[]git.GitRefFavorite, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetRefFavoritesArgs) *[]git.GitRefFavorite); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitRefFavorite) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetRefFavoritesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRefs provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRefs(_a0 context.Context, _a1 git.GetRefsArgs) (*git.GetRefsResponseValue, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetRefs") + } + + var r0 *git.GetRefsResponseValue + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetRefsArgs) (*git.GetRefsResponseValue, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetRefsArgs) *git.GetRefsResponseValue); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GetRefsResponseValue) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetRefsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRepositories provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRepositories(_a0 context.Context, _a1 git.GetRepositoriesArgs) (*[]git.GitRepository, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetRepositories") + } + + var r0 *[]git.GitRepository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetRepositoriesArgs) (*[]git.GitRepository, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetRepositoriesArgs) *[]git.GitRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitRepository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetRepositoriesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRepository provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRepository(_a0 context.Context, _a1 git.GetRepositoryArgs) (*git.GitRepository, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetRepository") + } + + var r0 *git.GitRepository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetRepositoryArgs) (*git.GitRepository, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetRepositoryArgs) *git.GitRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRepository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetRepositoryArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRepositoryWithParent provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRepositoryWithParent(_a0 context.Context, _a1 git.GetRepositoryWithParentArgs) (*git.GitRepository, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetRepositoryWithParent") + } + + var r0 *git.GitRepository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetRepositoryWithParentArgs) (*git.GitRepository, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetRepositoryWithParentArgs) *git.GitRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRepository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetRepositoryWithParentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRevert provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRevert(_a0 context.Context, _a1 git.GetRevertArgs) (*git.GitRevert, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetRevert") + } + + var r0 *git.GitRevert + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetRevertArgs) (*git.GitRevert, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetRevertArgs) *git.GitRevert); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRevert) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetRevertArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRevertForRefName provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRevertForRefName(_a0 context.Context, _a1 git.GetRevertForRefNameArgs) (*git.GitRevert, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetRevertForRefName") + } + + var r0 *git.GitRevert + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetRevertForRefNameArgs) (*git.GitRevert, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetRevertForRefNameArgs) *git.GitRevert); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRevert) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetRevertForRefNameArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetStatuses provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetStatuses(_a0 context.Context, _a1 git.GetStatusesArgs) (*[]git.GitStatus, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetStatuses") + } + + var r0 *[]git.GitStatus + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetStatusesArgs) (*[]git.GitStatus, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetStatusesArgs) *[]git.GitStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitStatus) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetStatusesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetSuggestions provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetSuggestions(_a0 context.Context, _a1 git.GetSuggestionsArgs) (*[]git.GitSuggestion, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetSuggestions") + } + + var r0 *[]git.GitSuggestion + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetSuggestionsArgs) (*[]git.GitSuggestion, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetSuggestionsArgs) *[]git.GitSuggestion); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitSuggestion) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetSuggestionsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetThreads provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetThreads(_a0 context.Context, _a1 git.GetThreadsArgs) (*[]git.GitPullRequestCommentThread, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetThreads") + } + + var r0 *[]git.GitPullRequestCommentThread + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetThreadsArgs) (*[]git.GitPullRequestCommentThread, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetThreadsArgs) *[]git.GitPullRequestCommentThread); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPullRequestCommentThread) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetThreadsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetTree provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetTree(_a0 context.Context, _a1 git.GetTreeArgs) (*git.GitTreeRef, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetTree") + } + + var r0 *git.GitTreeRef + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetTreeArgs) (*git.GitTreeRef, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetTreeArgs) *git.GitTreeRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitTreeRef) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetTreeArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetTreeZip provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetTreeZip(_a0 context.Context, _a1 git.GetTreeZipArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetTreeZip") + } + + var r0 io.ReadCloser + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.GetTreeZipArgs) (io.ReadCloser, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.GetTreeZipArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.GetTreeZipArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// QueryImportRequests provides a mock function with given fields: _a0, _a1 +func (_m *Client) QueryImportRequests(_a0 context.Context, _a1 git.QueryImportRequestsArgs) (*[]git.GitImportRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for QueryImportRequests") + } + + var r0 *[]git.GitImportRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.QueryImportRequestsArgs) (*[]git.GitImportRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.QueryImportRequestsArgs) *[]git.GitImportRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitImportRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.QueryImportRequestsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RestoreRepositoryFromRecycleBin provides a mock function with given fields: _a0, _a1 +func (_m *Client) RestoreRepositoryFromRecycleBin(_a0 context.Context, _a1 git.RestoreRepositoryFromRecycleBinArgs) (*git.GitRepository, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for RestoreRepositoryFromRecycleBin") + } + + var r0 *git.GitRepository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.RestoreRepositoryFromRecycleBinArgs) (*git.GitRepository, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.RestoreRepositoryFromRecycleBinArgs) *git.GitRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRepository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.RestoreRepositoryFromRecycleBinArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SharePullRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) SharePullRequest(_a0 context.Context, _a1 git.SharePullRequestArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for SharePullRequest") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.SharePullRequestArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// UpdateComment provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdateComment(_a0 context.Context, _a1 git.UpdateCommentArgs) (*git.Comment, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for UpdateComment") + } + + var r0 *git.Comment + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateCommentArgs) (*git.Comment, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateCommentArgs) *git.Comment); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.Comment) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.UpdateCommentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateImportRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdateImportRequest(_a0 context.Context, _a1 git.UpdateImportRequestArgs) (*git.GitImportRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for UpdateImportRequest") + } + + var r0 *git.GitImportRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateImportRequestArgs) (*git.GitImportRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateImportRequestArgs) *git.GitImportRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitImportRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.UpdateImportRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdatePullRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdatePullRequest(_a0 context.Context, _a1 git.UpdatePullRequestArgs) (*git.GitPullRequest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for UpdatePullRequest") + } + + var r0 *git.GitPullRequest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestArgs) (*git.GitPullRequest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestArgs) *git.GitPullRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.UpdatePullRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdatePullRequestIterationStatuses provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdatePullRequestIterationStatuses(_a0 context.Context, _a1 git.UpdatePullRequestIterationStatusesArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for UpdatePullRequestIterationStatuses") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestIterationStatusesArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// UpdatePullRequestProperties provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdatePullRequestProperties(_a0 context.Context, _a1 git.UpdatePullRequestPropertiesArgs) (interface{}, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for UpdatePullRequestProperties") + } + + var r0 interface{} + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestPropertiesArgs) (interface{}, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestPropertiesArgs) interface{}); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(interface{}) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.UpdatePullRequestPropertiesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdatePullRequestReviewers provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdatePullRequestReviewers(_a0 context.Context, _a1 git.UpdatePullRequestReviewersArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for UpdatePullRequestReviewers") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestReviewersArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// UpdatePullRequestStatuses provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdatePullRequestStatuses(_a0 context.Context, _a1 git.UpdatePullRequestStatusesArgs) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for UpdatePullRequestStatuses") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestStatusesArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// UpdateRef provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdateRef(_a0 context.Context, _a1 git.UpdateRefArgs) (*git.GitRef, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for UpdateRef") + } + + var r0 *git.GitRef + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateRefArgs) (*git.GitRef, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateRefArgs) *git.GitRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRef) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.UpdateRefArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateRefs provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdateRefs(_a0 context.Context, _a1 git.UpdateRefsArgs) (*[]git.GitRefUpdateResult, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for UpdateRefs") + } + + var r0 *[]git.GitRefUpdateResult + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateRefsArgs) (*[]git.GitRefUpdateResult, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateRefsArgs) *[]git.GitRefUpdateResult); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitRefUpdateResult) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.UpdateRefsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateRepository provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdateRepository(_a0 context.Context, _a1 git.UpdateRepositoryArgs) (*git.GitRepository, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for UpdateRepository") + } + + var r0 *git.GitRepository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateRepositoryArgs) (*git.GitRepository, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateRepositoryArgs) *git.GitRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRepository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.UpdateRepositoryArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateThread provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdateThread(_a0 context.Context, _a1 git.UpdateThreadArgs) (*git.GitPullRequestCommentThread, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for UpdateThread") + } + + var r0 *git.GitPullRequestCommentThread + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateThreadArgs) (*git.GitPullRequestCommentThread, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateThreadArgs) *git.GitPullRequestCommentThread); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestCommentThread) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, git.UpdateThreadArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewClient(t interface { @@ -27,6634 +3333,3 @@ func NewClient(t interface { return mock } - -// Client is an autogenerated mock type for the Client type -type Client struct { - mock.Mock -} - -type Client_Expecter struct { - mock *mock.Mock -} - -func (_m *Client) EXPECT() *Client_Expecter { - return &Client_Expecter{mock: &_m.Mock} -} - -// CreateAnnotatedTag provides a mock function for the type Client -func (_mock *Client) CreateAnnotatedTag(context1 context.Context, createAnnotatedTagArgs git.CreateAnnotatedTagArgs) (*git.GitAnnotatedTag, error) { - ret := _mock.Called(context1, createAnnotatedTagArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateAnnotatedTag") - } - - var r0 *git.GitAnnotatedTag - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateAnnotatedTagArgs) (*git.GitAnnotatedTag, error)); ok { - return returnFunc(context1, createAnnotatedTagArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateAnnotatedTagArgs) *git.GitAnnotatedTag); ok { - r0 = returnFunc(context1, createAnnotatedTagArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitAnnotatedTag) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateAnnotatedTagArgs) error); ok { - r1 = returnFunc(context1, createAnnotatedTagArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateAnnotatedTag_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateAnnotatedTag' -type Client_CreateAnnotatedTag_Call struct { - *mock.Call -} - -// CreateAnnotatedTag is a helper method to define mock.On call -// - context1 -// - createAnnotatedTagArgs -func (_e *Client_Expecter) CreateAnnotatedTag(context1 interface{}, createAnnotatedTagArgs interface{}) *Client_CreateAnnotatedTag_Call { - return &Client_CreateAnnotatedTag_Call{Call: _e.mock.On("CreateAnnotatedTag", context1, createAnnotatedTagArgs)} -} - -func (_c *Client_CreateAnnotatedTag_Call) Run(run func(context1 context.Context, createAnnotatedTagArgs git.CreateAnnotatedTagArgs)) *Client_CreateAnnotatedTag_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateAnnotatedTagArgs)) - }) - return _c -} - -func (_c *Client_CreateAnnotatedTag_Call) Return(gitAnnotatedTag *git.GitAnnotatedTag, err error) *Client_CreateAnnotatedTag_Call { - _c.Call.Return(gitAnnotatedTag, err) - return _c -} - -func (_c *Client_CreateAnnotatedTag_Call) RunAndReturn(run func(context1 context.Context, createAnnotatedTagArgs git.CreateAnnotatedTagArgs) (*git.GitAnnotatedTag, error)) *Client_CreateAnnotatedTag_Call { - _c.Call.Return(run) - return _c -} - -// CreateAttachment provides a mock function for the type Client -func (_mock *Client) CreateAttachment(context1 context.Context, createAttachmentArgs git.CreateAttachmentArgs) (*git.Attachment, error) { - ret := _mock.Called(context1, createAttachmentArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateAttachment") - } - - var r0 *git.Attachment - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateAttachmentArgs) (*git.Attachment, error)); ok { - return returnFunc(context1, createAttachmentArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateAttachmentArgs) *git.Attachment); ok { - r0 = returnFunc(context1, createAttachmentArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.Attachment) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateAttachmentArgs) error); ok { - r1 = returnFunc(context1, createAttachmentArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateAttachment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateAttachment' -type Client_CreateAttachment_Call struct { - *mock.Call -} - -// CreateAttachment is a helper method to define mock.On call -// - context1 -// - createAttachmentArgs -func (_e *Client_Expecter) CreateAttachment(context1 interface{}, createAttachmentArgs interface{}) *Client_CreateAttachment_Call { - return &Client_CreateAttachment_Call{Call: _e.mock.On("CreateAttachment", context1, createAttachmentArgs)} -} - -func (_c *Client_CreateAttachment_Call) Run(run func(context1 context.Context, createAttachmentArgs git.CreateAttachmentArgs)) *Client_CreateAttachment_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateAttachmentArgs)) - }) - return _c -} - -func (_c *Client_CreateAttachment_Call) Return(attachment *git.Attachment, err error) *Client_CreateAttachment_Call { - _c.Call.Return(attachment, err) - return _c -} - -func (_c *Client_CreateAttachment_Call) RunAndReturn(run func(context1 context.Context, createAttachmentArgs git.CreateAttachmentArgs) (*git.Attachment, error)) *Client_CreateAttachment_Call { - _c.Call.Return(run) - return _c -} - -// CreateCherryPick provides a mock function for the type Client -func (_mock *Client) CreateCherryPick(context1 context.Context, createCherryPickArgs git.CreateCherryPickArgs) (*git.GitCherryPick, error) { - ret := _mock.Called(context1, createCherryPickArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateCherryPick") - } - - var r0 *git.GitCherryPick - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateCherryPickArgs) (*git.GitCherryPick, error)); ok { - return returnFunc(context1, createCherryPickArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateCherryPickArgs) *git.GitCherryPick); ok { - r0 = returnFunc(context1, createCherryPickArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitCherryPick) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateCherryPickArgs) error); ok { - r1 = returnFunc(context1, createCherryPickArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateCherryPick_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateCherryPick' -type Client_CreateCherryPick_Call struct { - *mock.Call -} - -// CreateCherryPick is a helper method to define mock.On call -// - context1 -// - createCherryPickArgs -func (_e *Client_Expecter) CreateCherryPick(context1 interface{}, createCherryPickArgs interface{}) *Client_CreateCherryPick_Call { - return &Client_CreateCherryPick_Call{Call: _e.mock.On("CreateCherryPick", context1, createCherryPickArgs)} -} - -func (_c *Client_CreateCherryPick_Call) Run(run func(context1 context.Context, createCherryPickArgs git.CreateCherryPickArgs)) *Client_CreateCherryPick_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateCherryPickArgs)) - }) - return _c -} - -func (_c *Client_CreateCherryPick_Call) Return(gitCherryPick *git.GitCherryPick, err error) *Client_CreateCherryPick_Call { - _c.Call.Return(gitCherryPick, err) - return _c -} - -func (_c *Client_CreateCherryPick_Call) RunAndReturn(run func(context1 context.Context, createCherryPickArgs git.CreateCherryPickArgs) (*git.GitCherryPick, error)) *Client_CreateCherryPick_Call { - _c.Call.Return(run) - return _c -} - -// CreateComment provides a mock function for the type Client -func (_mock *Client) CreateComment(context1 context.Context, createCommentArgs git.CreateCommentArgs) (*git.Comment, error) { - ret := _mock.Called(context1, createCommentArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateComment") - } - - var r0 *git.Comment - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateCommentArgs) (*git.Comment, error)); ok { - return returnFunc(context1, createCommentArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateCommentArgs) *git.Comment); ok { - r0 = returnFunc(context1, createCommentArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.Comment) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateCommentArgs) error); ok { - r1 = returnFunc(context1, createCommentArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateComment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateComment' -type Client_CreateComment_Call struct { - *mock.Call -} - -// CreateComment is a helper method to define mock.On call -// - context1 -// - createCommentArgs -func (_e *Client_Expecter) CreateComment(context1 interface{}, createCommentArgs interface{}) *Client_CreateComment_Call { - return &Client_CreateComment_Call{Call: _e.mock.On("CreateComment", context1, createCommentArgs)} -} - -func (_c *Client_CreateComment_Call) Run(run func(context1 context.Context, createCommentArgs git.CreateCommentArgs)) *Client_CreateComment_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateCommentArgs)) - }) - return _c -} - -func (_c *Client_CreateComment_Call) Return(comment *git.Comment, err error) *Client_CreateComment_Call { - _c.Call.Return(comment, err) - return _c -} - -func (_c *Client_CreateComment_Call) RunAndReturn(run func(context1 context.Context, createCommentArgs git.CreateCommentArgs) (*git.Comment, error)) *Client_CreateComment_Call { - _c.Call.Return(run) - return _c -} - -// CreateCommitStatus provides a mock function for the type Client -func (_mock *Client) CreateCommitStatus(context1 context.Context, createCommitStatusArgs git.CreateCommitStatusArgs) (*git.GitStatus, error) { - ret := _mock.Called(context1, createCommitStatusArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateCommitStatus") - } - - var r0 *git.GitStatus - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateCommitStatusArgs) (*git.GitStatus, error)); ok { - return returnFunc(context1, createCommitStatusArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateCommitStatusArgs) *git.GitStatus); ok { - r0 = returnFunc(context1, createCommitStatusArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitStatus) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateCommitStatusArgs) error); ok { - r1 = returnFunc(context1, createCommitStatusArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateCommitStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateCommitStatus' -type Client_CreateCommitStatus_Call struct { - *mock.Call -} - -// CreateCommitStatus is a helper method to define mock.On call -// - context1 -// - createCommitStatusArgs -func (_e *Client_Expecter) CreateCommitStatus(context1 interface{}, createCommitStatusArgs interface{}) *Client_CreateCommitStatus_Call { - return &Client_CreateCommitStatus_Call{Call: _e.mock.On("CreateCommitStatus", context1, createCommitStatusArgs)} -} - -func (_c *Client_CreateCommitStatus_Call) Run(run func(context1 context.Context, createCommitStatusArgs git.CreateCommitStatusArgs)) *Client_CreateCommitStatus_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateCommitStatusArgs)) - }) - return _c -} - -func (_c *Client_CreateCommitStatus_Call) Return(gitStatus *git.GitStatus, err error) *Client_CreateCommitStatus_Call { - _c.Call.Return(gitStatus, err) - return _c -} - -func (_c *Client_CreateCommitStatus_Call) RunAndReturn(run func(context1 context.Context, createCommitStatusArgs git.CreateCommitStatusArgs) (*git.GitStatus, error)) *Client_CreateCommitStatus_Call { - _c.Call.Return(run) - return _c -} - -// CreateFavorite provides a mock function for the type Client -func (_mock *Client) CreateFavorite(context1 context.Context, createFavoriteArgs git.CreateFavoriteArgs) (*git.GitRefFavorite, error) { - ret := _mock.Called(context1, createFavoriteArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateFavorite") - } - - var r0 *git.GitRefFavorite - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateFavoriteArgs) (*git.GitRefFavorite, error)); ok { - return returnFunc(context1, createFavoriteArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateFavoriteArgs) *git.GitRefFavorite); ok { - r0 = returnFunc(context1, createFavoriteArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitRefFavorite) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateFavoriteArgs) error); ok { - r1 = returnFunc(context1, createFavoriteArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateFavorite_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateFavorite' -type Client_CreateFavorite_Call struct { - *mock.Call -} - -// CreateFavorite is a helper method to define mock.On call -// - context1 -// - createFavoriteArgs -func (_e *Client_Expecter) CreateFavorite(context1 interface{}, createFavoriteArgs interface{}) *Client_CreateFavorite_Call { - return &Client_CreateFavorite_Call{Call: _e.mock.On("CreateFavorite", context1, createFavoriteArgs)} -} - -func (_c *Client_CreateFavorite_Call) Run(run func(context1 context.Context, createFavoriteArgs git.CreateFavoriteArgs)) *Client_CreateFavorite_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateFavoriteArgs)) - }) - return _c -} - -func (_c *Client_CreateFavorite_Call) Return(gitRefFavorite *git.GitRefFavorite, err error) *Client_CreateFavorite_Call { - _c.Call.Return(gitRefFavorite, err) - return _c -} - -func (_c *Client_CreateFavorite_Call) RunAndReturn(run func(context1 context.Context, createFavoriteArgs git.CreateFavoriteArgs) (*git.GitRefFavorite, error)) *Client_CreateFavorite_Call { - _c.Call.Return(run) - return _c -} - -// CreateForkSyncRequest provides a mock function for the type Client -func (_mock *Client) CreateForkSyncRequest(context1 context.Context, createForkSyncRequestArgs git.CreateForkSyncRequestArgs) (*git.GitForkSyncRequest, error) { - ret := _mock.Called(context1, createForkSyncRequestArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateForkSyncRequest") - } - - var r0 *git.GitForkSyncRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateForkSyncRequestArgs) (*git.GitForkSyncRequest, error)); ok { - return returnFunc(context1, createForkSyncRequestArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateForkSyncRequestArgs) *git.GitForkSyncRequest); ok { - r0 = returnFunc(context1, createForkSyncRequestArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitForkSyncRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateForkSyncRequestArgs) error); ok { - r1 = returnFunc(context1, createForkSyncRequestArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateForkSyncRequest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateForkSyncRequest' -type Client_CreateForkSyncRequest_Call struct { - *mock.Call -} - -// CreateForkSyncRequest is a helper method to define mock.On call -// - context1 -// - createForkSyncRequestArgs -func (_e *Client_Expecter) CreateForkSyncRequest(context1 interface{}, createForkSyncRequestArgs interface{}) *Client_CreateForkSyncRequest_Call { - return &Client_CreateForkSyncRequest_Call{Call: _e.mock.On("CreateForkSyncRequest", context1, createForkSyncRequestArgs)} -} - -func (_c *Client_CreateForkSyncRequest_Call) Run(run func(context1 context.Context, createForkSyncRequestArgs git.CreateForkSyncRequestArgs)) *Client_CreateForkSyncRequest_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateForkSyncRequestArgs)) - }) - return _c -} - -func (_c *Client_CreateForkSyncRequest_Call) Return(gitForkSyncRequest *git.GitForkSyncRequest, err error) *Client_CreateForkSyncRequest_Call { - _c.Call.Return(gitForkSyncRequest, err) - return _c -} - -func (_c *Client_CreateForkSyncRequest_Call) RunAndReturn(run func(context1 context.Context, createForkSyncRequestArgs git.CreateForkSyncRequestArgs) (*git.GitForkSyncRequest, error)) *Client_CreateForkSyncRequest_Call { - _c.Call.Return(run) - return _c -} - -// CreateImportRequest provides a mock function for the type Client -func (_mock *Client) CreateImportRequest(context1 context.Context, createImportRequestArgs git.CreateImportRequestArgs) (*git.GitImportRequest, error) { - ret := _mock.Called(context1, createImportRequestArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateImportRequest") - } - - var r0 *git.GitImportRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateImportRequestArgs) (*git.GitImportRequest, error)); ok { - return returnFunc(context1, createImportRequestArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateImportRequestArgs) *git.GitImportRequest); ok { - r0 = returnFunc(context1, createImportRequestArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitImportRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateImportRequestArgs) error); ok { - r1 = returnFunc(context1, createImportRequestArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateImportRequest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateImportRequest' -type Client_CreateImportRequest_Call struct { - *mock.Call -} - -// CreateImportRequest is a helper method to define mock.On call -// - context1 -// - createImportRequestArgs -func (_e *Client_Expecter) CreateImportRequest(context1 interface{}, createImportRequestArgs interface{}) *Client_CreateImportRequest_Call { - return &Client_CreateImportRequest_Call{Call: _e.mock.On("CreateImportRequest", context1, createImportRequestArgs)} -} - -func (_c *Client_CreateImportRequest_Call) Run(run func(context1 context.Context, createImportRequestArgs git.CreateImportRequestArgs)) *Client_CreateImportRequest_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateImportRequestArgs)) - }) - return _c -} - -func (_c *Client_CreateImportRequest_Call) Return(gitImportRequest *git.GitImportRequest, err error) *Client_CreateImportRequest_Call { - _c.Call.Return(gitImportRequest, err) - return _c -} - -func (_c *Client_CreateImportRequest_Call) RunAndReturn(run func(context1 context.Context, createImportRequestArgs git.CreateImportRequestArgs) (*git.GitImportRequest, error)) *Client_CreateImportRequest_Call { - _c.Call.Return(run) - return _c -} - -// CreateLike provides a mock function for the type Client -func (_mock *Client) CreateLike(context1 context.Context, createLikeArgs git.CreateLikeArgs) error { - ret := _mock.Called(context1, createLikeArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateLike") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateLikeArgs) error); ok { - r0 = returnFunc(context1, createLikeArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_CreateLike_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateLike' -type Client_CreateLike_Call struct { - *mock.Call -} - -// CreateLike is a helper method to define mock.On call -// - context1 -// - createLikeArgs -func (_e *Client_Expecter) CreateLike(context1 interface{}, createLikeArgs interface{}) *Client_CreateLike_Call { - return &Client_CreateLike_Call{Call: _e.mock.On("CreateLike", context1, createLikeArgs)} -} - -func (_c *Client_CreateLike_Call) Run(run func(context1 context.Context, createLikeArgs git.CreateLikeArgs)) *Client_CreateLike_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateLikeArgs)) - }) - return _c -} - -func (_c *Client_CreateLike_Call) Return(err error) *Client_CreateLike_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_CreateLike_Call) RunAndReturn(run func(context1 context.Context, createLikeArgs git.CreateLikeArgs) error) *Client_CreateLike_Call { - _c.Call.Return(run) - return _c -} - -// CreateMergeRequest provides a mock function for the type Client -func (_mock *Client) CreateMergeRequest(context1 context.Context, createMergeRequestArgs git.CreateMergeRequestArgs) (*git.GitMerge, error) { - ret := _mock.Called(context1, createMergeRequestArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateMergeRequest") - } - - var r0 *git.GitMerge - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateMergeRequestArgs) (*git.GitMerge, error)); ok { - return returnFunc(context1, createMergeRequestArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateMergeRequestArgs) *git.GitMerge); ok { - r0 = returnFunc(context1, createMergeRequestArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitMerge) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateMergeRequestArgs) error); ok { - r1 = returnFunc(context1, createMergeRequestArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateMergeRequest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateMergeRequest' -type Client_CreateMergeRequest_Call struct { - *mock.Call -} - -// CreateMergeRequest is a helper method to define mock.On call -// - context1 -// - createMergeRequestArgs -func (_e *Client_Expecter) CreateMergeRequest(context1 interface{}, createMergeRequestArgs interface{}) *Client_CreateMergeRequest_Call { - return &Client_CreateMergeRequest_Call{Call: _e.mock.On("CreateMergeRequest", context1, createMergeRequestArgs)} -} - -func (_c *Client_CreateMergeRequest_Call) Run(run func(context1 context.Context, createMergeRequestArgs git.CreateMergeRequestArgs)) *Client_CreateMergeRequest_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateMergeRequestArgs)) - }) - return _c -} - -func (_c *Client_CreateMergeRequest_Call) Return(gitMerge *git.GitMerge, err error) *Client_CreateMergeRequest_Call { - _c.Call.Return(gitMerge, err) - return _c -} - -func (_c *Client_CreateMergeRequest_Call) RunAndReturn(run func(context1 context.Context, createMergeRequestArgs git.CreateMergeRequestArgs) (*git.GitMerge, error)) *Client_CreateMergeRequest_Call { - _c.Call.Return(run) - return _c -} - -// CreatePullRequest provides a mock function for the type Client -func (_mock *Client) CreatePullRequest(context1 context.Context, createPullRequestArgs git.CreatePullRequestArgs) (*git.GitPullRequest, error) { - ret := _mock.Called(context1, createPullRequestArgs) - - if len(ret) == 0 { - panic("no return value specified for CreatePullRequest") - } - - var r0 *git.GitPullRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestArgs) (*git.GitPullRequest, error)); ok { - return returnFunc(context1, createPullRequestArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestArgs) *git.GitPullRequest); ok { - r0 = returnFunc(context1, createPullRequestArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestArgs) error); ok { - r1 = returnFunc(context1, createPullRequestArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreatePullRequest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePullRequest' -type Client_CreatePullRequest_Call struct { - *mock.Call -} - -// CreatePullRequest is a helper method to define mock.On call -// - context1 -// - createPullRequestArgs -func (_e *Client_Expecter) CreatePullRequest(context1 interface{}, createPullRequestArgs interface{}) *Client_CreatePullRequest_Call { - return &Client_CreatePullRequest_Call{Call: _e.mock.On("CreatePullRequest", context1, createPullRequestArgs)} -} - -func (_c *Client_CreatePullRequest_Call) Run(run func(context1 context.Context, createPullRequestArgs git.CreatePullRequestArgs)) *Client_CreatePullRequest_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreatePullRequestArgs)) - }) - return _c -} - -func (_c *Client_CreatePullRequest_Call) Return(gitPullRequest *git.GitPullRequest, err error) *Client_CreatePullRequest_Call { - _c.Call.Return(gitPullRequest, err) - return _c -} - -func (_c *Client_CreatePullRequest_Call) RunAndReturn(run func(context1 context.Context, createPullRequestArgs git.CreatePullRequestArgs) (*git.GitPullRequest, error)) *Client_CreatePullRequest_Call { - _c.Call.Return(run) - return _c -} - -// CreatePullRequestIterationStatus provides a mock function for the type Client -func (_mock *Client) CreatePullRequestIterationStatus(context1 context.Context, createPullRequestIterationStatusArgs git.CreatePullRequestIterationStatusArgs) (*git.GitPullRequestStatus, error) { - ret := _mock.Called(context1, createPullRequestIterationStatusArgs) - - if len(ret) == 0 { - panic("no return value specified for CreatePullRequestIterationStatus") - } - - var r0 *git.GitPullRequestStatus - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestIterationStatusArgs) (*git.GitPullRequestStatus, error)); ok { - return returnFunc(context1, createPullRequestIterationStatusArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestIterationStatusArgs) *git.GitPullRequestStatus); ok { - r0 = returnFunc(context1, createPullRequestIterationStatusArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequestStatus) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestIterationStatusArgs) error); ok { - r1 = returnFunc(context1, createPullRequestIterationStatusArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreatePullRequestIterationStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePullRequestIterationStatus' -type Client_CreatePullRequestIterationStatus_Call struct { - *mock.Call -} - -// CreatePullRequestIterationStatus is a helper method to define mock.On call -// - context1 -// - createPullRequestIterationStatusArgs -func (_e *Client_Expecter) CreatePullRequestIterationStatus(context1 interface{}, createPullRequestIterationStatusArgs interface{}) *Client_CreatePullRequestIterationStatus_Call { - return &Client_CreatePullRequestIterationStatus_Call{Call: _e.mock.On("CreatePullRequestIterationStatus", context1, createPullRequestIterationStatusArgs)} -} - -func (_c *Client_CreatePullRequestIterationStatus_Call) Run(run func(context1 context.Context, createPullRequestIterationStatusArgs git.CreatePullRequestIterationStatusArgs)) *Client_CreatePullRequestIterationStatus_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreatePullRequestIterationStatusArgs)) - }) - return _c -} - -func (_c *Client_CreatePullRequestIterationStatus_Call) Return(gitPullRequestStatus *git.GitPullRequestStatus, err error) *Client_CreatePullRequestIterationStatus_Call { - _c.Call.Return(gitPullRequestStatus, err) - return _c -} - -func (_c *Client_CreatePullRequestIterationStatus_Call) RunAndReturn(run func(context1 context.Context, createPullRequestIterationStatusArgs git.CreatePullRequestIterationStatusArgs) (*git.GitPullRequestStatus, error)) *Client_CreatePullRequestIterationStatus_Call { - _c.Call.Return(run) - return _c -} - -// CreatePullRequestLabel provides a mock function for the type Client -func (_mock *Client) CreatePullRequestLabel(context1 context.Context, createPullRequestLabelArgs git.CreatePullRequestLabelArgs) (*core.WebApiTagDefinition, error) { - ret := _mock.Called(context1, createPullRequestLabelArgs) - - if len(ret) == 0 { - panic("no return value specified for CreatePullRequestLabel") - } - - var r0 *core.WebApiTagDefinition - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestLabelArgs) (*core.WebApiTagDefinition, error)); ok { - return returnFunc(context1, createPullRequestLabelArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestLabelArgs) *core.WebApiTagDefinition); ok { - r0 = returnFunc(context1, createPullRequestLabelArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*core.WebApiTagDefinition) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestLabelArgs) error); ok { - r1 = returnFunc(context1, createPullRequestLabelArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreatePullRequestLabel_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePullRequestLabel' -type Client_CreatePullRequestLabel_Call struct { - *mock.Call -} - -// CreatePullRequestLabel is a helper method to define mock.On call -// - context1 -// - createPullRequestLabelArgs -func (_e *Client_Expecter) CreatePullRequestLabel(context1 interface{}, createPullRequestLabelArgs interface{}) *Client_CreatePullRequestLabel_Call { - return &Client_CreatePullRequestLabel_Call{Call: _e.mock.On("CreatePullRequestLabel", context1, createPullRequestLabelArgs)} -} - -func (_c *Client_CreatePullRequestLabel_Call) Run(run func(context1 context.Context, createPullRequestLabelArgs git.CreatePullRequestLabelArgs)) *Client_CreatePullRequestLabel_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreatePullRequestLabelArgs)) - }) - return _c -} - -func (_c *Client_CreatePullRequestLabel_Call) Return(webApiTagDefinition *core.WebApiTagDefinition, err error) *Client_CreatePullRequestLabel_Call { - _c.Call.Return(webApiTagDefinition, err) - return _c -} - -func (_c *Client_CreatePullRequestLabel_Call) RunAndReturn(run func(context1 context.Context, createPullRequestLabelArgs git.CreatePullRequestLabelArgs) (*core.WebApiTagDefinition, error)) *Client_CreatePullRequestLabel_Call { - _c.Call.Return(run) - return _c -} - -// CreatePullRequestReviewer provides a mock function for the type Client -func (_mock *Client) CreatePullRequestReviewer(context1 context.Context, createPullRequestReviewerArgs git.CreatePullRequestReviewerArgs) (*git.IdentityRefWithVote, error) { - ret := _mock.Called(context1, createPullRequestReviewerArgs) - - if len(ret) == 0 { - panic("no return value specified for CreatePullRequestReviewer") - } - - var r0 *git.IdentityRefWithVote - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestReviewerArgs) (*git.IdentityRefWithVote, error)); ok { - return returnFunc(context1, createPullRequestReviewerArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestReviewerArgs) *git.IdentityRefWithVote); ok { - r0 = returnFunc(context1, createPullRequestReviewerArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.IdentityRefWithVote) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestReviewerArgs) error); ok { - r1 = returnFunc(context1, createPullRequestReviewerArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreatePullRequestReviewer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePullRequestReviewer' -type Client_CreatePullRequestReviewer_Call struct { - *mock.Call -} - -// CreatePullRequestReviewer is a helper method to define mock.On call -// - context1 -// - createPullRequestReviewerArgs -func (_e *Client_Expecter) CreatePullRequestReviewer(context1 interface{}, createPullRequestReviewerArgs interface{}) *Client_CreatePullRequestReviewer_Call { - return &Client_CreatePullRequestReviewer_Call{Call: _e.mock.On("CreatePullRequestReviewer", context1, createPullRequestReviewerArgs)} -} - -func (_c *Client_CreatePullRequestReviewer_Call) Run(run func(context1 context.Context, createPullRequestReviewerArgs git.CreatePullRequestReviewerArgs)) *Client_CreatePullRequestReviewer_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreatePullRequestReviewerArgs)) - }) - return _c -} - -func (_c *Client_CreatePullRequestReviewer_Call) Return(identityRefWithVote *git.IdentityRefWithVote, err error) *Client_CreatePullRequestReviewer_Call { - _c.Call.Return(identityRefWithVote, err) - return _c -} - -func (_c *Client_CreatePullRequestReviewer_Call) RunAndReturn(run func(context1 context.Context, createPullRequestReviewerArgs git.CreatePullRequestReviewerArgs) (*git.IdentityRefWithVote, error)) *Client_CreatePullRequestReviewer_Call { - _c.Call.Return(run) - return _c -} - -// CreatePullRequestReviewers provides a mock function for the type Client -func (_mock *Client) CreatePullRequestReviewers(context1 context.Context, createPullRequestReviewersArgs git.CreatePullRequestReviewersArgs) (*[]git.IdentityRefWithVote, error) { - ret := _mock.Called(context1, createPullRequestReviewersArgs) - - if len(ret) == 0 { - panic("no return value specified for CreatePullRequestReviewers") - } - - var r0 *[]git.IdentityRefWithVote - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestReviewersArgs) (*[]git.IdentityRefWithVote, error)); ok { - return returnFunc(context1, createPullRequestReviewersArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestReviewersArgs) *[]git.IdentityRefWithVote); ok { - r0 = returnFunc(context1, createPullRequestReviewersArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.IdentityRefWithVote) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestReviewersArgs) error); ok { - r1 = returnFunc(context1, createPullRequestReviewersArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreatePullRequestReviewers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePullRequestReviewers' -type Client_CreatePullRequestReviewers_Call struct { - *mock.Call -} - -// CreatePullRequestReviewers is a helper method to define mock.On call -// - context1 -// - createPullRequestReviewersArgs -func (_e *Client_Expecter) CreatePullRequestReviewers(context1 interface{}, createPullRequestReviewersArgs interface{}) *Client_CreatePullRequestReviewers_Call { - return &Client_CreatePullRequestReviewers_Call{Call: _e.mock.On("CreatePullRequestReviewers", context1, createPullRequestReviewersArgs)} -} - -func (_c *Client_CreatePullRequestReviewers_Call) Run(run func(context1 context.Context, createPullRequestReviewersArgs git.CreatePullRequestReviewersArgs)) *Client_CreatePullRequestReviewers_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreatePullRequestReviewersArgs)) - }) - return _c -} - -func (_c *Client_CreatePullRequestReviewers_Call) Return(identityRefWithVotes *[]git.IdentityRefWithVote, err error) *Client_CreatePullRequestReviewers_Call { - _c.Call.Return(identityRefWithVotes, err) - return _c -} - -func (_c *Client_CreatePullRequestReviewers_Call) RunAndReturn(run func(context1 context.Context, createPullRequestReviewersArgs git.CreatePullRequestReviewersArgs) (*[]git.IdentityRefWithVote, error)) *Client_CreatePullRequestReviewers_Call { - _c.Call.Return(run) - return _c -} - -// CreatePullRequestStatus provides a mock function for the type Client -func (_mock *Client) CreatePullRequestStatus(context1 context.Context, createPullRequestStatusArgs git.CreatePullRequestStatusArgs) (*git.GitPullRequestStatus, error) { - ret := _mock.Called(context1, createPullRequestStatusArgs) - - if len(ret) == 0 { - panic("no return value specified for CreatePullRequestStatus") - } - - var r0 *git.GitPullRequestStatus - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestStatusArgs) (*git.GitPullRequestStatus, error)); ok { - return returnFunc(context1, createPullRequestStatusArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestStatusArgs) *git.GitPullRequestStatus); ok { - r0 = returnFunc(context1, createPullRequestStatusArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequestStatus) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestStatusArgs) error); ok { - r1 = returnFunc(context1, createPullRequestStatusArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreatePullRequestStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePullRequestStatus' -type Client_CreatePullRequestStatus_Call struct { - *mock.Call -} - -// CreatePullRequestStatus is a helper method to define mock.On call -// - context1 -// - createPullRequestStatusArgs -func (_e *Client_Expecter) CreatePullRequestStatus(context1 interface{}, createPullRequestStatusArgs interface{}) *Client_CreatePullRequestStatus_Call { - return &Client_CreatePullRequestStatus_Call{Call: _e.mock.On("CreatePullRequestStatus", context1, createPullRequestStatusArgs)} -} - -func (_c *Client_CreatePullRequestStatus_Call) Run(run func(context1 context.Context, createPullRequestStatusArgs git.CreatePullRequestStatusArgs)) *Client_CreatePullRequestStatus_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreatePullRequestStatusArgs)) - }) - return _c -} - -func (_c *Client_CreatePullRequestStatus_Call) Return(gitPullRequestStatus *git.GitPullRequestStatus, err error) *Client_CreatePullRequestStatus_Call { - _c.Call.Return(gitPullRequestStatus, err) - return _c -} - -func (_c *Client_CreatePullRequestStatus_Call) RunAndReturn(run func(context1 context.Context, createPullRequestStatusArgs git.CreatePullRequestStatusArgs) (*git.GitPullRequestStatus, error)) *Client_CreatePullRequestStatus_Call { - _c.Call.Return(run) - return _c -} - -// CreatePush provides a mock function for the type Client -func (_mock *Client) CreatePush(context1 context.Context, createPushArgs git.CreatePushArgs) (*git.GitPush, error) { - ret := _mock.Called(context1, createPushArgs) - - if len(ret) == 0 { - panic("no return value specified for CreatePush") - } - - var r0 *git.GitPush - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePushArgs) (*git.GitPush, error)); ok { - return returnFunc(context1, createPushArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreatePushArgs) *git.GitPush); ok { - r0 = returnFunc(context1, createPushArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPush) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreatePushArgs) error); ok { - r1 = returnFunc(context1, createPushArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreatePush_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePush' -type Client_CreatePush_Call struct { - *mock.Call -} - -// CreatePush is a helper method to define mock.On call -// - context1 -// - createPushArgs -func (_e *Client_Expecter) CreatePush(context1 interface{}, createPushArgs interface{}) *Client_CreatePush_Call { - return &Client_CreatePush_Call{Call: _e.mock.On("CreatePush", context1, createPushArgs)} -} - -func (_c *Client_CreatePush_Call) Run(run func(context1 context.Context, createPushArgs git.CreatePushArgs)) *Client_CreatePush_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreatePushArgs)) - }) - return _c -} - -func (_c *Client_CreatePush_Call) Return(gitPush *git.GitPush, err error) *Client_CreatePush_Call { - _c.Call.Return(gitPush, err) - return _c -} - -func (_c *Client_CreatePush_Call) RunAndReturn(run func(context1 context.Context, createPushArgs git.CreatePushArgs) (*git.GitPush, error)) *Client_CreatePush_Call { - _c.Call.Return(run) - return _c -} - -// CreateRepository provides a mock function for the type Client -func (_mock *Client) CreateRepository(context1 context.Context, createRepositoryArgs git.CreateRepositoryArgs) (*git.GitRepository, error) { - ret := _mock.Called(context1, createRepositoryArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateRepository") - } - - var r0 *git.GitRepository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateRepositoryArgs) (*git.GitRepository, error)); ok { - return returnFunc(context1, createRepositoryArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateRepositoryArgs) *git.GitRepository); ok { - r0 = returnFunc(context1, createRepositoryArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitRepository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateRepositoryArgs) error); ok { - r1 = returnFunc(context1, createRepositoryArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateRepository' -type Client_CreateRepository_Call struct { - *mock.Call -} - -// CreateRepository is a helper method to define mock.On call -// - context1 -// - createRepositoryArgs -func (_e *Client_Expecter) CreateRepository(context1 interface{}, createRepositoryArgs interface{}) *Client_CreateRepository_Call { - return &Client_CreateRepository_Call{Call: _e.mock.On("CreateRepository", context1, createRepositoryArgs)} -} - -func (_c *Client_CreateRepository_Call) Run(run func(context1 context.Context, createRepositoryArgs git.CreateRepositoryArgs)) *Client_CreateRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateRepositoryArgs)) - }) - return _c -} - -func (_c *Client_CreateRepository_Call) Return(gitRepository *git.GitRepository, err error) *Client_CreateRepository_Call { - _c.Call.Return(gitRepository, err) - return _c -} - -func (_c *Client_CreateRepository_Call) RunAndReturn(run func(context1 context.Context, createRepositoryArgs git.CreateRepositoryArgs) (*git.GitRepository, error)) *Client_CreateRepository_Call { - _c.Call.Return(run) - return _c -} - -// CreateRevert provides a mock function for the type Client -func (_mock *Client) CreateRevert(context1 context.Context, createRevertArgs git.CreateRevertArgs) (*git.GitRevert, error) { - ret := _mock.Called(context1, createRevertArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateRevert") - } - - var r0 *git.GitRevert - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateRevertArgs) (*git.GitRevert, error)); ok { - return returnFunc(context1, createRevertArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateRevertArgs) *git.GitRevert); ok { - r0 = returnFunc(context1, createRevertArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitRevert) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateRevertArgs) error); ok { - r1 = returnFunc(context1, createRevertArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateRevert_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateRevert' -type Client_CreateRevert_Call struct { - *mock.Call -} - -// CreateRevert is a helper method to define mock.On call -// - context1 -// - createRevertArgs -func (_e *Client_Expecter) CreateRevert(context1 interface{}, createRevertArgs interface{}) *Client_CreateRevert_Call { - return &Client_CreateRevert_Call{Call: _e.mock.On("CreateRevert", context1, createRevertArgs)} -} - -func (_c *Client_CreateRevert_Call) Run(run func(context1 context.Context, createRevertArgs git.CreateRevertArgs)) *Client_CreateRevert_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateRevertArgs)) - }) - return _c -} - -func (_c *Client_CreateRevert_Call) Return(gitRevert *git.GitRevert, err error) *Client_CreateRevert_Call { - _c.Call.Return(gitRevert, err) - return _c -} - -func (_c *Client_CreateRevert_Call) RunAndReturn(run func(context1 context.Context, createRevertArgs git.CreateRevertArgs) (*git.GitRevert, error)) *Client_CreateRevert_Call { - _c.Call.Return(run) - return _c -} - -// CreateThread provides a mock function for the type Client -func (_mock *Client) CreateThread(context1 context.Context, createThreadArgs git.CreateThreadArgs) (*git.GitPullRequestCommentThread, error) { - ret := _mock.Called(context1, createThreadArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateThread") - } - - var r0 *git.GitPullRequestCommentThread - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateThreadArgs) (*git.GitPullRequestCommentThread, error)); ok { - return returnFunc(context1, createThreadArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateThreadArgs) *git.GitPullRequestCommentThread); ok { - r0 = returnFunc(context1, createThreadArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequestCommentThread) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateThreadArgs) error); ok { - r1 = returnFunc(context1, createThreadArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateThread_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateThread' -type Client_CreateThread_Call struct { - *mock.Call -} - -// CreateThread is a helper method to define mock.On call -// - context1 -// - createThreadArgs -func (_e *Client_Expecter) CreateThread(context1 interface{}, createThreadArgs interface{}) *Client_CreateThread_Call { - return &Client_CreateThread_Call{Call: _e.mock.On("CreateThread", context1, createThreadArgs)} -} - -func (_c *Client_CreateThread_Call) Run(run func(context1 context.Context, createThreadArgs git.CreateThreadArgs)) *Client_CreateThread_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateThreadArgs)) - }) - return _c -} - -func (_c *Client_CreateThread_Call) Return(gitPullRequestCommentThread *git.GitPullRequestCommentThread, err error) *Client_CreateThread_Call { - _c.Call.Return(gitPullRequestCommentThread, err) - return _c -} - -func (_c *Client_CreateThread_Call) RunAndReturn(run func(context1 context.Context, createThreadArgs git.CreateThreadArgs) (*git.GitPullRequestCommentThread, error)) *Client_CreateThread_Call { - _c.Call.Return(run) - return _c -} - -// CreateUnmaterializedPullRequestReviewer provides a mock function for the type Client -func (_mock *Client) CreateUnmaterializedPullRequestReviewer(context1 context.Context, createUnmaterializedPullRequestReviewerArgs git.CreateUnmaterializedPullRequestReviewerArgs) (*git.IdentityRefWithVote, error) { - ret := _mock.Called(context1, createUnmaterializedPullRequestReviewerArgs) - - if len(ret) == 0 { - panic("no return value specified for CreateUnmaterializedPullRequestReviewer") - } - - var r0 *git.IdentityRefWithVote - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateUnmaterializedPullRequestReviewerArgs) (*git.IdentityRefWithVote, error)); ok { - return returnFunc(context1, createUnmaterializedPullRequestReviewerArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.CreateUnmaterializedPullRequestReviewerArgs) *git.IdentityRefWithVote); ok { - r0 = returnFunc(context1, createUnmaterializedPullRequestReviewerArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.IdentityRefWithVote) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.CreateUnmaterializedPullRequestReviewerArgs) error); ok { - r1 = returnFunc(context1, createUnmaterializedPullRequestReviewerArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CreateUnmaterializedPullRequestReviewer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateUnmaterializedPullRequestReviewer' -type Client_CreateUnmaterializedPullRequestReviewer_Call struct { - *mock.Call -} - -// CreateUnmaterializedPullRequestReviewer is a helper method to define mock.On call -// - context1 -// - createUnmaterializedPullRequestReviewerArgs -func (_e *Client_Expecter) CreateUnmaterializedPullRequestReviewer(context1 interface{}, createUnmaterializedPullRequestReviewerArgs interface{}) *Client_CreateUnmaterializedPullRequestReviewer_Call { - return &Client_CreateUnmaterializedPullRequestReviewer_Call{Call: _e.mock.On("CreateUnmaterializedPullRequestReviewer", context1, createUnmaterializedPullRequestReviewerArgs)} -} - -func (_c *Client_CreateUnmaterializedPullRequestReviewer_Call) Run(run func(context1 context.Context, createUnmaterializedPullRequestReviewerArgs git.CreateUnmaterializedPullRequestReviewerArgs)) *Client_CreateUnmaterializedPullRequestReviewer_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.CreateUnmaterializedPullRequestReviewerArgs)) - }) - return _c -} - -func (_c *Client_CreateUnmaterializedPullRequestReviewer_Call) Return(identityRefWithVote *git.IdentityRefWithVote, err error) *Client_CreateUnmaterializedPullRequestReviewer_Call { - _c.Call.Return(identityRefWithVote, err) - return _c -} - -func (_c *Client_CreateUnmaterializedPullRequestReviewer_Call) RunAndReturn(run func(context1 context.Context, createUnmaterializedPullRequestReviewerArgs git.CreateUnmaterializedPullRequestReviewerArgs) (*git.IdentityRefWithVote, error)) *Client_CreateUnmaterializedPullRequestReviewer_Call { - _c.Call.Return(run) - return _c -} - -// DeleteAttachment provides a mock function for the type Client -func (_mock *Client) DeleteAttachment(context1 context.Context, deleteAttachmentArgs git.DeleteAttachmentArgs) error { - ret := _mock.Called(context1, deleteAttachmentArgs) - - if len(ret) == 0 { - panic("no return value specified for DeleteAttachment") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.DeleteAttachmentArgs) error); ok { - r0 = returnFunc(context1, deleteAttachmentArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_DeleteAttachment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteAttachment' -type Client_DeleteAttachment_Call struct { - *mock.Call -} - -// DeleteAttachment is a helper method to define mock.On call -// - context1 -// - deleteAttachmentArgs -func (_e *Client_Expecter) DeleteAttachment(context1 interface{}, deleteAttachmentArgs interface{}) *Client_DeleteAttachment_Call { - return &Client_DeleteAttachment_Call{Call: _e.mock.On("DeleteAttachment", context1, deleteAttachmentArgs)} -} - -func (_c *Client_DeleteAttachment_Call) Run(run func(context1 context.Context, deleteAttachmentArgs git.DeleteAttachmentArgs)) *Client_DeleteAttachment_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.DeleteAttachmentArgs)) - }) - return _c -} - -func (_c *Client_DeleteAttachment_Call) Return(err error) *Client_DeleteAttachment_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_DeleteAttachment_Call) RunAndReturn(run func(context1 context.Context, deleteAttachmentArgs git.DeleteAttachmentArgs) error) *Client_DeleteAttachment_Call { - _c.Call.Return(run) - return _c -} - -// DeleteComment provides a mock function for the type Client -func (_mock *Client) DeleteComment(context1 context.Context, deleteCommentArgs git.DeleteCommentArgs) error { - ret := _mock.Called(context1, deleteCommentArgs) - - if len(ret) == 0 { - panic("no return value specified for DeleteComment") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.DeleteCommentArgs) error); ok { - r0 = returnFunc(context1, deleteCommentArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_DeleteComment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteComment' -type Client_DeleteComment_Call struct { - *mock.Call -} - -// DeleteComment is a helper method to define mock.On call -// - context1 -// - deleteCommentArgs -func (_e *Client_Expecter) DeleteComment(context1 interface{}, deleteCommentArgs interface{}) *Client_DeleteComment_Call { - return &Client_DeleteComment_Call{Call: _e.mock.On("DeleteComment", context1, deleteCommentArgs)} -} - -func (_c *Client_DeleteComment_Call) Run(run func(context1 context.Context, deleteCommentArgs git.DeleteCommentArgs)) *Client_DeleteComment_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.DeleteCommentArgs)) - }) - return _c -} - -func (_c *Client_DeleteComment_Call) Return(err error) *Client_DeleteComment_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_DeleteComment_Call) RunAndReturn(run func(context1 context.Context, deleteCommentArgs git.DeleteCommentArgs) error) *Client_DeleteComment_Call { - _c.Call.Return(run) - return _c -} - -// DeleteLike provides a mock function for the type Client -func (_mock *Client) DeleteLike(context1 context.Context, deleteLikeArgs git.DeleteLikeArgs) error { - ret := _mock.Called(context1, deleteLikeArgs) - - if len(ret) == 0 { - panic("no return value specified for DeleteLike") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.DeleteLikeArgs) error); ok { - r0 = returnFunc(context1, deleteLikeArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_DeleteLike_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteLike' -type Client_DeleteLike_Call struct { - *mock.Call -} - -// DeleteLike is a helper method to define mock.On call -// - context1 -// - deleteLikeArgs -func (_e *Client_Expecter) DeleteLike(context1 interface{}, deleteLikeArgs interface{}) *Client_DeleteLike_Call { - return &Client_DeleteLike_Call{Call: _e.mock.On("DeleteLike", context1, deleteLikeArgs)} -} - -func (_c *Client_DeleteLike_Call) Run(run func(context1 context.Context, deleteLikeArgs git.DeleteLikeArgs)) *Client_DeleteLike_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.DeleteLikeArgs)) - }) - return _c -} - -func (_c *Client_DeleteLike_Call) Return(err error) *Client_DeleteLike_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_DeleteLike_Call) RunAndReturn(run func(context1 context.Context, deleteLikeArgs git.DeleteLikeArgs) error) *Client_DeleteLike_Call { - _c.Call.Return(run) - return _c -} - -// DeletePullRequestIterationStatus provides a mock function for the type Client -func (_mock *Client) DeletePullRequestIterationStatus(context1 context.Context, deletePullRequestIterationStatusArgs git.DeletePullRequestIterationStatusArgs) error { - ret := _mock.Called(context1, deletePullRequestIterationStatusArgs) - - if len(ret) == 0 { - panic("no return value specified for DeletePullRequestIterationStatus") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.DeletePullRequestIterationStatusArgs) error); ok { - r0 = returnFunc(context1, deletePullRequestIterationStatusArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_DeletePullRequestIterationStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeletePullRequestIterationStatus' -type Client_DeletePullRequestIterationStatus_Call struct { - *mock.Call -} - -// DeletePullRequestIterationStatus is a helper method to define mock.On call -// - context1 -// - deletePullRequestIterationStatusArgs -func (_e *Client_Expecter) DeletePullRequestIterationStatus(context1 interface{}, deletePullRequestIterationStatusArgs interface{}) *Client_DeletePullRequestIterationStatus_Call { - return &Client_DeletePullRequestIterationStatus_Call{Call: _e.mock.On("DeletePullRequestIterationStatus", context1, deletePullRequestIterationStatusArgs)} -} - -func (_c *Client_DeletePullRequestIterationStatus_Call) Run(run func(context1 context.Context, deletePullRequestIterationStatusArgs git.DeletePullRequestIterationStatusArgs)) *Client_DeletePullRequestIterationStatus_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.DeletePullRequestIterationStatusArgs)) - }) - return _c -} - -func (_c *Client_DeletePullRequestIterationStatus_Call) Return(err error) *Client_DeletePullRequestIterationStatus_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_DeletePullRequestIterationStatus_Call) RunAndReturn(run func(context1 context.Context, deletePullRequestIterationStatusArgs git.DeletePullRequestIterationStatusArgs) error) *Client_DeletePullRequestIterationStatus_Call { - _c.Call.Return(run) - return _c -} - -// DeletePullRequestLabels provides a mock function for the type Client -func (_mock *Client) DeletePullRequestLabels(context1 context.Context, deletePullRequestLabelsArgs git.DeletePullRequestLabelsArgs) error { - ret := _mock.Called(context1, deletePullRequestLabelsArgs) - - if len(ret) == 0 { - panic("no return value specified for DeletePullRequestLabels") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.DeletePullRequestLabelsArgs) error); ok { - r0 = returnFunc(context1, deletePullRequestLabelsArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_DeletePullRequestLabels_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeletePullRequestLabels' -type Client_DeletePullRequestLabels_Call struct { - *mock.Call -} - -// DeletePullRequestLabels is a helper method to define mock.On call -// - context1 -// - deletePullRequestLabelsArgs -func (_e *Client_Expecter) DeletePullRequestLabels(context1 interface{}, deletePullRequestLabelsArgs interface{}) *Client_DeletePullRequestLabels_Call { - return &Client_DeletePullRequestLabels_Call{Call: _e.mock.On("DeletePullRequestLabels", context1, deletePullRequestLabelsArgs)} -} - -func (_c *Client_DeletePullRequestLabels_Call) Run(run func(context1 context.Context, deletePullRequestLabelsArgs git.DeletePullRequestLabelsArgs)) *Client_DeletePullRequestLabels_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.DeletePullRequestLabelsArgs)) - }) - return _c -} - -func (_c *Client_DeletePullRequestLabels_Call) Return(err error) *Client_DeletePullRequestLabels_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_DeletePullRequestLabels_Call) RunAndReturn(run func(context1 context.Context, deletePullRequestLabelsArgs git.DeletePullRequestLabelsArgs) error) *Client_DeletePullRequestLabels_Call { - _c.Call.Return(run) - return _c -} - -// DeletePullRequestReviewer provides a mock function for the type Client -func (_mock *Client) DeletePullRequestReviewer(context1 context.Context, deletePullRequestReviewerArgs git.DeletePullRequestReviewerArgs) error { - ret := _mock.Called(context1, deletePullRequestReviewerArgs) - - if len(ret) == 0 { - panic("no return value specified for DeletePullRequestReviewer") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.DeletePullRequestReviewerArgs) error); ok { - r0 = returnFunc(context1, deletePullRequestReviewerArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_DeletePullRequestReviewer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeletePullRequestReviewer' -type Client_DeletePullRequestReviewer_Call struct { - *mock.Call -} - -// DeletePullRequestReviewer is a helper method to define mock.On call -// - context1 -// - deletePullRequestReviewerArgs -func (_e *Client_Expecter) DeletePullRequestReviewer(context1 interface{}, deletePullRequestReviewerArgs interface{}) *Client_DeletePullRequestReviewer_Call { - return &Client_DeletePullRequestReviewer_Call{Call: _e.mock.On("DeletePullRequestReviewer", context1, deletePullRequestReviewerArgs)} -} - -func (_c *Client_DeletePullRequestReviewer_Call) Run(run func(context1 context.Context, deletePullRequestReviewerArgs git.DeletePullRequestReviewerArgs)) *Client_DeletePullRequestReviewer_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.DeletePullRequestReviewerArgs)) - }) - return _c -} - -func (_c *Client_DeletePullRequestReviewer_Call) Return(err error) *Client_DeletePullRequestReviewer_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_DeletePullRequestReviewer_Call) RunAndReturn(run func(context1 context.Context, deletePullRequestReviewerArgs git.DeletePullRequestReviewerArgs) error) *Client_DeletePullRequestReviewer_Call { - _c.Call.Return(run) - return _c -} - -// DeletePullRequestStatus provides a mock function for the type Client -func (_mock *Client) DeletePullRequestStatus(context1 context.Context, deletePullRequestStatusArgs git.DeletePullRequestStatusArgs) error { - ret := _mock.Called(context1, deletePullRequestStatusArgs) - - if len(ret) == 0 { - panic("no return value specified for DeletePullRequestStatus") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.DeletePullRequestStatusArgs) error); ok { - r0 = returnFunc(context1, deletePullRequestStatusArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_DeletePullRequestStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeletePullRequestStatus' -type Client_DeletePullRequestStatus_Call struct { - *mock.Call -} - -// DeletePullRequestStatus is a helper method to define mock.On call -// - context1 -// - deletePullRequestStatusArgs -func (_e *Client_Expecter) DeletePullRequestStatus(context1 interface{}, deletePullRequestStatusArgs interface{}) *Client_DeletePullRequestStatus_Call { - return &Client_DeletePullRequestStatus_Call{Call: _e.mock.On("DeletePullRequestStatus", context1, deletePullRequestStatusArgs)} -} - -func (_c *Client_DeletePullRequestStatus_Call) Run(run func(context1 context.Context, deletePullRequestStatusArgs git.DeletePullRequestStatusArgs)) *Client_DeletePullRequestStatus_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.DeletePullRequestStatusArgs)) - }) - return _c -} - -func (_c *Client_DeletePullRequestStatus_Call) Return(err error) *Client_DeletePullRequestStatus_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_DeletePullRequestStatus_Call) RunAndReturn(run func(context1 context.Context, deletePullRequestStatusArgs git.DeletePullRequestStatusArgs) error) *Client_DeletePullRequestStatus_Call { - _c.Call.Return(run) - return _c -} - -// DeleteRefFavorite provides a mock function for the type Client -func (_mock *Client) DeleteRefFavorite(context1 context.Context, deleteRefFavoriteArgs git.DeleteRefFavoriteArgs) error { - ret := _mock.Called(context1, deleteRefFavoriteArgs) - - if len(ret) == 0 { - panic("no return value specified for DeleteRefFavorite") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.DeleteRefFavoriteArgs) error); ok { - r0 = returnFunc(context1, deleteRefFavoriteArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_DeleteRefFavorite_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteRefFavorite' -type Client_DeleteRefFavorite_Call struct { - *mock.Call -} - -// DeleteRefFavorite is a helper method to define mock.On call -// - context1 -// - deleteRefFavoriteArgs -func (_e *Client_Expecter) DeleteRefFavorite(context1 interface{}, deleteRefFavoriteArgs interface{}) *Client_DeleteRefFavorite_Call { - return &Client_DeleteRefFavorite_Call{Call: _e.mock.On("DeleteRefFavorite", context1, deleteRefFavoriteArgs)} -} - -func (_c *Client_DeleteRefFavorite_Call) Run(run func(context1 context.Context, deleteRefFavoriteArgs git.DeleteRefFavoriteArgs)) *Client_DeleteRefFavorite_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.DeleteRefFavoriteArgs)) - }) - return _c -} - -func (_c *Client_DeleteRefFavorite_Call) Return(err error) *Client_DeleteRefFavorite_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_DeleteRefFavorite_Call) RunAndReturn(run func(context1 context.Context, deleteRefFavoriteArgs git.DeleteRefFavoriteArgs) error) *Client_DeleteRefFavorite_Call { - _c.Call.Return(run) - return _c -} - -// DeleteRepository provides a mock function for the type Client -func (_mock *Client) DeleteRepository(context1 context.Context, deleteRepositoryArgs git.DeleteRepositoryArgs) error { - ret := _mock.Called(context1, deleteRepositoryArgs) - - if len(ret) == 0 { - panic("no return value specified for DeleteRepository") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.DeleteRepositoryArgs) error); ok { - r0 = returnFunc(context1, deleteRepositoryArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_DeleteRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteRepository' -type Client_DeleteRepository_Call struct { - *mock.Call -} - -// DeleteRepository is a helper method to define mock.On call -// - context1 -// - deleteRepositoryArgs -func (_e *Client_Expecter) DeleteRepository(context1 interface{}, deleteRepositoryArgs interface{}) *Client_DeleteRepository_Call { - return &Client_DeleteRepository_Call{Call: _e.mock.On("DeleteRepository", context1, deleteRepositoryArgs)} -} - -func (_c *Client_DeleteRepository_Call) Run(run func(context1 context.Context, deleteRepositoryArgs git.DeleteRepositoryArgs)) *Client_DeleteRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.DeleteRepositoryArgs)) - }) - return _c -} - -func (_c *Client_DeleteRepository_Call) Return(err error) *Client_DeleteRepository_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_DeleteRepository_Call) RunAndReturn(run func(context1 context.Context, deleteRepositoryArgs git.DeleteRepositoryArgs) error) *Client_DeleteRepository_Call { - _c.Call.Return(run) - return _c -} - -// DeleteRepositoryFromRecycleBin provides a mock function for the type Client -func (_mock *Client) DeleteRepositoryFromRecycleBin(context1 context.Context, deleteRepositoryFromRecycleBinArgs git.DeleteRepositoryFromRecycleBinArgs) error { - ret := _mock.Called(context1, deleteRepositoryFromRecycleBinArgs) - - if len(ret) == 0 { - panic("no return value specified for DeleteRepositoryFromRecycleBin") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.DeleteRepositoryFromRecycleBinArgs) error); ok { - r0 = returnFunc(context1, deleteRepositoryFromRecycleBinArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_DeleteRepositoryFromRecycleBin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteRepositoryFromRecycleBin' -type Client_DeleteRepositoryFromRecycleBin_Call struct { - *mock.Call -} - -// DeleteRepositoryFromRecycleBin is a helper method to define mock.On call -// - context1 -// - deleteRepositoryFromRecycleBinArgs -func (_e *Client_Expecter) DeleteRepositoryFromRecycleBin(context1 interface{}, deleteRepositoryFromRecycleBinArgs interface{}) *Client_DeleteRepositoryFromRecycleBin_Call { - return &Client_DeleteRepositoryFromRecycleBin_Call{Call: _e.mock.On("DeleteRepositoryFromRecycleBin", context1, deleteRepositoryFromRecycleBinArgs)} -} - -func (_c *Client_DeleteRepositoryFromRecycleBin_Call) Run(run func(context1 context.Context, deleteRepositoryFromRecycleBinArgs git.DeleteRepositoryFromRecycleBinArgs)) *Client_DeleteRepositoryFromRecycleBin_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.DeleteRepositoryFromRecycleBinArgs)) - }) - return _c -} - -func (_c *Client_DeleteRepositoryFromRecycleBin_Call) Return(err error) *Client_DeleteRepositoryFromRecycleBin_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_DeleteRepositoryFromRecycleBin_Call) RunAndReturn(run func(context1 context.Context, deleteRepositoryFromRecycleBinArgs git.DeleteRepositoryFromRecycleBinArgs) error) *Client_DeleteRepositoryFromRecycleBin_Call { - _c.Call.Return(run) - return _c -} - -// GetAnnotatedTag provides a mock function for the type Client -func (_mock *Client) GetAnnotatedTag(context1 context.Context, getAnnotatedTagArgs git.GetAnnotatedTagArgs) (*git.GitAnnotatedTag, error) { - ret := _mock.Called(context1, getAnnotatedTagArgs) - - if len(ret) == 0 { - panic("no return value specified for GetAnnotatedTag") - } - - var r0 *git.GitAnnotatedTag - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetAnnotatedTagArgs) (*git.GitAnnotatedTag, error)); ok { - return returnFunc(context1, getAnnotatedTagArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetAnnotatedTagArgs) *git.GitAnnotatedTag); ok { - r0 = returnFunc(context1, getAnnotatedTagArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitAnnotatedTag) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetAnnotatedTagArgs) error); ok { - r1 = returnFunc(context1, getAnnotatedTagArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetAnnotatedTag_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAnnotatedTag' -type Client_GetAnnotatedTag_Call struct { - *mock.Call -} - -// GetAnnotatedTag is a helper method to define mock.On call -// - context1 -// - getAnnotatedTagArgs -func (_e *Client_Expecter) GetAnnotatedTag(context1 interface{}, getAnnotatedTagArgs interface{}) *Client_GetAnnotatedTag_Call { - return &Client_GetAnnotatedTag_Call{Call: _e.mock.On("GetAnnotatedTag", context1, getAnnotatedTagArgs)} -} - -func (_c *Client_GetAnnotatedTag_Call) Run(run func(context1 context.Context, getAnnotatedTagArgs git.GetAnnotatedTagArgs)) *Client_GetAnnotatedTag_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetAnnotatedTagArgs)) - }) - return _c -} - -func (_c *Client_GetAnnotatedTag_Call) Return(gitAnnotatedTag *git.GitAnnotatedTag, err error) *Client_GetAnnotatedTag_Call { - _c.Call.Return(gitAnnotatedTag, err) - return _c -} - -func (_c *Client_GetAnnotatedTag_Call) RunAndReturn(run func(context1 context.Context, getAnnotatedTagArgs git.GetAnnotatedTagArgs) (*git.GitAnnotatedTag, error)) *Client_GetAnnotatedTag_Call { - _c.Call.Return(run) - return _c -} - -// GetAttachmentContent provides a mock function for the type Client -func (_mock *Client) GetAttachmentContent(context1 context.Context, getAttachmentContentArgs git.GetAttachmentContentArgs) (io.ReadCloser, error) { - ret := _mock.Called(context1, getAttachmentContentArgs) - - if len(ret) == 0 { - panic("no return value specified for GetAttachmentContent") - } - - var r0 io.ReadCloser - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetAttachmentContentArgs) (io.ReadCloser, error)); ok { - return returnFunc(context1, getAttachmentContentArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetAttachmentContentArgs) io.ReadCloser); ok { - r0 = returnFunc(context1, getAttachmentContentArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(io.ReadCloser) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetAttachmentContentArgs) error); ok { - r1 = returnFunc(context1, getAttachmentContentArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetAttachmentContent_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAttachmentContent' -type Client_GetAttachmentContent_Call struct { - *mock.Call -} - -// GetAttachmentContent is a helper method to define mock.On call -// - context1 -// - getAttachmentContentArgs -func (_e *Client_Expecter) GetAttachmentContent(context1 interface{}, getAttachmentContentArgs interface{}) *Client_GetAttachmentContent_Call { - return &Client_GetAttachmentContent_Call{Call: _e.mock.On("GetAttachmentContent", context1, getAttachmentContentArgs)} -} - -func (_c *Client_GetAttachmentContent_Call) Run(run func(context1 context.Context, getAttachmentContentArgs git.GetAttachmentContentArgs)) *Client_GetAttachmentContent_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetAttachmentContentArgs)) - }) - return _c -} - -func (_c *Client_GetAttachmentContent_Call) Return(readCloser io.ReadCloser, err error) *Client_GetAttachmentContent_Call { - _c.Call.Return(readCloser, err) - return _c -} - -func (_c *Client_GetAttachmentContent_Call) RunAndReturn(run func(context1 context.Context, getAttachmentContentArgs git.GetAttachmentContentArgs) (io.ReadCloser, error)) *Client_GetAttachmentContent_Call { - _c.Call.Return(run) - return _c -} - -// GetAttachmentZip provides a mock function for the type Client -func (_mock *Client) GetAttachmentZip(context1 context.Context, getAttachmentZipArgs git.GetAttachmentZipArgs) (io.ReadCloser, error) { - ret := _mock.Called(context1, getAttachmentZipArgs) - - if len(ret) == 0 { - panic("no return value specified for GetAttachmentZip") - } - - var r0 io.ReadCloser - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetAttachmentZipArgs) (io.ReadCloser, error)); ok { - return returnFunc(context1, getAttachmentZipArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetAttachmentZipArgs) io.ReadCloser); ok { - r0 = returnFunc(context1, getAttachmentZipArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(io.ReadCloser) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetAttachmentZipArgs) error); ok { - r1 = returnFunc(context1, getAttachmentZipArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetAttachmentZip_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAttachmentZip' -type Client_GetAttachmentZip_Call struct { - *mock.Call -} - -// GetAttachmentZip is a helper method to define mock.On call -// - context1 -// - getAttachmentZipArgs -func (_e *Client_Expecter) GetAttachmentZip(context1 interface{}, getAttachmentZipArgs interface{}) *Client_GetAttachmentZip_Call { - return &Client_GetAttachmentZip_Call{Call: _e.mock.On("GetAttachmentZip", context1, getAttachmentZipArgs)} -} - -func (_c *Client_GetAttachmentZip_Call) Run(run func(context1 context.Context, getAttachmentZipArgs git.GetAttachmentZipArgs)) *Client_GetAttachmentZip_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetAttachmentZipArgs)) - }) - return _c -} - -func (_c *Client_GetAttachmentZip_Call) Return(readCloser io.ReadCloser, err error) *Client_GetAttachmentZip_Call { - _c.Call.Return(readCloser, err) - return _c -} - -func (_c *Client_GetAttachmentZip_Call) RunAndReturn(run func(context1 context.Context, getAttachmentZipArgs git.GetAttachmentZipArgs) (io.ReadCloser, error)) *Client_GetAttachmentZip_Call { - _c.Call.Return(run) - return _c -} - -// GetAttachments provides a mock function for the type Client -func (_mock *Client) GetAttachments(context1 context.Context, getAttachmentsArgs git.GetAttachmentsArgs) (*[]git.Attachment, error) { - ret := _mock.Called(context1, getAttachmentsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetAttachments") - } - - var r0 *[]git.Attachment - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetAttachmentsArgs) (*[]git.Attachment, error)); ok { - return returnFunc(context1, getAttachmentsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetAttachmentsArgs) *[]git.Attachment); ok { - r0 = returnFunc(context1, getAttachmentsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.Attachment) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetAttachmentsArgs) error); ok { - r1 = returnFunc(context1, getAttachmentsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetAttachments_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAttachments' -type Client_GetAttachments_Call struct { - *mock.Call -} - -// GetAttachments is a helper method to define mock.On call -// - context1 -// - getAttachmentsArgs -func (_e *Client_Expecter) GetAttachments(context1 interface{}, getAttachmentsArgs interface{}) *Client_GetAttachments_Call { - return &Client_GetAttachments_Call{Call: _e.mock.On("GetAttachments", context1, getAttachmentsArgs)} -} - -func (_c *Client_GetAttachments_Call) Run(run func(context1 context.Context, getAttachmentsArgs git.GetAttachmentsArgs)) *Client_GetAttachments_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetAttachmentsArgs)) - }) - return _c -} - -func (_c *Client_GetAttachments_Call) Return(attachments *[]git.Attachment, err error) *Client_GetAttachments_Call { - _c.Call.Return(attachments, err) - return _c -} - -func (_c *Client_GetAttachments_Call) RunAndReturn(run func(context1 context.Context, getAttachmentsArgs git.GetAttachmentsArgs) (*[]git.Attachment, error)) *Client_GetAttachments_Call { - _c.Call.Return(run) - return _c -} - -// GetBlob provides a mock function for the type Client -func (_mock *Client) GetBlob(context1 context.Context, getBlobArgs git.GetBlobArgs) (*git.GitBlobRef, error) { - ret := _mock.Called(context1, getBlobArgs) - - if len(ret) == 0 { - panic("no return value specified for GetBlob") - } - - var r0 *git.GitBlobRef - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetBlobArgs) (*git.GitBlobRef, error)); ok { - return returnFunc(context1, getBlobArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetBlobArgs) *git.GitBlobRef); ok { - r0 = returnFunc(context1, getBlobArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitBlobRef) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetBlobArgs) error); ok { - r1 = returnFunc(context1, getBlobArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetBlob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlob' -type Client_GetBlob_Call struct { - *mock.Call -} - -// GetBlob is a helper method to define mock.On call -// - context1 -// - getBlobArgs -func (_e *Client_Expecter) GetBlob(context1 interface{}, getBlobArgs interface{}) *Client_GetBlob_Call { - return &Client_GetBlob_Call{Call: _e.mock.On("GetBlob", context1, getBlobArgs)} -} - -func (_c *Client_GetBlob_Call) Run(run func(context1 context.Context, getBlobArgs git.GetBlobArgs)) *Client_GetBlob_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetBlobArgs)) - }) - return _c -} - -func (_c *Client_GetBlob_Call) Return(gitBlobRef *git.GitBlobRef, err error) *Client_GetBlob_Call { - _c.Call.Return(gitBlobRef, err) - return _c -} - -func (_c *Client_GetBlob_Call) RunAndReturn(run func(context1 context.Context, getBlobArgs git.GetBlobArgs) (*git.GitBlobRef, error)) *Client_GetBlob_Call { - _c.Call.Return(run) - return _c -} - -// GetBlobContent provides a mock function for the type Client -func (_mock *Client) GetBlobContent(context1 context.Context, getBlobContentArgs git.GetBlobContentArgs) (io.ReadCloser, error) { - ret := _mock.Called(context1, getBlobContentArgs) - - if len(ret) == 0 { - panic("no return value specified for GetBlobContent") - } - - var r0 io.ReadCloser - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetBlobContentArgs) (io.ReadCloser, error)); ok { - return returnFunc(context1, getBlobContentArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetBlobContentArgs) io.ReadCloser); ok { - r0 = returnFunc(context1, getBlobContentArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(io.ReadCloser) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetBlobContentArgs) error); ok { - r1 = returnFunc(context1, getBlobContentArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetBlobContent_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlobContent' -type Client_GetBlobContent_Call struct { - *mock.Call -} - -// GetBlobContent is a helper method to define mock.On call -// - context1 -// - getBlobContentArgs -func (_e *Client_Expecter) GetBlobContent(context1 interface{}, getBlobContentArgs interface{}) *Client_GetBlobContent_Call { - return &Client_GetBlobContent_Call{Call: _e.mock.On("GetBlobContent", context1, getBlobContentArgs)} -} - -func (_c *Client_GetBlobContent_Call) Run(run func(context1 context.Context, getBlobContentArgs git.GetBlobContentArgs)) *Client_GetBlobContent_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetBlobContentArgs)) - }) - return _c -} - -func (_c *Client_GetBlobContent_Call) Return(readCloser io.ReadCloser, err error) *Client_GetBlobContent_Call { - _c.Call.Return(readCloser, err) - return _c -} - -func (_c *Client_GetBlobContent_Call) RunAndReturn(run func(context1 context.Context, getBlobContentArgs git.GetBlobContentArgs) (io.ReadCloser, error)) *Client_GetBlobContent_Call { - _c.Call.Return(run) - return _c -} - -// GetBlobZip provides a mock function for the type Client -func (_mock *Client) GetBlobZip(context1 context.Context, getBlobZipArgs git.GetBlobZipArgs) (io.ReadCloser, error) { - ret := _mock.Called(context1, getBlobZipArgs) - - if len(ret) == 0 { - panic("no return value specified for GetBlobZip") - } - - var r0 io.ReadCloser - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetBlobZipArgs) (io.ReadCloser, error)); ok { - return returnFunc(context1, getBlobZipArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetBlobZipArgs) io.ReadCloser); ok { - r0 = returnFunc(context1, getBlobZipArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(io.ReadCloser) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetBlobZipArgs) error); ok { - r1 = returnFunc(context1, getBlobZipArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetBlobZip_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlobZip' -type Client_GetBlobZip_Call struct { - *mock.Call -} - -// GetBlobZip is a helper method to define mock.On call -// - context1 -// - getBlobZipArgs -func (_e *Client_Expecter) GetBlobZip(context1 interface{}, getBlobZipArgs interface{}) *Client_GetBlobZip_Call { - return &Client_GetBlobZip_Call{Call: _e.mock.On("GetBlobZip", context1, getBlobZipArgs)} -} - -func (_c *Client_GetBlobZip_Call) Run(run func(context1 context.Context, getBlobZipArgs git.GetBlobZipArgs)) *Client_GetBlobZip_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetBlobZipArgs)) - }) - return _c -} - -func (_c *Client_GetBlobZip_Call) Return(readCloser io.ReadCloser, err error) *Client_GetBlobZip_Call { - _c.Call.Return(readCloser, err) - return _c -} - -func (_c *Client_GetBlobZip_Call) RunAndReturn(run func(context1 context.Context, getBlobZipArgs git.GetBlobZipArgs) (io.ReadCloser, error)) *Client_GetBlobZip_Call { - _c.Call.Return(run) - return _c -} - -// GetBlobsZip provides a mock function for the type Client -func (_mock *Client) GetBlobsZip(context1 context.Context, getBlobsZipArgs git.GetBlobsZipArgs) (io.ReadCloser, error) { - ret := _mock.Called(context1, getBlobsZipArgs) - - if len(ret) == 0 { - panic("no return value specified for GetBlobsZip") - } - - var r0 io.ReadCloser - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetBlobsZipArgs) (io.ReadCloser, error)); ok { - return returnFunc(context1, getBlobsZipArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetBlobsZipArgs) io.ReadCloser); ok { - r0 = returnFunc(context1, getBlobsZipArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(io.ReadCloser) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetBlobsZipArgs) error); ok { - r1 = returnFunc(context1, getBlobsZipArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetBlobsZip_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlobsZip' -type Client_GetBlobsZip_Call struct { - *mock.Call -} - -// GetBlobsZip is a helper method to define mock.On call -// - context1 -// - getBlobsZipArgs -func (_e *Client_Expecter) GetBlobsZip(context1 interface{}, getBlobsZipArgs interface{}) *Client_GetBlobsZip_Call { - return &Client_GetBlobsZip_Call{Call: _e.mock.On("GetBlobsZip", context1, getBlobsZipArgs)} -} - -func (_c *Client_GetBlobsZip_Call) Run(run func(context1 context.Context, getBlobsZipArgs git.GetBlobsZipArgs)) *Client_GetBlobsZip_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetBlobsZipArgs)) - }) - return _c -} - -func (_c *Client_GetBlobsZip_Call) Return(readCloser io.ReadCloser, err error) *Client_GetBlobsZip_Call { - _c.Call.Return(readCloser, err) - return _c -} - -func (_c *Client_GetBlobsZip_Call) RunAndReturn(run func(context1 context.Context, getBlobsZipArgs git.GetBlobsZipArgs) (io.ReadCloser, error)) *Client_GetBlobsZip_Call { - _c.Call.Return(run) - return _c -} - -// GetBranch provides a mock function for the type Client -func (_mock *Client) GetBranch(context1 context.Context, getBranchArgs git.GetBranchArgs) (*git.GitBranchStats, error) { - ret := _mock.Called(context1, getBranchArgs) - - if len(ret) == 0 { - panic("no return value specified for GetBranch") - } - - var r0 *git.GitBranchStats - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetBranchArgs) (*git.GitBranchStats, error)); ok { - return returnFunc(context1, getBranchArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetBranchArgs) *git.GitBranchStats); ok { - r0 = returnFunc(context1, getBranchArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitBranchStats) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetBranchArgs) error); ok { - r1 = returnFunc(context1, getBranchArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetBranch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBranch' -type Client_GetBranch_Call struct { - *mock.Call -} - -// GetBranch is a helper method to define mock.On call -// - context1 -// - getBranchArgs -func (_e *Client_Expecter) GetBranch(context1 interface{}, getBranchArgs interface{}) *Client_GetBranch_Call { - return &Client_GetBranch_Call{Call: _e.mock.On("GetBranch", context1, getBranchArgs)} -} - -func (_c *Client_GetBranch_Call) Run(run func(context1 context.Context, getBranchArgs git.GetBranchArgs)) *Client_GetBranch_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetBranchArgs)) - }) - return _c -} - -func (_c *Client_GetBranch_Call) Return(gitBranchStats *git.GitBranchStats, err error) *Client_GetBranch_Call { - _c.Call.Return(gitBranchStats, err) - return _c -} - -func (_c *Client_GetBranch_Call) RunAndReturn(run func(context1 context.Context, getBranchArgs git.GetBranchArgs) (*git.GitBranchStats, error)) *Client_GetBranch_Call { - _c.Call.Return(run) - return _c -} - -// GetBranches provides a mock function for the type Client -func (_mock *Client) GetBranches(context1 context.Context, getBranchesArgs git.GetBranchesArgs) (*[]git.GitBranchStats, error) { - ret := _mock.Called(context1, getBranchesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetBranches") - } - - var r0 *[]git.GitBranchStats - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetBranchesArgs) (*[]git.GitBranchStats, error)); ok { - return returnFunc(context1, getBranchesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetBranchesArgs) *[]git.GitBranchStats); ok { - r0 = returnFunc(context1, getBranchesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitBranchStats) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetBranchesArgs) error); ok { - r1 = returnFunc(context1, getBranchesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetBranches_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBranches' -type Client_GetBranches_Call struct { - *mock.Call -} - -// GetBranches is a helper method to define mock.On call -// - context1 -// - getBranchesArgs -func (_e *Client_Expecter) GetBranches(context1 interface{}, getBranchesArgs interface{}) *Client_GetBranches_Call { - return &Client_GetBranches_Call{Call: _e.mock.On("GetBranches", context1, getBranchesArgs)} -} - -func (_c *Client_GetBranches_Call) Run(run func(context1 context.Context, getBranchesArgs git.GetBranchesArgs)) *Client_GetBranches_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetBranchesArgs)) - }) - return _c -} - -func (_c *Client_GetBranches_Call) Return(gitBranchStatss *[]git.GitBranchStats, err error) *Client_GetBranches_Call { - _c.Call.Return(gitBranchStatss, err) - return _c -} - -func (_c *Client_GetBranches_Call) RunAndReturn(run func(context1 context.Context, getBranchesArgs git.GetBranchesArgs) (*[]git.GitBranchStats, error)) *Client_GetBranches_Call { - _c.Call.Return(run) - return _c -} - -// GetChanges provides a mock function for the type Client -func (_mock *Client) GetChanges(context1 context.Context, getChangesArgs git.GetChangesArgs) (*git.GitCommitChanges, error) { - ret := _mock.Called(context1, getChangesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetChanges") - } - - var r0 *git.GitCommitChanges - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetChangesArgs) (*git.GitCommitChanges, error)); ok { - return returnFunc(context1, getChangesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetChangesArgs) *git.GitCommitChanges); ok { - r0 = returnFunc(context1, getChangesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitCommitChanges) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetChangesArgs) error); ok { - r1 = returnFunc(context1, getChangesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetChanges_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetChanges' -type Client_GetChanges_Call struct { - *mock.Call -} - -// GetChanges is a helper method to define mock.On call -// - context1 -// - getChangesArgs -func (_e *Client_Expecter) GetChanges(context1 interface{}, getChangesArgs interface{}) *Client_GetChanges_Call { - return &Client_GetChanges_Call{Call: _e.mock.On("GetChanges", context1, getChangesArgs)} -} - -func (_c *Client_GetChanges_Call) Run(run func(context1 context.Context, getChangesArgs git.GetChangesArgs)) *Client_GetChanges_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetChangesArgs)) - }) - return _c -} - -func (_c *Client_GetChanges_Call) Return(gitCommitChanges *git.GitCommitChanges, err error) *Client_GetChanges_Call { - _c.Call.Return(gitCommitChanges, err) - return _c -} - -func (_c *Client_GetChanges_Call) RunAndReturn(run func(context1 context.Context, getChangesArgs git.GetChangesArgs) (*git.GitCommitChanges, error)) *Client_GetChanges_Call { - _c.Call.Return(run) - return _c -} - -// GetCherryPick provides a mock function for the type Client -func (_mock *Client) GetCherryPick(context1 context.Context, getCherryPickArgs git.GetCherryPickArgs) (*git.GitCherryPick, error) { - ret := _mock.Called(context1, getCherryPickArgs) - - if len(ret) == 0 { - panic("no return value specified for GetCherryPick") - } - - var r0 *git.GitCherryPick - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCherryPickArgs) (*git.GitCherryPick, error)); ok { - return returnFunc(context1, getCherryPickArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCherryPickArgs) *git.GitCherryPick); ok { - r0 = returnFunc(context1, getCherryPickArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitCherryPick) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetCherryPickArgs) error); ok { - r1 = returnFunc(context1, getCherryPickArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetCherryPick_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCherryPick' -type Client_GetCherryPick_Call struct { - *mock.Call -} - -// GetCherryPick is a helper method to define mock.On call -// - context1 -// - getCherryPickArgs -func (_e *Client_Expecter) GetCherryPick(context1 interface{}, getCherryPickArgs interface{}) *Client_GetCherryPick_Call { - return &Client_GetCherryPick_Call{Call: _e.mock.On("GetCherryPick", context1, getCherryPickArgs)} -} - -func (_c *Client_GetCherryPick_Call) Run(run func(context1 context.Context, getCherryPickArgs git.GetCherryPickArgs)) *Client_GetCherryPick_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetCherryPickArgs)) - }) - return _c -} - -func (_c *Client_GetCherryPick_Call) Return(gitCherryPick *git.GitCherryPick, err error) *Client_GetCherryPick_Call { - _c.Call.Return(gitCherryPick, err) - return _c -} - -func (_c *Client_GetCherryPick_Call) RunAndReturn(run func(context1 context.Context, getCherryPickArgs git.GetCherryPickArgs) (*git.GitCherryPick, error)) *Client_GetCherryPick_Call { - _c.Call.Return(run) - return _c -} - -// GetCherryPickForRefName provides a mock function for the type Client -func (_mock *Client) GetCherryPickForRefName(context1 context.Context, getCherryPickForRefNameArgs git.GetCherryPickForRefNameArgs) (*git.GitCherryPick, error) { - ret := _mock.Called(context1, getCherryPickForRefNameArgs) - - if len(ret) == 0 { - panic("no return value specified for GetCherryPickForRefName") - } - - var r0 *git.GitCherryPick - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCherryPickForRefNameArgs) (*git.GitCherryPick, error)); ok { - return returnFunc(context1, getCherryPickForRefNameArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCherryPickForRefNameArgs) *git.GitCherryPick); ok { - r0 = returnFunc(context1, getCherryPickForRefNameArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitCherryPick) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetCherryPickForRefNameArgs) error); ok { - r1 = returnFunc(context1, getCherryPickForRefNameArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetCherryPickForRefName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCherryPickForRefName' -type Client_GetCherryPickForRefName_Call struct { - *mock.Call -} - -// GetCherryPickForRefName is a helper method to define mock.On call -// - context1 -// - getCherryPickForRefNameArgs -func (_e *Client_Expecter) GetCherryPickForRefName(context1 interface{}, getCherryPickForRefNameArgs interface{}) *Client_GetCherryPickForRefName_Call { - return &Client_GetCherryPickForRefName_Call{Call: _e.mock.On("GetCherryPickForRefName", context1, getCherryPickForRefNameArgs)} -} - -func (_c *Client_GetCherryPickForRefName_Call) Run(run func(context1 context.Context, getCherryPickForRefNameArgs git.GetCherryPickForRefNameArgs)) *Client_GetCherryPickForRefName_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetCherryPickForRefNameArgs)) - }) - return _c -} - -func (_c *Client_GetCherryPickForRefName_Call) Return(gitCherryPick *git.GitCherryPick, err error) *Client_GetCherryPickForRefName_Call { - _c.Call.Return(gitCherryPick, err) - return _c -} - -func (_c *Client_GetCherryPickForRefName_Call) RunAndReturn(run func(context1 context.Context, getCherryPickForRefNameArgs git.GetCherryPickForRefNameArgs) (*git.GitCherryPick, error)) *Client_GetCherryPickForRefName_Call { - _c.Call.Return(run) - return _c -} - -// GetComment provides a mock function for the type Client -func (_mock *Client) GetComment(context1 context.Context, getCommentArgs git.GetCommentArgs) (*git.Comment, error) { - ret := _mock.Called(context1, getCommentArgs) - - if len(ret) == 0 { - panic("no return value specified for GetComment") - } - - var r0 *git.Comment - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCommentArgs) (*git.Comment, error)); ok { - return returnFunc(context1, getCommentArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCommentArgs) *git.Comment); ok { - r0 = returnFunc(context1, getCommentArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.Comment) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetCommentArgs) error); ok { - r1 = returnFunc(context1, getCommentArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetComment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetComment' -type Client_GetComment_Call struct { - *mock.Call -} - -// GetComment is a helper method to define mock.On call -// - context1 -// - getCommentArgs -func (_e *Client_Expecter) GetComment(context1 interface{}, getCommentArgs interface{}) *Client_GetComment_Call { - return &Client_GetComment_Call{Call: _e.mock.On("GetComment", context1, getCommentArgs)} -} - -func (_c *Client_GetComment_Call) Run(run func(context1 context.Context, getCommentArgs git.GetCommentArgs)) *Client_GetComment_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetCommentArgs)) - }) - return _c -} - -func (_c *Client_GetComment_Call) Return(comment *git.Comment, err error) *Client_GetComment_Call { - _c.Call.Return(comment, err) - return _c -} - -func (_c *Client_GetComment_Call) RunAndReturn(run func(context1 context.Context, getCommentArgs git.GetCommentArgs) (*git.Comment, error)) *Client_GetComment_Call { - _c.Call.Return(run) - return _c -} - -// GetComments provides a mock function for the type Client -func (_mock *Client) GetComments(context1 context.Context, getCommentsArgs git.GetCommentsArgs) (*[]git.Comment, error) { - ret := _mock.Called(context1, getCommentsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetComments") - } - - var r0 *[]git.Comment - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCommentsArgs) (*[]git.Comment, error)); ok { - return returnFunc(context1, getCommentsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCommentsArgs) *[]git.Comment); ok { - r0 = returnFunc(context1, getCommentsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.Comment) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetCommentsArgs) error); ok { - r1 = returnFunc(context1, getCommentsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetComments_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetComments' -type Client_GetComments_Call struct { - *mock.Call -} - -// GetComments is a helper method to define mock.On call -// - context1 -// - getCommentsArgs -func (_e *Client_Expecter) GetComments(context1 interface{}, getCommentsArgs interface{}) *Client_GetComments_Call { - return &Client_GetComments_Call{Call: _e.mock.On("GetComments", context1, getCommentsArgs)} -} - -func (_c *Client_GetComments_Call) Run(run func(context1 context.Context, getCommentsArgs git.GetCommentsArgs)) *Client_GetComments_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetCommentsArgs)) - }) - return _c -} - -func (_c *Client_GetComments_Call) Return(comments *[]git.Comment, err error) *Client_GetComments_Call { - _c.Call.Return(comments, err) - return _c -} - -func (_c *Client_GetComments_Call) RunAndReturn(run func(context1 context.Context, getCommentsArgs git.GetCommentsArgs) (*[]git.Comment, error)) *Client_GetComments_Call { - _c.Call.Return(run) - return _c -} - -// GetCommit provides a mock function for the type Client -func (_mock *Client) GetCommit(context1 context.Context, getCommitArgs git.GetCommitArgs) (*git.GitCommit, error) { - ret := _mock.Called(context1, getCommitArgs) - - if len(ret) == 0 { - panic("no return value specified for GetCommit") - } - - var r0 *git.GitCommit - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCommitArgs) (*git.GitCommit, error)); ok { - return returnFunc(context1, getCommitArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCommitArgs) *git.GitCommit); ok { - r0 = returnFunc(context1, getCommitArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitCommit) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetCommitArgs) error); ok { - r1 = returnFunc(context1, getCommitArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetCommit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCommit' -type Client_GetCommit_Call struct { - *mock.Call -} - -// GetCommit is a helper method to define mock.On call -// - context1 -// - getCommitArgs -func (_e *Client_Expecter) GetCommit(context1 interface{}, getCommitArgs interface{}) *Client_GetCommit_Call { - return &Client_GetCommit_Call{Call: _e.mock.On("GetCommit", context1, getCommitArgs)} -} - -func (_c *Client_GetCommit_Call) Run(run func(context1 context.Context, getCommitArgs git.GetCommitArgs)) *Client_GetCommit_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetCommitArgs)) - }) - return _c -} - -func (_c *Client_GetCommit_Call) Return(gitCommit *git.GitCommit, err error) *Client_GetCommit_Call { - _c.Call.Return(gitCommit, err) - return _c -} - -func (_c *Client_GetCommit_Call) RunAndReturn(run func(context1 context.Context, getCommitArgs git.GetCommitArgs) (*git.GitCommit, error)) *Client_GetCommit_Call { - _c.Call.Return(run) - return _c -} - -// GetCommitDiffs provides a mock function for the type Client -func (_mock *Client) GetCommitDiffs(context1 context.Context, getCommitDiffsArgs git.GetCommitDiffsArgs) (*git.GitCommitDiffs, error) { - ret := _mock.Called(context1, getCommitDiffsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetCommitDiffs") - } - - var r0 *git.GitCommitDiffs - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCommitDiffsArgs) (*git.GitCommitDiffs, error)); ok { - return returnFunc(context1, getCommitDiffsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCommitDiffsArgs) *git.GitCommitDiffs); ok { - r0 = returnFunc(context1, getCommitDiffsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitCommitDiffs) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetCommitDiffsArgs) error); ok { - r1 = returnFunc(context1, getCommitDiffsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetCommitDiffs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCommitDiffs' -type Client_GetCommitDiffs_Call struct { - *mock.Call -} - -// GetCommitDiffs is a helper method to define mock.On call -// - context1 -// - getCommitDiffsArgs -func (_e *Client_Expecter) GetCommitDiffs(context1 interface{}, getCommitDiffsArgs interface{}) *Client_GetCommitDiffs_Call { - return &Client_GetCommitDiffs_Call{Call: _e.mock.On("GetCommitDiffs", context1, getCommitDiffsArgs)} -} - -func (_c *Client_GetCommitDiffs_Call) Run(run func(context1 context.Context, getCommitDiffsArgs git.GetCommitDiffsArgs)) *Client_GetCommitDiffs_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetCommitDiffsArgs)) - }) - return _c -} - -func (_c *Client_GetCommitDiffs_Call) Return(gitCommitDiffs *git.GitCommitDiffs, err error) *Client_GetCommitDiffs_Call { - _c.Call.Return(gitCommitDiffs, err) - return _c -} - -func (_c *Client_GetCommitDiffs_Call) RunAndReturn(run func(context1 context.Context, getCommitDiffsArgs git.GetCommitDiffsArgs) (*git.GitCommitDiffs, error)) *Client_GetCommitDiffs_Call { - _c.Call.Return(run) - return _c -} - -// GetCommits provides a mock function for the type Client -func (_mock *Client) GetCommits(context1 context.Context, getCommitsArgs git.GetCommitsArgs) (*[]git.GitCommitRef, error) { - ret := _mock.Called(context1, getCommitsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetCommits") - } - - var r0 *[]git.GitCommitRef - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCommitsArgs) (*[]git.GitCommitRef, error)); ok { - return returnFunc(context1, getCommitsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCommitsArgs) *[]git.GitCommitRef); ok { - r0 = returnFunc(context1, getCommitsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitCommitRef) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetCommitsArgs) error); ok { - r1 = returnFunc(context1, getCommitsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetCommits_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCommits' -type Client_GetCommits_Call struct { - *mock.Call -} - -// GetCommits is a helper method to define mock.On call -// - context1 -// - getCommitsArgs -func (_e *Client_Expecter) GetCommits(context1 interface{}, getCommitsArgs interface{}) *Client_GetCommits_Call { - return &Client_GetCommits_Call{Call: _e.mock.On("GetCommits", context1, getCommitsArgs)} -} - -func (_c *Client_GetCommits_Call) Run(run func(context1 context.Context, getCommitsArgs git.GetCommitsArgs)) *Client_GetCommits_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetCommitsArgs)) - }) - return _c -} - -func (_c *Client_GetCommits_Call) Return(gitCommitRefs *[]git.GitCommitRef, err error) *Client_GetCommits_Call { - _c.Call.Return(gitCommitRefs, err) - return _c -} - -func (_c *Client_GetCommits_Call) RunAndReturn(run func(context1 context.Context, getCommitsArgs git.GetCommitsArgs) (*[]git.GitCommitRef, error)) *Client_GetCommits_Call { - _c.Call.Return(run) - return _c -} - -// GetCommitsBatch provides a mock function for the type Client -func (_mock *Client) GetCommitsBatch(context1 context.Context, getCommitsBatchArgs git.GetCommitsBatchArgs) (*[]git.GitCommitRef, error) { - ret := _mock.Called(context1, getCommitsBatchArgs) - - if len(ret) == 0 { - panic("no return value specified for GetCommitsBatch") - } - - var r0 *[]git.GitCommitRef - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCommitsBatchArgs) (*[]git.GitCommitRef, error)); ok { - return returnFunc(context1, getCommitsBatchArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetCommitsBatchArgs) *[]git.GitCommitRef); ok { - r0 = returnFunc(context1, getCommitsBatchArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitCommitRef) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetCommitsBatchArgs) error); ok { - r1 = returnFunc(context1, getCommitsBatchArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetCommitsBatch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCommitsBatch' -type Client_GetCommitsBatch_Call struct { - *mock.Call -} - -// GetCommitsBatch is a helper method to define mock.On call -// - context1 -// - getCommitsBatchArgs -func (_e *Client_Expecter) GetCommitsBatch(context1 interface{}, getCommitsBatchArgs interface{}) *Client_GetCommitsBatch_Call { - return &Client_GetCommitsBatch_Call{Call: _e.mock.On("GetCommitsBatch", context1, getCommitsBatchArgs)} -} - -func (_c *Client_GetCommitsBatch_Call) Run(run func(context1 context.Context, getCommitsBatchArgs git.GetCommitsBatchArgs)) *Client_GetCommitsBatch_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetCommitsBatchArgs)) - }) - return _c -} - -func (_c *Client_GetCommitsBatch_Call) Return(gitCommitRefs *[]git.GitCommitRef, err error) *Client_GetCommitsBatch_Call { - _c.Call.Return(gitCommitRefs, err) - return _c -} - -func (_c *Client_GetCommitsBatch_Call) RunAndReturn(run func(context1 context.Context, getCommitsBatchArgs git.GetCommitsBatchArgs) (*[]git.GitCommitRef, error)) *Client_GetCommitsBatch_Call { - _c.Call.Return(run) - return _c -} - -// GetDeletedRepositories provides a mock function for the type Client -func (_mock *Client) GetDeletedRepositories(context1 context.Context, getDeletedRepositoriesArgs git.GetDeletedRepositoriesArgs) (*[]git.GitDeletedRepository, error) { - ret := _mock.Called(context1, getDeletedRepositoriesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetDeletedRepositories") - } - - var r0 *[]git.GitDeletedRepository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetDeletedRepositoriesArgs) (*[]git.GitDeletedRepository, error)); ok { - return returnFunc(context1, getDeletedRepositoriesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetDeletedRepositoriesArgs) *[]git.GitDeletedRepository); ok { - r0 = returnFunc(context1, getDeletedRepositoriesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitDeletedRepository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetDeletedRepositoriesArgs) error); ok { - r1 = returnFunc(context1, getDeletedRepositoriesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetDeletedRepositories_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDeletedRepositories' -type Client_GetDeletedRepositories_Call struct { - *mock.Call -} - -// GetDeletedRepositories is a helper method to define mock.On call -// - context1 -// - getDeletedRepositoriesArgs -func (_e *Client_Expecter) GetDeletedRepositories(context1 interface{}, getDeletedRepositoriesArgs interface{}) *Client_GetDeletedRepositories_Call { - return &Client_GetDeletedRepositories_Call{Call: _e.mock.On("GetDeletedRepositories", context1, getDeletedRepositoriesArgs)} -} - -func (_c *Client_GetDeletedRepositories_Call) Run(run func(context1 context.Context, getDeletedRepositoriesArgs git.GetDeletedRepositoriesArgs)) *Client_GetDeletedRepositories_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetDeletedRepositoriesArgs)) - }) - return _c -} - -func (_c *Client_GetDeletedRepositories_Call) Return(gitDeletedRepositorys *[]git.GitDeletedRepository, err error) *Client_GetDeletedRepositories_Call { - _c.Call.Return(gitDeletedRepositorys, err) - return _c -} - -func (_c *Client_GetDeletedRepositories_Call) RunAndReturn(run func(context1 context.Context, getDeletedRepositoriesArgs git.GetDeletedRepositoriesArgs) (*[]git.GitDeletedRepository, error)) *Client_GetDeletedRepositories_Call { - _c.Call.Return(run) - return _c -} - -// GetForkSyncRequest provides a mock function for the type Client -func (_mock *Client) GetForkSyncRequest(context1 context.Context, getForkSyncRequestArgs git.GetForkSyncRequestArgs) (*git.GitForkSyncRequest, error) { - ret := _mock.Called(context1, getForkSyncRequestArgs) - - if len(ret) == 0 { - panic("no return value specified for GetForkSyncRequest") - } - - var r0 *git.GitForkSyncRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetForkSyncRequestArgs) (*git.GitForkSyncRequest, error)); ok { - return returnFunc(context1, getForkSyncRequestArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetForkSyncRequestArgs) *git.GitForkSyncRequest); ok { - r0 = returnFunc(context1, getForkSyncRequestArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitForkSyncRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetForkSyncRequestArgs) error); ok { - r1 = returnFunc(context1, getForkSyncRequestArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetForkSyncRequest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetForkSyncRequest' -type Client_GetForkSyncRequest_Call struct { - *mock.Call -} - -// GetForkSyncRequest is a helper method to define mock.On call -// - context1 -// - getForkSyncRequestArgs -func (_e *Client_Expecter) GetForkSyncRequest(context1 interface{}, getForkSyncRequestArgs interface{}) *Client_GetForkSyncRequest_Call { - return &Client_GetForkSyncRequest_Call{Call: _e.mock.On("GetForkSyncRequest", context1, getForkSyncRequestArgs)} -} - -func (_c *Client_GetForkSyncRequest_Call) Run(run func(context1 context.Context, getForkSyncRequestArgs git.GetForkSyncRequestArgs)) *Client_GetForkSyncRequest_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetForkSyncRequestArgs)) - }) - return _c -} - -func (_c *Client_GetForkSyncRequest_Call) Return(gitForkSyncRequest *git.GitForkSyncRequest, err error) *Client_GetForkSyncRequest_Call { - _c.Call.Return(gitForkSyncRequest, err) - return _c -} - -func (_c *Client_GetForkSyncRequest_Call) RunAndReturn(run func(context1 context.Context, getForkSyncRequestArgs git.GetForkSyncRequestArgs) (*git.GitForkSyncRequest, error)) *Client_GetForkSyncRequest_Call { - _c.Call.Return(run) - return _c -} - -// GetForkSyncRequests provides a mock function for the type Client -func (_mock *Client) GetForkSyncRequests(context1 context.Context, getForkSyncRequestsArgs git.GetForkSyncRequestsArgs) (*[]git.GitForkSyncRequest, error) { - ret := _mock.Called(context1, getForkSyncRequestsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetForkSyncRequests") - } - - var r0 *[]git.GitForkSyncRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetForkSyncRequestsArgs) (*[]git.GitForkSyncRequest, error)); ok { - return returnFunc(context1, getForkSyncRequestsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetForkSyncRequestsArgs) *[]git.GitForkSyncRequest); ok { - r0 = returnFunc(context1, getForkSyncRequestsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitForkSyncRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetForkSyncRequestsArgs) error); ok { - r1 = returnFunc(context1, getForkSyncRequestsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetForkSyncRequests_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetForkSyncRequests' -type Client_GetForkSyncRequests_Call struct { - *mock.Call -} - -// GetForkSyncRequests is a helper method to define mock.On call -// - context1 -// - getForkSyncRequestsArgs -func (_e *Client_Expecter) GetForkSyncRequests(context1 interface{}, getForkSyncRequestsArgs interface{}) *Client_GetForkSyncRequests_Call { - return &Client_GetForkSyncRequests_Call{Call: _e.mock.On("GetForkSyncRequests", context1, getForkSyncRequestsArgs)} -} - -func (_c *Client_GetForkSyncRequests_Call) Run(run func(context1 context.Context, getForkSyncRequestsArgs git.GetForkSyncRequestsArgs)) *Client_GetForkSyncRequests_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetForkSyncRequestsArgs)) - }) - return _c -} - -func (_c *Client_GetForkSyncRequests_Call) Return(gitForkSyncRequests *[]git.GitForkSyncRequest, err error) *Client_GetForkSyncRequests_Call { - _c.Call.Return(gitForkSyncRequests, err) - return _c -} - -func (_c *Client_GetForkSyncRequests_Call) RunAndReturn(run func(context1 context.Context, getForkSyncRequestsArgs git.GetForkSyncRequestsArgs) (*[]git.GitForkSyncRequest, error)) *Client_GetForkSyncRequests_Call { - _c.Call.Return(run) - return _c -} - -// GetForks provides a mock function for the type Client -func (_mock *Client) GetForks(context1 context.Context, getForksArgs git.GetForksArgs) (*[]git.GitRepositoryRef, error) { - ret := _mock.Called(context1, getForksArgs) - - if len(ret) == 0 { - panic("no return value specified for GetForks") - } - - var r0 *[]git.GitRepositoryRef - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetForksArgs) (*[]git.GitRepositoryRef, error)); ok { - return returnFunc(context1, getForksArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetForksArgs) *[]git.GitRepositoryRef); ok { - r0 = returnFunc(context1, getForksArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitRepositoryRef) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetForksArgs) error); ok { - r1 = returnFunc(context1, getForksArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetForks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetForks' -type Client_GetForks_Call struct { - *mock.Call -} - -// GetForks is a helper method to define mock.On call -// - context1 -// - getForksArgs -func (_e *Client_Expecter) GetForks(context1 interface{}, getForksArgs interface{}) *Client_GetForks_Call { - return &Client_GetForks_Call{Call: _e.mock.On("GetForks", context1, getForksArgs)} -} - -func (_c *Client_GetForks_Call) Run(run func(context1 context.Context, getForksArgs git.GetForksArgs)) *Client_GetForks_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetForksArgs)) - }) - return _c -} - -func (_c *Client_GetForks_Call) Return(gitRepositoryRefs *[]git.GitRepositoryRef, err error) *Client_GetForks_Call { - _c.Call.Return(gitRepositoryRefs, err) - return _c -} - -func (_c *Client_GetForks_Call) RunAndReturn(run func(context1 context.Context, getForksArgs git.GetForksArgs) (*[]git.GitRepositoryRef, error)) *Client_GetForks_Call { - _c.Call.Return(run) - return _c -} - -// GetImportRequest provides a mock function for the type Client -func (_mock *Client) GetImportRequest(context1 context.Context, getImportRequestArgs git.GetImportRequestArgs) (*git.GitImportRequest, error) { - ret := _mock.Called(context1, getImportRequestArgs) - - if len(ret) == 0 { - panic("no return value specified for GetImportRequest") - } - - var r0 *git.GitImportRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetImportRequestArgs) (*git.GitImportRequest, error)); ok { - return returnFunc(context1, getImportRequestArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetImportRequestArgs) *git.GitImportRequest); ok { - r0 = returnFunc(context1, getImportRequestArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitImportRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetImportRequestArgs) error); ok { - r1 = returnFunc(context1, getImportRequestArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetImportRequest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetImportRequest' -type Client_GetImportRequest_Call struct { - *mock.Call -} - -// GetImportRequest is a helper method to define mock.On call -// - context1 -// - getImportRequestArgs -func (_e *Client_Expecter) GetImportRequest(context1 interface{}, getImportRequestArgs interface{}) *Client_GetImportRequest_Call { - return &Client_GetImportRequest_Call{Call: _e.mock.On("GetImportRequest", context1, getImportRequestArgs)} -} - -func (_c *Client_GetImportRequest_Call) Run(run func(context1 context.Context, getImportRequestArgs git.GetImportRequestArgs)) *Client_GetImportRequest_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetImportRequestArgs)) - }) - return _c -} - -func (_c *Client_GetImportRequest_Call) Return(gitImportRequest *git.GitImportRequest, err error) *Client_GetImportRequest_Call { - _c.Call.Return(gitImportRequest, err) - return _c -} - -func (_c *Client_GetImportRequest_Call) RunAndReturn(run func(context1 context.Context, getImportRequestArgs git.GetImportRequestArgs) (*git.GitImportRequest, error)) *Client_GetImportRequest_Call { - _c.Call.Return(run) - return _c -} - -// GetItem provides a mock function for the type Client -func (_mock *Client) GetItem(context1 context.Context, getItemArgs git.GetItemArgs) (*git.GitItem, error) { - ret := _mock.Called(context1, getItemArgs) - - if len(ret) == 0 { - panic("no return value specified for GetItem") - } - - var r0 *git.GitItem - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetItemArgs) (*git.GitItem, error)); ok { - return returnFunc(context1, getItemArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetItemArgs) *git.GitItem); ok { - r0 = returnFunc(context1, getItemArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitItem) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetItemArgs) error); ok { - r1 = returnFunc(context1, getItemArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetItem_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetItem' -type Client_GetItem_Call struct { - *mock.Call -} - -// GetItem is a helper method to define mock.On call -// - context1 -// - getItemArgs -func (_e *Client_Expecter) GetItem(context1 interface{}, getItemArgs interface{}) *Client_GetItem_Call { - return &Client_GetItem_Call{Call: _e.mock.On("GetItem", context1, getItemArgs)} -} - -func (_c *Client_GetItem_Call) Run(run func(context1 context.Context, getItemArgs git.GetItemArgs)) *Client_GetItem_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetItemArgs)) - }) - return _c -} - -func (_c *Client_GetItem_Call) Return(gitItem *git.GitItem, err error) *Client_GetItem_Call { - _c.Call.Return(gitItem, err) - return _c -} - -func (_c *Client_GetItem_Call) RunAndReturn(run func(context1 context.Context, getItemArgs git.GetItemArgs) (*git.GitItem, error)) *Client_GetItem_Call { - _c.Call.Return(run) - return _c -} - -// GetItemContent provides a mock function for the type Client -func (_mock *Client) GetItemContent(context1 context.Context, getItemContentArgs git.GetItemContentArgs) (io.ReadCloser, error) { - ret := _mock.Called(context1, getItemContentArgs) - - if len(ret) == 0 { - panic("no return value specified for GetItemContent") - } - - var r0 io.ReadCloser - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetItemContentArgs) (io.ReadCloser, error)); ok { - return returnFunc(context1, getItemContentArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetItemContentArgs) io.ReadCloser); ok { - r0 = returnFunc(context1, getItemContentArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(io.ReadCloser) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetItemContentArgs) error); ok { - r1 = returnFunc(context1, getItemContentArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetItemContent_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetItemContent' -type Client_GetItemContent_Call struct { - *mock.Call -} - -// GetItemContent is a helper method to define mock.On call -// - context1 -// - getItemContentArgs -func (_e *Client_Expecter) GetItemContent(context1 interface{}, getItemContentArgs interface{}) *Client_GetItemContent_Call { - return &Client_GetItemContent_Call{Call: _e.mock.On("GetItemContent", context1, getItemContentArgs)} -} - -func (_c *Client_GetItemContent_Call) Run(run func(context1 context.Context, getItemContentArgs git.GetItemContentArgs)) *Client_GetItemContent_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetItemContentArgs)) - }) - return _c -} - -func (_c *Client_GetItemContent_Call) Return(readCloser io.ReadCloser, err error) *Client_GetItemContent_Call { - _c.Call.Return(readCloser, err) - return _c -} - -func (_c *Client_GetItemContent_Call) RunAndReturn(run func(context1 context.Context, getItemContentArgs git.GetItemContentArgs) (io.ReadCloser, error)) *Client_GetItemContent_Call { - _c.Call.Return(run) - return _c -} - -// GetItemText provides a mock function for the type Client -func (_mock *Client) GetItemText(context1 context.Context, getItemTextArgs git.GetItemTextArgs) (io.ReadCloser, error) { - ret := _mock.Called(context1, getItemTextArgs) - - if len(ret) == 0 { - panic("no return value specified for GetItemText") - } - - var r0 io.ReadCloser - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetItemTextArgs) (io.ReadCloser, error)); ok { - return returnFunc(context1, getItemTextArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetItemTextArgs) io.ReadCloser); ok { - r0 = returnFunc(context1, getItemTextArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(io.ReadCloser) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetItemTextArgs) error); ok { - r1 = returnFunc(context1, getItemTextArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetItemText_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetItemText' -type Client_GetItemText_Call struct { - *mock.Call -} - -// GetItemText is a helper method to define mock.On call -// - context1 -// - getItemTextArgs -func (_e *Client_Expecter) GetItemText(context1 interface{}, getItemTextArgs interface{}) *Client_GetItemText_Call { - return &Client_GetItemText_Call{Call: _e.mock.On("GetItemText", context1, getItemTextArgs)} -} - -func (_c *Client_GetItemText_Call) Run(run func(context1 context.Context, getItemTextArgs git.GetItemTextArgs)) *Client_GetItemText_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetItemTextArgs)) - }) - return _c -} - -func (_c *Client_GetItemText_Call) Return(readCloser io.ReadCloser, err error) *Client_GetItemText_Call { - _c.Call.Return(readCloser, err) - return _c -} - -func (_c *Client_GetItemText_Call) RunAndReturn(run func(context1 context.Context, getItemTextArgs git.GetItemTextArgs) (io.ReadCloser, error)) *Client_GetItemText_Call { - _c.Call.Return(run) - return _c -} - -// GetItemZip provides a mock function for the type Client -func (_mock *Client) GetItemZip(context1 context.Context, getItemZipArgs git.GetItemZipArgs) (io.ReadCloser, error) { - ret := _mock.Called(context1, getItemZipArgs) - - if len(ret) == 0 { - panic("no return value specified for GetItemZip") - } - - var r0 io.ReadCloser - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetItemZipArgs) (io.ReadCloser, error)); ok { - return returnFunc(context1, getItemZipArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetItemZipArgs) io.ReadCloser); ok { - r0 = returnFunc(context1, getItemZipArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(io.ReadCloser) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetItemZipArgs) error); ok { - r1 = returnFunc(context1, getItemZipArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetItemZip_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetItemZip' -type Client_GetItemZip_Call struct { - *mock.Call -} - -// GetItemZip is a helper method to define mock.On call -// - context1 -// - getItemZipArgs -func (_e *Client_Expecter) GetItemZip(context1 interface{}, getItemZipArgs interface{}) *Client_GetItemZip_Call { - return &Client_GetItemZip_Call{Call: _e.mock.On("GetItemZip", context1, getItemZipArgs)} -} - -func (_c *Client_GetItemZip_Call) Run(run func(context1 context.Context, getItemZipArgs git.GetItemZipArgs)) *Client_GetItemZip_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetItemZipArgs)) - }) - return _c -} - -func (_c *Client_GetItemZip_Call) Return(readCloser io.ReadCloser, err error) *Client_GetItemZip_Call { - _c.Call.Return(readCloser, err) - return _c -} - -func (_c *Client_GetItemZip_Call) RunAndReturn(run func(context1 context.Context, getItemZipArgs git.GetItemZipArgs) (io.ReadCloser, error)) *Client_GetItemZip_Call { - _c.Call.Return(run) - return _c -} - -// GetItems provides a mock function for the type Client -func (_mock *Client) GetItems(context1 context.Context, getItemsArgs git.GetItemsArgs) (*[]git.GitItem, error) { - ret := _mock.Called(context1, getItemsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetItems") - } - - var r0 *[]git.GitItem - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetItemsArgs) (*[]git.GitItem, error)); ok { - return returnFunc(context1, getItemsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetItemsArgs) *[]git.GitItem); ok { - r0 = returnFunc(context1, getItemsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitItem) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetItemsArgs) error); ok { - r1 = returnFunc(context1, getItemsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetItems_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetItems' -type Client_GetItems_Call struct { - *mock.Call -} - -// GetItems is a helper method to define mock.On call -// - context1 -// - getItemsArgs -func (_e *Client_Expecter) GetItems(context1 interface{}, getItemsArgs interface{}) *Client_GetItems_Call { - return &Client_GetItems_Call{Call: _e.mock.On("GetItems", context1, getItemsArgs)} -} - -func (_c *Client_GetItems_Call) Run(run func(context1 context.Context, getItemsArgs git.GetItemsArgs)) *Client_GetItems_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetItemsArgs)) - }) - return _c -} - -func (_c *Client_GetItems_Call) Return(gitItems *[]git.GitItem, err error) *Client_GetItems_Call { - _c.Call.Return(gitItems, err) - return _c -} - -func (_c *Client_GetItems_Call) RunAndReturn(run func(context1 context.Context, getItemsArgs git.GetItemsArgs) (*[]git.GitItem, error)) *Client_GetItems_Call { - _c.Call.Return(run) - return _c -} - -// GetItemsBatch provides a mock function for the type Client -func (_mock *Client) GetItemsBatch(context1 context.Context, getItemsBatchArgs git.GetItemsBatchArgs) (*[][]git.GitItem, error) { - ret := _mock.Called(context1, getItemsBatchArgs) - - if len(ret) == 0 { - panic("no return value specified for GetItemsBatch") - } - - var r0 *[][]git.GitItem - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetItemsBatchArgs) (*[][]git.GitItem, error)); ok { - return returnFunc(context1, getItemsBatchArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetItemsBatchArgs) *[][]git.GitItem); ok { - r0 = returnFunc(context1, getItemsBatchArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[][]git.GitItem) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetItemsBatchArgs) error); ok { - r1 = returnFunc(context1, getItemsBatchArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetItemsBatch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetItemsBatch' -type Client_GetItemsBatch_Call struct { - *mock.Call -} - -// GetItemsBatch is a helper method to define mock.On call -// - context1 -// - getItemsBatchArgs -func (_e *Client_Expecter) GetItemsBatch(context1 interface{}, getItemsBatchArgs interface{}) *Client_GetItemsBatch_Call { - return &Client_GetItemsBatch_Call{Call: _e.mock.On("GetItemsBatch", context1, getItemsBatchArgs)} -} - -func (_c *Client_GetItemsBatch_Call) Run(run func(context1 context.Context, getItemsBatchArgs git.GetItemsBatchArgs)) *Client_GetItemsBatch_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetItemsBatchArgs)) - }) - return _c -} - -func (_c *Client_GetItemsBatch_Call) Return(gitItemss *[][]git.GitItem, err error) *Client_GetItemsBatch_Call { - _c.Call.Return(gitItemss, err) - return _c -} - -func (_c *Client_GetItemsBatch_Call) RunAndReturn(run func(context1 context.Context, getItemsBatchArgs git.GetItemsBatchArgs) (*[][]git.GitItem, error)) *Client_GetItemsBatch_Call { - _c.Call.Return(run) - return _c -} - -// GetLikes provides a mock function for the type Client -func (_mock *Client) GetLikes(context1 context.Context, getLikesArgs git.GetLikesArgs) (*[]webapi.IdentityRef, error) { - ret := _mock.Called(context1, getLikesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetLikes") - } - - var r0 *[]webapi.IdentityRef - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetLikesArgs) (*[]webapi.IdentityRef, error)); ok { - return returnFunc(context1, getLikesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetLikesArgs) *[]webapi.IdentityRef); ok { - r0 = returnFunc(context1, getLikesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]webapi.IdentityRef) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetLikesArgs) error); ok { - r1 = returnFunc(context1, getLikesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetLikes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLikes' -type Client_GetLikes_Call struct { - *mock.Call -} - -// GetLikes is a helper method to define mock.On call -// - context1 -// - getLikesArgs -func (_e *Client_Expecter) GetLikes(context1 interface{}, getLikesArgs interface{}) *Client_GetLikes_Call { - return &Client_GetLikes_Call{Call: _e.mock.On("GetLikes", context1, getLikesArgs)} -} - -func (_c *Client_GetLikes_Call) Run(run func(context1 context.Context, getLikesArgs git.GetLikesArgs)) *Client_GetLikes_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetLikesArgs)) - }) - return _c -} - -func (_c *Client_GetLikes_Call) Return(identityRefs *[]webapi.IdentityRef, err error) *Client_GetLikes_Call { - _c.Call.Return(identityRefs, err) - return _c -} - -func (_c *Client_GetLikes_Call) RunAndReturn(run func(context1 context.Context, getLikesArgs git.GetLikesArgs) (*[]webapi.IdentityRef, error)) *Client_GetLikes_Call { - _c.Call.Return(run) - return _c -} - -// GetMergeBases provides a mock function for the type Client -func (_mock *Client) GetMergeBases(context1 context.Context, getMergeBasesArgs git.GetMergeBasesArgs) (*[]git.GitCommitRef, error) { - ret := _mock.Called(context1, getMergeBasesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetMergeBases") - } - - var r0 *[]git.GitCommitRef - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetMergeBasesArgs) (*[]git.GitCommitRef, error)); ok { - return returnFunc(context1, getMergeBasesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetMergeBasesArgs) *[]git.GitCommitRef); ok { - r0 = returnFunc(context1, getMergeBasesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitCommitRef) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetMergeBasesArgs) error); ok { - r1 = returnFunc(context1, getMergeBasesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetMergeBases_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetMergeBases' -type Client_GetMergeBases_Call struct { - *mock.Call -} - -// GetMergeBases is a helper method to define mock.On call -// - context1 -// - getMergeBasesArgs -func (_e *Client_Expecter) GetMergeBases(context1 interface{}, getMergeBasesArgs interface{}) *Client_GetMergeBases_Call { - return &Client_GetMergeBases_Call{Call: _e.mock.On("GetMergeBases", context1, getMergeBasesArgs)} -} - -func (_c *Client_GetMergeBases_Call) Run(run func(context1 context.Context, getMergeBasesArgs git.GetMergeBasesArgs)) *Client_GetMergeBases_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetMergeBasesArgs)) - }) - return _c -} - -func (_c *Client_GetMergeBases_Call) Return(gitCommitRefs *[]git.GitCommitRef, err error) *Client_GetMergeBases_Call { - _c.Call.Return(gitCommitRefs, err) - return _c -} - -func (_c *Client_GetMergeBases_Call) RunAndReturn(run func(context1 context.Context, getMergeBasesArgs git.GetMergeBasesArgs) (*[]git.GitCommitRef, error)) *Client_GetMergeBases_Call { - _c.Call.Return(run) - return _c -} - -// GetMergeRequest provides a mock function for the type Client -func (_mock *Client) GetMergeRequest(context1 context.Context, getMergeRequestArgs git.GetMergeRequestArgs) (*git.GitMerge, error) { - ret := _mock.Called(context1, getMergeRequestArgs) - - if len(ret) == 0 { - panic("no return value specified for GetMergeRequest") - } - - var r0 *git.GitMerge - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetMergeRequestArgs) (*git.GitMerge, error)); ok { - return returnFunc(context1, getMergeRequestArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetMergeRequestArgs) *git.GitMerge); ok { - r0 = returnFunc(context1, getMergeRequestArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitMerge) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetMergeRequestArgs) error); ok { - r1 = returnFunc(context1, getMergeRequestArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetMergeRequest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetMergeRequest' -type Client_GetMergeRequest_Call struct { - *mock.Call -} - -// GetMergeRequest is a helper method to define mock.On call -// - context1 -// - getMergeRequestArgs -func (_e *Client_Expecter) GetMergeRequest(context1 interface{}, getMergeRequestArgs interface{}) *Client_GetMergeRequest_Call { - return &Client_GetMergeRequest_Call{Call: _e.mock.On("GetMergeRequest", context1, getMergeRequestArgs)} -} - -func (_c *Client_GetMergeRequest_Call) Run(run func(context1 context.Context, getMergeRequestArgs git.GetMergeRequestArgs)) *Client_GetMergeRequest_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetMergeRequestArgs)) - }) - return _c -} - -func (_c *Client_GetMergeRequest_Call) Return(gitMerge *git.GitMerge, err error) *Client_GetMergeRequest_Call { - _c.Call.Return(gitMerge, err) - return _c -} - -func (_c *Client_GetMergeRequest_Call) RunAndReturn(run func(context1 context.Context, getMergeRequestArgs git.GetMergeRequestArgs) (*git.GitMerge, error)) *Client_GetMergeRequest_Call { - _c.Call.Return(run) - return _c -} - -// GetPermission provides a mock function for the type Client -func (_mock *Client) GetPermission(context1 context.Context, getPermissionArgs git.GetPermissionArgs) (*bool, error) { - ret := _mock.Called(context1, getPermissionArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPermission") - } - - var r0 *bool - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPermissionArgs) (*bool, error)); ok { - return returnFunc(context1, getPermissionArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPermissionArgs) *bool); ok { - r0 = returnFunc(context1, getPermissionArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*bool) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPermissionArgs) error); ok { - r1 = returnFunc(context1, getPermissionArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPermission_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPermission' -type Client_GetPermission_Call struct { - *mock.Call -} - -// GetPermission is a helper method to define mock.On call -// - context1 -// - getPermissionArgs -func (_e *Client_Expecter) GetPermission(context1 interface{}, getPermissionArgs interface{}) *Client_GetPermission_Call { - return &Client_GetPermission_Call{Call: _e.mock.On("GetPermission", context1, getPermissionArgs)} -} - -func (_c *Client_GetPermission_Call) Run(run func(context1 context.Context, getPermissionArgs git.GetPermissionArgs)) *Client_GetPermission_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPermissionArgs)) - }) - return _c -} - -func (_c *Client_GetPermission_Call) Return(b *bool, err error) *Client_GetPermission_Call { - _c.Call.Return(b, err) - return _c -} - -func (_c *Client_GetPermission_Call) RunAndReturn(run func(context1 context.Context, getPermissionArgs git.GetPermissionArgs) (*bool, error)) *Client_GetPermission_Call { - _c.Call.Return(run) - return _c -} - -// GetPolicyConfigurations provides a mock function for the type Client -func (_mock *Client) GetPolicyConfigurations(context1 context.Context, getPolicyConfigurationsArgs git.GetPolicyConfigurationsArgs) (*git.GitPolicyConfigurationResponse, error) { - ret := _mock.Called(context1, getPolicyConfigurationsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPolicyConfigurations") - } - - var r0 *git.GitPolicyConfigurationResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPolicyConfigurationsArgs) (*git.GitPolicyConfigurationResponse, error)); ok { - return returnFunc(context1, getPolicyConfigurationsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPolicyConfigurationsArgs) *git.GitPolicyConfigurationResponse); ok { - r0 = returnFunc(context1, getPolicyConfigurationsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPolicyConfigurationResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPolicyConfigurationsArgs) error); ok { - r1 = returnFunc(context1, getPolicyConfigurationsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPolicyConfigurations_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPolicyConfigurations' -type Client_GetPolicyConfigurations_Call struct { - *mock.Call -} - -// GetPolicyConfigurations is a helper method to define mock.On call -// - context1 -// - getPolicyConfigurationsArgs -func (_e *Client_Expecter) GetPolicyConfigurations(context1 interface{}, getPolicyConfigurationsArgs interface{}) *Client_GetPolicyConfigurations_Call { - return &Client_GetPolicyConfigurations_Call{Call: _e.mock.On("GetPolicyConfigurations", context1, getPolicyConfigurationsArgs)} -} - -func (_c *Client_GetPolicyConfigurations_Call) Run(run func(context1 context.Context, getPolicyConfigurationsArgs git.GetPolicyConfigurationsArgs)) *Client_GetPolicyConfigurations_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPolicyConfigurationsArgs)) - }) - return _c -} - -func (_c *Client_GetPolicyConfigurations_Call) Return(gitPolicyConfigurationResponse *git.GitPolicyConfigurationResponse, err error) *Client_GetPolicyConfigurations_Call { - _c.Call.Return(gitPolicyConfigurationResponse, err) - return _c -} - -func (_c *Client_GetPolicyConfigurations_Call) RunAndReturn(run func(context1 context.Context, getPolicyConfigurationsArgs git.GetPolicyConfigurationsArgs) (*git.GitPolicyConfigurationResponse, error)) *Client_GetPolicyConfigurations_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequest provides a mock function for the type Client -func (_mock *Client) GetPullRequest(context1 context.Context, getPullRequestArgs git.GetPullRequestArgs) (*git.GitPullRequest, error) { - ret := _mock.Called(context1, getPullRequestArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequest") - } - - var r0 *git.GitPullRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestArgs) (*git.GitPullRequest, error)); ok { - return returnFunc(context1, getPullRequestArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestArgs) *git.GitPullRequest); ok { - r0 = returnFunc(context1, getPullRequestArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestArgs) error); ok { - r1 = returnFunc(context1, getPullRequestArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequest' -type Client_GetPullRequest_Call struct { - *mock.Call -} - -// GetPullRequest is a helper method to define mock.On call -// - context1 -// - getPullRequestArgs -func (_e *Client_Expecter) GetPullRequest(context1 interface{}, getPullRequestArgs interface{}) *Client_GetPullRequest_Call { - return &Client_GetPullRequest_Call{Call: _e.mock.On("GetPullRequest", context1, getPullRequestArgs)} -} - -func (_c *Client_GetPullRequest_Call) Run(run func(context1 context.Context, getPullRequestArgs git.GetPullRequestArgs)) *Client_GetPullRequest_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequest_Call) Return(gitPullRequest *git.GitPullRequest, err error) *Client_GetPullRequest_Call { - _c.Call.Return(gitPullRequest, err) - return _c -} - -func (_c *Client_GetPullRequest_Call) RunAndReturn(run func(context1 context.Context, getPullRequestArgs git.GetPullRequestArgs) (*git.GitPullRequest, error)) *Client_GetPullRequest_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestById provides a mock function for the type Client -func (_mock *Client) GetPullRequestById(context1 context.Context, getPullRequestByIdArgs git.GetPullRequestByIdArgs) (*git.GitPullRequest, error) { - ret := _mock.Called(context1, getPullRequestByIdArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestById") - } - - var r0 *git.GitPullRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestByIdArgs) (*git.GitPullRequest, error)); ok { - return returnFunc(context1, getPullRequestByIdArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestByIdArgs) *git.GitPullRequest); ok { - r0 = returnFunc(context1, getPullRequestByIdArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestByIdArgs) error); ok { - r1 = returnFunc(context1, getPullRequestByIdArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestById_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestById' -type Client_GetPullRequestById_Call struct { - *mock.Call -} - -// GetPullRequestById is a helper method to define mock.On call -// - context1 -// - getPullRequestByIdArgs -func (_e *Client_Expecter) GetPullRequestById(context1 interface{}, getPullRequestByIdArgs interface{}) *Client_GetPullRequestById_Call { - return &Client_GetPullRequestById_Call{Call: _e.mock.On("GetPullRequestById", context1, getPullRequestByIdArgs)} -} - -func (_c *Client_GetPullRequestById_Call) Run(run func(context1 context.Context, getPullRequestByIdArgs git.GetPullRequestByIdArgs)) *Client_GetPullRequestById_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestByIdArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestById_Call) Return(gitPullRequest *git.GitPullRequest, err error) *Client_GetPullRequestById_Call { - _c.Call.Return(gitPullRequest, err) - return _c -} - -func (_c *Client_GetPullRequestById_Call) RunAndReturn(run func(context1 context.Context, getPullRequestByIdArgs git.GetPullRequestByIdArgs) (*git.GitPullRequest, error)) *Client_GetPullRequestById_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestCommits provides a mock function for the type Client -func (_mock *Client) GetPullRequestCommits(context1 context.Context, getPullRequestCommitsArgs git.GetPullRequestCommitsArgs) (*git.GetPullRequestCommitsResponseValue, error) { - ret := _mock.Called(context1, getPullRequestCommitsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestCommits") - } - - var r0 *git.GetPullRequestCommitsResponseValue - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestCommitsArgs) (*git.GetPullRequestCommitsResponseValue, error)); ok { - return returnFunc(context1, getPullRequestCommitsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestCommitsArgs) *git.GetPullRequestCommitsResponseValue); ok { - r0 = returnFunc(context1, getPullRequestCommitsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GetPullRequestCommitsResponseValue) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestCommitsArgs) error); ok { - r1 = returnFunc(context1, getPullRequestCommitsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestCommits_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestCommits' -type Client_GetPullRequestCommits_Call struct { - *mock.Call -} - -// GetPullRequestCommits is a helper method to define mock.On call -// - context1 -// - getPullRequestCommitsArgs -func (_e *Client_Expecter) GetPullRequestCommits(context1 interface{}, getPullRequestCommitsArgs interface{}) *Client_GetPullRequestCommits_Call { - return &Client_GetPullRequestCommits_Call{Call: _e.mock.On("GetPullRequestCommits", context1, getPullRequestCommitsArgs)} -} - -func (_c *Client_GetPullRequestCommits_Call) Run(run func(context1 context.Context, getPullRequestCommitsArgs git.GetPullRequestCommitsArgs)) *Client_GetPullRequestCommits_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestCommitsArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestCommits_Call) Return(getPullRequestCommitsResponseValue *git.GetPullRequestCommitsResponseValue, err error) *Client_GetPullRequestCommits_Call { - _c.Call.Return(getPullRequestCommitsResponseValue, err) - return _c -} - -func (_c *Client_GetPullRequestCommits_Call) RunAndReturn(run func(context1 context.Context, getPullRequestCommitsArgs git.GetPullRequestCommitsArgs) (*git.GetPullRequestCommitsResponseValue, error)) *Client_GetPullRequestCommits_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestIteration provides a mock function for the type Client -func (_mock *Client) GetPullRequestIteration(context1 context.Context, getPullRequestIterationArgs git.GetPullRequestIterationArgs) (*git.GitPullRequestIteration, error) { - ret := _mock.Called(context1, getPullRequestIterationArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestIteration") - } - - var r0 *git.GitPullRequestIteration - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationArgs) (*git.GitPullRequestIteration, error)); ok { - return returnFunc(context1, getPullRequestIterationArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationArgs) *git.GitPullRequestIteration); ok { - r0 = returnFunc(context1, getPullRequestIterationArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequestIteration) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationArgs) error); ok { - r1 = returnFunc(context1, getPullRequestIterationArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestIteration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestIteration' -type Client_GetPullRequestIteration_Call struct { - *mock.Call -} - -// GetPullRequestIteration is a helper method to define mock.On call -// - context1 -// - getPullRequestIterationArgs -func (_e *Client_Expecter) GetPullRequestIteration(context1 interface{}, getPullRequestIterationArgs interface{}) *Client_GetPullRequestIteration_Call { - return &Client_GetPullRequestIteration_Call{Call: _e.mock.On("GetPullRequestIteration", context1, getPullRequestIterationArgs)} -} - -func (_c *Client_GetPullRequestIteration_Call) Run(run func(context1 context.Context, getPullRequestIterationArgs git.GetPullRequestIterationArgs)) *Client_GetPullRequestIteration_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestIterationArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestIteration_Call) Return(gitPullRequestIteration *git.GitPullRequestIteration, err error) *Client_GetPullRequestIteration_Call { - _c.Call.Return(gitPullRequestIteration, err) - return _c -} - -func (_c *Client_GetPullRequestIteration_Call) RunAndReturn(run func(context1 context.Context, getPullRequestIterationArgs git.GetPullRequestIterationArgs) (*git.GitPullRequestIteration, error)) *Client_GetPullRequestIteration_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestIterationChanges provides a mock function for the type Client -func (_mock *Client) GetPullRequestIterationChanges(context1 context.Context, getPullRequestIterationChangesArgs git.GetPullRequestIterationChangesArgs) (*git.GitPullRequestIterationChanges, error) { - ret := _mock.Called(context1, getPullRequestIterationChangesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestIterationChanges") - } - - var r0 *git.GitPullRequestIterationChanges - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationChangesArgs) (*git.GitPullRequestIterationChanges, error)); ok { - return returnFunc(context1, getPullRequestIterationChangesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationChangesArgs) *git.GitPullRequestIterationChanges); ok { - r0 = returnFunc(context1, getPullRequestIterationChangesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequestIterationChanges) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationChangesArgs) error); ok { - r1 = returnFunc(context1, getPullRequestIterationChangesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestIterationChanges_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestIterationChanges' -type Client_GetPullRequestIterationChanges_Call struct { - *mock.Call -} - -// GetPullRequestIterationChanges is a helper method to define mock.On call -// - context1 -// - getPullRequestIterationChangesArgs -func (_e *Client_Expecter) GetPullRequestIterationChanges(context1 interface{}, getPullRequestIterationChangesArgs interface{}) *Client_GetPullRequestIterationChanges_Call { - return &Client_GetPullRequestIterationChanges_Call{Call: _e.mock.On("GetPullRequestIterationChanges", context1, getPullRequestIterationChangesArgs)} -} - -func (_c *Client_GetPullRequestIterationChanges_Call) Run(run func(context1 context.Context, getPullRequestIterationChangesArgs git.GetPullRequestIterationChangesArgs)) *Client_GetPullRequestIterationChanges_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestIterationChangesArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestIterationChanges_Call) Return(gitPullRequestIterationChanges *git.GitPullRequestIterationChanges, err error) *Client_GetPullRequestIterationChanges_Call { - _c.Call.Return(gitPullRequestIterationChanges, err) - return _c -} - -func (_c *Client_GetPullRequestIterationChanges_Call) RunAndReturn(run func(context1 context.Context, getPullRequestIterationChangesArgs git.GetPullRequestIterationChangesArgs) (*git.GitPullRequestIterationChanges, error)) *Client_GetPullRequestIterationChanges_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestIterationCommits provides a mock function for the type Client -func (_mock *Client) GetPullRequestIterationCommits(context1 context.Context, getPullRequestIterationCommitsArgs git.GetPullRequestIterationCommitsArgs) (*[]git.GitCommitRef, error) { - ret := _mock.Called(context1, getPullRequestIterationCommitsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestIterationCommits") - } - - var r0 *[]git.GitCommitRef - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationCommitsArgs) (*[]git.GitCommitRef, error)); ok { - return returnFunc(context1, getPullRequestIterationCommitsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationCommitsArgs) *[]git.GitCommitRef); ok { - r0 = returnFunc(context1, getPullRequestIterationCommitsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitCommitRef) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationCommitsArgs) error); ok { - r1 = returnFunc(context1, getPullRequestIterationCommitsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestIterationCommits_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestIterationCommits' -type Client_GetPullRequestIterationCommits_Call struct { - *mock.Call -} - -// GetPullRequestIterationCommits is a helper method to define mock.On call -// - context1 -// - getPullRequestIterationCommitsArgs -func (_e *Client_Expecter) GetPullRequestIterationCommits(context1 interface{}, getPullRequestIterationCommitsArgs interface{}) *Client_GetPullRequestIterationCommits_Call { - return &Client_GetPullRequestIterationCommits_Call{Call: _e.mock.On("GetPullRequestIterationCommits", context1, getPullRequestIterationCommitsArgs)} -} - -func (_c *Client_GetPullRequestIterationCommits_Call) Run(run func(context1 context.Context, getPullRequestIterationCommitsArgs git.GetPullRequestIterationCommitsArgs)) *Client_GetPullRequestIterationCommits_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestIterationCommitsArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestIterationCommits_Call) Return(gitCommitRefs *[]git.GitCommitRef, err error) *Client_GetPullRequestIterationCommits_Call { - _c.Call.Return(gitCommitRefs, err) - return _c -} - -func (_c *Client_GetPullRequestIterationCommits_Call) RunAndReturn(run func(context1 context.Context, getPullRequestIterationCommitsArgs git.GetPullRequestIterationCommitsArgs) (*[]git.GitCommitRef, error)) *Client_GetPullRequestIterationCommits_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestIterationStatus provides a mock function for the type Client -func (_mock *Client) GetPullRequestIterationStatus(context1 context.Context, getPullRequestIterationStatusArgs git.GetPullRequestIterationStatusArgs) (*git.GitPullRequestStatus, error) { - ret := _mock.Called(context1, getPullRequestIterationStatusArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestIterationStatus") - } - - var r0 *git.GitPullRequestStatus - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationStatusArgs) (*git.GitPullRequestStatus, error)); ok { - return returnFunc(context1, getPullRequestIterationStatusArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationStatusArgs) *git.GitPullRequestStatus); ok { - r0 = returnFunc(context1, getPullRequestIterationStatusArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequestStatus) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationStatusArgs) error); ok { - r1 = returnFunc(context1, getPullRequestIterationStatusArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestIterationStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestIterationStatus' -type Client_GetPullRequestIterationStatus_Call struct { - *mock.Call -} - -// GetPullRequestIterationStatus is a helper method to define mock.On call -// - context1 -// - getPullRequestIterationStatusArgs -func (_e *Client_Expecter) GetPullRequestIterationStatus(context1 interface{}, getPullRequestIterationStatusArgs interface{}) *Client_GetPullRequestIterationStatus_Call { - return &Client_GetPullRequestIterationStatus_Call{Call: _e.mock.On("GetPullRequestIterationStatus", context1, getPullRequestIterationStatusArgs)} -} - -func (_c *Client_GetPullRequestIterationStatus_Call) Run(run func(context1 context.Context, getPullRequestIterationStatusArgs git.GetPullRequestIterationStatusArgs)) *Client_GetPullRequestIterationStatus_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestIterationStatusArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestIterationStatus_Call) Return(gitPullRequestStatus *git.GitPullRequestStatus, err error) *Client_GetPullRequestIterationStatus_Call { - _c.Call.Return(gitPullRequestStatus, err) - return _c -} - -func (_c *Client_GetPullRequestIterationStatus_Call) RunAndReturn(run func(context1 context.Context, getPullRequestIterationStatusArgs git.GetPullRequestIterationStatusArgs) (*git.GitPullRequestStatus, error)) *Client_GetPullRequestIterationStatus_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestIterationStatuses provides a mock function for the type Client -func (_mock *Client) GetPullRequestIterationStatuses(context1 context.Context, getPullRequestIterationStatusesArgs git.GetPullRequestIterationStatusesArgs) (*[]git.GitPullRequestStatus, error) { - ret := _mock.Called(context1, getPullRequestIterationStatusesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestIterationStatuses") - } - - var r0 *[]git.GitPullRequestStatus - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationStatusesArgs) (*[]git.GitPullRequestStatus, error)); ok { - return returnFunc(context1, getPullRequestIterationStatusesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationStatusesArgs) *[]git.GitPullRequestStatus); ok { - r0 = returnFunc(context1, getPullRequestIterationStatusesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitPullRequestStatus) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationStatusesArgs) error); ok { - r1 = returnFunc(context1, getPullRequestIterationStatusesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestIterationStatuses_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestIterationStatuses' -type Client_GetPullRequestIterationStatuses_Call struct { - *mock.Call -} - -// GetPullRequestIterationStatuses is a helper method to define mock.On call -// - context1 -// - getPullRequestIterationStatusesArgs -func (_e *Client_Expecter) GetPullRequestIterationStatuses(context1 interface{}, getPullRequestIterationStatusesArgs interface{}) *Client_GetPullRequestIterationStatuses_Call { - return &Client_GetPullRequestIterationStatuses_Call{Call: _e.mock.On("GetPullRequestIterationStatuses", context1, getPullRequestIterationStatusesArgs)} -} - -func (_c *Client_GetPullRequestIterationStatuses_Call) Run(run func(context1 context.Context, getPullRequestIterationStatusesArgs git.GetPullRequestIterationStatusesArgs)) *Client_GetPullRequestIterationStatuses_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestIterationStatusesArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestIterationStatuses_Call) Return(gitPullRequestStatuss *[]git.GitPullRequestStatus, err error) *Client_GetPullRequestIterationStatuses_Call { - _c.Call.Return(gitPullRequestStatuss, err) - return _c -} - -func (_c *Client_GetPullRequestIterationStatuses_Call) RunAndReturn(run func(context1 context.Context, getPullRequestIterationStatusesArgs git.GetPullRequestIterationStatusesArgs) (*[]git.GitPullRequestStatus, error)) *Client_GetPullRequestIterationStatuses_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestIterations provides a mock function for the type Client -func (_mock *Client) GetPullRequestIterations(context1 context.Context, getPullRequestIterationsArgs git.GetPullRequestIterationsArgs) (*[]git.GitPullRequestIteration, error) { - ret := _mock.Called(context1, getPullRequestIterationsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestIterations") - } - - var r0 *[]git.GitPullRequestIteration - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationsArgs) (*[]git.GitPullRequestIteration, error)); ok { - return returnFunc(context1, getPullRequestIterationsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationsArgs) *[]git.GitPullRequestIteration); ok { - r0 = returnFunc(context1, getPullRequestIterationsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitPullRequestIteration) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationsArgs) error); ok { - r1 = returnFunc(context1, getPullRequestIterationsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestIterations_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestIterations' -type Client_GetPullRequestIterations_Call struct { - *mock.Call -} - -// GetPullRequestIterations is a helper method to define mock.On call -// - context1 -// - getPullRequestIterationsArgs -func (_e *Client_Expecter) GetPullRequestIterations(context1 interface{}, getPullRequestIterationsArgs interface{}) *Client_GetPullRequestIterations_Call { - return &Client_GetPullRequestIterations_Call{Call: _e.mock.On("GetPullRequestIterations", context1, getPullRequestIterationsArgs)} -} - -func (_c *Client_GetPullRequestIterations_Call) Run(run func(context1 context.Context, getPullRequestIterationsArgs git.GetPullRequestIterationsArgs)) *Client_GetPullRequestIterations_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestIterationsArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestIterations_Call) Return(gitPullRequestIterations *[]git.GitPullRequestIteration, err error) *Client_GetPullRequestIterations_Call { - _c.Call.Return(gitPullRequestIterations, err) - return _c -} - -func (_c *Client_GetPullRequestIterations_Call) RunAndReturn(run func(context1 context.Context, getPullRequestIterationsArgs git.GetPullRequestIterationsArgs) (*[]git.GitPullRequestIteration, error)) *Client_GetPullRequestIterations_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestLabel provides a mock function for the type Client -func (_mock *Client) GetPullRequestLabel(context1 context.Context, getPullRequestLabelArgs git.GetPullRequestLabelArgs) (*core.WebApiTagDefinition, error) { - ret := _mock.Called(context1, getPullRequestLabelArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestLabel") - } - - var r0 *core.WebApiTagDefinition - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestLabelArgs) (*core.WebApiTagDefinition, error)); ok { - return returnFunc(context1, getPullRequestLabelArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestLabelArgs) *core.WebApiTagDefinition); ok { - r0 = returnFunc(context1, getPullRequestLabelArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*core.WebApiTagDefinition) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestLabelArgs) error); ok { - r1 = returnFunc(context1, getPullRequestLabelArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestLabel_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestLabel' -type Client_GetPullRequestLabel_Call struct { - *mock.Call -} - -// GetPullRequestLabel is a helper method to define mock.On call -// - context1 -// - getPullRequestLabelArgs -func (_e *Client_Expecter) GetPullRequestLabel(context1 interface{}, getPullRequestLabelArgs interface{}) *Client_GetPullRequestLabel_Call { - return &Client_GetPullRequestLabel_Call{Call: _e.mock.On("GetPullRequestLabel", context1, getPullRequestLabelArgs)} -} - -func (_c *Client_GetPullRequestLabel_Call) Run(run func(context1 context.Context, getPullRequestLabelArgs git.GetPullRequestLabelArgs)) *Client_GetPullRequestLabel_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestLabelArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestLabel_Call) Return(webApiTagDefinition *core.WebApiTagDefinition, err error) *Client_GetPullRequestLabel_Call { - _c.Call.Return(webApiTagDefinition, err) - return _c -} - -func (_c *Client_GetPullRequestLabel_Call) RunAndReturn(run func(context1 context.Context, getPullRequestLabelArgs git.GetPullRequestLabelArgs) (*core.WebApiTagDefinition, error)) *Client_GetPullRequestLabel_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestLabels provides a mock function for the type Client -func (_mock *Client) GetPullRequestLabels(context1 context.Context, getPullRequestLabelsArgs git.GetPullRequestLabelsArgs) (*[]core.WebApiTagDefinition, error) { - ret := _mock.Called(context1, getPullRequestLabelsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestLabels") - } - - var r0 *[]core.WebApiTagDefinition - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestLabelsArgs) (*[]core.WebApiTagDefinition, error)); ok { - return returnFunc(context1, getPullRequestLabelsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestLabelsArgs) *[]core.WebApiTagDefinition); ok { - r0 = returnFunc(context1, getPullRequestLabelsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]core.WebApiTagDefinition) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestLabelsArgs) error); ok { - r1 = returnFunc(context1, getPullRequestLabelsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestLabels_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestLabels' -type Client_GetPullRequestLabels_Call struct { - *mock.Call -} - -// GetPullRequestLabels is a helper method to define mock.On call -// - context1 -// - getPullRequestLabelsArgs -func (_e *Client_Expecter) GetPullRequestLabels(context1 interface{}, getPullRequestLabelsArgs interface{}) *Client_GetPullRequestLabels_Call { - return &Client_GetPullRequestLabels_Call{Call: _e.mock.On("GetPullRequestLabels", context1, getPullRequestLabelsArgs)} -} - -func (_c *Client_GetPullRequestLabels_Call) Run(run func(context1 context.Context, getPullRequestLabelsArgs git.GetPullRequestLabelsArgs)) *Client_GetPullRequestLabels_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestLabelsArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestLabels_Call) Return(webApiTagDefinitions *[]core.WebApiTagDefinition, err error) *Client_GetPullRequestLabels_Call { - _c.Call.Return(webApiTagDefinitions, err) - return _c -} - -func (_c *Client_GetPullRequestLabels_Call) RunAndReturn(run func(context1 context.Context, getPullRequestLabelsArgs git.GetPullRequestLabelsArgs) (*[]core.WebApiTagDefinition, error)) *Client_GetPullRequestLabels_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestProperties provides a mock function for the type Client -func (_mock *Client) GetPullRequestProperties(context1 context.Context, getPullRequestPropertiesArgs git.GetPullRequestPropertiesArgs) (interface{}, error) { - ret := _mock.Called(context1, getPullRequestPropertiesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestProperties") - } - - var r0 interface{} - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestPropertiesArgs) (interface{}, error)); ok { - return returnFunc(context1, getPullRequestPropertiesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestPropertiesArgs) interface{}); ok { - r0 = returnFunc(context1, getPullRequestPropertiesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(interface{}) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestPropertiesArgs) error); ok { - r1 = returnFunc(context1, getPullRequestPropertiesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestProperties_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestProperties' -type Client_GetPullRequestProperties_Call struct { - *mock.Call -} - -// GetPullRequestProperties is a helper method to define mock.On call -// - context1 -// - getPullRequestPropertiesArgs -func (_e *Client_Expecter) GetPullRequestProperties(context1 interface{}, getPullRequestPropertiesArgs interface{}) *Client_GetPullRequestProperties_Call { - return &Client_GetPullRequestProperties_Call{Call: _e.mock.On("GetPullRequestProperties", context1, getPullRequestPropertiesArgs)} -} - -func (_c *Client_GetPullRequestProperties_Call) Run(run func(context1 context.Context, getPullRequestPropertiesArgs git.GetPullRequestPropertiesArgs)) *Client_GetPullRequestProperties_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestPropertiesArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestProperties_Call) Return(ifaceVal interface{}, err error) *Client_GetPullRequestProperties_Call { - _c.Call.Return(ifaceVal, err) - return _c -} - -func (_c *Client_GetPullRequestProperties_Call) RunAndReturn(run func(context1 context.Context, getPullRequestPropertiesArgs git.GetPullRequestPropertiesArgs) (interface{}, error)) *Client_GetPullRequestProperties_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestQuery provides a mock function for the type Client -func (_mock *Client) GetPullRequestQuery(context1 context.Context, getPullRequestQueryArgs git.GetPullRequestQueryArgs) (*git.GitPullRequestQuery, error) { - ret := _mock.Called(context1, getPullRequestQueryArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestQuery") - } - - var r0 *git.GitPullRequestQuery - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestQueryArgs) (*git.GitPullRequestQuery, error)); ok { - return returnFunc(context1, getPullRequestQueryArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestQueryArgs) *git.GitPullRequestQuery); ok { - r0 = returnFunc(context1, getPullRequestQueryArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequestQuery) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestQueryArgs) error); ok { - r1 = returnFunc(context1, getPullRequestQueryArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestQuery_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestQuery' -type Client_GetPullRequestQuery_Call struct { - *mock.Call -} - -// GetPullRequestQuery is a helper method to define mock.On call -// - context1 -// - getPullRequestQueryArgs -func (_e *Client_Expecter) GetPullRequestQuery(context1 interface{}, getPullRequestQueryArgs interface{}) *Client_GetPullRequestQuery_Call { - return &Client_GetPullRequestQuery_Call{Call: _e.mock.On("GetPullRequestQuery", context1, getPullRequestQueryArgs)} -} - -func (_c *Client_GetPullRequestQuery_Call) Run(run func(context1 context.Context, getPullRequestQueryArgs git.GetPullRequestQueryArgs)) *Client_GetPullRequestQuery_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestQueryArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestQuery_Call) Return(gitPullRequestQuery *git.GitPullRequestQuery, err error) *Client_GetPullRequestQuery_Call { - _c.Call.Return(gitPullRequestQuery, err) - return _c -} - -func (_c *Client_GetPullRequestQuery_Call) RunAndReturn(run func(context1 context.Context, getPullRequestQueryArgs git.GetPullRequestQueryArgs) (*git.GitPullRequestQuery, error)) *Client_GetPullRequestQuery_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestReviewer provides a mock function for the type Client -func (_mock *Client) GetPullRequestReviewer(context1 context.Context, getPullRequestReviewerArgs git.GetPullRequestReviewerArgs) (*git.IdentityRefWithVote, error) { - ret := _mock.Called(context1, getPullRequestReviewerArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestReviewer") - } - - var r0 *git.IdentityRefWithVote - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestReviewerArgs) (*git.IdentityRefWithVote, error)); ok { - return returnFunc(context1, getPullRequestReviewerArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestReviewerArgs) *git.IdentityRefWithVote); ok { - r0 = returnFunc(context1, getPullRequestReviewerArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.IdentityRefWithVote) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestReviewerArgs) error); ok { - r1 = returnFunc(context1, getPullRequestReviewerArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestReviewer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestReviewer' -type Client_GetPullRequestReviewer_Call struct { - *mock.Call -} - -// GetPullRequestReviewer is a helper method to define mock.On call -// - context1 -// - getPullRequestReviewerArgs -func (_e *Client_Expecter) GetPullRequestReviewer(context1 interface{}, getPullRequestReviewerArgs interface{}) *Client_GetPullRequestReviewer_Call { - return &Client_GetPullRequestReviewer_Call{Call: _e.mock.On("GetPullRequestReviewer", context1, getPullRequestReviewerArgs)} -} - -func (_c *Client_GetPullRequestReviewer_Call) Run(run func(context1 context.Context, getPullRequestReviewerArgs git.GetPullRequestReviewerArgs)) *Client_GetPullRequestReviewer_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestReviewerArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestReviewer_Call) Return(identityRefWithVote *git.IdentityRefWithVote, err error) *Client_GetPullRequestReviewer_Call { - _c.Call.Return(identityRefWithVote, err) - return _c -} - -func (_c *Client_GetPullRequestReviewer_Call) RunAndReturn(run func(context1 context.Context, getPullRequestReviewerArgs git.GetPullRequestReviewerArgs) (*git.IdentityRefWithVote, error)) *Client_GetPullRequestReviewer_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestReviewers provides a mock function for the type Client -func (_mock *Client) GetPullRequestReviewers(context1 context.Context, getPullRequestReviewersArgs git.GetPullRequestReviewersArgs) (*[]git.IdentityRefWithVote, error) { - ret := _mock.Called(context1, getPullRequestReviewersArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestReviewers") - } - - var r0 *[]git.IdentityRefWithVote - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestReviewersArgs) (*[]git.IdentityRefWithVote, error)); ok { - return returnFunc(context1, getPullRequestReviewersArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestReviewersArgs) *[]git.IdentityRefWithVote); ok { - r0 = returnFunc(context1, getPullRequestReviewersArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.IdentityRefWithVote) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestReviewersArgs) error); ok { - r1 = returnFunc(context1, getPullRequestReviewersArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestReviewers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestReviewers' -type Client_GetPullRequestReviewers_Call struct { - *mock.Call -} - -// GetPullRequestReviewers is a helper method to define mock.On call -// - context1 -// - getPullRequestReviewersArgs -func (_e *Client_Expecter) GetPullRequestReviewers(context1 interface{}, getPullRequestReviewersArgs interface{}) *Client_GetPullRequestReviewers_Call { - return &Client_GetPullRequestReviewers_Call{Call: _e.mock.On("GetPullRequestReviewers", context1, getPullRequestReviewersArgs)} -} - -func (_c *Client_GetPullRequestReviewers_Call) Run(run func(context1 context.Context, getPullRequestReviewersArgs git.GetPullRequestReviewersArgs)) *Client_GetPullRequestReviewers_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestReviewersArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestReviewers_Call) Return(identityRefWithVotes *[]git.IdentityRefWithVote, err error) *Client_GetPullRequestReviewers_Call { - _c.Call.Return(identityRefWithVotes, err) - return _c -} - -func (_c *Client_GetPullRequestReviewers_Call) RunAndReturn(run func(context1 context.Context, getPullRequestReviewersArgs git.GetPullRequestReviewersArgs) (*[]git.IdentityRefWithVote, error)) *Client_GetPullRequestReviewers_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestStatus provides a mock function for the type Client -func (_mock *Client) GetPullRequestStatus(context1 context.Context, getPullRequestStatusArgs git.GetPullRequestStatusArgs) (*git.GitPullRequestStatus, error) { - ret := _mock.Called(context1, getPullRequestStatusArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestStatus") - } - - var r0 *git.GitPullRequestStatus - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestStatusArgs) (*git.GitPullRequestStatus, error)); ok { - return returnFunc(context1, getPullRequestStatusArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestStatusArgs) *git.GitPullRequestStatus); ok { - r0 = returnFunc(context1, getPullRequestStatusArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequestStatus) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestStatusArgs) error); ok { - r1 = returnFunc(context1, getPullRequestStatusArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestStatus' -type Client_GetPullRequestStatus_Call struct { - *mock.Call -} - -// GetPullRequestStatus is a helper method to define mock.On call -// - context1 -// - getPullRequestStatusArgs -func (_e *Client_Expecter) GetPullRequestStatus(context1 interface{}, getPullRequestStatusArgs interface{}) *Client_GetPullRequestStatus_Call { - return &Client_GetPullRequestStatus_Call{Call: _e.mock.On("GetPullRequestStatus", context1, getPullRequestStatusArgs)} -} - -func (_c *Client_GetPullRequestStatus_Call) Run(run func(context1 context.Context, getPullRequestStatusArgs git.GetPullRequestStatusArgs)) *Client_GetPullRequestStatus_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestStatusArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestStatus_Call) Return(gitPullRequestStatus *git.GitPullRequestStatus, err error) *Client_GetPullRequestStatus_Call { - _c.Call.Return(gitPullRequestStatus, err) - return _c -} - -func (_c *Client_GetPullRequestStatus_Call) RunAndReturn(run func(context1 context.Context, getPullRequestStatusArgs git.GetPullRequestStatusArgs) (*git.GitPullRequestStatus, error)) *Client_GetPullRequestStatus_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestStatuses provides a mock function for the type Client -func (_mock *Client) GetPullRequestStatuses(context1 context.Context, getPullRequestStatusesArgs git.GetPullRequestStatusesArgs) (*[]git.GitPullRequestStatus, error) { - ret := _mock.Called(context1, getPullRequestStatusesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestStatuses") - } - - var r0 *[]git.GitPullRequestStatus - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestStatusesArgs) (*[]git.GitPullRequestStatus, error)); ok { - return returnFunc(context1, getPullRequestStatusesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestStatusesArgs) *[]git.GitPullRequestStatus); ok { - r0 = returnFunc(context1, getPullRequestStatusesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitPullRequestStatus) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestStatusesArgs) error); ok { - r1 = returnFunc(context1, getPullRequestStatusesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestStatuses_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestStatuses' -type Client_GetPullRequestStatuses_Call struct { - *mock.Call -} - -// GetPullRequestStatuses is a helper method to define mock.On call -// - context1 -// - getPullRequestStatusesArgs -func (_e *Client_Expecter) GetPullRequestStatuses(context1 interface{}, getPullRequestStatusesArgs interface{}) *Client_GetPullRequestStatuses_Call { - return &Client_GetPullRequestStatuses_Call{Call: _e.mock.On("GetPullRequestStatuses", context1, getPullRequestStatusesArgs)} -} - -func (_c *Client_GetPullRequestStatuses_Call) Run(run func(context1 context.Context, getPullRequestStatusesArgs git.GetPullRequestStatusesArgs)) *Client_GetPullRequestStatuses_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestStatusesArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestStatuses_Call) Return(gitPullRequestStatuss *[]git.GitPullRequestStatus, err error) *Client_GetPullRequestStatuses_Call { - _c.Call.Return(gitPullRequestStatuss, err) - return _c -} - -func (_c *Client_GetPullRequestStatuses_Call) RunAndReturn(run func(context1 context.Context, getPullRequestStatusesArgs git.GetPullRequestStatusesArgs) (*[]git.GitPullRequestStatus, error)) *Client_GetPullRequestStatuses_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestThread provides a mock function for the type Client -func (_mock *Client) GetPullRequestThread(context1 context.Context, getPullRequestThreadArgs git.GetPullRequestThreadArgs) (*git.GitPullRequestCommentThread, error) { - ret := _mock.Called(context1, getPullRequestThreadArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestThread") - } - - var r0 *git.GitPullRequestCommentThread - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestThreadArgs) (*git.GitPullRequestCommentThread, error)); ok { - return returnFunc(context1, getPullRequestThreadArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestThreadArgs) *git.GitPullRequestCommentThread); ok { - r0 = returnFunc(context1, getPullRequestThreadArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequestCommentThread) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestThreadArgs) error); ok { - r1 = returnFunc(context1, getPullRequestThreadArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestThread_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestThread' -type Client_GetPullRequestThread_Call struct { - *mock.Call -} - -// GetPullRequestThread is a helper method to define mock.On call -// - context1 -// - getPullRequestThreadArgs -func (_e *Client_Expecter) GetPullRequestThread(context1 interface{}, getPullRequestThreadArgs interface{}) *Client_GetPullRequestThread_Call { - return &Client_GetPullRequestThread_Call{Call: _e.mock.On("GetPullRequestThread", context1, getPullRequestThreadArgs)} -} - -func (_c *Client_GetPullRequestThread_Call) Run(run func(context1 context.Context, getPullRequestThreadArgs git.GetPullRequestThreadArgs)) *Client_GetPullRequestThread_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestThreadArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestThread_Call) Return(gitPullRequestCommentThread *git.GitPullRequestCommentThread, err error) *Client_GetPullRequestThread_Call { - _c.Call.Return(gitPullRequestCommentThread, err) - return _c -} - -func (_c *Client_GetPullRequestThread_Call) RunAndReturn(run func(context1 context.Context, getPullRequestThreadArgs git.GetPullRequestThreadArgs) (*git.GitPullRequestCommentThread, error)) *Client_GetPullRequestThread_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestWorkItemRefs provides a mock function for the type Client -func (_mock *Client) GetPullRequestWorkItemRefs(context1 context.Context, getPullRequestWorkItemRefsArgs git.GetPullRequestWorkItemRefsArgs) (*[]webapi.ResourceRef, error) { - ret := _mock.Called(context1, getPullRequestWorkItemRefsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestWorkItemRefs") - } - - var r0 *[]webapi.ResourceRef - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestWorkItemRefsArgs) (*[]webapi.ResourceRef, error)); ok { - return returnFunc(context1, getPullRequestWorkItemRefsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestWorkItemRefsArgs) *[]webapi.ResourceRef); ok { - r0 = returnFunc(context1, getPullRequestWorkItemRefsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]webapi.ResourceRef) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestWorkItemRefsArgs) error); ok { - r1 = returnFunc(context1, getPullRequestWorkItemRefsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestWorkItemRefs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestWorkItemRefs' -type Client_GetPullRequestWorkItemRefs_Call struct { - *mock.Call -} - -// GetPullRequestWorkItemRefs is a helper method to define mock.On call -// - context1 -// - getPullRequestWorkItemRefsArgs -func (_e *Client_Expecter) GetPullRequestWorkItemRefs(context1 interface{}, getPullRequestWorkItemRefsArgs interface{}) *Client_GetPullRequestWorkItemRefs_Call { - return &Client_GetPullRequestWorkItemRefs_Call{Call: _e.mock.On("GetPullRequestWorkItemRefs", context1, getPullRequestWorkItemRefsArgs)} -} - -func (_c *Client_GetPullRequestWorkItemRefs_Call) Run(run func(context1 context.Context, getPullRequestWorkItemRefsArgs git.GetPullRequestWorkItemRefsArgs)) *Client_GetPullRequestWorkItemRefs_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestWorkItemRefsArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestWorkItemRefs_Call) Return(resourceRefs *[]webapi.ResourceRef, err error) *Client_GetPullRequestWorkItemRefs_Call { - _c.Call.Return(resourceRefs, err) - return _c -} - -func (_c *Client_GetPullRequestWorkItemRefs_Call) RunAndReturn(run func(context1 context.Context, getPullRequestWorkItemRefsArgs git.GetPullRequestWorkItemRefsArgs) (*[]webapi.ResourceRef, error)) *Client_GetPullRequestWorkItemRefs_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequests provides a mock function for the type Client -func (_mock *Client) GetPullRequests(context1 context.Context, getPullRequestsArgs git.GetPullRequestsArgs) (*[]git.GitPullRequest, error) { - ret := _mock.Called(context1, getPullRequestsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequests") - } - - var r0 *[]git.GitPullRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestsArgs) (*[]git.GitPullRequest, error)); ok { - return returnFunc(context1, getPullRequestsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestsArgs) *[]git.GitPullRequest); ok { - r0 = returnFunc(context1, getPullRequestsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitPullRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestsArgs) error); ok { - r1 = returnFunc(context1, getPullRequestsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequests_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequests' -type Client_GetPullRequests_Call struct { - *mock.Call -} - -// GetPullRequests is a helper method to define mock.On call -// - context1 -// - getPullRequestsArgs -func (_e *Client_Expecter) GetPullRequests(context1 interface{}, getPullRequestsArgs interface{}) *Client_GetPullRequests_Call { - return &Client_GetPullRequests_Call{Call: _e.mock.On("GetPullRequests", context1, getPullRequestsArgs)} -} - -func (_c *Client_GetPullRequests_Call) Run(run func(context1 context.Context, getPullRequestsArgs git.GetPullRequestsArgs)) *Client_GetPullRequests_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestsArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequests_Call) Return(gitPullRequests *[]git.GitPullRequest, err error) *Client_GetPullRequests_Call { - _c.Call.Return(gitPullRequests, err) - return _c -} - -func (_c *Client_GetPullRequests_Call) RunAndReturn(run func(context1 context.Context, getPullRequestsArgs git.GetPullRequestsArgs) (*[]git.GitPullRequest, error)) *Client_GetPullRequests_Call { - _c.Call.Return(run) - return _c -} - -// GetPullRequestsByProject provides a mock function for the type Client -func (_mock *Client) GetPullRequestsByProject(context1 context.Context, getPullRequestsByProjectArgs git.GetPullRequestsByProjectArgs) (*[]git.GitPullRequest, error) { - ret := _mock.Called(context1, getPullRequestsByProjectArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPullRequestsByProject") - } - - var r0 *[]git.GitPullRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestsByProjectArgs) (*[]git.GitPullRequest, error)); ok { - return returnFunc(context1, getPullRequestsByProjectArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPullRequestsByProjectArgs) *[]git.GitPullRequest); ok { - r0 = returnFunc(context1, getPullRequestsByProjectArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitPullRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPullRequestsByProjectArgs) error); ok { - r1 = returnFunc(context1, getPullRequestsByProjectArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPullRequestsByProject_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPullRequestsByProject' -type Client_GetPullRequestsByProject_Call struct { - *mock.Call -} - -// GetPullRequestsByProject is a helper method to define mock.On call -// - context1 -// - getPullRequestsByProjectArgs -func (_e *Client_Expecter) GetPullRequestsByProject(context1 interface{}, getPullRequestsByProjectArgs interface{}) *Client_GetPullRequestsByProject_Call { - return &Client_GetPullRequestsByProject_Call{Call: _e.mock.On("GetPullRequestsByProject", context1, getPullRequestsByProjectArgs)} -} - -func (_c *Client_GetPullRequestsByProject_Call) Run(run func(context1 context.Context, getPullRequestsByProjectArgs git.GetPullRequestsByProjectArgs)) *Client_GetPullRequestsByProject_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPullRequestsByProjectArgs)) - }) - return _c -} - -func (_c *Client_GetPullRequestsByProject_Call) Return(gitPullRequests *[]git.GitPullRequest, err error) *Client_GetPullRequestsByProject_Call { - _c.Call.Return(gitPullRequests, err) - return _c -} - -func (_c *Client_GetPullRequestsByProject_Call) RunAndReturn(run func(context1 context.Context, getPullRequestsByProjectArgs git.GetPullRequestsByProjectArgs) (*[]git.GitPullRequest, error)) *Client_GetPullRequestsByProject_Call { - _c.Call.Return(run) - return _c -} - -// GetPush provides a mock function for the type Client -func (_mock *Client) GetPush(context1 context.Context, getPushArgs git.GetPushArgs) (*git.GitPush, error) { - ret := _mock.Called(context1, getPushArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPush") - } - - var r0 *git.GitPush - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPushArgs) (*git.GitPush, error)); ok { - return returnFunc(context1, getPushArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPushArgs) *git.GitPush); ok { - r0 = returnFunc(context1, getPushArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPush) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPushArgs) error); ok { - r1 = returnFunc(context1, getPushArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPush_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPush' -type Client_GetPush_Call struct { - *mock.Call -} - -// GetPush is a helper method to define mock.On call -// - context1 -// - getPushArgs -func (_e *Client_Expecter) GetPush(context1 interface{}, getPushArgs interface{}) *Client_GetPush_Call { - return &Client_GetPush_Call{Call: _e.mock.On("GetPush", context1, getPushArgs)} -} - -func (_c *Client_GetPush_Call) Run(run func(context1 context.Context, getPushArgs git.GetPushArgs)) *Client_GetPush_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPushArgs)) - }) - return _c -} - -func (_c *Client_GetPush_Call) Return(gitPush *git.GitPush, err error) *Client_GetPush_Call { - _c.Call.Return(gitPush, err) - return _c -} - -func (_c *Client_GetPush_Call) RunAndReturn(run func(context1 context.Context, getPushArgs git.GetPushArgs) (*git.GitPush, error)) *Client_GetPush_Call { - _c.Call.Return(run) - return _c -} - -// GetPushCommits provides a mock function for the type Client -func (_mock *Client) GetPushCommits(context1 context.Context, getPushCommitsArgs git.GetPushCommitsArgs) (*[]git.GitCommitRef, error) { - ret := _mock.Called(context1, getPushCommitsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPushCommits") - } - - var r0 *[]git.GitCommitRef - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPushCommitsArgs) (*[]git.GitCommitRef, error)); ok { - return returnFunc(context1, getPushCommitsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPushCommitsArgs) *[]git.GitCommitRef); ok { - r0 = returnFunc(context1, getPushCommitsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitCommitRef) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPushCommitsArgs) error); ok { - r1 = returnFunc(context1, getPushCommitsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPushCommits_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPushCommits' -type Client_GetPushCommits_Call struct { - *mock.Call -} - -// GetPushCommits is a helper method to define mock.On call -// - context1 -// - getPushCommitsArgs -func (_e *Client_Expecter) GetPushCommits(context1 interface{}, getPushCommitsArgs interface{}) *Client_GetPushCommits_Call { - return &Client_GetPushCommits_Call{Call: _e.mock.On("GetPushCommits", context1, getPushCommitsArgs)} -} - -func (_c *Client_GetPushCommits_Call) Run(run func(context1 context.Context, getPushCommitsArgs git.GetPushCommitsArgs)) *Client_GetPushCommits_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPushCommitsArgs)) - }) - return _c -} - -func (_c *Client_GetPushCommits_Call) Return(gitCommitRefs *[]git.GitCommitRef, err error) *Client_GetPushCommits_Call { - _c.Call.Return(gitCommitRefs, err) - return _c -} - -func (_c *Client_GetPushCommits_Call) RunAndReturn(run func(context1 context.Context, getPushCommitsArgs git.GetPushCommitsArgs) (*[]git.GitCommitRef, error)) *Client_GetPushCommits_Call { - _c.Call.Return(run) - return _c -} - -// GetPushes provides a mock function for the type Client -func (_mock *Client) GetPushes(context1 context.Context, getPushesArgs git.GetPushesArgs) (*[]git.GitPush, error) { - ret := _mock.Called(context1, getPushesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetPushes") - } - - var r0 *[]git.GitPush - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPushesArgs) (*[]git.GitPush, error)); ok { - return returnFunc(context1, getPushesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetPushesArgs) *[]git.GitPush); ok { - r0 = returnFunc(context1, getPushesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitPush) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetPushesArgs) error); ok { - r1 = returnFunc(context1, getPushesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetPushes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPushes' -type Client_GetPushes_Call struct { - *mock.Call -} - -// GetPushes is a helper method to define mock.On call -// - context1 -// - getPushesArgs -func (_e *Client_Expecter) GetPushes(context1 interface{}, getPushesArgs interface{}) *Client_GetPushes_Call { - return &Client_GetPushes_Call{Call: _e.mock.On("GetPushes", context1, getPushesArgs)} -} - -func (_c *Client_GetPushes_Call) Run(run func(context1 context.Context, getPushesArgs git.GetPushesArgs)) *Client_GetPushes_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetPushesArgs)) - }) - return _c -} - -func (_c *Client_GetPushes_Call) Return(gitPushs *[]git.GitPush, err error) *Client_GetPushes_Call { - _c.Call.Return(gitPushs, err) - return _c -} - -func (_c *Client_GetPushes_Call) RunAndReturn(run func(context1 context.Context, getPushesArgs git.GetPushesArgs) (*[]git.GitPush, error)) *Client_GetPushes_Call { - _c.Call.Return(run) - return _c -} - -// GetRecycleBinRepositories provides a mock function for the type Client -func (_mock *Client) GetRecycleBinRepositories(context1 context.Context, getRecycleBinRepositoriesArgs git.GetRecycleBinRepositoriesArgs) (*[]git.GitDeletedRepository, error) { - ret := _mock.Called(context1, getRecycleBinRepositoriesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetRecycleBinRepositories") - } - - var r0 *[]git.GitDeletedRepository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRecycleBinRepositoriesArgs) (*[]git.GitDeletedRepository, error)); ok { - return returnFunc(context1, getRecycleBinRepositoriesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRecycleBinRepositoriesArgs) *[]git.GitDeletedRepository); ok { - r0 = returnFunc(context1, getRecycleBinRepositoriesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitDeletedRepository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetRecycleBinRepositoriesArgs) error); ok { - r1 = returnFunc(context1, getRecycleBinRepositoriesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetRecycleBinRepositories_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRecycleBinRepositories' -type Client_GetRecycleBinRepositories_Call struct { - *mock.Call -} - -// GetRecycleBinRepositories is a helper method to define mock.On call -// - context1 -// - getRecycleBinRepositoriesArgs -func (_e *Client_Expecter) GetRecycleBinRepositories(context1 interface{}, getRecycleBinRepositoriesArgs interface{}) *Client_GetRecycleBinRepositories_Call { - return &Client_GetRecycleBinRepositories_Call{Call: _e.mock.On("GetRecycleBinRepositories", context1, getRecycleBinRepositoriesArgs)} -} - -func (_c *Client_GetRecycleBinRepositories_Call) Run(run func(context1 context.Context, getRecycleBinRepositoriesArgs git.GetRecycleBinRepositoriesArgs)) *Client_GetRecycleBinRepositories_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetRecycleBinRepositoriesArgs)) - }) - return _c -} - -func (_c *Client_GetRecycleBinRepositories_Call) Return(gitDeletedRepositorys *[]git.GitDeletedRepository, err error) *Client_GetRecycleBinRepositories_Call { - _c.Call.Return(gitDeletedRepositorys, err) - return _c -} - -func (_c *Client_GetRecycleBinRepositories_Call) RunAndReturn(run func(context1 context.Context, getRecycleBinRepositoriesArgs git.GetRecycleBinRepositoriesArgs) (*[]git.GitDeletedRepository, error)) *Client_GetRecycleBinRepositories_Call { - _c.Call.Return(run) - return _c -} - -// GetRefFavorite provides a mock function for the type Client -func (_mock *Client) GetRefFavorite(context1 context.Context, getRefFavoriteArgs git.GetRefFavoriteArgs) (*git.GitRefFavorite, error) { - ret := _mock.Called(context1, getRefFavoriteArgs) - - if len(ret) == 0 { - panic("no return value specified for GetRefFavorite") - } - - var r0 *git.GitRefFavorite - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRefFavoriteArgs) (*git.GitRefFavorite, error)); ok { - return returnFunc(context1, getRefFavoriteArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRefFavoriteArgs) *git.GitRefFavorite); ok { - r0 = returnFunc(context1, getRefFavoriteArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitRefFavorite) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetRefFavoriteArgs) error); ok { - r1 = returnFunc(context1, getRefFavoriteArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetRefFavorite_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRefFavorite' -type Client_GetRefFavorite_Call struct { - *mock.Call -} - -// GetRefFavorite is a helper method to define mock.On call -// - context1 -// - getRefFavoriteArgs -func (_e *Client_Expecter) GetRefFavorite(context1 interface{}, getRefFavoriteArgs interface{}) *Client_GetRefFavorite_Call { - return &Client_GetRefFavorite_Call{Call: _e.mock.On("GetRefFavorite", context1, getRefFavoriteArgs)} -} - -func (_c *Client_GetRefFavorite_Call) Run(run func(context1 context.Context, getRefFavoriteArgs git.GetRefFavoriteArgs)) *Client_GetRefFavorite_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetRefFavoriteArgs)) - }) - return _c -} - -func (_c *Client_GetRefFavorite_Call) Return(gitRefFavorite *git.GitRefFavorite, err error) *Client_GetRefFavorite_Call { - _c.Call.Return(gitRefFavorite, err) - return _c -} - -func (_c *Client_GetRefFavorite_Call) RunAndReturn(run func(context1 context.Context, getRefFavoriteArgs git.GetRefFavoriteArgs) (*git.GitRefFavorite, error)) *Client_GetRefFavorite_Call { - _c.Call.Return(run) - return _c -} - -// GetRefFavorites provides a mock function for the type Client -func (_mock *Client) GetRefFavorites(context1 context.Context, getRefFavoritesArgs git.GetRefFavoritesArgs) (*[]git.GitRefFavorite, error) { - ret := _mock.Called(context1, getRefFavoritesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetRefFavorites") - } - - var r0 *[]git.GitRefFavorite - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRefFavoritesArgs) (*[]git.GitRefFavorite, error)); ok { - return returnFunc(context1, getRefFavoritesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRefFavoritesArgs) *[]git.GitRefFavorite); ok { - r0 = returnFunc(context1, getRefFavoritesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitRefFavorite) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetRefFavoritesArgs) error); ok { - r1 = returnFunc(context1, getRefFavoritesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetRefFavorites_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRefFavorites' -type Client_GetRefFavorites_Call struct { - *mock.Call -} - -// GetRefFavorites is a helper method to define mock.On call -// - context1 -// - getRefFavoritesArgs -func (_e *Client_Expecter) GetRefFavorites(context1 interface{}, getRefFavoritesArgs interface{}) *Client_GetRefFavorites_Call { - return &Client_GetRefFavorites_Call{Call: _e.mock.On("GetRefFavorites", context1, getRefFavoritesArgs)} -} - -func (_c *Client_GetRefFavorites_Call) Run(run func(context1 context.Context, getRefFavoritesArgs git.GetRefFavoritesArgs)) *Client_GetRefFavorites_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetRefFavoritesArgs)) - }) - return _c -} - -func (_c *Client_GetRefFavorites_Call) Return(gitRefFavorites *[]git.GitRefFavorite, err error) *Client_GetRefFavorites_Call { - _c.Call.Return(gitRefFavorites, err) - return _c -} - -func (_c *Client_GetRefFavorites_Call) RunAndReturn(run func(context1 context.Context, getRefFavoritesArgs git.GetRefFavoritesArgs) (*[]git.GitRefFavorite, error)) *Client_GetRefFavorites_Call { - _c.Call.Return(run) - return _c -} - -// GetRefs provides a mock function for the type Client -func (_mock *Client) GetRefs(context1 context.Context, getRefsArgs git.GetRefsArgs) (*git.GetRefsResponseValue, error) { - ret := _mock.Called(context1, getRefsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetRefs") - } - - var r0 *git.GetRefsResponseValue - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRefsArgs) (*git.GetRefsResponseValue, error)); ok { - return returnFunc(context1, getRefsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRefsArgs) *git.GetRefsResponseValue); ok { - r0 = returnFunc(context1, getRefsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GetRefsResponseValue) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetRefsArgs) error); ok { - r1 = returnFunc(context1, getRefsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetRefs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRefs' -type Client_GetRefs_Call struct { - *mock.Call -} - -// GetRefs is a helper method to define mock.On call -// - context1 -// - getRefsArgs -func (_e *Client_Expecter) GetRefs(context1 interface{}, getRefsArgs interface{}) *Client_GetRefs_Call { - return &Client_GetRefs_Call{Call: _e.mock.On("GetRefs", context1, getRefsArgs)} -} - -func (_c *Client_GetRefs_Call) Run(run func(context1 context.Context, getRefsArgs git.GetRefsArgs)) *Client_GetRefs_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetRefsArgs)) - }) - return _c -} - -func (_c *Client_GetRefs_Call) Return(getRefsResponseValue *git.GetRefsResponseValue, err error) *Client_GetRefs_Call { - _c.Call.Return(getRefsResponseValue, err) - return _c -} - -func (_c *Client_GetRefs_Call) RunAndReturn(run func(context1 context.Context, getRefsArgs git.GetRefsArgs) (*git.GetRefsResponseValue, error)) *Client_GetRefs_Call { - _c.Call.Return(run) - return _c -} - -// GetRepositories provides a mock function for the type Client -func (_mock *Client) GetRepositories(context1 context.Context, getRepositoriesArgs git.GetRepositoriesArgs) (*[]git.GitRepository, error) { - ret := _mock.Called(context1, getRepositoriesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetRepositories") - } - - var r0 *[]git.GitRepository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRepositoriesArgs) (*[]git.GitRepository, error)); ok { - return returnFunc(context1, getRepositoriesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRepositoriesArgs) *[]git.GitRepository); ok { - r0 = returnFunc(context1, getRepositoriesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitRepository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetRepositoriesArgs) error); ok { - r1 = returnFunc(context1, getRepositoriesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetRepositories_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRepositories' -type Client_GetRepositories_Call struct { - *mock.Call -} - -// GetRepositories is a helper method to define mock.On call -// - context1 -// - getRepositoriesArgs -func (_e *Client_Expecter) GetRepositories(context1 interface{}, getRepositoriesArgs interface{}) *Client_GetRepositories_Call { - return &Client_GetRepositories_Call{Call: _e.mock.On("GetRepositories", context1, getRepositoriesArgs)} -} - -func (_c *Client_GetRepositories_Call) Run(run func(context1 context.Context, getRepositoriesArgs git.GetRepositoriesArgs)) *Client_GetRepositories_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetRepositoriesArgs)) - }) - return _c -} - -func (_c *Client_GetRepositories_Call) Return(gitRepositorys *[]git.GitRepository, err error) *Client_GetRepositories_Call { - _c.Call.Return(gitRepositorys, err) - return _c -} - -func (_c *Client_GetRepositories_Call) RunAndReturn(run func(context1 context.Context, getRepositoriesArgs git.GetRepositoriesArgs) (*[]git.GitRepository, error)) *Client_GetRepositories_Call { - _c.Call.Return(run) - return _c -} - -// GetRepository provides a mock function for the type Client -func (_mock *Client) GetRepository(context1 context.Context, getRepositoryArgs git.GetRepositoryArgs) (*git.GitRepository, error) { - ret := _mock.Called(context1, getRepositoryArgs) - - if len(ret) == 0 { - panic("no return value specified for GetRepository") - } - - var r0 *git.GitRepository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRepositoryArgs) (*git.GitRepository, error)); ok { - return returnFunc(context1, getRepositoryArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRepositoryArgs) *git.GitRepository); ok { - r0 = returnFunc(context1, getRepositoryArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitRepository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetRepositoryArgs) error); ok { - r1 = returnFunc(context1, getRepositoryArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRepository' -type Client_GetRepository_Call struct { - *mock.Call -} - -// GetRepository is a helper method to define mock.On call -// - context1 -// - getRepositoryArgs -func (_e *Client_Expecter) GetRepository(context1 interface{}, getRepositoryArgs interface{}) *Client_GetRepository_Call { - return &Client_GetRepository_Call{Call: _e.mock.On("GetRepository", context1, getRepositoryArgs)} -} - -func (_c *Client_GetRepository_Call) Run(run func(context1 context.Context, getRepositoryArgs git.GetRepositoryArgs)) *Client_GetRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetRepositoryArgs)) - }) - return _c -} - -func (_c *Client_GetRepository_Call) Return(gitRepository *git.GitRepository, err error) *Client_GetRepository_Call { - _c.Call.Return(gitRepository, err) - return _c -} - -func (_c *Client_GetRepository_Call) RunAndReturn(run func(context1 context.Context, getRepositoryArgs git.GetRepositoryArgs) (*git.GitRepository, error)) *Client_GetRepository_Call { - _c.Call.Return(run) - return _c -} - -// GetRepositoryWithParent provides a mock function for the type Client -func (_mock *Client) GetRepositoryWithParent(context1 context.Context, getRepositoryWithParentArgs git.GetRepositoryWithParentArgs) (*git.GitRepository, error) { - ret := _mock.Called(context1, getRepositoryWithParentArgs) - - if len(ret) == 0 { - panic("no return value specified for GetRepositoryWithParent") - } - - var r0 *git.GitRepository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRepositoryWithParentArgs) (*git.GitRepository, error)); ok { - return returnFunc(context1, getRepositoryWithParentArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRepositoryWithParentArgs) *git.GitRepository); ok { - r0 = returnFunc(context1, getRepositoryWithParentArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitRepository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetRepositoryWithParentArgs) error); ok { - r1 = returnFunc(context1, getRepositoryWithParentArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetRepositoryWithParent_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRepositoryWithParent' -type Client_GetRepositoryWithParent_Call struct { - *mock.Call -} - -// GetRepositoryWithParent is a helper method to define mock.On call -// - context1 -// - getRepositoryWithParentArgs -func (_e *Client_Expecter) GetRepositoryWithParent(context1 interface{}, getRepositoryWithParentArgs interface{}) *Client_GetRepositoryWithParent_Call { - return &Client_GetRepositoryWithParent_Call{Call: _e.mock.On("GetRepositoryWithParent", context1, getRepositoryWithParentArgs)} -} - -func (_c *Client_GetRepositoryWithParent_Call) Run(run func(context1 context.Context, getRepositoryWithParentArgs git.GetRepositoryWithParentArgs)) *Client_GetRepositoryWithParent_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetRepositoryWithParentArgs)) - }) - return _c -} - -func (_c *Client_GetRepositoryWithParent_Call) Return(gitRepository *git.GitRepository, err error) *Client_GetRepositoryWithParent_Call { - _c.Call.Return(gitRepository, err) - return _c -} - -func (_c *Client_GetRepositoryWithParent_Call) RunAndReturn(run func(context1 context.Context, getRepositoryWithParentArgs git.GetRepositoryWithParentArgs) (*git.GitRepository, error)) *Client_GetRepositoryWithParent_Call { - _c.Call.Return(run) - return _c -} - -// GetRevert provides a mock function for the type Client -func (_mock *Client) GetRevert(context1 context.Context, getRevertArgs git.GetRevertArgs) (*git.GitRevert, error) { - ret := _mock.Called(context1, getRevertArgs) - - if len(ret) == 0 { - panic("no return value specified for GetRevert") - } - - var r0 *git.GitRevert - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRevertArgs) (*git.GitRevert, error)); ok { - return returnFunc(context1, getRevertArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRevertArgs) *git.GitRevert); ok { - r0 = returnFunc(context1, getRevertArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitRevert) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetRevertArgs) error); ok { - r1 = returnFunc(context1, getRevertArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetRevert_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRevert' -type Client_GetRevert_Call struct { - *mock.Call -} - -// GetRevert is a helper method to define mock.On call -// - context1 -// - getRevertArgs -func (_e *Client_Expecter) GetRevert(context1 interface{}, getRevertArgs interface{}) *Client_GetRevert_Call { - return &Client_GetRevert_Call{Call: _e.mock.On("GetRevert", context1, getRevertArgs)} -} - -func (_c *Client_GetRevert_Call) Run(run func(context1 context.Context, getRevertArgs git.GetRevertArgs)) *Client_GetRevert_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetRevertArgs)) - }) - return _c -} - -func (_c *Client_GetRevert_Call) Return(gitRevert *git.GitRevert, err error) *Client_GetRevert_Call { - _c.Call.Return(gitRevert, err) - return _c -} - -func (_c *Client_GetRevert_Call) RunAndReturn(run func(context1 context.Context, getRevertArgs git.GetRevertArgs) (*git.GitRevert, error)) *Client_GetRevert_Call { - _c.Call.Return(run) - return _c -} - -// GetRevertForRefName provides a mock function for the type Client -func (_mock *Client) GetRevertForRefName(context1 context.Context, getRevertForRefNameArgs git.GetRevertForRefNameArgs) (*git.GitRevert, error) { - ret := _mock.Called(context1, getRevertForRefNameArgs) - - if len(ret) == 0 { - panic("no return value specified for GetRevertForRefName") - } - - var r0 *git.GitRevert - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRevertForRefNameArgs) (*git.GitRevert, error)); ok { - return returnFunc(context1, getRevertForRefNameArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetRevertForRefNameArgs) *git.GitRevert); ok { - r0 = returnFunc(context1, getRevertForRefNameArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitRevert) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetRevertForRefNameArgs) error); ok { - r1 = returnFunc(context1, getRevertForRefNameArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetRevertForRefName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRevertForRefName' -type Client_GetRevertForRefName_Call struct { - *mock.Call -} - -// GetRevertForRefName is a helper method to define mock.On call -// - context1 -// - getRevertForRefNameArgs -func (_e *Client_Expecter) GetRevertForRefName(context1 interface{}, getRevertForRefNameArgs interface{}) *Client_GetRevertForRefName_Call { - return &Client_GetRevertForRefName_Call{Call: _e.mock.On("GetRevertForRefName", context1, getRevertForRefNameArgs)} -} - -func (_c *Client_GetRevertForRefName_Call) Run(run func(context1 context.Context, getRevertForRefNameArgs git.GetRevertForRefNameArgs)) *Client_GetRevertForRefName_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetRevertForRefNameArgs)) - }) - return _c -} - -func (_c *Client_GetRevertForRefName_Call) Return(gitRevert *git.GitRevert, err error) *Client_GetRevertForRefName_Call { - _c.Call.Return(gitRevert, err) - return _c -} - -func (_c *Client_GetRevertForRefName_Call) RunAndReturn(run func(context1 context.Context, getRevertForRefNameArgs git.GetRevertForRefNameArgs) (*git.GitRevert, error)) *Client_GetRevertForRefName_Call { - _c.Call.Return(run) - return _c -} - -// GetStatuses provides a mock function for the type Client -func (_mock *Client) GetStatuses(context1 context.Context, getStatusesArgs git.GetStatusesArgs) (*[]git.GitStatus, error) { - ret := _mock.Called(context1, getStatusesArgs) - - if len(ret) == 0 { - panic("no return value specified for GetStatuses") - } - - var r0 *[]git.GitStatus - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetStatusesArgs) (*[]git.GitStatus, error)); ok { - return returnFunc(context1, getStatusesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetStatusesArgs) *[]git.GitStatus); ok { - r0 = returnFunc(context1, getStatusesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitStatus) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetStatusesArgs) error); ok { - r1 = returnFunc(context1, getStatusesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetStatuses_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStatuses' -type Client_GetStatuses_Call struct { - *mock.Call -} - -// GetStatuses is a helper method to define mock.On call -// - context1 -// - getStatusesArgs -func (_e *Client_Expecter) GetStatuses(context1 interface{}, getStatusesArgs interface{}) *Client_GetStatuses_Call { - return &Client_GetStatuses_Call{Call: _e.mock.On("GetStatuses", context1, getStatusesArgs)} -} - -func (_c *Client_GetStatuses_Call) Run(run func(context1 context.Context, getStatusesArgs git.GetStatusesArgs)) *Client_GetStatuses_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetStatusesArgs)) - }) - return _c -} - -func (_c *Client_GetStatuses_Call) Return(gitStatuss *[]git.GitStatus, err error) *Client_GetStatuses_Call { - _c.Call.Return(gitStatuss, err) - return _c -} - -func (_c *Client_GetStatuses_Call) RunAndReturn(run func(context1 context.Context, getStatusesArgs git.GetStatusesArgs) (*[]git.GitStatus, error)) *Client_GetStatuses_Call { - _c.Call.Return(run) - return _c -} - -// GetSuggestions provides a mock function for the type Client -func (_mock *Client) GetSuggestions(context1 context.Context, getSuggestionsArgs git.GetSuggestionsArgs) (*[]git.GitSuggestion, error) { - ret := _mock.Called(context1, getSuggestionsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetSuggestions") - } - - var r0 *[]git.GitSuggestion - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetSuggestionsArgs) (*[]git.GitSuggestion, error)); ok { - return returnFunc(context1, getSuggestionsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetSuggestionsArgs) *[]git.GitSuggestion); ok { - r0 = returnFunc(context1, getSuggestionsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitSuggestion) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetSuggestionsArgs) error); ok { - r1 = returnFunc(context1, getSuggestionsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetSuggestions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSuggestions' -type Client_GetSuggestions_Call struct { - *mock.Call -} - -// GetSuggestions is a helper method to define mock.On call -// - context1 -// - getSuggestionsArgs -func (_e *Client_Expecter) GetSuggestions(context1 interface{}, getSuggestionsArgs interface{}) *Client_GetSuggestions_Call { - return &Client_GetSuggestions_Call{Call: _e.mock.On("GetSuggestions", context1, getSuggestionsArgs)} -} - -func (_c *Client_GetSuggestions_Call) Run(run func(context1 context.Context, getSuggestionsArgs git.GetSuggestionsArgs)) *Client_GetSuggestions_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetSuggestionsArgs)) - }) - return _c -} - -func (_c *Client_GetSuggestions_Call) Return(gitSuggestions *[]git.GitSuggestion, err error) *Client_GetSuggestions_Call { - _c.Call.Return(gitSuggestions, err) - return _c -} - -func (_c *Client_GetSuggestions_Call) RunAndReturn(run func(context1 context.Context, getSuggestionsArgs git.GetSuggestionsArgs) (*[]git.GitSuggestion, error)) *Client_GetSuggestions_Call { - _c.Call.Return(run) - return _c -} - -// GetThreads provides a mock function for the type Client -func (_mock *Client) GetThreads(context1 context.Context, getThreadsArgs git.GetThreadsArgs) (*[]git.GitPullRequestCommentThread, error) { - ret := _mock.Called(context1, getThreadsArgs) - - if len(ret) == 0 { - panic("no return value specified for GetThreads") - } - - var r0 *[]git.GitPullRequestCommentThread - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetThreadsArgs) (*[]git.GitPullRequestCommentThread, error)); ok { - return returnFunc(context1, getThreadsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetThreadsArgs) *[]git.GitPullRequestCommentThread); ok { - r0 = returnFunc(context1, getThreadsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitPullRequestCommentThread) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetThreadsArgs) error); ok { - r1 = returnFunc(context1, getThreadsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetThreads_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetThreads' -type Client_GetThreads_Call struct { - *mock.Call -} - -// GetThreads is a helper method to define mock.On call -// - context1 -// - getThreadsArgs -func (_e *Client_Expecter) GetThreads(context1 interface{}, getThreadsArgs interface{}) *Client_GetThreads_Call { - return &Client_GetThreads_Call{Call: _e.mock.On("GetThreads", context1, getThreadsArgs)} -} - -func (_c *Client_GetThreads_Call) Run(run func(context1 context.Context, getThreadsArgs git.GetThreadsArgs)) *Client_GetThreads_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetThreadsArgs)) - }) - return _c -} - -func (_c *Client_GetThreads_Call) Return(gitPullRequestCommentThreads *[]git.GitPullRequestCommentThread, err error) *Client_GetThreads_Call { - _c.Call.Return(gitPullRequestCommentThreads, err) - return _c -} - -func (_c *Client_GetThreads_Call) RunAndReturn(run func(context1 context.Context, getThreadsArgs git.GetThreadsArgs) (*[]git.GitPullRequestCommentThread, error)) *Client_GetThreads_Call { - _c.Call.Return(run) - return _c -} - -// GetTree provides a mock function for the type Client -func (_mock *Client) GetTree(context1 context.Context, getTreeArgs git.GetTreeArgs) (*git.GitTreeRef, error) { - ret := _mock.Called(context1, getTreeArgs) - - if len(ret) == 0 { - panic("no return value specified for GetTree") - } - - var r0 *git.GitTreeRef - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetTreeArgs) (*git.GitTreeRef, error)); ok { - return returnFunc(context1, getTreeArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetTreeArgs) *git.GitTreeRef); ok { - r0 = returnFunc(context1, getTreeArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitTreeRef) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetTreeArgs) error); ok { - r1 = returnFunc(context1, getTreeArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetTree_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTree' -type Client_GetTree_Call struct { - *mock.Call -} - -// GetTree is a helper method to define mock.On call -// - context1 -// - getTreeArgs -func (_e *Client_Expecter) GetTree(context1 interface{}, getTreeArgs interface{}) *Client_GetTree_Call { - return &Client_GetTree_Call{Call: _e.mock.On("GetTree", context1, getTreeArgs)} -} - -func (_c *Client_GetTree_Call) Run(run func(context1 context.Context, getTreeArgs git.GetTreeArgs)) *Client_GetTree_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetTreeArgs)) - }) - return _c -} - -func (_c *Client_GetTree_Call) Return(gitTreeRef *git.GitTreeRef, err error) *Client_GetTree_Call { - _c.Call.Return(gitTreeRef, err) - return _c -} - -func (_c *Client_GetTree_Call) RunAndReturn(run func(context1 context.Context, getTreeArgs git.GetTreeArgs) (*git.GitTreeRef, error)) *Client_GetTree_Call { - _c.Call.Return(run) - return _c -} - -// GetTreeZip provides a mock function for the type Client -func (_mock *Client) GetTreeZip(context1 context.Context, getTreeZipArgs git.GetTreeZipArgs) (io.ReadCloser, error) { - ret := _mock.Called(context1, getTreeZipArgs) - - if len(ret) == 0 { - panic("no return value specified for GetTreeZip") - } - - var r0 io.ReadCloser - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetTreeZipArgs) (io.ReadCloser, error)); ok { - return returnFunc(context1, getTreeZipArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.GetTreeZipArgs) io.ReadCloser); ok { - r0 = returnFunc(context1, getTreeZipArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(io.ReadCloser) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.GetTreeZipArgs) error); ok { - r1 = returnFunc(context1, getTreeZipArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetTreeZip_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTreeZip' -type Client_GetTreeZip_Call struct { - *mock.Call -} - -// GetTreeZip is a helper method to define mock.On call -// - context1 -// - getTreeZipArgs -func (_e *Client_Expecter) GetTreeZip(context1 interface{}, getTreeZipArgs interface{}) *Client_GetTreeZip_Call { - return &Client_GetTreeZip_Call{Call: _e.mock.On("GetTreeZip", context1, getTreeZipArgs)} -} - -func (_c *Client_GetTreeZip_Call) Run(run func(context1 context.Context, getTreeZipArgs git.GetTreeZipArgs)) *Client_GetTreeZip_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.GetTreeZipArgs)) - }) - return _c -} - -func (_c *Client_GetTreeZip_Call) Return(readCloser io.ReadCloser, err error) *Client_GetTreeZip_Call { - _c.Call.Return(readCloser, err) - return _c -} - -func (_c *Client_GetTreeZip_Call) RunAndReturn(run func(context1 context.Context, getTreeZipArgs git.GetTreeZipArgs) (io.ReadCloser, error)) *Client_GetTreeZip_Call { - _c.Call.Return(run) - return _c -} - -// QueryImportRequests provides a mock function for the type Client -func (_mock *Client) QueryImportRequests(context1 context.Context, queryImportRequestsArgs git.QueryImportRequestsArgs) (*[]git.GitImportRequest, error) { - ret := _mock.Called(context1, queryImportRequestsArgs) - - if len(ret) == 0 { - panic("no return value specified for QueryImportRequests") - } - - var r0 *[]git.GitImportRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.QueryImportRequestsArgs) (*[]git.GitImportRequest, error)); ok { - return returnFunc(context1, queryImportRequestsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.QueryImportRequestsArgs) *[]git.GitImportRequest); ok { - r0 = returnFunc(context1, queryImportRequestsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitImportRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.QueryImportRequestsArgs) error); ok { - r1 = returnFunc(context1, queryImportRequestsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_QueryImportRequests_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'QueryImportRequests' -type Client_QueryImportRequests_Call struct { - *mock.Call -} - -// QueryImportRequests is a helper method to define mock.On call -// - context1 -// - queryImportRequestsArgs -func (_e *Client_Expecter) QueryImportRequests(context1 interface{}, queryImportRequestsArgs interface{}) *Client_QueryImportRequests_Call { - return &Client_QueryImportRequests_Call{Call: _e.mock.On("QueryImportRequests", context1, queryImportRequestsArgs)} -} - -func (_c *Client_QueryImportRequests_Call) Run(run func(context1 context.Context, queryImportRequestsArgs git.QueryImportRequestsArgs)) *Client_QueryImportRequests_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.QueryImportRequestsArgs)) - }) - return _c -} - -func (_c *Client_QueryImportRequests_Call) Return(gitImportRequests *[]git.GitImportRequest, err error) *Client_QueryImportRequests_Call { - _c.Call.Return(gitImportRequests, err) - return _c -} - -func (_c *Client_QueryImportRequests_Call) RunAndReturn(run func(context1 context.Context, queryImportRequestsArgs git.QueryImportRequestsArgs) (*[]git.GitImportRequest, error)) *Client_QueryImportRequests_Call { - _c.Call.Return(run) - return _c -} - -// RestoreRepositoryFromRecycleBin provides a mock function for the type Client -func (_mock *Client) RestoreRepositoryFromRecycleBin(context1 context.Context, restoreRepositoryFromRecycleBinArgs git.RestoreRepositoryFromRecycleBinArgs) (*git.GitRepository, error) { - ret := _mock.Called(context1, restoreRepositoryFromRecycleBinArgs) - - if len(ret) == 0 { - panic("no return value specified for RestoreRepositoryFromRecycleBin") - } - - var r0 *git.GitRepository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.RestoreRepositoryFromRecycleBinArgs) (*git.GitRepository, error)); ok { - return returnFunc(context1, restoreRepositoryFromRecycleBinArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.RestoreRepositoryFromRecycleBinArgs) *git.GitRepository); ok { - r0 = returnFunc(context1, restoreRepositoryFromRecycleBinArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitRepository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.RestoreRepositoryFromRecycleBinArgs) error); ok { - r1 = returnFunc(context1, restoreRepositoryFromRecycleBinArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_RestoreRepositoryFromRecycleBin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RestoreRepositoryFromRecycleBin' -type Client_RestoreRepositoryFromRecycleBin_Call struct { - *mock.Call -} - -// RestoreRepositoryFromRecycleBin is a helper method to define mock.On call -// - context1 -// - restoreRepositoryFromRecycleBinArgs -func (_e *Client_Expecter) RestoreRepositoryFromRecycleBin(context1 interface{}, restoreRepositoryFromRecycleBinArgs interface{}) *Client_RestoreRepositoryFromRecycleBin_Call { - return &Client_RestoreRepositoryFromRecycleBin_Call{Call: _e.mock.On("RestoreRepositoryFromRecycleBin", context1, restoreRepositoryFromRecycleBinArgs)} -} - -func (_c *Client_RestoreRepositoryFromRecycleBin_Call) Run(run func(context1 context.Context, restoreRepositoryFromRecycleBinArgs git.RestoreRepositoryFromRecycleBinArgs)) *Client_RestoreRepositoryFromRecycleBin_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.RestoreRepositoryFromRecycleBinArgs)) - }) - return _c -} - -func (_c *Client_RestoreRepositoryFromRecycleBin_Call) Return(gitRepository *git.GitRepository, err error) *Client_RestoreRepositoryFromRecycleBin_Call { - _c.Call.Return(gitRepository, err) - return _c -} - -func (_c *Client_RestoreRepositoryFromRecycleBin_Call) RunAndReturn(run func(context1 context.Context, restoreRepositoryFromRecycleBinArgs git.RestoreRepositoryFromRecycleBinArgs) (*git.GitRepository, error)) *Client_RestoreRepositoryFromRecycleBin_Call { - _c.Call.Return(run) - return _c -} - -// SharePullRequest provides a mock function for the type Client -func (_mock *Client) SharePullRequest(context1 context.Context, sharePullRequestArgs git.SharePullRequestArgs) error { - ret := _mock.Called(context1, sharePullRequestArgs) - - if len(ret) == 0 { - panic("no return value specified for SharePullRequest") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.SharePullRequestArgs) error); ok { - r0 = returnFunc(context1, sharePullRequestArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_SharePullRequest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SharePullRequest' -type Client_SharePullRequest_Call struct { - *mock.Call -} - -// SharePullRequest is a helper method to define mock.On call -// - context1 -// - sharePullRequestArgs -func (_e *Client_Expecter) SharePullRequest(context1 interface{}, sharePullRequestArgs interface{}) *Client_SharePullRequest_Call { - return &Client_SharePullRequest_Call{Call: _e.mock.On("SharePullRequest", context1, sharePullRequestArgs)} -} - -func (_c *Client_SharePullRequest_Call) Run(run func(context1 context.Context, sharePullRequestArgs git.SharePullRequestArgs)) *Client_SharePullRequest_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.SharePullRequestArgs)) - }) - return _c -} - -func (_c *Client_SharePullRequest_Call) Return(err error) *Client_SharePullRequest_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_SharePullRequest_Call) RunAndReturn(run func(context1 context.Context, sharePullRequestArgs git.SharePullRequestArgs) error) *Client_SharePullRequest_Call { - _c.Call.Return(run) - return _c -} - -// UpdateComment provides a mock function for the type Client -func (_mock *Client) UpdateComment(context1 context.Context, updateCommentArgs git.UpdateCommentArgs) (*git.Comment, error) { - ret := _mock.Called(context1, updateCommentArgs) - - if len(ret) == 0 { - panic("no return value specified for UpdateComment") - } - - var r0 *git.Comment - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdateCommentArgs) (*git.Comment, error)); ok { - return returnFunc(context1, updateCommentArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdateCommentArgs) *git.Comment); ok { - r0 = returnFunc(context1, updateCommentArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.Comment) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.UpdateCommentArgs) error); ok { - r1 = returnFunc(context1, updateCommentArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_UpdateComment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateComment' -type Client_UpdateComment_Call struct { - *mock.Call -} - -// UpdateComment is a helper method to define mock.On call -// - context1 -// - updateCommentArgs -func (_e *Client_Expecter) UpdateComment(context1 interface{}, updateCommentArgs interface{}) *Client_UpdateComment_Call { - return &Client_UpdateComment_Call{Call: _e.mock.On("UpdateComment", context1, updateCommentArgs)} -} - -func (_c *Client_UpdateComment_Call) Run(run func(context1 context.Context, updateCommentArgs git.UpdateCommentArgs)) *Client_UpdateComment_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.UpdateCommentArgs)) - }) - return _c -} - -func (_c *Client_UpdateComment_Call) Return(comment *git.Comment, err error) *Client_UpdateComment_Call { - _c.Call.Return(comment, err) - return _c -} - -func (_c *Client_UpdateComment_Call) RunAndReturn(run func(context1 context.Context, updateCommentArgs git.UpdateCommentArgs) (*git.Comment, error)) *Client_UpdateComment_Call { - _c.Call.Return(run) - return _c -} - -// UpdateImportRequest provides a mock function for the type Client -func (_mock *Client) UpdateImportRequest(context1 context.Context, updateImportRequestArgs git.UpdateImportRequestArgs) (*git.GitImportRequest, error) { - ret := _mock.Called(context1, updateImportRequestArgs) - - if len(ret) == 0 { - panic("no return value specified for UpdateImportRequest") - } - - var r0 *git.GitImportRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdateImportRequestArgs) (*git.GitImportRequest, error)); ok { - return returnFunc(context1, updateImportRequestArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdateImportRequestArgs) *git.GitImportRequest); ok { - r0 = returnFunc(context1, updateImportRequestArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitImportRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.UpdateImportRequestArgs) error); ok { - r1 = returnFunc(context1, updateImportRequestArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_UpdateImportRequest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateImportRequest' -type Client_UpdateImportRequest_Call struct { - *mock.Call -} - -// UpdateImportRequest is a helper method to define mock.On call -// - context1 -// - updateImportRequestArgs -func (_e *Client_Expecter) UpdateImportRequest(context1 interface{}, updateImportRequestArgs interface{}) *Client_UpdateImportRequest_Call { - return &Client_UpdateImportRequest_Call{Call: _e.mock.On("UpdateImportRequest", context1, updateImportRequestArgs)} -} - -func (_c *Client_UpdateImportRequest_Call) Run(run func(context1 context.Context, updateImportRequestArgs git.UpdateImportRequestArgs)) *Client_UpdateImportRequest_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.UpdateImportRequestArgs)) - }) - return _c -} - -func (_c *Client_UpdateImportRequest_Call) Return(gitImportRequest *git.GitImportRequest, err error) *Client_UpdateImportRequest_Call { - _c.Call.Return(gitImportRequest, err) - return _c -} - -func (_c *Client_UpdateImportRequest_Call) RunAndReturn(run func(context1 context.Context, updateImportRequestArgs git.UpdateImportRequestArgs) (*git.GitImportRequest, error)) *Client_UpdateImportRequest_Call { - _c.Call.Return(run) - return _c -} - -// UpdatePullRequest provides a mock function for the type Client -func (_mock *Client) UpdatePullRequest(context1 context.Context, updatePullRequestArgs git.UpdatePullRequestArgs) (*git.GitPullRequest, error) { - ret := _mock.Called(context1, updatePullRequestArgs) - - if len(ret) == 0 { - panic("no return value specified for UpdatePullRequest") - } - - var r0 *git.GitPullRequest - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestArgs) (*git.GitPullRequest, error)); ok { - return returnFunc(context1, updatePullRequestArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestArgs) *git.GitPullRequest); ok { - r0 = returnFunc(context1, updatePullRequestArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequest) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.UpdatePullRequestArgs) error); ok { - r1 = returnFunc(context1, updatePullRequestArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_UpdatePullRequest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdatePullRequest' -type Client_UpdatePullRequest_Call struct { - *mock.Call -} - -// UpdatePullRequest is a helper method to define mock.On call -// - context1 -// - updatePullRequestArgs -func (_e *Client_Expecter) UpdatePullRequest(context1 interface{}, updatePullRequestArgs interface{}) *Client_UpdatePullRequest_Call { - return &Client_UpdatePullRequest_Call{Call: _e.mock.On("UpdatePullRequest", context1, updatePullRequestArgs)} -} - -func (_c *Client_UpdatePullRequest_Call) Run(run func(context1 context.Context, updatePullRequestArgs git.UpdatePullRequestArgs)) *Client_UpdatePullRequest_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.UpdatePullRequestArgs)) - }) - return _c -} - -func (_c *Client_UpdatePullRequest_Call) Return(gitPullRequest *git.GitPullRequest, err error) *Client_UpdatePullRequest_Call { - _c.Call.Return(gitPullRequest, err) - return _c -} - -func (_c *Client_UpdatePullRequest_Call) RunAndReturn(run func(context1 context.Context, updatePullRequestArgs git.UpdatePullRequestArgs) (*git.GitPullRequest, error)) *Client_UpdatePullRequest_Call { - _c.Call.Return(run) - return _c -} - -// UpdatePullRequestIterationStatuses provides a mock function for the type Client -func (_mock *Client) UpdatePullRequestIterationStatuses(context1 context.Context, updatePullRequestIterationStatusesArgs git.UpdatePullRequestIterationStatusesArgs) error { - ret := _mock.Called(context1, updatePullRequestIterationStatusesArgs) - - if len(ret) == 0 { - panic("no return value specified for UpdatePullRequestIterationStatuses") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestIterationStatusesArgs) error); ok { - r0 = returnFunc(context1, updatePullRequestIterationStatusesArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_UpdatePullRequestIterationStatuses_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdatePullRequestIterationStatuses' -type Client_UpdatePullRequestIterationStatuses_Call struct { - *mock.Call -} - -// UpdatePullRequestIterationStatuses is a helper method to define mock.On call -// - context1 -// - updatePullRequestIterationStatusesArgs -func (_e *Client_Expecter) UpdatePullRequestIterationStatuses(context1 interface{}, updatePullRequestIterationStatusesArgs interface{}) *Client_UpdatePullRequestIterationStatuses_Call { - return &Client_UpdatePullRequestIterationStatuses_Call{Call: _e.mock.On("UpdatePullRequestIterationStatuses", context1, updatePullRequestIterationStatusesArgs)} -} - -func (_c *Client_UpdatePullRequestIterationStatuses_Call) Run(run func(context1 context.Context, updatePullRequestIterationStatusesArgs git.UpdatePullRequestIterationStatusesArgs)) *Client_UpdatePullRequestIterationStatuses_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.UpdatePullRequestIterationStatusesArgs)) - }) - return _c -} - -func (_c *Client_UpdatePullRequestIterationStatuses_Call) Return(err error) *Client_UpdatePullRequestIterationStatuses_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_UpdatePullRequestIterationStatuses_Call) RunAndReturn(run func(context1 context.Context, updatePullRequestIterationStatusesArgs git.UpdatePullRequestIterationStatusesArgs) error) *Client_UpdatePullRequestIterationStatuses_Call { - _c.Call.Return(run) - return _c -} - -// UpdatePullRequestProperties provides a mock function for the type Client -func (_mock *Client) UpdatePullRequestProperties(context1 context.Context, updatePullRequestPropertiesArgs git.UpdatePullRequestPropertiesArgs) (interface{}, error) { - ret := _mock.Called(context1, updatePullRequestPropertiesArgs) - - if len(ret) == 0 { - panic("no return value specified for UpdatePullRequestProperties") - } - - var r0 interface{} - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestPropertiesArgs) (interface{}, error)); ok { - return returnFunc(context1, updatePullRequestPropertiesArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestPropertiesArgs) interface{}); ok { - r0 = returnFunc(context1, updatePullRequestPropertiesArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(interface{}) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.UpdatePullRequestPropertiesArgs) error); ok { - r1 = returnFunc(context1, updatePullRequestPropertiesArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_UpdatePullRequestProperties_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdatePullRequestProperties' -type Client_UpdatePullRequestProperties_Call struct { - *mock.Call -} - -// UpdatePullRequestProperties is a helper method to define mock.On call -// - context1 -// - updatePullRequestPropertiesArgs -func (_e *Client_Expecter) UpdatePullRequestProperties(context1 interface{}, updatePullRequestPropertiesArgs interface{}) *Client_UpdatePullRequestProperties_Call { - return &Client_UpdatePullRequestProperties_Call{Call: _e.mock.On("UpdatePullRequestProperties", context1, updatePullRequestPropertiesArgs)} -} - -func (_c *Client_UpdatePullRequestProperties_Call) Run(run func(context1 context.Context, updatePullRequestPropertiesArgs git.UpdatePullRequestPropertiesArgs)) *Client_UpdatePullRequestProperties_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.UpdatePullRequestPropertiesArgs)) - }) - return _c -} - -func (_c *Client_UpdatePullRequestProperties_Call) Return(ifaceVal interface{}, err error) *Client_UpdatePullRequestProperties_Call { - _c.Call.Return(ifaceVal, err) - return _c -} - -func (_c *Client_UpdatePullRequestProperties_Call) RunAndReturn(run func(context1 context.Context, updatePullRequestPropertiesArgs git.UpdatePullRequestPropertiesArgs) (interface{}, error)) *Client_UpdatePullRequestProperties_Call { - _c.Call.Return(run) - return _c -} - -// UpdatePullRequestReviewer provides a mock function for the type Client -func (_mock *Client) UpdatePullRequestReviewer(context1 context.Context, updatePullRequestReviewerArgs git.UpdatePullRequestReviewerArgs) (*git.IdentityRefWithVote, error) { - ret := _mock.Called(context1, updatePullRequestReviewerArgs) - - if len(ret) == 0 { - panic("no return value specified for UpdatePullRequestReviewer") - } - - var r0 *git.IdentityRefWithVote - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestReviewerArgs) (*git.IdentityRefWithVote, error)); ok { - return returnFunc(context1, updatePullRequestReviewerArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestReviewerArgs) *git.IdentityRefWithVote); ok { - r0 = returnFunc(context1, updatePullRequestReviewerArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.IdentityRefWithVote) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.UpdatePullRequestReviewerArgs) error); ok { - r1 = returnFunc(context1, updatePullRequestReviewerArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_UpdatePullRequestReviewer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdatePullRequestReviewer' -type Client_UpdatePullRequestReviewer_Call struct { - *mock.Call -} - -// UpdatePullRequestReviewer is a helper method to define mock.On call -// - context1 -// - updatePullRequestReviewerArgs -func (_e *Client_Expecter) UpdatePullRequestReviewer(context1 interface{}, updatePullRequestReviewerArgs interface{}) *Client_UpdatePullRequestReviewer_Call { - return &Client_UpdatePullRequestReviewer_Call{Call: _e.mock.On("UpdatePullRequestReviewer", context1, updatePullRequestReviewerArgs)} -} - -func (_c *Client_UpdatePullRequestReviewer_Call) Run(run func(context1 context.Context, updatePullRequestReviewerArgs git.UpdatePullRequestReviewerArgs)) *Client_UpdatePullRequestReviewer_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.UpdatePullRequestReviewerArgs)) - }) - return _c -} - -func (_c *Client_UpdatePullRequestReviewer_Call) Return(identityRefWithVote *git.IdentityRefWithVote, err error) *Client_UpdatePullRequestReviewer_Call { - _c.Call.Return(identityRefWithVote, err) - return _c -} - -func (_c *Client_UpdatePullRequestReviewer_Call) RunAndReturn(run func(context1 context.Context, updatePullRequestReviewerArgs git.UpdatePullRequestReviewerArgs) (*git.IdentityRefWithVote, error)) *Client_UpdatePullRequestReviewer_Call { - _c.Call.Return(run) - return _c -} - -// UpdatePullRequestReviewers provides a mock function for the type Client -func (_mock *Client) UpdatePullRequestReviewers(context1 context.Context, updatePullRequestReviewersArgs git.UpdatePullRequestReviewersArgs) error { - ret := _mock.Called(context1, updatePullRequestReviewersArgs) - - if len(ret) == 0 { - panic("no return value specified for UpdatePullRequestReviewers") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestReviewersArgs) error); ok { - r0 = returnFunc(context1, updatePullRequestReviewersArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_UpdatePullRequestReviewers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdatePullRequestReviewers' -type Client_UpdatePullRequestReviewers_Call struct { - *mock.Call -} - -// UpdatePullRequestReviewers is a helper method to define mock.On call -// - context1 -// - updatePullRequestReviewersArgs -func (_e *Client_Expecter) UpdatePullRequestReviewers(context1 interface{}, updatePullRequestReviewersArgs interface{}) *Client_UpdatePullRequestReviewers_Call { - return &Client_UpdatePullRequestReviewers_Call{Call: _e.mock.On("UpdatePullRequestReviewers", context1, updatePullRequestReviewersArgs)} -} - -func (_c *Client_UpdatePullRequestReviewers_Call) Run(run func(context1 context.Context, updatePullRequestReviewersArgs git.UpdatePullRequestReviewersArgs)) *Client_UpdatePullRequestReviewers_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.UpdatePullRequestReviewersArgs)) - }) - return _c -} - -func (_c *Client_UpdatePullRequestReviewers_Call) Return(err error) *Client_UpdatePullRequestReviewers_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_UpdatePullRequestReviewers_Call) RunAndReturn(run func(context1 context.Context, updatePullRequestReviewersArgs git.UpdatePullRequestReviewersArgs) error) *Client_UpdatePullRequestReviewers_Call { - _c.Call.Return(run) - return _c -} - -// UpdatePullRequestStatuses provides a mock function for the type Client -func (_mock *Client) UpdatePullRequestStatuses(context1 context.Context, updatePullRequestStatusesArgs git.UpdatePullRequestStatusesArgs) error { - ret := _mock.Called(context1, updatePullRequestStatusesArgs) - - if len(ret) == 0 { - panic("no return value specified for UpdatePullRequestStatuses") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestStatusesArgs) error); ok { - r0 = returnFunc(context1, updatePullRequestStatusesArgs) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_UpdatePullRequestStatuses_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdatePullRequestStatuses' -type Client_UpdatePullRequestStatuses_Call struct { - *mock.Call -} - -// UpdatePullRequestStatuses is a helper method to define mock.On call -// - context1 -// - updatePullRequestStatusesArgs -func (_e *Client_Expecter) UpdatePullRequestStatuses(context1 interface{}, updatePullRequestStatusesArgs interface{}) *Client_UpdatePullRequestStatuses_Call { - return &Client_UpdatePullRequestStatuses_Call{Call: _e.mock.On("UpdatePullRequestStatuses", context1, updatePullRequestStatusesArgs)} -} - -func (_c *Client_UpdatePullRequestStatuses_Call) Run(run func(context1 context.Context, updatePullRequestStatusesArgs git.UpdatePullRequestStatusesArgs)) *Client_UpdatePullRequestStatuses_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.UpdatePullRequestStatusesArgs)) - }) - return _c -} - -func (_c *Client_UpdatePullRequestStatuses_Call) Return(err error) *Client_UpdatePullRequestStatuses_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_UpdatePullRequestStatuses_Call) RunAndReturn(run func(context1 context.Context, updatePullRequestStatusesArgs git.UpdatePullRequestStatusesArgs) error) *Client_UpdatePullRequestStatuses_Call { - _c.Call.Return(run) - return _c -} - -// UpdateRef provides a mock function for the type Client -func (_mock *Client) UpdateRef(context1 context.Context, updateRefArgs git.UpdateRefArgs) (*git.GitRef, error) { - ret := _mock.Called(context1, updateRefArgs) - - if len(ret) == 0 { - panic("no return value specified for UpdateRef") - } - - var r0 *git.GitRef - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdateRefArgs) (*git.GitRef, error)); ok { - return returnFunc(context1, updateRefArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdateRefArgs) *git.GitRef); ok { - r0 = returnFunc(context1, updateRefArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitRef) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.UpdateRefArgs) error); ok { - r1 = returnFunc(context1, updateRefArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_UpdateRef_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateRef' -type Client_UpdateRef_Call struct { - *mock.Call -} - -// UpdateRef is a helper method to define mock.On call -// - context1 -// - updateRefArgs -func (_e *Client_Expecter) UpdateRef(context1 interface{}, updateRefArgs interface{}) *Client_UpdateRef_Call { - return &Client_UpdateRef_Call{Call: _e.mock.On("UpdateRef", context1, updateRefArgs)} -} - -func (_c *Client_UpdateRef_Call) Run(run func(context1 context.Context, updateRefArgs git.UpdateRefArgs)) *Client_UpdateRef_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.UpdateRefArgs)) - }) - return _c -} - -func (_c *Client_UpdateRef_Call) Return(gitRef *git.GitRef, err error) *Client_UpdateRef_Call { - _c.Call.Return(gitRef, err) - return _c -} - -func (_c *Client_UpdateRef_Call) RunAndReturn(run func(context1 context.Context, updateRefArgs git.UpdateRefArgs) (*git.GitRef, error)) *Client_UpdateRef_Call { - _c.Call.Return(run) - return _c -} - -// UpdateRefs provides a mock function for the type Client -func (_mock *Client) UpdateRefs(context1 context.Context, updateRefsArgs git.UpdateRefsArgs) (*[]git.GitRefUpdateResult, error) { - ret := _mock.Called(context1, updateRefsArgs) - - if len(ret) == 0 { - panic("no return value specified for UpdateRefs") - } - - var r0 *[]git.GitRefUpdateResult - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdateRefsArgs) (*[]git.GitRefUpdateResult, error)); ok { - return returnFunc(context1, updateRefsArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdateRefsArgs) *[]git.GitRefUpdateResult); ok { - r0 = returnFunc(context1, updateRefsArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*[]git.GitRefUpdateResult) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.UpdateRefsArgs) error); ok { - r1 = returnFunc(context1, updateRefsArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_UpdateRefs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateRefs' -type Client_UpdateRefs_Call struct { - *mock.Call -} - -// UpdateRefs is a helper method to define mock.On call -// - context1 -// - updateRefsArgs -func (_e *Client_Expecter) UpdateRefs(context1 interface{}, updateRefsArgs interface{}) *Client_UpdateRefs_Call { - return &Client_UpdateRefs_Call{Call: _e.mock.On("UpdateRefs", context1, updateRefsArgs)} -} - -func (_c *Client_UpdateRefs_Call) Run(run func(context1 context.Context, updateRefsArgs git.UpdateRefsArgs)) *Client_UpdateRefs_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.UpdateRefsArgs)) - }) - return _c -} - -func (_c *Client_UpdateRefs_Call) Return(gitRefUpdateResults *[]git.GitRefUpdateResult, err error) *Client_UpdateRefs_Call { - _c.Call.Return(gitRefUpdateResults, err) - return _c -} - -func (_c *Client_UpdateRefs_Call) RunAndReturn(run func(context1 context.Context, updateRefsArgs git.UpdateRefsArgs) (*[]git.GitRefUpdateResult, error)) *Client_UpdateRefs_Call { - _c.Call.Return(run) - return _c -} - -// UpdateRepository provides a mock function for the type Client -func (_mock *Client) UpdateRepository(context1 context.Context, updateRepositoryArgs git.UpdateRepositoryArgs) (*git.GitRepository, error) { - ret := _mock.Called(context1, updateRepositoryArgs) - - if len(ret) == 0 { - panic("no return value specified for UpdateRepository") - } - - var r0 *git.GitRepository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdateRepositoryArgs) (*git.GitRepository, error)); ok { - return returnFunc(context1, updateRepositoryArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdateRepositoryArgs) *git.GitRepository); ok { - r0 = returnFunc(context1, updateRepositoryArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitRepository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.UpdateRepositoryArgs) error); ok { - r1 = returnFunc(context1, updateRepositoryArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_UpdateRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateRepository' -type Client_UpdateRepository_Call struct { - *mock.Call -} - -// UpdateRepository is a helper method to define mock.On call -// - context1 -// - updateRepositoryArgs -func (_e *Client_Expecter) UpdateRepository(context1 interface{}, updateRepositoryArgs interface{}) *Client_UpdateRepository_Call { - return &Client_UpdateRepository_Call{Call: _e.mock.On("UpdateRepository", context1, updateRepositoryArgs)} -} - -func (_c *Client_UpdateRepository_Call) Run(run func(context1 context.Context, updateRepositoryArgs git.UpdateRepositoryArgs)) *Client_UpdateRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.UpdateRepositoryArgs)) - }) - return _c -} - -func (_c *Client_UpdateRepository_Call) Return(gitRepository *git.GitRepository, err error) *Client_UpdateRepository_Call { - _c.Call.Return(gitRepository, err) - return _c -} - -func (_c *Client_UpdateRepository_Call) RunAndReturn(run func(context1 context.Context, updateRepositoryArgs git.UpdateRepositoryArgs) (*git.GitRepository, error)) *Client_UpdateRepository_Call { - _c.Call.Return(run) - return _c -} - -// UpdateThread provides a mock function for the type Client -func (_mock *Client) UpdateThread(context1 context.Context, updateThreadArgs git.UpdateThreadArgs) (*git.GitPullRequestCommentThread, error) { - ret := _mock.Called(context1, updateThreadArgs) - - if len(ret) == 0 { - panic("no return value specified for UpdateThread") - } - - var r0 *git.GitPullRequestCommentThread - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdateThreadArgs) (*git.GitPullRequestCommentThread, error)); ok { - return returnFunc(context1, updateThreadArgs) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, git.UpdateThreadArgs) *git.GitPullRequestCommentThread); ok { - r0 = returnFunc(context1, updateThreadArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.GitPullRequestCommentThread) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, git.UpdateThreadArgs) error); ok { - r1 = returnFunc(context1, updateThreadArgs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_UpdateThread_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateThread' -type Client_UpdateThread_Call struct { - *mock.Call -} - -// UpdateThread is a helper method to define mock.On call -// - context1 -// - updateThreadArgs -func (_e *Client_Expecter) UpdateThread(context1 interface{}, updateThreadArgs interface{}) *Client_UpdateThread_Call { - return &Client_UpdateThread_Call{Call: _e.mock.On("UpdateThread", context1, updateThreadArgs)} -} - -func (_c *Client_UpdateThread_Call) Run(run func(context1 context.Context, updateThreadArgs git.UpdateThreadArgs)) *Client_UpdateThread_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(git.UpdateThreadArgs)) - }) - return _c -} - -func (_c *Client_UpdateThread_Call) Return(gitPullRequestCommentThread *git.GitPullRequestCommentThread, err error) *Client_UpdateThread_Call { - _c.Call.Return(gitPullRequestCommentThread, err) - return _c -} - -func (_c *Client_UpdateThread_Call) RunAndReturn(run func(context1 context.Context, updateThreadArgs git.UpdateThreadArgs) (*git.GitPullRequestCommentThread, error)) *Client_UpdateThread_Call { - _c.Call.Return(run) - return _c -} diff --git a/applicationset/services/scm_provider/azure_devops_test.go b/applicationset/services/scm_provider/azure_devops_test.go index 0b8b914efa..d718802ad3 100644 --- a/applicationset/services/scm_provider/azure_devops_test.go +++ b/applicationset/services/scm_provider/azure_devops_test.go @@ -2,7 +2,6 @@ package scm_provider import ( "context" - "errors" "fmt" "testing" @@ -12,10 +11,10 @@ import ( "github.com/stretchr/testify/require" "k8s.io/utils/ptr" - "github.com/microsoft/azure-devops-go-api/azuredevops/v7" - azureGit "github.com/microsoft/azure-devops-go-api/azuredevops/v7/git" + "github.com/microsoft/azure-devops-go-api/azuredevops" + azureGit "github.com/microsoft/azure-devops-go-api/azuredevops/git" - azureMock "github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider/azure_devops/git/mocks" + azureMock "github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider/azure_devops/git/mocks" ) func s(input string) *string { @@ -29,7 +28,7 @@ func TestAzureDevopsRepoHasPath(t *testing.T) { path := "dir/subdir/item.yaml" branchName := "my/featurebranch" - ctx := t.Context() + ctx := context.Background() uuid := uuid.New().String() testCases := []struct { @@ -42,7 +41,7 @@ func TestAzureDevopsRepoHasPath(t *testing.T) { }{ { name: "RepoHasPath when Azure DevOps client factory fails returns error", - clientError: errors.New("Client factory error"), + clientError: fmt.Errorf("Client factory error"), }, { name: "RepoHasPath when found returns true", @@ -63,7 +62,7 @@ func TestAzureDevopsRepoHasPath(t *testing.T) { { name: "RepoHasPath when unknown Azure DevOps error occurs returns error", pathFound: false, - azureDevopsError: errors.New("Undefined error from Azure Devops"), + azureDevopsError: fmt.Errorf("Undefined error from Azure Devops"), returnError: true, errorMessage: "failed to check for path existence", }, @@ -115,7 +114,7 @@ func TestGetDefaultBranchOnDisabledRepo(t *testing.T) { repoName := "myorg_project_repo" defaultBranch := "main" - ctx := t.Context() + ctx := context.Background() testCases := []struct { name string @@ -134,7 +133,7 @@ func TestGetDefaultBranchOnDisabledRepo(t *testing.T) { }, { name: "other error when calling azure devops returns error", - azureDevOpsError: errors.New("some unknown error"), + azureDevOpsError: fmt.Errorf("some unknown error"), shouldReturnError: true, }, } @@ -174,7 +173,7 @@ func TestGetAllBranchesOnDisabledRepo(t *testing.T) { repoName := "myorg_project_repo" defaultBranch := "main" - ctx := t.Context() + ctx := context.Background() testCases := []struct { name string @@ -193,7 +192,7 @@ func TestGetAllBranchesOnDisabledRepo(t *testing.T) { }, { name: "other error when calling azure devops returns error", - azureDevOpsError: errors.New("some unknown error"), + azureDevOpsError: fmt.Errorf("some unknown error"), shouldReturnError: true, }, } @@ -233,7 +232,7 @@ func TestAzureDevOpsGetDefaultBranchStripsRefsName(t *testing.T) { teamProject := "myorg_project" repoName := "myorg_project_repo" - ctx := t.Context() + ctx := context.Background() uuid := uuid.New().String() strippedBranchName := "somebranch" defaultBranch := fmt.Sprintf("refs/heads/%v", strippedBranchName) @@ -264,7 +263,7 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) { teamProject := "myorg_project" repoName := "myorg_project_repo" - ctx := t.Context() + ctx := context.Background() uuid := uuid.New().String() defaultBranch := "main" @@ -272,7 +271,7 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) { testCases := []struct { name string expectedBranch *azureGit.GitBranchStats - getBranchesAPIError error + getBranchesApiError error clientError error }{ { @@ -281,11 +280,11 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) { }, { name: "GetBranches AllBranches false when request fails returns error and empty result", - getBranchesAPIError: errors.New("Remote Azure Devops GetBranches error"), + getBranchesApiError: fmt.Errorf("Remote Azure Devops GetBranches error"), }, { name: "GetBranches AllBranches false when Azure DevOps client fails returns error", - clientError: errors.New("Could not get Azure Devops API client"), + clientError: fmt.Errorf("Could not get Azure Devops API client"), }, { name: "GetBranches AllBranches false when branch returned with long commit SHA", @@ -300,7 +299,7 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) { clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}} clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock, testCase.clientError) - gitClientMock.On("GetBranch", ctx, azureGit.GetBranchArgs{RepositoryId: &repoName, Project: &teamProject, Name: &defaultBranch}).Return(testCase.expectedBranch, testCase.getBranchesAPIError) + gitClientMock.On("GetBranch", ctx, azureGit.GetBranchArgs{RepositoryId: &repoName, Project: &teamProject, Name: &defaultBranch}).Return(testCase.expectedBranch, testCase.getBranchesApiError) repo := &Repository{Organization: organization, Repository: repoName, RepositoryId: uuid, Branch: defaultBranch} @@ -314,9 +313,9 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) { return } - if testCase.getBranchesAPIError != nil { + if testCase.getBranchesApiError != nil { assert.Empty(t, branches) - require.ErrorContains(t, err, testCase.getBranchesAPIError.Error()) + require.ErrorContains(t, err, testCase.getBranchesApiError.Error()) } else { if testCase.expectedBranch != nil { assert.NotEmpty(t, branches) @@ -335,13 +334,13 @@ func TestAzureDevopsGetBranches(t *testing.T) { teamProject := "myorg_project" repoName := "myorg_project_repo" - ctx := t.Context() + ctx := context.Background() uuid := uuid.New().String() testCases := []struct { name string expectedBranches *[]azureGit.GitBranchStats - getBranchesAPIError error + getBranchesApiError error clientError error allBranches bool expectedProcessingErrorMsg string @@ -353,7 +352,7 @@ func TestAzureDevopsGetBranches(t *testing.T) { }, { name: "GetBranches when Azure DevOps request fails returns error and empty result", - getBranchesAPIError: errors.New("Remote Azure Devops GetBranches error"), + getBranchesApiError: fmt.Errorf("Remote Azure Devops GetBranches error"), allBranches: true, }, { @@ -363,7 +362,7 @@ func TestAzureDevopsGetBranches(t *testing.T) { }, { name: "GetBranches when git client retrievel fails returns error", - clientError: errors.New("Could not get Azure Devops API client"), + clientError: fmt.Errorf("Could not get Azure Devops API client"), allBranches: true, }, { @@ -384,7 +383,7 @@ func TestAzureDevopsGetBranches(t *testing.T) { clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}} clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock, testCase.clientError) - gitClientMock.On("GetBranches", ctx, azureGit.GetBranchesArgs{RepositoryId: &repoName, Project: &teamProject}).Return(testCase.expectedBranches, testCase.getBranchesAPIError) + gitClientMock.On("GetBranches", ctx, azureGit.GetBranchesArgs{RepositoryId: &repoName, Project: &teamProject}).Return(testCase.expectedBranches, testCase.getBranchesApiError) repo := &Repository{Organization: organization, Repository: repoName, RepositoryId: uuid} @@ -403,9 +402,9 @@ func TestAzureDevopsGetBranches(t *testing.T) { return } - if testCase.getBranchesAPIError != nil { + if testCase.getBranchesApiError != nil { assert.Empty(t, branches) - require.ErrorContains(t, err, testCase.getBranchesAPIError.Error()) + require.ErrorContains(t, err, testCase.getBranchesApiError.Error()) } else { if len(*testCase.expectedBranches) > 0 { assert.NotEmpty(t, branches) @@ -427,7 +426,7 @@ func TestGetAzureDevopsRepositories(t *testing.T) { teamProject := "myorg_project" uuid := uuid.New() - ctx := t.Context() + ctx := context.Background() repoId := &uuid @@ -448,7 +447,7 @@ func TestGetAzureDevopsRepositories(t *testing.T) { }, { name: "ListRepos when Azure DevOps request fails returns error", - getRepositoriesError: errors.New("Could not get repos"), + getRepositoriesError: fmt.Errorf("Could not get repos"), }, { name: "ListRepos when repo has no name returns empty list", diff --git a/applicationset/services/scm_provider/bitbucket_cloud.go b/applicationset/services/scm_provider/bitbucket_cloud.go index 518200855a..4468aee687 100644 --- a/applicationset/services/scm_provider/bitbucket_cloud.go +++ b/applicationset/services/scm_provider/bitbucket_cloud.go @@ -2,7 +2,6 @@ package scm_provider import ( "context" - "errors" "fmt" "net/http" "strings" @@ -52,7 +51,7 @@ func (c *ExtendedClient) GetContents(repo *Repository, path string) (bool, error var _ SCMProviderService = &BitBucketCloudProvider{} -func NewBitBucketCloudProvider(owner string, user string, password string, allBranches bool) (*BitBucketCloudProvider, error) { +func NewBitBucketCloudProvider(ctx context.Context, owner string, user string, password string, allBranches bool) (*BitBucketCloudProvider, error) { client := &ExtendedClient{ bitbucket.NewBasicAuth(user, password), user, @@ -62,7 +61,7 @@ func NewBitBucketCloudProvider(owner string, user string, password string, allBr return &BitBucketCloudProvider{client: client, owner: owner, allBranches: allBranches}, nil } -func (g *BitBucketCloudProvider) GetBranches(_ context.Context, repo *Repository) ([]*Repository, error) { +func (g *BitBucketCloudProvider) GetBranches(ctx context.Context, repo *Repository) ([]*Repository, error) { repos := []*Repository{} branches, err := g.listBranches(repo) if err != nil { @@ -87,7 +86,7 @@ func (g *BitBucketCloudProvider) GetBranches(_ context.Context, repo *Repository return repos, nil } -func (g *BitBucketCloudProvider) ListRepos(_ context.Context, cloneProtocol string) ([]*Repository, error) { +func (g *BitBucketCloudProvider) ListRepos(ctx context.Context, cloneProtocol string) ([]*Repository, error) { if cloneProtocol == "" { cloneProtocol = "ssh" } @@ -101,7 +100,7 @@ func (g *BitBucketCloudProvider) ListRepos(_ context.Context, cloneProtocol stri return nil, fmt.Errorf("error listing repositories for %s: %w", g.owner, err) } for _, bitBucketRepo := range accountReposResp.Items { - cloneURL, err := findCloneURL(cloneProtocol, &bitBucketRepo) + cloneUrl, err := findCloneURL(cloneProtocol, &bitBucketRepo) if err != nil { return nil, fmt.Errorf("error fetching clone url for repo %s: %w", bitBucketRepo.Slug, err) } @@ -109,7 +108,7 @@ func (g *BitBucketCloudProvider) ListRepos(_ context.Context, cloneProtocol stri Organization: g.owner, Repository: bitBucketRepo.Slug, Branch: bitBucketRepo.Mainbranch.Name, - URL: *cloneURL, + URL: *cloneUrl, Labels: []string{}, RepositoryId: bitBucketRepo.Uuid, }) @@ -117,7 +116,7 @@ func (g *BitBucketCloudProvider) ListRepos(_ context.Context, cloneProtocol stri return repos, nil } -func (g *BitBucketCloudProvider) RepoHasPath(_ context.Context, repo *Repository, path string) (bool, error) { +func (g *BitBucketCloudProvider) RepoHasPath(ctx context.Context, repo *Repository, path string) (bool, error) { contents, err := g.client.GetContents(repo, path) if err != nil { return false, err @@ -154,19 +153,19 @@ func (g *BitBucketCloudProvider) listBranches(repo *Repository) ([]bitbucket.Rep } func findCloneURL(cloneProtocol string, repo *bitbucket.Repository) (*string, error) { - cloneLinks, ok := repo.Links["clone"].([]any) + cloneLinks, ok := repo.Links["clone"].([]interface{}) if !ok { - return nil, errors.New("unknown type returned from repo links") + return nil, fmt.Errorf("unknown type returned from repo links") } for _, link := range cloneLinks { - linkEntry, ok := link.(map[string]any) + linkEntry, ok := link.(map[string]interface{}) if !ok { - return nil, errors.New("unknown type returned from clone link") + return nil, fmt.Errorf("unknown type returned from clone link") } if linkEntry["name"] == cloneProtocol { url, ok := linkEntry["href"].(string) if !ok { - return nil, errors.New("could not find href for clone link") + return nil, fmt.Errorf("could not find href for clone link") } return &url, nil } diff --git a/applicationset/services/scm_provider/bitbucket_cloud_test.go b/applicationset/services/scm_provider/bitbucket_cloud_test.go index d9462e46a0..d4127dbbf4 100644 --- a/applicationset/services/scm_provider/bitbucket_cloud_test.go +++ b/applicationset/services/scm_provider/bitbucket_cloud_test.go @@ -1,6 +1,7 @@ package scm_provider import ( + "context" "fmt" "net/http" "net/http/httptest" @@ -9,7 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestBitbucketHasRepo(t *testing.T) { @@ -86,14 +87,14 @@ func TestBitbucketHasRepo(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - provider, _ := NewBitBucketCloudProvider(c.owner, "user", "password", false) + provider, _ := NewBitBucketCloudProvider(context.Background(), c.owner, "user", "password", false) repo := &Repository{ Organization: c.owner, Repository: c.repo, SHA: c.sha, Branch: "main", } - hasPath, err := provider.RepoHasPath(t.Context(), repo, c.path) + hasPath, err := provider.RepoHasPath(context.Background(), repo, c.path) if err != nil { require.Error(t, fmt.Errorf("Error in test %w", err)) } @@ -486,8 +487,8 @@ func TestBitbucketListRepos(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - provider, _ := NewBitBucketCloudProvider(c.owner, "user", "password", c.allBranches) - rawRepos, err := ListRepos(t.Context(), provider, c.filters, c.proto) + provider, _ := NewBitBucketCloudProvider(context.Background(), c.owner, "user", "password", c.allBranches) + rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto) if c.hasError { require.Error(t, err) } else { diff --git a/applicationset/services/scm_provider/bitbucket_server.go b/applicationset/services/scm_provider/bitbucket_server.go index cbe0c6aad4..79baa727a1 100644 --- a/applicationset/services/scm_provider/bitbucket_server.go +++ b/applicationset/services/scm_provider/bitbucket_server.go @@ -10,7 +10,7 @@ import ( bitbucketv1 "github.com/gfleury/go-bitbucket-v1" log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/applicationset/utils" + "github.com/argoproj/argo-cd/v2/applicationset/utils" ) type BitbucketServerProvider struct { @@ -64,7 +64,7 @@ func newBitbucketServerProvider(ctx context.Context, bitbucketConfig *bitbucketv } func (b *BitbucketServerProvider) ListRepos(_ context.Context, cloneProtocol string) ([]*Repository, error) { - paged := map[string]any{ + paged := map[string]interface{}{ "limit": 100, } repos := []*Repository{} @@ -122,7 +122,7 @@ func (b *BitbucketServerProvider) ListRepos(_ context.Context, cloneProtocol str } func (b *BitbucketServerProvider) RepoHasPath(_ context.Context, repo *Repository, path string) (bool, error) { - opts := map[string]any{ + opts := map[string]interface{}{ "limit": 100, "at": repo.Branch, "type_": true, @@ -174,7 +174,7 @@ func (b *BitbucketServerProvider) listBranches(repo *Repository) ([]bitbucketv1. } // Otherwise, scrape the GetBranches API. branches := []bitbucketv1.Branch{} - paged := map[string]any{ + paged := map[string]interface{}{ "limit": 100, } for { diff --git a/applicationset/services/scm_provider/bitbucket_server_test.go b/applicationset/services/scm_provider/bitbucket_server_test.go index 5559eb231c..5b4a957fea 100644 --- a/applicationset/services/scm_provider/bitbucket_server_test.go +++ b/applicationset/services/scm_provider/bitbucket_server_test.go @@ -1,6 +1,7 @@ package scm_provider import ( + "context" "crypto/x509" "encoding/pem" "io" @@ -102,9 +103,9 @@ func TestListReposNoAuth(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil) require.NoError(t, err) - repos, err := provider.ListRepos(t.Context(), "ssh") + repos, err := provider.ListRepos(context.Background(), "ssh") verifyDefaultRepo(t, err, repos) } @@ -194,9 +195,9 @@ func TestListReposPagination(t *testing.T) { } })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil) require.NoError(t, err) - repos, err := provider.ListRepos(t.Context(), "ssh") + repos, err := provider.ListRepos(context.Background(), "ssh") require.NoError(t, err) assert.Len(t, repos, 2) assert.Equal(t, Repository{ @@ -271,9 +272,9 @@ func TestGetBranchesBranchPagination(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil) require.NoError(t, err) - repos, err := provider.GetBranches(t.Context(), &Repository{ + repos, err := provider.GetBranches(context.Background(), &Repository{ Organization: "PROJECT", Repository: "REPO", URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", @@ -306,7 +307,8 @@ func TestGetBranchesBranchPagination(t *testing.T) { func TestGetBranchesDefaultOnly(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Empty(t, r.Header.Get("Authorization")) - if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { + switch r.RequestURI { + case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default": _, err := io.WriteString(w, `{ "id": "refs/heads/default", "displayId": "default", @@ -323,9 +325,9 @@ func TestGetBranchesDefaultOnly(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) require.NoError(t, err) - repos, err := provider.GetBranches(t.Context(), &Repository{ + repos, err := provider.GetBranches(context.Background(), &Repository{ Organization: "PROJECT", Repository: "REPO", URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", @@ -348,15 +350,16 @@ func TestGetBranchesDefaultOnly(t *testing.T) { func TestGetBranchesMissingDefault(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Empty(t, r.Header.Get("Authorization")) - if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { + switch r.RequestURI { + case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default": http.Error(w, "Not found", http.StatusNotFound) } defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) require.NoError(t, err) - repos, err := provider.GetBranches(t.Context(), &Repository{ + repos, err := provider.GetBranches(context.Background(), &Repository{ Organization: "PROJECT", Repository: "REPO", URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", @@ -368,16 +371,17 @@ func TestGetBranchesMissingDefault(t *testing.T) { } func TestGetBranchesEmptyRepo(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Empty(t, r.Header.Get("Authorization")) - if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { + switch r.RequestURI { + case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default": return } })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) require.NoError(t, err) - repos, err := provider.GetBranches(t.Context(), &Repository{ + repos, err := provider.GetBranches(context.Background(), &Repository{ Organization: "PROJECT", Repository: "REPO", URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", @@ -391,15 +395,16 @@ func TestGetBranchesEmptyRepo(t *testing.T) { func TestGetBranchesErrorDefaultBranch(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Empty(t, r.Header.Get("Authorization")) - if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { + switch r.RequestURI { + case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default": http.Error(w, "Internal server error", http.StatusInternalServerError) } defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) require.NoError(t, err) - _, err = provider.GetBranches(t.Context(), &Repository{ + _, err = provider.GetBranches(context.Background(), &Repository{ Organization: "PROJECT", Repository: "REPO", URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", @@ -451,7 +456,7 @@ func TestListReposTLS(t *testing.T) { defer ts.Close() var certs []byte - if test.passCerts { + if test.passCerts == true { for _, cert := range ts.TLS.Certificates { for _, c := range cert.Certificate { parsedCert, err := x509.ParseCertificate(c) @@ -464,9 +469,9 @@ func TestListReposTLS(t *testing.T) { } } - provider, err := NewBitbucketServerProviderBasicAuth(t.Context(), "user", "password", ts.URL, "PROJECT", true, "", test.tlsInsecure, certs) + provider, err := NewBitbucketServerProviderBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", true, "", test.tlsInsecure, certs) require.NoError(t, err) - _, err = provider.ListRepos(t.Context(), "ssh") + _, err = provider.ListRepos(context.Background(), "ssh") if test.requireErr { require.Error(t, err) } else { @@ -483,9 +488,9 @@ func TestListReposBasicAuth(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderBasicAuth(t.Context(), "user", "password", ts.URL, "PROJECT", true, "", false, nil) + provider, err := NewBitbucketServerProviderBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", true, "", false, nil) require.NoError(t, err) - repos, err := provider.ListRepos(t.Context(), "ssh") + repos, err := provider.ListRepos(context.Background(), "ssh") verifyDefaultRepo(t, err, repos) } @@ -496,16 +501,17 @@ func TestListReposBearerAuth(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderBearerToken(t.Context(), "tolkien", ts.URL, "PROJECT", true, "", false, nil) + provider, err := NewBitbucketServerProviderBearerToken(context.Background(), "tolkien", ts.URL, "PROJECT", true, "", false, nil) require.NoError(t, err) - repos, err := provider.ListRepos(t.Context(), "ssh") + repos, err := provider.ListRepos(context.Background(), "ssh") verifyDefaultRepo(t, err, repos) } func TestListReposDefaultBranch(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Empty(t, r.Header.Get("Authorization")) - if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { + switch r.RequestURI { + case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default": _, err := io.WriteString(w, `{ "id": "refs/heads/default", "displayId": "default", @@ -522,9 +528,9 @@ func TestListReposDefaultBranch(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) require.NoError(t, err) - repos, err := provider.ListRepos(t.Context(), "ssh") + repos, err := provider.ListRepos(context.Background(), "ssh") require.NoError(t, err) assert.Len(t, repos, 1) assert.Equal(t, Repository{ @@ -541,15 +547,16 @@ func TestListReposDefaultBranch(t *testing.T) { func TestListReposMissingDefaultBranch(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Empty(t, r.Header.Get("Authorization")) - if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { + switch r.RequestURI { + case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default": http.Error(w, "Not found", http.StatusNotFound) } defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) require.NoError(t, err) - repos, err := provider.ListRepos(t.Context(), "ssh") + repos, err := provider.ListRepos(context.Background(), "ssh") require.NoError(t, err) assert.Empty(t, repos) } @@ -557,15 +564,16 @@ func TestListReposMissingDefaultBranch(t *testing.T) { func TestListReposErrorDefaultBranch(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Empty(t, r.Header.Get("Authorization")) - if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { + switch r.RequestURI { + case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default": http.Error(w, "Internal server error", http.StatusInternalServerError) } defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) require.NoError(t, err) - _, err = provider.ListRepos(t.Context(), "ssh") + _, err = provider.ListRepos(context.Background(), "ssh") require.Error(t, err) } @@ -575,9 +583,9 @@ func TestListReposCloneProtocol(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil) require.NoError(t, err) - repos, err := provider.ListRepos(t.Context(), "https") + repos, err := provider.ListRepos(context.Background(), "https") require.NoError(t, err) assert.Len(t, repos, 1) assert.Equal(t, Repository{ @@ -597,9 +605,9 @@ func TestListReposUnknownProtocol(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil) require.NoError(t, err) - _, errProtocol := provider.ListRepos(t.Context(), "http") + _, errProtocol := provider.ListRepos(context.Background(), "http") require.Error(t, errProtocol) } @@ -635,37 +643,37 @@ func TestBitbucketServerHasPath(t *testing.T) { } })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil) require.NoError(t, err) repo := &Repository{ Organization: "PROJECT", Repository: "REPO", Branch: "main", } - ok, err := provider.RepoHasPath(t.Context(), repo, "pkg") + ok, err := provider.RepoHasPath(context.Background(), repo, "pkg") require.NoError(t, err) assert.True(t, ok) - ok, err = provider.RepoHasPath(t.Context(), repo, "pkg/") + ok, err = provider.RepoHasPath(context.Background(), repo, "pkg/") require.NoError(t, err) assert.True(t, ok) - ok, err = provider.RepoHasPath(t.Context(), repo, "anotherpkg/file.txt") + ok, err = provider.RepoHasPath(context.Background(), repo, "anotherpkg/file.txt") require.NoError(t, err) assert.True(t, ok) - ok, err = provider.RepoHasPath(t.Context(), repo, "anotherpkg/missing.txt") + ok, err = provider.RepoHasPath(context.Background(), repo, "anotherpkg/missing.txt") require.NoError(t, err) assert.False(t, ok) - ok, err = provider.RepoHasPath(t.Context(), repo, "notathing") + ok, err = provider.RepoHasPath(context.Background(), repo, "notathing") require.NoError(t, err) assert.False(t, ok) - ok, err = provider.RepoHasPath(t.Context(), repo, "return-redirect") + ok, err = provider.RepoHasPath(context.Background(), repo, "return-redirect") require.NoError(t, err) assert.True(t, ok) - _, err = provider.RepoHasPath(t.Context(), repo, "unauthorized-response") + _, err = provider.RepoHasPath(context.Background(), repo, "unauthorized-response") require.Error(t, err) } diff --git a/applicationset/services/scm_provider/gitea.go b/applicationset/services/scm_provider/gitea.go index b633d0c5ef..500aa0e981 100644 --- a/applicationset/services/scm_provider/gitea.go +++ b/applicationset/services/scm_provider/gitea.go @@ -19,7 +19,7 @@ type GiteaProvider struct { var _ SCMProviderService = &GiteaProvider{} -func NewGiteaProvider(owner, token, url string, allBranches, insecure bool) (*GiteaProvider, error) { +func NewGiteaProvider(ctx context.Context, owner, token, url string, allBranches, insecure bool) (*GiteaProvider, error) { if token == "" { token = os.Getenv("GITEA_TOKEN") } @@ -46,7 +46,7 @@ func NewGiteaProvider(owner, token, url string, allBranches, insecure bool) (*Gi }, nil } -func (g *GiteaProvider) GetBranches(_ context.Context, repo *Repository) ([]*Repository, error) { +func (g *GiteaProvider) GetBranches(ctx context.Context, repo *Repository) ([]*Repository, error) { if !g.allBranches { branch, status, err := g.client.GetRepoBranch(g.owner, repo.Repository, repo.Branch) if status.StatusCode == http.StatusNotFound { @@ -87,7 +87,7 @@ func (g *GiteaProvider) GetBranches(_ context.Context, repo *Repository) ([]*Rep return repos, nil } -func (g *GiteaProvider) ListRepos(_ context.Context, cloneProtocol string) ([]*Repository, error) { +func (g *GiteaProvider) ListRepos(ctx context.Context, cloneProtocol string) ([]*Repository, error) { repos := []*Repository{} repoOpts := gitea.ListOrgReposOptions{} giteaRepos, _, err := g.client.ListOrgRepos(g.owner, repoOpts) @@ -126,15 +126,15 @@ func (g *GiteaProvider) ListRepos(_ context.Context, cloneProtocol string) ([]*R return repos, nil } -func (g *GiteaProvider) RepoHasPath(_ context.Context, repo *Repository, path string) (bool, error) { +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 == http.StatusNotFound { return false, nil } + if fmt.Sprint(err) == "expect file, got directory" { + return true, nil + } if err != nil { - if err.Error() == "expect file, got directory" { - return true, nil - } return false, err } return true, nil diff --git a/applicationset/services/scm_provider/gitea_test.go b/applicationset/services/scm_provider/gitea_test.go index e14c56669f..1253d30c9a 100644 --- a/applicationset/services/scm_provider/gitea_test.go +++ b/applicationset/services/scm_provider/gitea_test.go @@ -1,6 +1,7 @@ package scm_provider import ( + "context" "io" "net/http" "net/http/httptest" @@ -9,8 +10,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider/testdata" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider/testdata" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func giteaMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { @@ -303,8 +304,8 @@ func TestGiteaListRepos(t *testing.T) { defer ts.Close() for _, c := range cases { t.Run(c.name, func(t *testing.T) { - provider, _ := NewGiteaProvider("test-argocd", "", ts.URL, c.allBranches, false) - rawRepos, err := ListRepos(t.Context(), provider, c.filters, c.proto) + provider, _ := NewGiteaProvider(context.Background(), "test-argocd", "", ts.URL, c.allBranches, false) + rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto) if c.hasError { require.Error(t, err) } else { @@ -333,7 +334,7 @@ func TestGiteaHasPath(t *testing.T) { giteaMockHandler(t)(w, r) })) defer ts.Close() - host, _ := NewGiteaProvider("gitea", "", ts.URL, false, false) + host, _ := NewGiteaProvider(context.Background(), "gitea", "", ts.URL, false, false) repo := &Repository{ Organization: "gitea", Repository: "go-sdk", @@ -341,19 +342,19 @@ func TestGiteaHasPath(t *testing.T) { } t.Run("file exists", func(t *testing.T) { - ok, err := host.RepoHasPath(t.Context(), repo, "README.md") + ok, err := host.RepoHasPath(context.Background(), repo, "README.md") require.NoError(t, err) assert.True(t, ok) }) t.Run("directory exists", func(t *testing.T) { - ok, err := host.RepoHasPath(t.Context(), repo, "gitea") + ok, err := host.RepoHasPath(context.Background(), repo, "gitea") require.NoError(t, err) assert.True(t, ok) }) t.Run("does not exists", func(t *testing.T) { - ok, err := host.RepoHasPath(t.Context(), repo, "notathing") + ok, err := host.RepoHasPath(context.Background(), repo, "notathing") require.NoError(t, err) assert.False(t, ok) }) diff --git a/applicationset/services/scm_provider/github.go b/applicationset/services/scm_provider/github.go index 41680b0145..2e2f2a7faf 100644 --- a/applicationset/services/scm_provider/github.go +++ b/applicationset/services/scm_provider/github.go @@ -6,7 +6,8 @@ import ( "net/http" "os" - "github.com/google/go-github/v69/github" + "github.com/google/go-github/v66/github" + "golang.org/x/oauth2" ) type GithubProvider struct { @@ -17,19 +18,21 @@ type GithubProvider struct { var _ SCMProviderService = &GithubProvider{} -func NewGithubProvider(organization string, token string, url string, allBranches bool) (*GithubProvider, error) { +func NewGithubProvider(ctx context.Context, organization string, token string, url string, allBranches bool) (*GithubProvider, error) { + var ts oauth2.TokenSource // Undocumented environment variable to set a default token, to be used in testing to dodge anonymous rate limits. if token == "" { token = os.Getenv("GITHUB_TOKEN") } - httpClient := &http.Client{} + if token != "" { + ts = oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: token}, + ) + } + httpClient := oauth2.NewClient(ctx, ts) var client *github.Client if url == "" { - if token == "" { - client = github.NewClient(httpClient) - } else { - client = github.NewClient(httpClient).WithAuthToken(token) - } + client = github.NewClient(httpClient) } else { var err error client, err = github.NewClient(httpClient).WithEnterpriseURLs(url, url) diff --git a/applicationset/services/scm_provider/github_app.go b/applicationset/services/scm_provider/github_app.go index 8ee26cec41..5429ed48ee 100644 --- a/applicationset/services/scm_provider/github_app.go +++ b/applicationset/services/scm_provider/github_app.go @@ -1,8 +1,8 @@ package scm_provider import ( - "github.com/argoproj/argo-cd/v3/applicationset/services/github_app_auth" - "github.com/argoproj/argo-cd/v3/applicationset/services/internal/github_app" + "github.com/argoproj/argo-cd/v2/applicationset/services/github_app_auth" + "github.com/argoproj/argo-cd/v2/applicationset/services/internal/github_app" ) func NewGithubAppProviderFor(g github_app_auth.Authentication, organization string, url string, allBranches bool) (*GithubProvider, error) { diff --git a/applicationset/services/scm_provider/github_test.go b/applicationset/services/scm_provider/github_test.go index 42e4635e98..747f895ab7 100644 --- a/applicationset/services/scm_provider/github_test.go +++ b/applicationset/services/scm_provider/github_test.go @@ -1,6 +1,7 @@ package scm_provider import ( + "context" "io" "net/http" "net/http/httptest" @@ -9,7 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func githubMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { @@ -242,8 +243,8 @@ func TestGithubListRepos(t *testing.T) { defer ts.Close() for _, c := range cases { t.Run(c.name, func(t *testing.T) { - provider, _ := NewGithubProvider("argoproj", "", ts.URL, c.allBranches) - rawRepos, err := ListRepos(t.Context(), provider, c.filters, c.proto) + provider, _ := NewGithubProvider(context.Background(), "argoproj", "", ts.URL, c.allBranches) + rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto) if c.hasError { require.Error(t, err) } else { @@ -272,17 +273,17 @@ func TestGithubHasPath(t *testing.T) { githubMockHandler(t)(w, r) })) defer ts.Close() - host, _ := NewGithubProvider("argoproj", "", ts.URL, false) + host, _ := NewGithubProvider(context.Background(), "argoproj", "", ts.URL, false) repo := &Repository{ Organization: "argoproj", Repository: "argo-cd", Branch: "master", } - ok, err := host.RepoHasPath(t.Context(), repo, "pkg/") + ok, err := host.RepoHasPath(context.Background(), repo, "pkg/") require.NoError(t, err) assert.True(t, ok) - ok, err = host.RepoHasPath(t.Context(), repo, "notathing/") + ok, err = host.RepoHasPath(context.Background(), repo, "notathing/") require.NoError(t, err) assert.False(t, ok) } @@ -292,13 +293,13 @@ func TestGithubGetBranches(t *testing.T) { githubMockHandler(t)(w, r) })) defer ts.Close() - host, _ := NewGithubProvider("argoproj", "", ts.URL, false) + host, _ := NewGithubProvider(context.Background(), "argoproj", "", ts.URL, false) repo := &Repository{ Organization: "argoproj", Repository: "argo-cd", Branch: "master", } - repos, err := host.GetBranches(t.Context(), repo) + repos, err := host.GetBranches(context.Background(), repo) if err != nil { require.NoError(t, err) } else { @@ -310,12 +311,12 @@ func TestGithubGetBranches(t *testing.T) { Repository: "applicationset", Branch: "main", } - _, err = host.GetBranches(t.Context(), repo2) + _, err = host.GetBranches(context.Background(), repo2) require.NoError(t, err) // Get all branches host.allBranches = true - repos, err = host.GetBranches(t.Context(), repo) + repos, err = host.GetBranches(context.Background(), repo) if err != nil { require.NoError(t, err) } else { diff --git a/applicationset/services/scm_provider/gitlab.go b/applicationset/services/scm_provider/gitlab.go index 2ab3234c5f..e77455296b 100644 --- a/applicationset/services/scm_provider/gitlab.go +++ b/applicationset/services/scm_provider/gitlab.go @@ -8,9 +8,9 @@ import ( "os" "github.com/hashicorp/go-retryablehttp" - gitlab "gitlab.com/gitlab-org/api/client-go" + "github.com/xanzy/go-gitlab" - "github.com/argoproj/argo-cd/v3/applicationset/utils" + "github.com/argoproj/argo-cd/v2/applicationset/utils" ) type GitlabProvider struct { @@ -24,7 +24,7 @@ type GitlabProvider struct { var _ SCMProviderService = &GitlabProvider{} -func NewGitlabProvider(organization string, token string, url string, allBranches, includeSubgroups, includeSharedProjects, insecure bool, scmRootCAPath, topic string, caCerts []byte) (*GitlabProvider, error) { +func NewGitlabProvider(ctx context.Context, organization string, token string, url string, allBranches, includeSubgroups, includeSharedProjects, insecure bool, scmRootCAPath, topic string, caCerts []byte) (*GitlabProvider, error) { // Undocumented environment variable to set a default token, to be used in testing to dodge anonymous rate limits. if token == "" { token = os.Getenv("GITLAB_TOKEN") @@ -75,7 +75,7 @@ func (g *GitlabProvider) GetBranches(ctx context.Context, repo *Repository) ([]* return repos, nil } -func (g *GitlabProvider) ListRepos(_ context.Context, cloneProtocol string) ([]*Repository, error) { +func (g *GitlabProvider) ListRepos(ctx context.Context, cloneProtocol string) ([]*Repository, error) { opt := &gitlab.ListGroupProjectsOptions{ ListOptions: gitlab.ListOptions{PerPage: 100}, IncludeSubGroups: &g.includeSubgroups, diff --git a/applicationset/services/scm_provider/gitlab_test.go b/applicationset/services/scm_provider/gitlab_test.go index 9f37de4bc6..bf980538d5 100644 --- a/applicationset/services/scm_provider/gitlab_test.go +++ b/applicationset/services/scm_provider/gitlab_test.go @@ -1,6 +1,7 @@ package scm_provider import ( + "context" "crypto/x509" "encoding/pem" "fmt" @@ -12,7 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func gitlabMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { @@ -1150,8 +1151,8 @@ func TestGitlabListRepos(t *testing.T) { })) for _, c := range cases { t.Run(c.name, func(t *testing.T) { - provider, _ := NewGitlabProvider("test-argocd-proton", "", ts.URL, c.allBranches, c.includeSubgroups, c.includeSharedProjects, c.insecure, "", c.topic, nil) - rawRepos, err := ListRepos(t.Context(), provider, c.filters, c.proto) + provider, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, c.allBranches, c.includeSubgroups, c.includeSharedProjects, c.insecure, "", c.topic, nil) + rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto) if c.hasError { require.Error(t, err) } else { @@ -1189,7 +1190,7 @@ func TestGitlabHasPath(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { gitlabMockHandler(t)(w, r) })) - host, _ := NewGitlabProvider("test-argocd-proton", "", ts.URL, false, true, true, false, "", "", nil) + host, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, false, true, true, false, "", "", nil) repo := &Repository{ Organization: "test-argocd-proton", Repository: "argocd", @@ -1234,7 +1235,7 @@ func TestGitlabHasPath(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - ok, err := host.RepoHasPath(t.Context(), repo, c.path) + ok, err := host.RepoHasPath(context.Background(), repo, c.path) require.NoError(t, err) assert.Equal(t, c.exists, ok) }) @@ -1245,14 +1246,14 @@ func TestGitlabGetBranches(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { gitlabMockHandler(t)(w, r) })) - host, _ := NewGitlabProvider("test-argocd-proton", "", ts.URL, false, true, true, false, "", "", nil) + host, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, false, true, true, false, "", "", nil) repo := &Repository{ RepositoryId: 27084533, Branch: "master", } t.Run("branch exists", func(t *testing.T) { - repos, err := host.GetBranches(t.Context(), repo) + repos, err := host.GetBranches(context.Background(), repo) require.NoError(t, err) assert.Equal(t, "master", repos[0].Branch) }) @@ -1262,7 +1263,7 @@ func TestGitlabGetBranches(t *testing.T) { Branch: "foo", } t.Run("unknown branch", func(t *testing.T) { - _, err := host.GetBranches(t.Context(), repo2) + _, err := host.GetBranches(context.Background(), repo2) require.NoError(t, err) }) } @@ -1309,7 +1310,7 @@ func TestGetBranchesTLS(t *testing.T) { defer ts.Close() var certs []byte - if test.passCerts { + if test.passCerts == true { for _, cert := range ts.TLS.Certificates { for _, c := range cert.Certificate { parsedCert, err := x509.ParseCertificate(c) @@ -1322,13 +1323,13 @@ func TestGetBranchesTLS(t *testing.T) { } } - host, err := NewGitlabProvider("test-argocd-proton", "", ts.URL, false, true, true, test.tlsInsecure, "", "", certs) + host, err := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, false, true, true, test.tlsInsecure, "", "", certs) require.NoError(t, err) repo := &Repository{ RepositoryId: 27084533, Branch: "master", } - _, err = host.GetBranches(t.Context(), repo) + _, err = host.GetBranches(context.Background(), repo) if test.requireErr { require.Error(t, err) } else { diff --git a/applicationset/services/scm_provider/types.go b/applicationset/services/scm_provider/types.go index b839088392..dde6db03c7 100644 --- a/applicationset/services/scm_provider/types.go +++ b/applicationset/services/scm_provider/types.go @@ -13,7 +13,7 @@ type Repository struct { Branch string SHA string Labels []string - RepositoryId any + RepositoryId interface{} } type SCMProviderService interface { diff --git a/applicationset/services/scm_provider/utils.go b/applicationset/services/scm_provider/utils.go index d9d8ac63a6..b7cdbf4606 100644 --- a/applicationset/services/scm_provider/utils.go +++ b/applicationset/services/scm_provider/utils.go @@ -6,7 +6,7 @@ import ( "regexp" "strings" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func compileFilters(filters []argoprojiov1alpha1.SCMProviderGeneratorFilter) ([]*Filter, error) { @@ -172,10 +172,9 @@ func getApplicableFilters(filters []*Filter) map[FilterType][]*Filter { FilterTypeRepo: {}, } for _, filter := range filters { - switch filter.FilterType { - case FilterTypeBranch: + if filter.FilterType == FilterTypeBranch { filterMap[FilterTypeBranch] = append(filterMap[FilterTypeBranch], filter) - case FilterTypeRepo: + } else if filter.FilterType == FilterTypeRepo { filterMap[FilterTypeRepo] = append(filterMap[FilterTypeRepo], filter) } } diff --git a/applicationset/services/scm_provider/utils_test.go b/applicationset/services/scm_provider/utils_test.go index 5a805484ff..83c6c4fc23 100644 --- a/applicationset/services/scm_provider/utils_test.go +++ b/applicationset/services/scm_provider/utils_test.go @@ -1,13 +1,14 @@ package scm_provider import ( + "context" "regexp" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func strp(s string) *string { @@ -36,7 +37,7 @@ func TestFilterRepoMatch(t *testing.T) { RepositoryMatch: strp("n|hr"), }, } - repos, err := ListRepos(t.Context(), provider, filters, "") + repos, err := ListRepos(context.Background(), provider, filters, "") require.NoError(t, err) assert.Len(t, repos, 2) assert.Equal(t, "one", repos[0].Repository) @@ -65,7 +66,7 @@ func TestFilterLabelMatch(t *testing.T) { LabelMatch: strp("^prod-.*$"), }, } - repos, err := ListRepos(t.Context(), provider, filters, "") + repos, err := ListRepos(context.Background(), provider, filters, "") require.NoError(t, err) assert.Len(t, repos, 2) assert.Equal(t, "one", repos[0].Repository) @@ -91,7 +92,7 @@ func TestFilterPathExists(t *testing.T) { PathsExist: []string{"two"}, }, } - repos, err := ListRepos(t.Context(), provider, filters, "") + repos, err := ListRepos(context.Background(), provider, filters, "") require.NoError(t, err) assert.Len(t, repos, 1) assert.Equal(t, "two", repos[0].Repository) @@ -116,7 +117,7 @@ func TestFilterPathDoesntExists(t *testing.T) { PathsDoNotExist: []string{"two"}, }, } - repos, err := ListRepos(t.Context(), provider, filters, "") + repos, err := ListRepos(context.Background(), provider, filters, "") require.NoError(t, err) assert.Len(t, repos, 2) } @@ -134,7 +135,7 @@ func TestFilterRepoMatchBadRegexp(t *testing.T) { RepositoryMatch: strp("("), }, } - _, err := ListRepos(t.Context(), provider, filters, "") + _, err := ListRepos(context.Background(), provider, filters, "") require.Error(t, err) } @@ -151,7 +152,7 @@ func TestFilterLabelMatchBadRegexp(t *testing.T) { LabelMatch: strp("("), }, } - _, err := ListRepos(t.Context(), provider, filters, "") + _, err := ListRepos(context.Background(), provider, filters, "") require.Error(t, err) } @@ -185,7 +186,7 @@ func TestFilterBranchMatch(t *testing.T) { BranchMatch: strp("w"), }, } - repos, err := ListRepos(t.Context(), provider, filters, "") + repos, err := ListRepos(context.Background(), provider, filters, "") require.NoError(t, err) assert.Len(t, repos, 2) assert.Equal(t, "one", repos[0].Repository) @@ -217,7 +218,7 @@ func TestMultiFilterAnd(t *testing.T) { LabelMatch: strp("^prod-.*$"), }, } - repos, err := ListRepos(t.Context(), provider, filters, "") + repos, err := ListRepos(context.Background(), provider, filters, "") require.NoError(t, err) assert.Len(t, repos, 1) assert.Equal(t, "two", repos[0].Repository) @@ -248,7 +249,7 @@ func TestMultiFilterOr(t *testing.T) { LabelMatch: strp("^prod-.*$"), }, } - repos, err := ListRepos(t.Context(), provider, filters, "") + repos, err := ListRepos(context.Background(), provider, filters, "") require.NoError(t, err) assert.Len(t, repos, 3) assert.Equal(t, "one", repos[0].Repository) @@ -274,7 +275,7 @@ func TestNoFilters(t *testing.T) { }, } filters := []argoprojiov1alpha1.SCMProviderGeneratorFilter{} - repos, err := ListRepos(t.Context(), provider, filters, "") + repos, err := ListRepos(context.Background(), provider, filters, "") require.NoError(t, err) assert.Len(t, repos, 3) assert.Equal(t, "one", repos[0].Repository) diff --git a/applicationset/status/resource_status.go b/applicationset/status/resource_status.go index f1ac822550..4e9db5ff56 100644 --- a/applicationset/status/resource_status.go +++ b/applicationset/status/resource_status.go @@ -1,23 +1,37 @@ package status import ( - argov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func BuildResourceStatus(statusMap map[string]argov1alpha1.ResourceStatus, apps []argov1alpha1.Application) map[string]argov1alpha1.ResourceStatus { appMap := map[string]argov1alpha1.Application{} for _, app := range apps { + appCopy := app appMap[app.Name] = app gvk := app.GroupVersionKind() - var status argov1alpha1.ResourceStatus + // Create status if it does not exist + status, ok := statusMap[app.Name] + if !ok { + status = argov1alpha1.ResourceStatus{ + Group: gvk.Group, + Version: gvk.Version, + Kind: gvk.Kind, + Name: app.Name, + Namespace: app.Namespace, + Status: app.Status.Sync.Status, + Health: &appCopy.Status.Health, + } + } + status.Group = gvk.Group status.Version = gvk.Version status.Kind = gvk.Kind status.Name = app.Name status.Namespace = app.Namespace status.Status = app.Status.Sync.Status - status.Health = &argov1alpha1.HealthStatus{Status: app.Status.Health.Status} + status.Health = &appCopy.Status.Health statusMap[app.Name] = status } diff --git a/applicationset/utils/applicationset_lister.go b/applicationset/utils/applicationset_lister.go index e7764f6fc0..5e9d659363 100644 --- a/applicationset/utils/applicationset_lister.go +++ b/applicationset/utils/applicationset_lister.go @@ -6,8 +6,8 @@ import ( "k8s.io/apimachinery/pkg/labels" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - listers "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" ) // Implements AppsetLister interface with controller-runtime client @@ -15,16 +15,16 @@ type AppsetLister struct { Client ctrlclient.Client } -func NewAppsetLister(client ctrlclient.Client) listers.ApplicationSetLister { +func NewAppsetLister(client ctrlclient.Client) ApplicationSetLister { return &AppsetLister{Client: client} } -func (l *AppsetLister) List(_ labels.Selector) (ret []*v1alpha1.ApplicationSet, err error) { +func (l *AppsetLister) List(selector labels.Selector) (ret []*ApplicationSet, err error) { return clientListAppsets(l.Client, ctrlclient.ListOptions{}) } // ApplicationSets returns an object that can list and get ApplicationSets. -func (l *AppsetLister) ApplicationSets(namespace string) listers.ApplicationSetNamespaceLister { +func (l *AppsetLister) ApplicationSets(namespace string) ApplicationSetNamespaceLister { return &appsetNamespaceLister{ Client: l.Client, Namespace: namespace, @@ -37,19 +37,19 @@ type appsetNamespaceLister struct { Namespace string } -func (n *appsetNamespaceLister) List(_ labels.Selector) (ret []*v1alpha1.ApplicationSet, err error) { +func (n *appsetNamespaceLister) List(selector labels.Selector) (ret []*ApplicationSet, err error) { return clientListAppsets(n.Client, ctrlclient.ListOptions{Namespace: n.Namespace}) } -func (n *appsetNamespaceLister) Get(_ string) (*v1alpha1.ApplicationSet, error) { - appset := v1alpha1.ApplicationSet{} +func (n *appsetNamespaceLister) Get(name string) (*ApplicationSet, error) { + appset := ApplicationSet{} err := n.Client.Get(context.TODO(), ctrlclient.ObjectKeyFromObject(&appset), &appset) return &appset, err } -func clientListAppsets(client ctrlclient.Client, listOptions ctrlclient.ListOptions) (ret []*v1alpha1.ApplicationSet, err error) { - var appsetlist v1alpha1.ApplicationSetList - var results []*v1alpha1.ApplicationSet +func clientListAppsets(client ctrlclient.Client, listOptions ctrlclient.ListOptions) (ret []*ApplicationSet, err error) { + var appsetlist ApplicationSetList + var results []*ApplicationSet err = client.List(context.TODO(), &appsetlist, &listOptions) diff --git a/applicationset/utils/clusterUtils.go b/applicationset/utils/clusterUtils.go index 5ba1f4584d..b95854e600 100644 --- a/applicationset/utils/clusterUtils.go +++ b/applicationset/utils/clusterUtils.go @@ -3,23 +3,104 @@ package utils import ( "context" "fmt" + "sync" - "github.com/argoproj/argo-cd/v3/common" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/db" + "github.com/argoproj/argo-cd/v2/common" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/db" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ) -// ClusterSpecifier contains only the name and server URL of a cluster. We use this struct to avoid partially-populating -// the full Cluster struct, which would be misleading. -type ClusterSpecifier struct { - Name string - Server string +// The contents of this file are from +// github.com/argoproj/argo-cd/util/db/cluster.go +// +// The main difference is that ListClusters(...) calls the kubeclient directly, +// via `g.clientset.CoreV1().Secrets`, rather than using the `db.listClusterSecrets()`` +// which appears to have a race condition on when it is called. +// +// I was reminded of this issue that I opened, which might be related: +// https://github.com/argoproj/argo-cd/issues/4755 +// +// I hope to upstream this change in some form, so that we do not need to worry about +// Argo CD changing the logic on us. + +var ( + localCluster = appv1.Cluster{ + Name: "in-cluster", + Server: appv1.KubernetesInternalAPIServerAddr, + ConnectionState: appv1.ConnectionState{Status: appv1.ConnectionStatusSuccessful}, + } + initLocalCluster sync.Once +) + +const ( + ArgoCDSecretTypeLabel = "argocd.argoproj.io/secret-type" + ArgoCDSecretTypeCluster = "cluster" +) + +// ValidateDestination checks: +// if we used destination name we infer the server url +// if we used both name and server then we return an invalid spec error +func ValidateDestination(ctx context.Context, dest *appv1.ApplicationDestination, clientset kubernetes.Interface, argoCDNamespace string) error { + if dest.IsServerInferred() && dest.IsNameInferred() { + return fmt.Errorf("application destination can't have both name and server inferred: %s %s", dest.Name, dest.Server) + } + if dest.Name != "" { + if dest.Server == "" { + server, err := getDestinationBy(ctx, dest.Name, clientset, argoCDNamespace, true) + if err != nil { + return fmt.Errorf("unable to find destination server: %w", err) + } + if server == "" { + return fmt.Errorf("application references destination cluster %s which does not exist", dest.Name) + } + dest.SetInferredServer(server) + } else if !dest.IsServerInferred() && !dest.IsNameInferred() { + return fmt.Errorf("application destination can't have both name and server defined: %s %s", dest.Name, dest.Server) + } + } else if dest.Server != "" { + if dest.Name == "" { + serverName, err := getDestinationBy(ctx, dest.Server, clientset, argoCDNamespace, false) + if err != nil { + return fmt.Errorf("unable to find destination server: %w", err) + } + if serverName == "" { + return fmt.Errorf("application references destination cluster %s which does not exist", dest.Server) + } + dest.SetInferredName(serverName) + } + } + return nil } -func ListClusters(ctx context.Context, clientset kubernetes.Interface, namespace string) ([]ClusterSpecifier, error) { +func getDestinationBy(ctx context.Context, cluster string, clientset kubernetes.Interface, argoCDNamespace string, byName bool) (string, error) { + // settingsMgr := settings.NewSettingsManager(context.TODO(), clientset, namespace) + // argoDB := db.NewDB(namespace, settingsMgr, clientset) + // clusterList, err := argoDB.ListClusters(ctx) + clusterList, err := ListClusters(ctx, clientset, argoCDNamespace) + if err != nil { + return "", err + } + var servers []string + for _, c := range clusterList.Items { + if byName && c.Name == cluster { + servers = append(servers, c.Server) + } + if !byName && c.Server == cluster { + servers = append(servers, c.Name) + } + } + if len(servers) > 1 { + return "", fmt.Errorf("there are %d clusters with the same name: %v", len(servers), servers) + } else if len(servers) == 0 { + return "", fmt.Errorf("there are no clusters with this name: %s", cluster) + } + return servers[0], nil +} + +func ListClusters(ctx context.Context, clientset kubernetes.Interface, namespace string) (*appv1.ClusterList, error) { clusterSecretsList, err := clientset.CoreV1().Secrets(namespace).List(ctx, metav1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeCluster}) if err != nil { @@ -32,29 +113,54 @@ func ListClusters(ctx context.Context, clientset kubernetes.Interface, namespace clusterSecrets := clusterSecretsList.Items - clusterList := make([]ClusterSpecifier, len(clusterSecrets)) - + clusterList := appv1.ClusterList{ + Items: make([]appv1.Cluster, len(clusterSecrets)), + } hasInClusterCredentials := false for i, clusterSecret := range clusterSecrets { + // This line has changed from the original Argo CD code: now receives an error, and handles it cluster, err := db.SecretToCluster(&clusterSecret) if err != nil || cluster == nil { return nil, fmt.Errorf("unable to convert cluster secret to cluster object '%s': %w", clusterSecret.Name, err) } - clusterList[i] = ClusterSpecifier{ - Name: cluster.Name, - Server: cluster.Server, - } + + // db.SecretToCluster populates these, but they're not meant to be available to the caller. + cluster.Labels = nil + cluster.Annotations = nil + + clusterList.Items[i] = *cluster if cluster.Server == appv1.KubernetesInternalAPIServerAddr { hasInClusterCredentials = true } } if !hasInClusterCredentials { - // There was no secret for the in-cluster config, so we add it here. We don't fully-populate the Cluster struct, - // since only the name and server fields are used by the generator. - clusterList = append(clusterList, ClusterSpecifier{ - Name: "in-cluster", - Server: appv1.KubernetesInternalAPIServerAddr, - }) + localCluster := getLocalCluster(clientset) + if localCluster != nil { + clusterList.Items = append(clusterList.Items, *localCluster) + } } - return clusterList, nil + return &clusterList, nil +} + +func getLocalCluster(clientset kubernetes.Interface) *appv1.Cluster { + initLocalCluster.Do(func() { + info, err := clientset.Discovery().ServerVersion() + if err == nil { + // nolint:staticcheck + localCluster.ServerVersion = fmt.Sprintf("%s.%s", info.Major, info.Minor) + // nolint:staticcheck + localCluster.ConnectionState = appv1.ConnectionState{Status: appv1.ConnectionStatusSuccessful} + } else { + // nolint:staticcheck + localCluster.ConnectionState = appv1.ConnectionState{ + Status: appv1.ConnectionStatusFailed, + Message: err.Error(), + } + } + }) + cluster := localCluster.DeepCopy() + now := metav1.Now() + // nolint:staticcheck + cluster.ConnectionState.ModifiedAt = &now + return cluster } diff --git a/applicationset/utils/clusterUtils_test.go b/applicationset/utils/clusterUtils_test.go new file mode 100644 index 0000000000..7d71db9f97 --- /dev/null +++ b/applicationset/utils/clusterUtils_test.go @@ -0,0 +1,135 @@ +package utils + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/fake" + kubetesting "k8s.io/client-go/testing" + + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +const ( + fakeNamespace = "fake-ns" +) + +func createClusterSecret(secretName string, clusterName string, clusterServer string) *corev1.Secret { + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: fakeNamespace, + Labels: map[string]string{ + ArgoCDSecretTypeLabel: ArgoCDSecretTypeCluster, + }, + }, + Data: map[string][]byte{ + "name": []byte(clusterName), + "server": []byte(clusterServer), + "config": []byte("{\"username\":\"foo\",\"password\":\"foo\"}"), + }, + } + + return secret +} + +// From util/argo/argo_test.go +// (ported to use kubeclientset) +func TestValidateDestination(t *testing.T) { + t.Run("Validate destination with server url", func(t *testing.T) { + dest := argoappv1.ApplicationDestination{ + Server: "https://127.0.0.1:6443", + Namespace: "default", + } + + secret := createClusterSecret("my-secret", "minikube", "https://127.0.0.1:6443") + objects := []runtime.Object{} + objects = append(objects, secret) + kubeclientset := fake.NewSimpleClientset(objects...) + + appCond := ValidateDestination(context.Background(), &dest, kubeclientset, fakeNamespace) + require.NoError(t, appCond) + assert.False(t, dest.IsServerInferred()) + }) + + t.Run("Validate destination with server name", func(t *testing.T) { + dest := argoappv1.ApplicationDestination{ + Name: "minikube", + } + + secret := createClusterSecret("my-secret", "minikube", "https://127.0.0.1:6443") + objects := []runtime.Object{} + objects = append(objects, secret) + kubeclientset := fake.NewSimpleClientset(objects...) + + appCond := ValidateDestination(context.Background(), &dest, kubeclientset, fakeNamespace) + require.NoError(t, appCond) + assert.Equal(t, "https://127.0.0.1:6443", dest.Server) + assert.True(t, dest.IsServerInferred()) + }) + + t.Run("Error when having both server url and name", func(t *testing.T) { + dest := argoappv1.ApplicationDestination{ + Server: "https://127.0.0.1:6443", + Name: "minikube", + Namespace: "default", + } + + err := ValidateDestination(context.Background(), &dest, nil, fakeNamespace) + assert.Equal(t, "application destination can't have both name and server defined: minikube https://127.0.0.1:6443", err.Error()) + assert.False(t, dest.IsServerInferred()) + }) + + t.Run("List clusters fails", func(t *testing.T) { + dest := argoappv1.ApplicationDestination{ + Name: "minikube", + } + kubeclientset := fake.NewSimpleClientset() + + kubeclientset.PrependReactor("list", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + return true, nil, fmt.Errorf("an error occurred") + }) + + err := ValidateDestination(context.Background(), &dest, kubeclientset, fakeNamespace) + assert.Equal(t, "unable to find destination server: an error occurred", err.Error()) + assert.False(t, dest.IsServerInferred()) + }) + + t.Run("Destination cluster does not exist", func(t *testing.T) { + dest := argoappv1.ApplicationDestination{ + Name: "minikube", + } + + secret := createClusterSecret("dind", "dind", "https://127.0.0.1:6443") + objects := []runtime.Object{} + objects = append(objects, secret) + kubeclientset := fake.NewSimpleClientset(objects...) + + err := ValidateDestination(context.Background(), &dest, kubeclientset, fakeNamespace) + assert.Equal(t, "unable to find destination server: there are no clusters with this name: minikube", err.Error()) + assert.False(t, dest.IsServerInferred()) + }) + + t.Run("Validate too many clusters with the same name", func(t *testing.T) { + dest := argoappv1.ApplicationDestination{ + Name: "dind", + } + + secret := createClusterSecret("dind", "dind", "https://127.0.0.1:2443") + secret2 := createClusterSecret("dind2", "dind", "https://127.0.0.1:8443") + + objects := []runtime.Object{} + objects = append(objects, secret, secret2) + kubeclientset := fake.NewSimpleClientset(objects...) + + err := ValidateDestination(context.Background(), &dest, kubeclientset, fakeNamespace) + assert.Equal(t, "unable to find destination server: there are 2 clusters with the same name: [https://127.0.0.1:2443 https://127.0.0.1:8443]", err.Error()) + assert.False(t, dest.IsServerInferred()) + }) +} diff --git a/applicationset/utils/createOrUpdate.go b/applicationset/utils/createOrUpdate.go index 1367e11cde..c602f002b0 100644 --- a/applicationset/utils/createOrUpdate.go +++ b/applicationset/utils/createOrUpdate.go @@ -3,7 +3,6 @@ package utils import ( "context" "encoding/json" - stderrors "errors" "fmt" log "github.com/sirupsen/logrus" @@ -18,10 +17,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo" - argodiff "github.com/argoproj/argo-cd/v3/util/argo/diff" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" + argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo" + argodiff "github.com/argoproj/argo-cd/v2/util/argo/diff" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" ) // CreateOrUpdate overrides "sigs.k8s.io/controller-runtime" function @@ -79,10 +78,10 @@ func CreateOrUpdate(ctx context.Context, logCtx *log.Entry, c client.Client, ign return a.Cmp(b) == 0 }, func(a, b metav1.MicroTime) bool { - return a.UTC().Equal(b.UTC()) + return a.UTC() == b.UTC() }, func(a, b metav1.Time) bool { - return a.UTC().Equal(b.UTC()) + return a.UTC() == b.UTC() }, func(a, b labels.Selector) bool { return a.String() == b.String() @@ -115,7 +114,7 @@ func LogPatch(logCtx *log.Entry, patch client.Patch, obj *argov1alpha1.Applicati logCtx.Errorf("failed to generate patch: %v", err) } // Get the patch as a plain object so it is easier to work with in json logs. - var patchObj map[string]any + var patchObj map[string]interface{} err = json.Unmarshal(patchBytes, &patchObj) if err != nil { logCtx.Errorf("failed to unmarshal patch: %v", err) @@ -129,7 +128,7 @@ func mutate(f controllerutil.MutateFn, key client.ObjectKey, obj client.Object) return fmt.Errorf("error while wrapping using MutateFn: %w", err) } if newKey := client.ObjectKeyFromObject(obj); key != newKey { - return stderrors.New("MutateFn cannot mutate object name and/or object namespace") + return fmt.Errorf("MutateFn cannot mutate object name and/or object namespace") } return nil } @@ -163,12 +162,12 @@ func applyIgnoreDifferences(applicationSetIgnoreDifferences argov1alpha1.Applica if len(result.Lives) != 1 { return fmt.Errorf("expected 1 normalized application, got %d", len(result.Lives)) } - foundJSONNormalized, err := json.Marshal(result.Lives[0].Object) + foundJsonNormalized, err := json.Marshal(result.Lives[0].Object) if err != nil { return fmt.Errorf("failed to marshal normalized app to json: %w", err) } foundNormalized := &argov1alpha1.Application{} - err = json.Unmarshal(foundJSONNormalized, &foundNormalized) + err = json.Unmarshal(foundJsonNormalized, &foundNormalized) if err != nil { return fmt.Errorf("failed to unmarshal normalized app to json: %w", err) } @@ -176,12 +175,12 @@ func applyIgnoreDifferences(applicationSetIgnoreDifferences argov1alpha1.Applica return fmt.Errorf("expected 1 normalized application, got %d", len(result.Targets)) } foundNormalized.DeepCopyInto(found) - generatedJSONNormalized, err := json.Marshal(result.Targets[0].Object) + generatedJsonNormalized, err := json.Marshal(result.Targets[0].Object) if err != nil { return fmt.Errorf("failed to marshal normalized app to json: %w", err) } generatedAppNormalized := &argov1alpha1.Application{} - err = json.Unmarshal(generatedJSONNormalized, &generatedAppNormalized) + err = json.Unmarshal(generatedJsonNormalized, &generatedAppNormalized) if err != nil { return fmt.Errorf("failed to unmarshal normalized app json to structured app: %w", err) } diff --git a/applicationset/utils/createOrUpdate_test.go b/applicationset/utils/createOrUpdate_test.go index 263dbeeb69..de64541337 100644 --- a/applicationset/utils/createOrUpdate_test.go +++ b/applicationset/utils/createOrUpdate_test.go @@ -8,8 +8,8 @@ import ( "gopkg.in/yaml.v3" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" ) func Test_applyIgnoreDifferences(t *testing.T) { diff --git a/applicationset/utils/kubernetes.go b/applicationset/utils/kubernetes.go index b06d499b60..b5708bad2a 100644 --- a/applicationset/utils/kubernetes.go +++ b/applicationset/utils/kubernetes.go @@ -4,12 +4,12 @@ import ( "context" "fmt" - "github.com/argoproj/argo-cd/v3/common" + "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/v3/pkg/apis/application/v1alpha1" + 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) diff --git a/applicationset/utils/kubernetes_test.go b/applicationset/utils/kubernetes_test.go index 80c9ca5e2e..d8e86b89b0 100644 --- a/applicationset/utils/kubernetes_test.go +++ b/applicationset/utils/kubernetes_test.go @@ -1,6 +1,7 @@ package utils import ( + "context" "testing" "github.com/stretchr/testify/assert" @@ -9,7 +10,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client/fake" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestGetSecretRef(t *testing.T) { @@ -20,7 +21,7 @@ func TestGetSecretRef(t *testing.T) { }, } client := fake.NewClientBuilder().WithObjects(secret).Build() - ctx := t.Context() + ctx := context.Background() cases := []struct { name, namespace, token string @@ -85,7 +86,7 @@ func TestGetConfigMapData(t *testing.T) { }, } client := fake.NewClientBuilder().WithObjects(configMap).Build() - ctx := t.Context() + ctx := context.Background() cases := []struct { name, namespace, data string diff --git a/applicationset/utils/map.go b/applicationset/utils/map.go index 42cd39b715..0d71f20b50 100644 --- a/applicationset/utils/map.go +++ b/applicationset/utils/map.go @@ -4,7 +4,7 @@ import ( "fmt" ) -func ConvertToMapStringString(mapStringInterface map[string]any) map[string]string { +func ConvertToMapStringString(mapStringInterface map[string]interface{}) map[string]string { mapStringString := make(map[string]string, len(mapStringInterface)) for key, value := range mapStringInterface { @@ -13,8 +13,8 @@ func ConvertToMapStringString(mapStringInterface map[string]any) map[string]stri return mapStringString } -func ConvertToMapStringInterface(mapStringString map[string]string) map[string]any { - mapStringInterface := make(map[string]any, len(mapStringString)) +func ConvertToMapStringInterface(mapStringString map[string]string) map[string]interface{} { + mapStringInterface := make(map[string]interface{}, len(mapStringString)) for key, value := range mapStringString { mapStringInterface[key] = value @@ -22,7 +22,7 @@ func ConvertToMapStringInterface(mapStringString map[string]string) map[string]a return mapStringInterface } -func CombineStringMaps(aSI map[string]any, bSI map[string]any) (map[string]string, error) { +func CombineStringMaps(aSI map[string]interface{}, bSI map[string]interface{}) (map[string]string, error) { a := ConvertToMapStringString(aSI) b := ConvertToMapStringString(bSI) @@ -44,7 +44,7 @@ func CombineStringMaps(aSI map[string]any, bSI map[string]any) (map[string]strin } // CombineStringMapsAllowDuplicates merges two maps. Where there are duplicates, take the latter map's value. -func CombineStringMapsAllowDuplicates(aSI map[string]any, bSI map[string]any) (map[string]string, error) { +func CombineStringMapsAllowDuplicates(aSI map[string]interface{}, bSI map[string]interface{}) (map[string]string, error) { a := ConvertToMapStringString(aSI) b := ConvertToMapStringString(bSI) diff --git a/applicationset/utils/map_test.go b/applicationset/utils/map_test.go index 679ea356cc..c12216e0e1 100644 --- a/applicationset/utils/map_test.go +++ b/applicationset/utils/map_test.go @@ -1,7 +1,7 @@ package utils import ( - "errors" + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -11,29 +11,29 @@ import ( func TestCombineStringMaps(t *testing.T) { testCases := []struct { name string - left map[string]any - right map[string]any + left map[string]interface{} + right map[string]interface{} expected map[string]string expectedErr error }{ { name: "combines the maps", - left: map[string]any{"foo": "bar"}, - right: map[string]any{"a": "b"}, + left: map[string]interface{}{"foo": "bar"}, + right: map[string]interface{}{"a": "b"}, expected: map[string]string{"a": "b", "foo": "bar"}, expectedErr: nil, }, { name: "fails if keys are the same but value isn't", - left: map[string]any{"foo": "bar", "a": "fail"}, - right: map[string]any{"a": "b", "c": "d"}, + left: map[string]interface{}{"foo": "bar", "a": "fail"}, + right: map[string]interface{}{"a": "b", "c": "d"}, expected: map[string]string{"a": "b", "foo": "bar"}, - expectedErr: errors.New("found duplicate key a with different value, a: fail ,b: b"), + expectedErr: fmt.Errorf("found duplicate key a with different value, a: fail ,b: b"), }, { name: "pass if keys & values are the same", - left: map[string]any{"foo": "bar", "a": "b"}, - right: map[string]any{"a": "b", "c": "d"}, + left: map[string]interface{}{"foo": "bar", "a": "b"}, + right: map[string]interface{}{"a": "b", "c": "d"}, expected: map[string]string{"a": "b", "c": "d", "foo": "bar"}, expectedErr: nil, }, diff --git a/applicationset/utils/mocks/Renderer.go b/applicationset/utils/mocks/Renderer.go index e16665dd30..ca82e9e38b 100644 --- a/applicationset/utils/mocks/Renderer.go +++ b/applicationset/utils/mocks/Renderer.go @@ -1,14 +1,76 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" mock "github.com/stretchr/testify/mock" + + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) +// Renderer is an autogenerated mock type for the Renderer type +type Renderer struct { + mock.Mock +} + +// RenderTemplateParams provides a mock function with given fields: tmpl, syncPolicy, params, useGoTemplate, goTemplateOptions +func (_m *Renderer) RenderTemplateParams(tmpl *v1alpha1.Application, syncPolicy *v1alpha1.ApplicationSetSyncPolicy, params map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (*v1alpha1.Application, error) { + ret := _m.Called(tmpl, syncPolicy, params, useGoTemplate, goTemplateOptions) + + if len(ret) == 0 { + panic("no return value specified for RenderTemplateParams") + } + + var r0 *v1alpha1.Application + var r1 error + if rf, ok := ret.Get(0).(func(*v1alpha1.Application, *v1alpha1.ApplicationSetSyncPolicy, map[string]interface{}, bool, []string) (*v1alpha1.Application, error)); ok { + return rf(tmpl, syncPolicy, params, useGoTemplate, goTemplateOptions) + } + if rf, ok := ret.Get(0).(func(*v1alpha1.Application, *v1alpha1.ApplicationSetSyncPolicy, map[string]interface{}, bool, []string) *v1alpha1.Application); ok { + r0 = rf(tmpl, syncPolicy, params, useGoTemplate, goTemplateOptions) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Application) + } + } + + if rf, ok := ret.Get(1).(func(*v1alpha1.Application, *v1alpha1.ApplicationSetSyncPolicy, map[string]interface{}, bool, []string) error); ok { + r1 = rf(tmpl, syncPolicy, params, useGoTemplate, goTemplateOptions) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Replace provides a mock function with given fields: tmpl, replaceMap, useGoTemplate, goTemplateOptions +func (_m *Renderer) Replace(tmpl string, replaceMap map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (string, error) { + ret := _m.Called(tmpl, replaceMap, useGoTemplate, goTemplateOptions) + + if len(ret) == 0 { + panic("no return value specified for Replace") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, map[string]interface{}, bool, []string) (string, error)); ok { + return rf(tmpl, replaceMap, useGoTemplate, goTemplateOptions) + } + if rf, ok := ret.Get(0).(func(string, map[string]interface{}, bool, []string) string); ok { + r0 = rf(tmpl, replaceMap, useGoTemplate, goTemplateOptions) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string, map[string]interface{}, bool, []string) error); ok { + r1 = rf(tmpl, replaceMap, useGoTemplate, goTemplateOptions) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewRenderer creates a new instance of Renderer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewRenderer(t interface { @@ -22,133 +84,3 @@ func NewRenderer(t interface { return mock } - -// Renderer is an autogenerated mock type for the Renderer type -type Renderer struct { - mock.Mock -} - -type Renderer_Expecter struct { - mock *mock.Mock -} - -func (_m *Renderer) EXPECT() *Renderer_Expecter { - return &Renderer_Expecter{mock: &_m.Mock} -} - -// RenderTemplateParams provides a mock function for the type Renderer -func (_mock *Renderer) RenderTemplateParams(tmpl *v1alpha1.Application, syncPolicy *v1alpha1.ApplicationSetSyncPolicy, params map[string]any, useGoTemplate bool, goTemplateOptions []string) (*v1alpha1.Application, error) { - ret := _mock.Called(tmpl, syncPolicy, params, useGoTemplate, goTemplateOptions) - - if len(ret) == 0 { - panic("no return value specified for RenderTemplateParams") - } - - var r0 *v1alpha1.Application - var r1 error - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Application, *v1alpha1.ApplicationSetSyncPolicy, map[string]any, bool, []string) (*v1alpha1.Application, error)); ok { - return returnFunc(tmpl, syncPolicy, params, useGoTemplate, goTemplateOptions) - } - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Application, *v1alpha1.ApplicationSetSyncPolicy, map[string]any, bool, []string) *v1alpha1.Application); ok { - r0 = returnFunc(tmpl, syncPolicy, params, useGoTemplate, goTemplateOptions) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Application) - } - } - if returnFunc, ok := ret.Get(1).(func(*v1alpha1.Application, *v1alpha1.ApplicationSetSyncPolicy, map[string]any, bool, []string) error); ok { - r1 = returnFunc(tmpl, syncPolicy, params, useGoTemplate, goTemplateOptions) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Renderer_RenderTemplateParams_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RenderTemplateParams' -type Renderer_RenderTemplateParams_Call struct { - *mock.Call -} - -// RenderTemplateParams is a helper method to define mock.On call -// - tmpl -// - syncPolicy -// - params -// - useGoTemplate -// - goTemplateOptions -func (_e *Renderer_Expecter) RenderTemplateParams(tmpl interface{}, syncPolicy interface{}, params interface{}, useGoTemplate interface{}, goTemplateOptions interface{}) *Renderer_RenderTemplateParams_Call { - return &Renderer_RenderTemplateParams_Call{Call: _e.mock.On("RenderTemplateParams", tmpl, syncPolicy, params, useGoTemplate, goTemplateOptions)} -} - -func (_c *Renderer_RenderTemplateParams_Call) Run(run func(tmpl *v1alpha1.Application, syncPolicy *v1alpha1.ApplicationSetSyncPolicy, params map[string]any, useGoTemplate bool, goTemplateOptions []string)) *Renderer_RenderTemplateParams_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.Application), args[1].(*v1alpha1.ApplicationSetSyncPolicy), args[2].(map[string]any), args[3].(bool), args[4].([]string)) - }) - return _c -} - -func (_c *Renderer_RenderTemplateParams_Call) Return(application *v1alpha1.Application, err error) *Renderer_RenderTemplateParams_Call { - _c.Call.Return(application, err) - return _c -} - -func (_c *Renderer_RenderTemplateParams_Call) RunAndReturn(run func(tmpl *v1alpha1.Application, syncPolicy *v1alpha1.ApplicationSetSyncPolicy, params map[string]any, useGoTemplate bool, goTemplateOptions []string) (*v1alpha1.Application, error)) *Renderer_RenderTemplateParams_Call { - _c.Call.Return(run) - return _c -} - -// Replace provides a mock function for the type Renderer -func (_mock *Renderer) Replace(tmpl string, replaceMap map[string]any, useGoTemplate bool, goTemplateOptions []string) (string, error) { - ret := _mock.Called(tmpl, replaceMap, useGoTemplate, goTemplateOptions) - - if len(ret) == 0 { - panic("no return value specified for Replace") - } - - var r0 string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string, map[string]any, bool, []string) (string, error)); ok { - return returnFunc(tmpl, replaceMap, useGoTemplate, goTemplateOptions) - } - if returnFunc, ok := ret.Get(0).(func(string, map[string]any, bool, []string) string); ok { - r0 = returnFunc(tmpl, replaceMap, useGoTemplate, goTemplateOptions) - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func(string, map[string]any, bool, []string) error); ok { - r1 = returnFunc(tmpl, replaceMap, useGoTemplate, goTemplateOptions) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Renderer_Replace_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Replace' -type Renderer_Replace_Call struct { - *mock.Call -} - -// Replace is a helper method to define mock.On call -// - tmpl -// - replaceMap -// - useGoTemplate -// - goTemplateOptions -func (_e *Renderer_Expecter) Replace(tmpl interface{}, replaceMap interface{}, useGoTemplate interface{}, goTemplateOptions interface{}) *Renderer_Replace_Call { - return &Renderer_Replace_Call{Call: _e.mock.On("Replace", tmpl, replaceMap, useGoTemplate, goTemplateOptions)} -} - -func (_c *Renderer_Replace_Call) Run(run func(tmpl string, replaceMap map[string]any, useGoTemplate bool, goTemplateOptions []string)) *Renderer_Replace_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(map[string]any), args[2].(bool), args[3].([]string)) - }) - return _c -} - -func (_c *Renderer_Replace_Call) Return(s string, err error) *Renderer_Replace_Call { - _c.Call.Return(s, err) - return _c -} - -func (_c *Renderer_Replace_Call) RunAndReturn(run func(tmpl string, replaceMap map[string]any, useGoTemplate bool, goTemplateOptions []string) (string, error)) *Renderer_Replace_Call { - _c.Call.Return(run) - return _c -} diff --git a/applicationset/utils/policy.go b/applicationset/utils/policy.go index cf9e6302db..a06509265a 100644 --- a/applicationset/utils/policy.go +++ b/applicationset/utils/policy.go @@ -1,7 +1,7 @@ package utils import ( - argov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) // Policies is a registry of available policies. diff --git a/applicationset/utils/selector.go b/applicationset/utils/selector.go index eae0324236..6012fdb46f 100644 --- a/applicationset/utils/selector.go +++ b/applicationset/utils/selector.go @@ -6,7 +6,7 @@ import ( "strconv" "strings" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/selection" "k8s.io/apimachinery/pkg/util/validation" @@ -69,11 +69,11 @@ func (s internalSelector) Add(reqs ...Requirement) Selector { type nothingSelector struct{} -func (n nothingSelector) Matches(_ labels.Labels) bool { +func (n nothingSelector) Matches(l labels.Labels) bool { return false } -func (n nothingSelector) Add(_ ...Requirement) Selector { +func (n nothingSelector) Add(r ...Requirement) Selector { return n } @@ -90,7 +90,7 @@ func everything() Selector { // LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements // labels.Selector // Note: This function should be kept in sync with the selector methods in pkg/labels/selector.go -func LabelSelectorAsSelector(ps *metav1.LabelSelector) (Selector, error) { +func LabelSelectorAsSelector(ps *v1.LabelSelector) (Selector, error) { if ps == nil { return nothing(), nil } @@ -108,13 +108,13 @@ func LabelSelectorAsSelector(ps *metav1.LabelSelector) (Selector, error) { for _, expr := range ps.MatchExpressions { var op selection.Operator switch expr.Operator { - case metav1.LabelSelectorOpIn: + case v1.LabelSelectorOpIn: op = selection.In - case metav1.LabelSelectorOpNotIn: + case v1.LabelSelectorOpNotIn: op = selection.NotIn - case metav1.LabelSelectorOpExists: + case v1.LabelSelectorOpExists: op = selection.Exists - case metav1.LabelSelectorOpDoesNotExist: + case v1.LabelSelectorOpDoesNotExist: op = selection.DoesNotExist default: return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator) diff --git a/applicationset/utils/template_functions.go b/applicationset/utils/template_functions.go index f0985cf9de..84ab870404 100644 --- a/applicationset/utils/template_functions.go +++ b/applicationset/utils/template_functions.go @@ -29,7 +29,7 @@ func SanitizeName(name string) string { // always return a string, even on marshal error (empty string). // // This is designed to be called from a template. -func toYAML(v any) (string, error) { +func toYAML(v interface{}) (string, error) { data, err := yaml.Marshal(v) if err != nil { // Swallow errors inside of a template. @@ -39,14 +39,14 @@ func toYAML(v any) (string, error) { } // This has been copied from helm and may be removed as soon as it is retrofited in sprig -// fromYAML converts a YAML document into a map[string]any. +// fromYAML converts a YAML document into a map[string]interface{}. // // This is not a general-purpose YAML parser, and will not parse all valid // YAML documents. Additionally, because its intended use is within templates // it tolerates errors. It will insert the returned error message string into // m["Error"] in the returned map. -func fromYAML(str string) (map[string]any, error) { - m := map[string]any{} +func fromYAML(str string) (map[string]interface{}, error) { + m := map[string]interface{}{} if err := yaml.Unmarshal([]byte(str), &m); err != nil { return nil, err @@ -55,14 +55,14 @@ func fromYAML(str string) (map[string]any, error) { } // This has been copied from helm and may be removed as soon as it is retrofited in sprig -// fromYAMLArray converts a YAML array into a []any. +// fromYAMLArray converts a YAML array into a []interface{}. // // This is not a general-purpose YAML parser, and will not parse all valid // YAML documents. Additionally, because its intended use is within templates // it tolerates errors. It will insert the returned error message string as // the first and only item in the returned array. -func fromYAMLArray(str string) ([]any, error) { - a := []any{} +func fromYAMLArray(str string) ([]interface{}, error) { + a := []interface{}{} if err := yaml.Unmarshal([]byte(str), &a); err != nil { return nil, err diff --git a/applicationset/utils/utils.go b/applicationset/utils/utils.go index 368fcbb6c9..4122dee28a 100644 --- a/applicationset/utils/utils.go +++ b/applicationset/utils/utils.go @@ -5,7 +5,6 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" - "errors" "fmt" "io" "os" @@ -23,8 +22,8 @@ import ( log "github.com/sirupsen/logrus" - argoappsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/glob" + argoappsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/glob" ) var sprigFuncMap = sprig.GenericFuncMap() // a singleton for better performance @@ -42,8 +41,8 @@ func init() { } type Renderer interface { - RenderTemplateParams(tmpl *argoappsv1.Application, syncPolicy *argoappsv1.ApplicationSetSyncPolicy, params map[string]any, useGoTemplate bool, goTemplateOptions []string) (*argoappsv1.Application, error) - Replace(tmpl string, replaceMap map[string]any, useGoTemplate bool, goTemplateOptions []string) (string, error) + RenderTemplateParams(tmpl *argoappsv1.Application, syncPolicy *argoappsv1.ApplicationSetSyncPolicy, params map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (*argoappsv1.Application, error) + Replace(tmpl string, replaceMap map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (string, error) } type Render struct{} @@ -81,7 +80,7 @@ func ConvertYAMLToJSON(str string) (string, error) { // This function is in charge of searching all String fields of the object recursively and apply templating // thanks to https://gist.github.com/randallmlough/1fd78ec8a1034916ca52281e3b886dc7 -func (r *Render) deeplyReplace(copy, original reflect.Value, replaceMap map[string]any, useGoTemplate bool, goTemplateOptions []string) error { +func (r *Render) deeplyReplace(copy, original reflect.Value, replaceMap map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) error { switch original.Kind() { // The first cases handle nested structures and translate them recursively // If it is a pointer we need to unwrap and call once again @@ -131,19 +130,19 @@ func (r *Render) deeplyReplace(copy, original reflect.Value, replaceMap map[stri // If it is a struct we translate each field case reflect.Struct: - for i := 0; i < original.NumField(); i++ { + for i := 0; i < original.NumField(); i += 1 { currentType := fmt.Sprintf("%s.%s", original.Type().Field(i).Name, original.Type().PkgPath()) // specific case time if currentType == "time.Time" { copy.Field(i).Set(original.Field(i)) } else if currentType == "Raw.k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" || currentType == "Raw.k8s.io/apimachinery/pkg/runtime" { - var unmarshaled any + var unmarshaled interface{} originalBytes := original.Field(i).Bytes() - convertedToJSON, err := ConvertYAMLToJSON(string(originalBytes)) + convertedToJson, err := ConvertYAMLToJSON(string(originalBytes)) if err != nil { - return fmt.Errorf("error while converting template to json %q: %w", convertedToJSON, err) + return fmt.Errorf("error while converting template to json %q: %w", convertedToJson, err) } - err = json.Unmarshal([]byte(convertedToJSON), &unmarshaled) + err = json.Unmarshal([]byte(convertedToJson), &unmarshaled) if err != nil { return fmt.Errorf("failed to unmarshal JSON field: %w", err) } @@ -153,7 +152,7 @@ func (r *Render) deeplyReplace(copy, original reflect.Value, replaceMap map[stri if err != nil { return fmt.Errorf("failed to deeply replace JSON field contents: %w", err) } - jsonCopyInterface := jsonCopy.Interface().(*any) + jsonCopyInterface := jsonCopy.Interface().(*interface{}) data, err := json.Marshal(jsonCopyInterface) if err != nil { return fmt.Errorf("failed to marshal templated JSON field: %w", err) @@ -173,7 +172,7 @@ func (r *Render) deeplyReplace(copy, original reflect.Value, replaceMap map[stri copyValueIntoUnexported(copy, reflect.MakeSlice(original.Type(), original.Len(), original.Cap())) } - for i := 0; i < original.Len(); i++ { + for i := 0; i < original.Len(); i += 1 { if err := r.deeplyReplace(copy.Index(i), original.Index(i), replaceMap, useGoTemplate, goTemplateOptions); err != nil { // Not wrapping the error, since this is a recursive function. Avoids excessively long error messages. return err @@ -250,9 +249,9 @@ func isNillable(v reflect.Value) bool { return false } -func (r *Render) RenderTemplateParams(tmpl *argoappsv1.Application, syncPolicy *argoappsv1.ApplicationSetSyncPolicy, params map[string]any, useGoTemplate bool, goTemplateOptions []string) (*argoappsv1.Application, error) { +func (r *Render) RenderTemplateParams(tmpl *argoappsv1.Application, syncPolicy *argoappsv1.ApplicationSetSyncPolicy, params map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (*argoappsv1.Application, error) { if tmpl == nil { - return nil, errors.New("application template is empty") + return nil, fmt.Errorf("application template is empty") } if len(params) == 0 { @@ -274,16 +273,16 @@ func (r *Render) RenderTemplateParams(tmpl *argoappsv1.Application, syncPolicy * // b) there IS a syncPolicy, but preserveResourcesOnDeletion is set to false // See TestRenderTemplateParamsFinalizers in util_test.go for test-based definition of behaviour if (syncPolicy == nil || !syncPolicy.PreserveResourcesOnDeletion) && - len(replacedTmpl.Finalizers) == 0 { - replacedTmpl.Finalizers = []string{"resources-finalizer.argocd.argoproj.io"} + len(replacedTmpl.ObjectMeta.Finalizers) == 0 { + replacedTmpl.ObjectMeta.Finalizers = []string{"resources-finalizer.argocd.argoproj.io"} } return replacedTmpl, nil } -func (r *Render) RenderGeneratorParams(gen *argoappsv1.ApplicationSetGenerator, params map[string]any, useGoTemplate bool, goTemplateOptions []string) (*argoappsv1.ApplicationSetGenerator, error) { +func (r *Render) RenderGeneratorParams(gen *argoappsv1.ApplicationSetGenerator, params map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (*argoappsv1.ApplicationSetGenerator, error) { if gen == nil { - return nil, errors.New("generator is empty") + return nil, fmt.Errorf("generator is empty") } if len(params) == 0 { @@ -306,7 +305,7 @@ var isTemplatedRegex = regexp.MustCompile(".*{{.*}}.*") // Replace executes basic string substitution of a template with replacement values. // remaining in the substituted template. -func (r *Render) Replace(tmpl string, replaceMap map[string]any, useGoTemplate bool, goTemplateOptions []string) (string, error) { +func (r *Render) Replace(tmpl string, replaceMap map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (string, error) { if useGoTemplate { template, err := template.New("").Funcs(sprigFuncMap).Parse(tmpl) if err != nil { @@ -336,7 +335,7 @@ func (r *Render) Replace(tmpl string, replaceMap map[string]any, useGoTemplate b trimmedTag := strings.TrimSpace(tag) replacement, ok := replaceMap[trimmedTag].(string) if len(trimmedTag) == 0 || !ok { - return fmt.Fprintf(w, "{{%s}}", tag) + return w.Write([]byte(fmt.Sprintf("{{%s}}", tag))) } return w.Write([]byte(replacement)) }) @@ -353,12 +352,12 @@ func CheckInvalidGenerators(applicationSetInfo *argoappsv1.ApplicationSet) error gnames = append(gnames, n) } sort.Strings(gnames) - aname := applicationSetInfo.Name + aname := applicationSetInfo.ObjectMeta.Name msg := "ApplicationSet %s contains unrecognized generators: %s" errorMessage = fmt.Errorf(msg, aname, strings.Join(gnames, ", ")) log.Warnf(msg, aname, strings.Join(gnames, ", ")) } else if hasInvalidGenerators { - name := applicationSetInfo.Name + name := applicationSetInfo.ObjectMeta.Name msg := "ApplicationSet %s contains unrecognized generators" errorMessage = fmt.Errorf(msg, name) log.Warnf(msg, name) @@ -394,21 +393,21 @@ func invalidGenerators(applicationSetInfo *argoappsv1.ApplicationSet) (bool, map func addInvalidGeneratorNames(names map[string]bool, applicationSetInfo *argoappsv1.ApplicationSet, index int) { // The generator names are stored in the "kubectl.kubernetes.io/last-applied-configuration" annotation - config := applicationSetInfo.Annotations["kubectl.kubernetes.io/last-applied-configuration"] - var values map[string]any + config := applicationSetInfo.ObjectMeta.Annotations["kubectl.kubernetes.io/last-applied-configuration"] + var values map[string]interface{} err := json.Unmarshal([]byte(config), &values) if err != nil { log.Warnf("couldn't unmarshal kubectl.kubernetes.io/last-applied-configuration: %+v", config) return } - spec, ok := values["spec"].(map[string]any) + spec, ok := values["spec"].(map[string]interface{}) if !ok { log.Warn("coundn't get spec from kubectl.kubernetes.io/last-applied-configuration annotation") return } - generators, ok := spec["generators"].([]any) + generators, ok := spec["generators"].([]interface{}) if !ok { log.Warn("coundn't get generators from kubectl.kubernetes.io/last-applied-configuration annotation") return @@ -419,7 +418,7 @@ func addInvalidGeneratorNames(names map[string]bool, applicationSetInfo *argoapp return } - generator, ok := generators[index].(map[string]any) + generator, ok := generators[index].(map[string]interface{}) if !ok { log.Warn("coundn't get generator from kubectl.kubernetes.io/last-applied-configuration annotation") return @@ -457,7 +456,7 @@ func NormalizeBitbucketBasePath(basePath string) string { // // Returns: // - string: The generated URL-friendly slug based on the input name and options. -func SlugifyName(args ...any) string { +func SlugifyName(args ...interface{}) string { // Default values for arguments maxSize := 50 EnableSmartTruncate := true @@ -489,7 +488,7 @@ func SlugifyName(args ...any) string { return urlSlug } -func getTLSConfigWithCACert(scmRootCAPath string, caCerts []byte) *tls.Config { +func getTlsConfigWithCACert(scmRootCAPath string, caCerts []byte) *tls.Config { tlsConfig := &tls.Config{} if scmRootCAPath != "" { @@ -518,8 +517,8 @@ func getTLSConfigWithCACert(scmRootCAPath string, caCerts []byte) *tls.Config { return tlsConfig } -func GetTlsConfig(scmRootCAPath string, insecure bool, caCerts []byte) *tls.Config { //nolint:revive //FIXME(var-naming) - tlsConfig := getTLSConfigWithCACert(scmRootCAPath, caCerts) +func GetTlsConfig(scmRootCAPath string, insecure bool, caCerts []byte) *tls.Config { + tlsConfig := getTlsConfigWithCACert(scmRootCAPath, caCerts) if insecure { tlsConfig.InsecureSkipVerify = true diff --git a/applicationset/utils/utils_test.go b/applicationset/utils/utils_test.go index 351d144e2f..8d19a2cffa 100644 --- a/applicationset/utils/utils_test.go +++ b/applicationset/utils/utils_test.go @@ -17,7 +17,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - argoappsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoappsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestRenderTemplateParams(t *testing.T) { @@ -62,14 +62,14 @@ func TestRenderTemplateParams(t *testing.T) { tests := []struct { name string fieldVal string - params map[string]any + params map[string]interface{} expectedVal string }{ { name: "simple substitution", fieldVal: "{{one}}", expectedVal: "two", - params: map[string]any{ + params: map[string]interface{}{ "one": "two", }, }, @@ -77,7 +77,7 @@ func TestRenderTemplateParams(t *testing.T) { name: "simple substitution with whitespace", fieldVal: "{{ one }}", expectedVal: "two", - params: map[string]any{ + params: map[string]interface{}{ "one": "two", }, }, @@ -86,7 +86,7 @@ func TestRenderTemplateParams(t *testing.T) { name: "template characters but not in a template", fieldVal: "}} {{", expectedVal: "}} {{", - params: map[string]any{ + params: map[string]interface{}{ "one": "two", }, }, @@ -95,7 +95,7 @@ func TestRenderTemplateParams(t *testing.T) { name: "nested template", fieldVal: "{{ }}", expectedVal: "{{ }}", - params: map[string]any{ + params: map[string]interface{}{ "one": "{{ }}", }, }, @@ -103,7 +103,7 @@ func TestRenderTemplateParams(t *testing.T) { name: "field with whitespace", fieldVal: "{{ }}", expectedVal: "{{ }}", - params: map[string]any{ + params: map[string]interface{}{ " ": "two", "": "three", }, @@ -113,7 +113,7 @@ func TestRenderTemplateParams(t *testing.T) { name: "template contains itself, containing itself", fieldVal: "{{one}}", expectedVal: "{{one}}", - params: map[string]any{ + params: map[string]interface{}{ "{{one}}": "{{one}}", }, }, @@ -122,7 +122,7 @@ func TestRenderTemplateParams(t *testing.T) { name: "template contains itself, containing something else", fieldVal: "{{one}}", expectedVal: "{{one}}", - params: map[string]any{ + params: map[string]interface{}{ "{{one}}": "{{two}}", }, }, @@ -131,7 +131,7 @@ func TestRenderTemplateParams(t *testing.T) { name: "templates are case sensitive", fieldVal: "{{ONE}}", expectedVal: "{{ONE}}", - params: map[string]any{ + params: map[string]interface{}{ "{{one}}": "two", }, }, @@ -139,7 +139,7 @@ func TestRenderTemplateParams(t *testing.T) { name: "multiple on a line", fieldVal: "{{one}}{{one}}", expectedVal: "twotwo", - params: map[string]any{ + params: map[string]interface{}{ "one": "two", }, }, @@ -147,7 +147,7 @@ func TestRenderTemplateParams(t *testing.T) { name: "multiple different on a line", fieldVal: "{{one}}{{three}}", expectedVal: "twofour", - params: map[string]any{ + params: map[string]interface{}{ "one": "two", "three": "four", }, @@ -156,7 +156,7 @@ func TestRenderTemplateParams(t *testing.T) { name: "multiple different on a line with quote", fieldVal: "{{one}} {{three}}", expectedVal: "\"hello\" world four", - params: map[string]any{ + params: map[string]interface{}{ "one": "\"hello\" world", "three": "four", }, @@ -180,14 +180,14 @@ func TestRenderTemplateParams(t *testing.T) { // the target field has been templated into the expected value actualValue := *getPtrFunc(newApplication) assert.Equal(t, test.expectedVal, actualValue, "Field '%s' had an unexpected value. expected: '%s' value: '%s'", fieldName, test.expectedVal, actualValue) - assert.Equal(t, "annotation-value", newApplication.Annotations["annotation-key"]) - assert.Equal(t, "annotation-value2", newApplication.Annotations["annotation-key2"]) - assert.Equal(t, "label-value", newApplication.Labels["label-key"]) - assert.Equal(t, "label-value2", newApplication.Labels["label-key2"]) - assert.Equal(t, "application-one", newApplication.Name) - assert.Equal(t, "default", newApplication.Namespace) - assert.Equal(t, newApplication.UID, types.UID("d546da12-06b7-4f9a-8ea2-3adb16a20e2b")) - assert.Equal(t, newApplication.CreationTimestamp, application.CreationTimestamp) + assert.Equal(t, "annotation-value", newApplication.ObjectMeta.Annotations["annotation-key"]) + assert.Equal(t, "annotation-value2", newApplication.ObjectMeta.Annotations["annotation-key2"]) + assert.Equal(t, "label-value", newApplication.ObjectMeta.Labels["label-key"]) + assert.Equal(t, "label-value2", newApplication.ObjectMeta.Labels["label-key2"]) + assert.Equal(t, "application-one", newApplication.ObjectMeta.Name) + assert.Equal(t, "default", newApplication.ObjectMeta.Namespace) + assert.Equal(t, newApplication.ObjectMeta.UID, types.UID("d546da12-06b7-4f9a-8ea2-3adb16a20e2b")) + assert.Equal(t, newApplication.ObjectMeta.CreationTimestamp, application.ObjectMeta.CreationTimestamp) require.NoError(t, err) } }) @@ -195,7 +195,7 @@ func TestRenderTemplateParams(t *testing.T) { } func TestRenderHelmValuesObjectJson(t *testing.T) { - params := map[string]any{ + params := map[string]interface{}{ "test": "Hello world", } @@ -240,15 +240,15 @@ func TestRenderHelmValuesObjectJson(t *testing.T) { require.NoError(t, err) assert.NotNil(t, newApplication) - var unmarshaled any + var unmarshaled interface{} err = json.Unmarshal(newApplication.Spec.Source.Helm.ValuesObject.Raw, &unmarshaled) require.NoError(t, err) - assert.Equal(t, "Hello world", unmarshaled.(map[string]any)["some"].(map[string]any)["string"]) + assert.Equal(t, "Hello world", unmarshaled.(map[string]interface{})["some"].(map[string]interface{})["string"]) } func TestRenderHelmValuesObjectYaml(t *testing.T) { - params := map[string]any{ + params := map[string]interface{}{ "test": "Hello world", } @@ -290,11 +290,11 @@ func TestRenderHelmValuesObjectYaml(t *testing.T) { require.NoError(t, err) assert.NotNil(t, newApplication) - var unmarshaled any + var unmarshaled interface{} err = json.Unmarshal(newApplication.Spec.Source.Helm.ValuesObject.Raw, &unmarshaled) require.NoError(t, err) - assert.Equal(t, "Hello world", unmarshaled.(map[string]any)["some"].(map[string]any)["string"]) + assert.Equal(t, "Hello world", unmarshaled.(map[string]interface{})["some"].(map[string]interface{})["string"]) } func TestRenderTemplateParamsGoTemplate(t *testing.T) { @@ -339,7 +339,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { tests := []struct { name string fieldVal string - params map[string]any + params map[string]interface{} expectedVal string errorMessage string templateOptions []string @@ -348,7 +348,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "simple substitution", fieldVal: "{{ .one }}", expectedVal: "two", - params: map[string]any{ + params: map[string]interface{}{ "one": "two", }, }, @@ -356,7 +356,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "simple substitution with whitespace", fieldVal: "{{ .one }}", expectedVal: "two", - params: map[string]any{ + params: map[string]interface{}{ "one": "two", }, }, @@ -364,7 +364,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "template contains itself, containing itself", fieldVal: "{{ .one }}", expectedVal: "{{one}}", - params: map[string]any{ + params: map[string]interface{}{ "one": "{{one}}", }, }, @@ -373,7 +373,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "template contains itself, containing something else", fieldVal: "{{ .one }}", expectedVal: "{{two}}", - params: map[string]any{ + params: map[string]interface{}{ "one": "{{two}}", }, }, @@ -381,7 +381,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "multiple on a line", fieldVal: "{{.one}}{{.one}}", expectedVal: "twotwo", - params: map[string]any{ + params: map[string]interface{}{ "one": "two", }, }, @@ -389,7 +389,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "multiple different on a line", fieldVal: "{{.one}}{{.three}}", expectedVal: "twofour", - params: map[string]any{ + params: map[string]interface{}{ "one": "two", "three": "four", }, @@ -398,7 +398,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "multiple different on a line with quote", fieldVal: "{{.one}} {{.three}}", expectedVal: "\"hello\" world four", - params: map[string]any{ + params: map[string]interface{}{ "one": "\"hello\" world", "three": "four", }, @@ -407,9 +407,9 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "depth", fieldVal: "{{ .image.version }}", expectedVal: "latest", - params: map[string]any{ + params: map[string]interface{}{ "replicas": 3, - "image": map[string]any{ + "image": map[string]interface{}{ "name": "busybox", "version": "latest", }, @@ -419,9 +419,9 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "multiple depth", fieldVal: "{{ .image.name }}:{{ .image.version }}", expectedVal: "busybox:latest", - params: map[string]any{ + params: map[string]interface{}{ "replicas": 3, - "image": map[string]any{ + "image": map[string]interface{}{ "name": "busybox", "version": "latest", }, @@ -431,9 +431,9 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "if ok", fieldVal: "{{ if .hpa.enabled }}{{ .hpa.maxReplicas }}{{ else }}{{ .replicas }}{{ end }}", expectedVal: "5", - params: map[string]any{ + params: map[string]interface{}{ "replicas": 3, - "hpa": map[string]any{ + "hpa": map[string]interface{}{ "enabled": true, "minReplicas": 1, "maxReplicas": 5, @@ -444,9 +444,9 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "if not ok", fieldVal: "{{ if .hpa.enabled }}{{ .hpa.maxReplicas }}{{ else }}{{ .replicas }}{{ end }}", expectedVal: "3", - params: map[string]any{ + params: map[string]interface{}{ "replicas": 3, - "hpa": map[string]any{ + "hpa": map[string]interface{}{ "enabled": false, "minReplicas": 1, "maxReplicas": 5, @@ -457,16 +457,16 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "loop", fieldVal: "{{ range .volumes }}[{{ .name }}]{{ end }}", expectedVal: "[volume-one][volume-two]", - params: map[string]any{ + params: map[string]interface{}{ "replicas": 3, - "volumes": []map[string]any{ + "volumes": []map[string]interface{}{ { "name": "volume-one", - "emptyDir": map[string]any{}, + "emptyDir": map[string]interface{}{}, }, { "name": "volume-two", - "emptyDir": map[string]any{}, + "emptyDir": map[string]interface{}{}, }, }, }, @@ -475,8 +475,8 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "Index", fieldVal: `{{ index .admin "admin-ca" }}, {{ index .admin "admin-jks" }}`, expectedVal: "value admin ca, value admin jks", - params: map[string]any{ - "admin": map[string]any{ + params: map[string]interface{}{ + "admin": map[string]interface{}{ "admin-ca": "value admin ca", "admin-jks": "value admin jks", }, @@ -486,8 +486,8 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "Index", fieldVal: `{{ index .admin "admin-ca" }}, \\ "Hello world", {{ index .admin "admin-jks" }}`, expectedVal: `value "admin" ca with \, \\ "Hello world", value admin jks`, - params: map[string]any{ - "admin": map[string]any{ + params: map[string]interface{}{ + "admin": map[string]interface{}{ "admin-ca": `value "admin" ca with \`, "admin-jks": "value admin jks", }, @@ -497,7 +497,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "quote", fieldVal: `{{.quote}}`, expectedVal: `"`, - params: map[string]any{ + params: map[string]interface{}{ "quote": `"`, }, }, @@ -505,13 +505,13 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "Test No Data", fieldVal: `{{.data}}`, expectedVal: "{{.data}}", - params: map[string]any{}, + params: map[string]interface{}{}, }, { name: "Test Parse Error", fieldVal: `{{functiondoesnotexist}}`, expectedVal: "", - params: map[string]any{ + params: map[string]interface{}{ "data": `a data string`, }, errorMessage: `failed to parse template {{functiondoesnotexist}}: template: :1: function "functiondoesnotexist" not defined`, @@ -520,7 +520,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "Test template error", fieldVal: `{{.data.test}}`, expectedVal: "", - params: map[string]any{ + params: map[string]interface{}{ "data": `a data string`, }, errorMessage: `failed to execute go template {{.data.test}}: template: :1:7: executing "" at <.data.test>: can't evaluate field test in type interface {}`, @@ -529,7 +529,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "lookup missing value with missingkey=default", fieldVal: `--> {{.doesnotexist}} <--`, expectedVal: `--> <--`, - params: map[string]any{ + params: map[string]interface{}{ // if no params are passed then for some reason templating is skipped "unused": "this is not used", }, @@ -538,7 +538,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "lookup missing value with missingkey=error", fieldVal: `--> {{.doesnotexist}} <--`, expectedVal: "", - params: map[string]any{ + params: map[string]interface{}{ // if no params are passed then for some reason templating is skipped "unused": "this is not used", }, @@ -549,9 +549,9 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "toYaml", fieldVal: `{{ toYaml . | indent 2 }}`, expectedVal: " foo:\n bar:\n bool: true\n number: 2\n str: Hello world", - params: map[string]any{ - "foo": map[string]any{ - "bar": map[string]any{ + params: map[string]interface{}{ + "foo": map[string]interface{}{ + "bar": map[string]interface{}{ "bool": true, "number": 2, "str": "Hello world", @@ -564,8 +564,8 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { fieldVal: `{{ toYaml . | indent 2 }}`, expectedVal: " foo:\n bar:\n bool: true\n number: 2\n str: Hello world", errorMessage: "failed to execute go template {{ toYaml . | indent 2 }}: template: :1:3: executing \"\" at : error calling toYaml: error marshaling into JSON: json: unsupported type: func(*string)", - params: map[string]any{ - "foo": func(_ *string) { + params: map[string]interface{}{ + "foo": func(test *string) { }, }, }, @@ -573,7 +573,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "fromYaml", fieldVal: `{{ get (fromYaml .value) "hello" }}`, expectedVal: "world", - params: map[string]any{ + params: map[string]interface{}{ "value": "hello: world", }, }, @@ -582,7 +582,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { fieldVal: `{{ get (fromYaml .value) "hello" }}`, expectedVal: "world", errorMessage: "failed to execute go template {{ get (fromYaml .value) \"hello\" }}: template: :1:8: executing \"\" at : error calling fromYaml: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type map[string]interface {}", - params: map[string]any{ + params: map[string]interface{}{ "value": "non\n compliant\n yaml", }, }, @@ -590,7 +590,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { name: "fromYamlArray", fieldVal: `{{ fromYamlArray .value | last }}`, expectedVal: "bonjour tout le monde", - params: map[string]any{ + params: map[string]interface{}{ "value": "- hello world\n- bonjour tout le monde", }, }, @@ -599,7 +599,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { fieldVal: `{{ fromYamlArray .value | last }}`, expectedVal: "bonjour tout le monde", errorMessage: "failed to execute go template {{ fromYamlArray .value | last }}: template: :1:3: executing \"\" at : error calling fromYamlArray: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type []interface {}", - params: map[string]any{ + params: map[string]interface{}{ "value": "non\n compliant\n yaml", }, }, @@ -627,14 +627,14 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { require.NoError(t, err) actualValue := *getPtrFunc(newApplication) assert.Equal(t, test.expectedVal, actualValue, "Field '%s' had an unexpected value. expected: '%s' value: '%s'", fieldName, test.expectedVal, actualValue) - assert.Equal(t, "annotation-value", newApplication.Annotations["annotation-key"]) - assert.Equal(t, "annotation-value2", newApplication.Annotations["annotation-key2"]) - assert.Equal(t, "label-value", newApplication.Labels["label-key"]) - assert.Equal(t, "label-value2", newApplication.Labels["label-key2"]) - assert.Equal(t, "application-one", newApplication.Name) - assert.Equal(t, "default", newApplication.Namespace) - assert.Equal(t, newApplication.UID, types.UID("d546da12-06b7-4f9a-8ea2-3adb16a20e2b")) - assert.Equal(t, newApplication.CreationTimestamp, application.CreationTimestamp) + assert.Equal(t, "annotation-value", newApplication.ObjectMeta.Annotations["annotation-key"]) + assert.Equal(t, "annotation-value2", newApplication.ObjectMeta.Annotations["annotation-key2"]) + assert.Equal(t, "label-value", newApplication.ObjectMeta.Labels["label-key"]) + assert.Equal(t, "label-value2", newApplication.ObjectMeta.Labels["label-key2"]) + assert.Equal(t, "application-one", newApplication.ObjectMeta.Name) + assert.Equal(t, "default", newApplication.ObjectMeta.Namespace) + assert.Equal(t, newApplication.ObjectMeta.UID, types.UID("d546da12-06b7-4f9a-8ea2-3adb16a20e2b")) + assert.Equal(t, newApplication.ObjectMeta.CreationTimestamp, application.ObjectMeta.CreationTimestamp) } } }) @@ -645,7 +645,7 @@ func TestRenderGeneratorParams_does_not_panic(t *testing.T) { // This test verifies that the RenderGeneratorParams function does not panic when the value in a map is a non- // nillable type. This is a regression test. render := Render{} - params := map[string]any{ + params := map[string]interface{}{ "branch": "master", } generator := &argoappsv1.ApplicationSetGenerator{ @@ -679,7 +679,7 @@ func TestRenderTemplateKeys(t *testing.T) { }, } - params := map[string]any{ + params := map[string]interface{}{ "key": "some-key", "value": "some-value", } @@ -687,8 +687,8 @@ func TestRenderTemplateKeys(t *testing.T) { render := Render{} newApplication, err := render.RenderTemplateParams(application, nil, params, false, nil) require.NoError(t, err) - require.Contains(t, newApplication.Annotations, "annotation-some-key") - assert.Equal(t, "annotation-some-value", newApplication.Annotations["annotation-some-key"]) + require.Contains(t, newApplication.ObjectMeta.Annotations, "annotation-some-key") + assert.Equal(t, "annotation-some-value", newApplication.ObjectMeta.Annotations["annotation-some-key"]) }) t.Run("gotemplate", func(t *testing.T) { application := &argoappsv1.Application{ @@ -699,7 +699,7 @@ func TestRenderTemplateKeys(t *testing.T) { }, } - params := map[string]any{ + params := map[string]interface{}{ "key": "some-key", "value": "some-value", } @@ -707,8 +707,8 @@ func TestRenderTemplateKeys(t *testing.T) { render := Render{} newApplication, err := render.RenderTemplateParams(application, nil, params, true, nil) require.NoError(t, err) - require.Contains(t, newApplication.Annotations, "annotation-some-key") - assert.Equal(t, "annotation-some-value", newApplication.Annotations["annotation-some-key"]) + require.Contains(t, newApplication.ObjectMeta.Annotations, "annotation-some-key") + assert.Equal(t, "annotation-some-value", newApplication.ObjectMeta.Annotations["annotation-some-key"]) }) } @@ -804,7 +804,7 @@ func TestRenderTemplateParamsFinalizers(t *testing.T) { application := emptyApplication.DeepCopy() application.Finalizers = c.existingFinalizers - params := map[string]any{ + params := map[string]interface{}{ "one": "two", } @@ -1331,42 +1331,42 @@ WkBKOclmOV2xlTVuPw== scmRootCAPath string insecure bool caCerts []byte - validateCertInTLSConfig bool + validateCertInTlsConfig bool }{ { name: "Insecure mode configured, SCM Root CA Path not set", scmRootCAPath: "", insecure: true, caCerts: nil, - validateCertInTLSConfig: false, + validateCertInTlsConfig: false, }, { name: "SCM Root CA Path set, Insecure mode set to false", scmRootCAPath: rootCAPath, insecure: false, caCerts: nil, - validateCertInTLSConfig: true, + validateCertInTlsConfig: true, }, { name: "SCM Root CA Path set, Insecure mode set to true", scmRootCAPath: rootCAPath, insecure: true, caCerts: nil, - validateCertInTLSConfig: true, + validateCertInTlsConfig: true, }, { name: "Cert passed, Insecure mode set to false", scmRootCAPath: "", insecure: false, caCerts: []byte(certFromCM), - validateCertInTLSConfig: true, + validateCertInTlsConfig: true, }, { name: "SCM Root CA Path set, cert passed, Insecure mode set to false", scmRootCAPath: rootCAPath, insecure: false, caCerts: []byte(certFromCM), - validateCertInTLSConfig: true, + validateCertInTlsConfig: true, }, } @@ -1384,7 +1384,7 @@ WkBKOclmOV2xlTVuPw== assert.True(t, ok) } assert.NotNil(t, tlsConfig) - if testCase.validateCertInTLSConfig { + if testCase.validateCertInTlsConfig { assert.True(t, tlsConfig.RootCAs.Equal(certPool)) } }) diff --git a/applicationset/webhook/testdata/gitlab-event.json b/applicationset/webhook/testdata/gitlab-event.json index 9371005e18..83ac0b4fcb 100644 --- a/applicationset/webhook/testdata/gitlab-event.json +++ b/applicationset/webhook/testdata/gitlab-event.json @@ -1,65 +1,65 @@ { - "object_kind": "push", - "event_name": "push", - "before": "e5ba5f6c13b64670048daa88e4c053d60b0e115a", - "after": "bb0748feaa336d841c251017e4e374c22d0c8a98", - "ref": "refs/heads/master", - "checkout_sha": "bb0748feaa336d841c251017e4e374c22d0c8a98", - "message": null, - "user_id": 1, - "user_name": "name", - "user_username": "username", - "user_email": "", - "user_avatar": "", - "project_id": 1, - "project": { - "id": 1, - "name": "project", - "description": "", - "web_url": "https://gitlab.com/group/name", - "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", - "git_http_url": "https://gitlab.com/group/name.git", - "namespace": "group", - "visibility_level": 1, - "path_with_namespace": "group/name", - "default_branch": "master", - "ci_config_path": null, - "homepage": "https://gitlab.com/group/name", - "url": "ssh://git@gitlab.com:2222/group/name.git", - "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", - "http_url": "https://gitlab.com/group/name.git" - }, - "commits": [ - { - "id": "bb0748feaa336d841c251017e4e374c22d0c8a98", - "message": "Test commit message\n", - "timestamp": "2020-01-06T03:47:55Z", - "url": "https://gitlab.com/group/name/commit/bb0748feaa336d841c251017e4e374c22d0c8a98", - "author": { - "name": "User", - "email": "user@example.com" - }, - "added": [ - "file.yaml" - ], - "modified": [ - ], - "removed": [ - - ] + "object_kind": "push", + "event_name": "push", + "before": "e5ba5f6c13b64670048daa88e4c053d60b0e115a", + "after": "bb0748feaa336d841c251017e4e374c22d0c8a98", + "ref": "refs/heads/master", + "checkout_sha": "bb0748feaa336d841c251017e4e374c22d0c8a98", + "message": null, + "user_id": 1, + "user_name": "name", + "user_username": "username", + "user_email": "", + "user_avatar": "", + "project_id": 1, + "project": { + "id": 1, + "name": "project", + "description": "", + "web_url": "https://gitlab/group/name", + "avatar_url": null, + "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", + "git_http_url": "https://gitlab/group/name.git", + "namespace": "group", + "visibility_level": 1, + "path_with_namespace": "group/name", + "default_branch": "master", + "ci_config_path": null, + "homepage": "https://gitlab/group/name", + "url": "ssh://git@gitlab:2222/group/name.git", + "ssh_url": "ssh://git@gitlab:2222/group/name.git", + "http_url": "https://gitlab/group/name.git" + }, + "commits": [ + { + "id": "bb0748feaa336d841c251017e4e374c22d0c8a98", + "message": "Test commit message\n", + "timestamp": "2020-01-06T03:47:55Z", + "url": "https://gitlab/group/name/commit/bb0748feaa336d841c251017e4e374c22d0c8a98", + "author": { + "name": "User", + "email": "user@example.com" + }, + "added": [ + "file.yaml" + ], + "modified": [ + ], + "removed": [ + + ] + } + ], + "total_commits_count": 1, + "push_options": { + }, + "repository": { + "name": "name", + "url": "ssh://git@gitlab:2222/group/name.git", + "description": "", + "homepage": "https://gitlab/group/name", + "git_http_url": "https://gitlab/group/name.git", + "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", + "visibility_level": 10 } - ], - "total_commits_count": 1, - "push_options": { - }, - "repository": { - "name": "name", - "url": "ssh://git@gitlab.com:2222/group/name.git", - "description": "", - "homepage": "https://gitlab.com/group/name", - "git_http_url": "https://gitlab.com/group/name.git", - "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", - "visibility_level": 10 - } -} + } \ No newline at end of file diff --git a/applicationset/webhook/testdata/gitlab-merge-request-approval-event.json b/applicationset/webhook/testdata/gitlab-merge-request-approval-event.json index f7137298a1..bef2fee493 100644 --- a/applicationset/webhook/testdata/gitlab-merge-request-approval-event.json +++ b/applicationset/webhook/testdata/gitlab-merge-request-approval-event.json @@ -14,7 +14,7 @@ "description": "", "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", "git_http_url": "https://gitlab.com/group/name.git", "namespace": "group", "visibility_level": 1, @@ -22,17 +22,17 @@ "default_branch": "master", "ci_config_path": null, "homepage": "https://gitlab.com/group/name", - "url": "ssh://git@gitlab.com:2222/group/name.git", - "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "url": "ssh://git@gitlab:2222/group/name.git", + "ssh_url": "ssh://git@gitlab:2222/group/name.git", "http_url": "https://gitlab.com/group/name.git" }, "repository": { "name": "name", - "url": "ssh://git@gitlab.com:2222/group/name.git", + "url": "ssh://git@gitlab:2222/group/name.git", "description": "", "homepage": "https://gitlab.com/group/name", "git_http_url": "https://gitlab.com/group/name.git", - "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", "visibility_level": 10 }, "object_attributes": { @@ -60,7 +60,7 @@ "description": "Aut reprehenderit ut est.", "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", "git_http_url": "https://gitlab.com/group/name.git", "namespace": "Awesome Space", "visibility_level": 20, @@ -68,7 +68,7 @@ "default_branch": "master", "homepage": "https://gitlab.com/group/name", "url": "https://gitlab.com/group/name.git", - "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "ssh_url": "ssh://git@gitlab:2222/group/name.git", "http_url": "https://gitlab.com/group/name.git" }, "target": { @@ -76,7 +76,7 @@ "description": "Aut reprehenderit ut est.", "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", "git_http_url": "https://gitlab.com/group/name.git", "namespace": "Awesome Space", "visibility_level": 20, @@ -84,7 +84,7 @@ "default_branch": "master", "homepage": "https://gitlab.com/group/name", "url": "https://gitlab.com/group/name.git", - "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "ssh_url": "ssh://git@gitlab:2222/group/name.git", "http_url": "https://gitlab.com/group/name.git" }, "last_commit": { diff --git a/applicationset/webhook/testdata/gitlab-merge-request-open-event.json b/applicationset/webhook/testdata/gitlab-merge-request-open-event.json index 953ac8d366..e4e226a46d 100644 --- a/applicationset/webhook/testdata/gitlab-merge-request-open-event.json +++ b/applicationset/webhook/testdata/gitlab-merge-request-open-event.json @@ -14,7 +14,7 @@ "description": "", "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", "git_http_url": "https://gitlab.com/group/name.git", "namespace": "group", "visibility_level": 1, @@ -22,17 +22,17 @@ "default_branch": "master", "ci_config_path": null, "homepage": "https://gitlab.com/group/name", - "url": "ssh://git@gitlab.com:2222/group/name.git", - "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "url": "ssh://git@gitlab:2222/group/name.git", + "ssh_url": "ssh://git@gitlab:2222/group/name.git", "http_url": "https://gitlab.com/group/name.git" }, "repository": { "name": "name", - "url": "ssh://git@gitlab.com:2222/group/name.git", + "url": "ssh://git@gitlab:2222/group/name.git", "description": "", "homepage": "https://gitlab.com/group/name", "git_http_url": "https://gitlab.com/group/name.git", - "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", "visibility_level": 10 }, "object_attributes": { @@ -60,7 +60,7 @@ "description": "Aut reprehenderit ut est.", "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", "git_http_url": "https://gitlab.com/group/name.git", "namespace": "Awesome Space", "visibility_level": 20, @@ -68,7 +68,7 @@ "default_branch": "master", "homepage": "https://gitlab.com/group/name", "url": "https://gitlab.com/group/name.git", - "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "ssh_url": "ssh://git@gitlab:2222/group/name.git", "http_url": "https://gitlab.com/group/name.git" }, "target": { @@ -76,7 +76,7 @@ "description": "Aut reprehenderit ut est.", "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", "git_http_url": "https://gitlab.com/group/name.git", "namespace": "Awesome Space", "visibility_level": 20, @@ -84,7 +84,7 @@ "default_branch": "master", "homepage": "https://gitlab.com/group/name", "url": "https://gitlab.com/group/name.git", - "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "ssh_url": "ssh://git@gitlab:2222/group/name.git", "http_url": "https://gitlab.com/group/name.git" }, "last_commit": { diff --git a/applicationset/webhook/webhook.go b/applicationset/webhook/webhook.go index 28f00b1cf6..5c78001a1d 100644 --- a/applicationset/webhook/webhook.go +++ b/applicationset/webhook/webhook.go @@ -7,7 +7,6 @@ import ( "net/http" "net/url" "regexp" - "slices" "strconv" "strings" "sync" @@ -16,11 +15,11 @@ import ( "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/argoproj/argo-cd/v3/applicationset/generators" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - argosettings "github.com/argoproj/argo-cd/v3/util/settings" - "github.com/argoproj/argo-cd/v3/util/webhook" + "github.com/argoproj/argo-cd/v2/applicationset/generators" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + argosettings "github.com/argoproj/argo-cd/v2/util/settings" + "github.com/argoproj/argo-cd/v2/util/webhook" "github.com/go-playground/webhooks/v6/azuredevops" "github.com/go-playground/webhooks/v6/github" @@ -38,7 +37,7 @@ type WebhookHandler struct { azuredevops *azuredevops.Webhook client client.Client generators map[string]generators.Generator - queue chan any + queue chan interface{} } type gitGeneratorInfo struct { @@ -73,19 +72,19 @@ func NewWebhookHandler(namespace string, webhookParallelism int, argocdSettingsM // register the webhook secrets stored under "argocd-secret" for verifying incoming payloads argocdSettings, err := argocdSettingsMgr.GetSettings() if err != nil { - return nil, fmt.Errorf("failed to get argocd settings: %w", err) + return nil, fmt.Errorf("Failed to get argocd settings: %w", err) } githubHandler, err := github.New(github.Options.Secret(argocdSettings.WebhookGitHubSecret)) if err != nil { - return nil, fmt.Errorf("unable to init GitHub webhook: %w", err) + return nil, fmt.Errorf("Unable to init GitHub webhook: %w", err) } gitlabHandler, err := gitlab.New(gitlab.Options.Secret(argocdSettings.WebhookGitLabSecret)) if err != nil { - return nil, fmt.Errorf("unable to init GitLab webhook: %w", err) + return nil, fmt.Errorf("Unable to init GitLab webhook: %w", err) } azuredevopsHandler, err := azuredevops.New(azuredevops.Options.BasicAuth(argocdSettings.WebhookAzureDevOpsUsername, argocdSettings.WebhookAzureDevOpsPassword)) if err != nil { - return nil, fmt.Errorf("unable to init Azure DevOps webhook: %w", err) + return nil, fmt.Errorf("Unable to init Azure DevOps webhook: %w", err) } webhookHandler := &WebhookHandler{ @@ -95,7 +94,7 @@ func NewWebhookHandler(namespace string, webhookParallelism int, argocdSettingsM azuredevops: azuredevopsHandler, client: client, generators: generators, - queue: make(chan any, payloadQueueSize), + queue: make(chan interface{}, payloadQueueSize), } webhookHandler.startWorkerPool(webhookParallelism) @@ -119,7 +118,7 @@ func (h *WebhookHandler) startWorkerPool(webhookParallelism int) { } } -func (h *WebhookHandler) HandleEvent(payload any) { +func (h *WebhookHandler) HandleEvent(payload interface{}) { gitGenInfo := getGitGeneratorInfo(payload) prGenInfo := getPRGeneratorInfo(payload) if gitGenInfo == nil && prGenInfo == nil { @@ -158,14 +157,14 @@ func (h *WebhookHandler) HandleEvent(payload any) { } func (h *WebhookHandler) Handler(w http.ResponseWriter, r *http.Request) { - var payload any + var payload interface{} var err error switch { case r.Header.Get("X-GitHub-Event") != "": payload, err = h.github.Parse(r, github.PushEvent, github.PullRequestEvent, github.PingEvent) case r.Header.Get("X-Gitlab-Event") != "": - payload, err = h.gitlab.Parse(r, gitlab.PushEvents, gitlab.TagEvents, gitlab.MergeRequestEvents, gitlab.SystemHookEvents) + payload, err = h.gitlab.Parse(r, gitlab.PushEvents, gitlab.TagEvents, gitlab.MergeRequestEvents) case r.Header.Get("X-Vss-Activityid") != "": payload, err = h.azuredevops.Parse(r, azuredevops.GitPushEventType, azuredevops.GitPullRequestCreatedEventType, azuredevops.GitPullRequestUpdatedEventType, azuredevops.GitPullRequestMergedEventType) default: @@ -180,7 +179,7 @@ func (h *WebhookHandler) Handler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { status = http.StatusMethodNotAllowed } - http.Error(w, "Webhook processing failed: "+html.EscapeString(err.Error()), status) + http.Error(w, fmt.Sprintf("Webhook processing failed: %s", html.EscapeString(err.Error())), status) return } @@ -192,7 +191,7 @@ func (h *WebhookHandler) Handler(w http.ResponseWriter, r *http.Request) { } } -func getGitGeneratorInfo(payload any) *gitGeneratorInfo { +func getGitGeneratorInfo(payload interface{}) *gitGeneratorInfo { var ( webURL string revision string @@ -218,7 +217,13 @@ func getGitGeneratorInfo(payload any) *gitGeneratorInfo { } log.Infof("Received push event repo: %s, revision: %s, touchedHead: %v", webURL, revision, touchedHead) - repoRegexp, err := webhook.GetWebURLRegex(webURL) + urlObj, err := url.Parse(webURL) + if err != nil { + log.Errorf("Failed to parse repoURL '%s'", webURL) + return nil + } + regexpStr := `(?i)(http://|https://|\w+@|ssh://(\w+@)?)` + urlObj.Hostname() + "(:[0-9]+|)[:/]" + urlObj.Path[1:] + "(\\.git)?$" + repoRegexp, err := regexp.Compile(regexpStr) if err != nil { log.Errorf("Failed to compile regexp for repoURL '%s'", webURL) return nil @@ -231,16 +236,22 @@ func getGitGeneratorInfo(payload any) *gitGeneratorInfo { } } -func getPRGeneratorInfo(payload any) *prGeneratorInfo { +func getPRGeneratorInfo(payload interface{}) *prGeneratorInfo { var info prGeneratorInfo switch payload := payload.(type) { case github.PullRequestPayload: - if !slices.Contains(githubAllowedPullRequestActions, payload.Action) { + if !isAllowedGithubPullRequestAction(payload.Action) { return nil } apiURL := payload.Repository.URL - apiRegexp, err := webhook.GetAPIURLRegex(apiURL) + urlObj, err := url.Parse(apiURL) + if err != nil { + log.Errorf("Failed to parse repoURL '%s'", apiURL) + return nil + } + regexpStr := `(?i)(http://|https://|\w+@|ssh://(\w+@)?)` + urlObj.Hostname() + "(:[0-9]+|)[:/]" + apiRegexp, err := regexp.Compile(regexpStr) if err != nil { log.Errorf("Failed to compile regexp for repoURL '%s'", apiURL) return nil @@ -251,7 +262,7 @@ func getPRGeneratorInfo(payload any) *prGeneratorInfo { APIRegexp: apiRegexp, } case gitlab.MergeRequestEventPayload: - if !slices.Contains(gitlabAllowedPullRequestActions, payload.ObjectAttributes.Action) { + if !isAllowedGitlabPullRequestAction(payload.ObjectAttributes.Action) { return nil } @@ -267,7 +278,7 @@ func getPRGeneratorInfo(payload any) *prGeneratorInfo { APIHostname: urlObj.Hostname(), } case azuredevops.GitPullRequestEvent: - if !slices.Contains(azuredevopsAllowedPullRequestActions, string(payload.EventType)) { + if !isAllowedAzureDevOpsPullRequestAction(string(payload.EventType)) { return nil } @@ -312,6 +323,33 @@ var azuredevopsAllowedPullRequestActions = []string{ "git.pullrequest.updated", } +func isAllowedGithubPullRequestAction(action string) bool { + for _, allow := range githubAllowedPullRequestActions { + if allow == action { + return true + } + } + return false +} + +func isAllowedGitlabPullRequestAction(action string) bool { + for _, allow := range gitlabAllowedPullRequestActions { + if allow == action { + return true + } + } + return false +} + +func isAllowedAzureDevOpsPullRequestAction(action string) bool { + for _, allow := range azuredevopsAllowedPullRequestActions { + if allow == action { + return true + } + } + return false +} + func shouldRefreshGitGenerator(gen *v1alpha1.GitGenerator, info *gitGeneratorInfo) bool { if gen == nil || info == nil { return false @@ -479,7 +517,7 @@ func (h *WebhookHandler) shouldRefreshMatrixGenerator(gen *v1alpha1.MatrixGenera // Generate params for first child generator relGenerators := generators.GetRelevantGenerators(requestedGenerator0, h.generators) - params := []map[string]any{} + params := []map[string]interface{}{} for _, g := range relGenerators { p, err := g.GenerateParams(requestedGenerator0, appSet, h.client) if err != nil { diff --git a/applicationset/webhook/webhook_test.go b/applicationset/webhook/webhook_test.go index 311c522ebe..33a8d134ea 100644 --- a/applicationset/webhook/webhook_test.go +++ b/applicationset/webhook/webhook_test.go @@ -2,6 +2,7 @@ package webhook import ( "bytes" + "context" "fmt" "io" "net/http" @@ -23,26 +24,26 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "github.com/argoproj/argo-cd/v3/applicationset/generators" - "github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - argosettings "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/applicationset/generators" + "github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + argosettings "github.com/argoproj/argo-cd/v2/util/settings" ) type generatorMock struct { mock.Mock } -func (g *generatorMock) GetTemplate(_ *v1alpha1.ApplicationSetGenerator) *v1alpha1.ApplicationSetTemplate { +func (g *generatorMock) GetTemplate(appSetGenerator *v1alpha1.ApplicationSetGenerator) *v1alpha1.ApplicationSetTemplate { return &v1alpha1.ApplicationSetTemplate{} } -func (g *generatorMock) GenerateParams(_ *v1alpha1.ApplicationSetGenerator, _ *v1alpha1.ApplicationSet, _ client.Client) ([]map[string]any, error) { - return []map[string]any{}, nil +func (g *generatorMock) GenerateParams(appSetGenerator *v1alpha1.ApplicationSetGenerator, _ *v1alpha1.ApplicationSet, client client.Client) ([]map[string]interface{}, error) { + return []map[string]interface{}{}, nil } -func (g *generatorMock) GetRequeueAfter(_ *v1alpha1.ApplicationSetGenerator) time.Duration { +func (g *generatorMock) GetRequeueAfter(appSetGenerator *v1alpha1.ApplicationSetGenerator) time.Duration { d, _ := time.ParseDuration("10s") return d } @@ -62,7 +63,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-GitHub-Event", headerValue: "push", payloadFile: "github-commit-event.json", - effectedAppSets: []string{"git-github", "git-github-ssh", "git-github-alt-ssh", "matrix-git-github", "merge-git-github", "matrix-scm-git-github", "matrix-nested-git-github", "merge-nested-git-github", "plugin", "matrix-pull-request-github-plugin"}, + effectedAppSets: []string{"git-github", "matrix-git-github", "merge-git-github", "matrix-scm-git-github", "matrix-nested-git-github", "merge-nested-git-github", "plugin", "matrix-pull-request-github-plugin"}, expectedStatusCode: http.StatusOK, expectedRefresh: true, }, @@ -80,7 +81,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-GitHub-Event", headerValue: "push", payloadFile: "github-commit-branch-event.json", - effectedAppSets: []string{"git-github", "git-github-ssh", "git-github-alt-ssh", "plugin", "matrix-pull-request-github-plugin"}, + effectedAppSets: []string{"git-github", "plugin", "matrix-pull-request-github-plugin"}, expectedStatusCode: http.StatusOK, expectedRefresh: true, }, @@ -89,7 +90,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-GitHub-Event", headerValue: "ping", payloadFile: "github-ping-event.json", - effectedAppSets: []string{"git-github", "git-github-ssh", "git-github-alt-ssh", "plugin"}, + effectedAppSets: []string{"git-github", "plugin"}, expectedStatusCode: http.StatusOK, expectedRefresh: false, }, @@ -98,16 +99,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-Gitlab-Event", headerValue: "Push Hook", payloadFile: "gitlab-event.json", - effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin", "matrix-pull-request-github-plugin"}, - expectedStatusCode: http.StatusOK, - expectedRefresh: true, - }, - { - desc: "WebHook from a System Hook via Commit", - headerKey: "X-Gitlab-Event", - headerValue: "System Hook", - payloadFile: "gitlab-event.json", - effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin", "matrix-pull-request-github-plugin"}, + effectedAppSets: []string{"git-gitlab", "plugin", "matrix-pull-request-github-plugin"}, expectedStatusCode: http.StatusOK, expectedRefresh: true, }, @@ -116,7 +108,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-Random-Event", headerValue: "Push Hook", payloadFile: "gitlab-event.json", - effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin"}, + effectedAppSets: []string{"git-gitlab", "plugin"}, expectedStatusCode: http.StatusBadRequest, expectedRefresh: false, }, @@ -125,7 +117,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-Random-Event", headerValue: "Push Hook", payloadFile: "invalid-event.json", - effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin"}, + effectedAppSets: []string{"git-gitlab", "plugin"}, expectedStatusCode: http.StatusBadRequest, expectedRefresh: false, }, @@ -208,11 +200,7 @@ func TestWebhookHandler(t *testing.T) { fc := fake.NewClientBuilder().WithScheme(scheme).WithObjects( fakeAppWithGitGenerator("git-github", namespace, "https://github.com/org/repo"), fakeAppWithGitGenerator("git-github-copy", namespace, "https://github.com/org/repo-copy"), - fakeAppWithGitGenerator("git-github-ssh", namespace, "ssh://git@github.com/org/repo"), - fakeAppWithGitGenerator("git-github-alt-ssh", namespace, "ssh://git@ssh.github.com:443/org/repo"), - fakeAppWithGitGenerator("git-gitlab", namespace, "https://gitlab.com/group/name"), - fakeAppWithGitGenerator("git-gitlab-ssh", namespace, "ssh://git@gitlab.com/group/name"), - fakeAppWithGitGenerator("git-gitlab-alt-ssh", namespace, "ssh://git@altssh.gitlab.com:443/group/name"), + fakeAppWithGitGenerator("git-gitlab", namespace, "https://gitlab/group/name"), fakeAppWithGitGenerator("git-azure-devops", namespace, "https://dev.azure.com/fabrikam-fiber-inc/DefaultCollection/_git/Fabrikam-Fiber-Git"), fakeAppWithGitGeneratorWithRevision("github-shorthand", namespace, "https://github.com/org/repo", "env/dev"), fakeAppWithGithubPullRequestGenerator("pull-request-github", namespace, "CodErTOcat", "Hello-World"), @@ -229,7 +217,7 @@ func TestWebhookHandler(t *testing.T) { fakeAppWithMergeAndPullRequestGenerator("merge-pull-request-github", namespace, "Codertocat", "Hello-World"), fakeAppWithMergeAndNestedGitGenerator("merge-nested-git-github", namespace, "https://github.com/org/repo"), ).Build() - set := argosettings.NewSettingsManager(t.Context(), fakeClient, namespace) + set := argosettings.NewSettingsManager(context.TODO(), fakeClient, namespace) h, err := NewWebhookHandler(namespace, webhookParallelism, set, fc, mockGenerators()) require.NoError(t, err) @@ -246,7 +234,7 @@ func TestWebhookHandler(t *testing.T) { assert.Equal(t, test.expectedStatusCode, w.Code) list := &v1alpha1.ApplicationSetList{} - err = fc.List(t.Context(), list) + err = fc.List(context.TODO(), list) require.NoError(t, err) effectedAppSetsAsExpected := make(map[string]bool) for _, appSetName := range test.effectedAppSets { diff --git a/assets/swagger.json b/assets/swagger.json index 5f4f2fbe33..9436a6a6f4 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -920,11 +920,6 @@ "type": "string", "name": "project", "in": "query" - }, - { - "type": "boolean", - "name": "matchCase", - "in": "query" } ], "responses": { @@ -1158,11 +1153,6 @@ "type": "string", "name": "project", "in": "query" - }, - { - "type": "boolean", - "name": "matchCase", - "in": "query" } ], "responses": { @@ -1490,8 +1480,43 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/applicationResourceActionRunRequest" + "type": "string" } + }, + { + "type": "string", + "name": "namespace", + "in": "query" + }, + { + "type": "string", + "name": "resourceName", + "in": "query" + }, + { + "type": "string", + "name": "version", + "in": "query" + }, + { + "type": "string", + "name": "group", + "in": "query" + }, + { + "type": "string", + "name": "kind", + "in": "query" + }, + { + "type": "string", + "name": "appNamespace", + "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -3746,18 +3771,6 @@ "description": "Whether to force HTTP basic auth.", "name": "forceHttpBasicAuth", "in": "query" - }, - { - "type": "boolean", - "description": "Whether to use azure workload identity for authentication.", - "name": "useAzureWorkloadIdentity", - "in": "query" - }, - { - "type": "string", - "description": "BearerToken contains the bearer token used for Git auth at the repo server.", - "name": "bearerToken", - "in": "query" } ], "responses": { @@ -4584,18 +4597,6 @@ "description": "Whether to force HTTP basic auth.", "name": "forceHttpBasicAuth", "in": "query" - }, - { - "type": "boolean", - "description": "Whether to use azure workload identity for authentication.", - "name": "useAzureWorkloadIdentity", - "in": "query" - }, - { - "type": "string", - "description": "BearerToken contains the bearer token used for Git auth at the repo server.", - "name": "bearerToken", - "in": "query" } ], "responses": { @@ -4997,55 +4998,6 @@ "applicationOperationTerminateResponse": { "type": "object" }, - "applicationResourceActionParameters": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "applicationResourceActionRunRequest": { - "type": "object", - "properties": { - "action": { - "type": "string" - }, - "appNamespace": { - "type": "string" - }, - "group": { - "type": "string" - }, - "kind": { - "type": "string" - }, - "name": { - "type": "string" - }, - "namespace": { - "type": "string" - }, - "project": { - "type": "string" - }, - "resourceActionParameters": { - "type": "array", - "items": { - "$ref": "#/definitions/applicationResourceActionParameters" - } - }, - "resourceName": { - "type": "string" - }, - "version": { - "type": "string" - } - } - }, "applicationResourceActionsListResponse": { "type": "object", "properties": { @@ -5115,51 +5067,41 @@ } }, "applicationv1alpha1ResourceStatus": { - "description": "ResourceStatus holds the current synchronization and health status of a Kubernetes resource.", "type": "object", + "title": "ResourceStatus holds the current sync and health status of a resource\nTODO: describe members of this type", "properties": { "group": { - "description": "Group represents the API group of the resource (e.g., \"apps\" for Deployments).", "type": "string" }, "health": { "$ref": "#/definitions/v1alpha1HealthStatus" }, "hook": { - "description": "Hook is true if the resource is used as a lifecycle hook in an Argo CD application.", "type": "boolean" }, "kind": { - "description": "Kind specifies the type of the resource (e.g., \"Deployment\", \"Service\").", "type": "string" }, "name": { - "description": "Name is the unique name of the resource within the namespace.", "type": "string" }, "namespace": { - "description": "Namespace defines the Kubernetes namespace where the resource is located.", "type": "string" }, "requiresDeletionConfirmation": { - "description": "RequiresDeletionConfirmation is true if the resource requires explicit user confirmation before deletion.", "type": "boolean" }, "requiresPruning": { - "description": "RequiresPruning is true if the resource needs to be pruned (deleted) as part of synchronization.", "type": "boolean" }, "status": { - "description": "Status represents the synchronization state of the resource (e.g., Synced, OutOfSync).", "type": "string" }, "syncWave": { - "description": "SyncWave determines the order in which resources are applied during a sync operation.\nLower values are applied first.", "type": "integer", "format": "int64" }, "version": { - "description": "Version indicates the API version of the resource (e.g., \"v1\", \"v1beta1\").", "type": "string" } } @@ -6453,7 +6395,6 @@ }, "v1PortStatus": { "type": "object", - "title": "PortStatus represents the error condition of a service port", "properties": { "error": { "type": "string", @@ -6493,24 +6434,6 @@ } } }, - "v1alpha1AppHealthStatus": { - "type": "object", - "title": "AppHealthStatus contains information about the currently observed health state of an application", - "properties": { - "lastTransitionTime": { - "$ref": "#/definitions/v1Time" - }, - "message": { - "description": "Deprecated: this field is not used and will be removed in a future release.", - "type": "string", - "title": "Message is a human-readable informational message describing the health status" - }, - "status": { - "type": "string", - "title": "Status holds the status code of the application" - } - } - }, "v1alpha1AppProject": { "type": "object", "title": "AppProject provides a logical grouping of applications, providing controls for:\n* where the apps may deploy to (cluster whitelist)\n* what may be deployed (repository whitelist, resource whitelist/blacklist)\n* who can access these applications (roles, OIDC group claims bindings)\n* and what they can do (RBAC policies)\n* automation access to these roles (JWT tokens)\n+genclient\n+genclient:noStatus\n+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object\n+kubebuilder:resource:path=appprojects,shortName=appproj;appprojs", @@ -6561,7 +6484,7 @@ }, "description": { "type": "string", - "title": "Description contains optional project description\n+kubebuilder:validation:MaxLength=255" + "title": "Description contains optional project description" }, "destinationServiceAccounts": { "description": "DestinationServiceAccounts holds information about the service accounts to be impersonated for the application sync operation for each destination.", @@ -6981,8 +6904,8 @@ "type": "object", "properties": { "applyNestedSelectors": { - "description": "ApplyNestedSelectors enables selectors defined within the generators of two level-nested matrix or merge generators\nDeprecated: This field is ignored, and the behavior is always enabled. The field will be removed in a future\nversion of the ApplicationSet CRD.", - "type": "boolean" + "type": "boolean", + "title": "ApplyNestedSelectors enables selectors defined within the generators of two level-nested matrix or merge generators" }, "generators": { "type": "array", @@ -7340,10 +7263,6 @@ "type": "boolean", "title": "ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps" }, - "ignoreMissingComponents": { - "type": "boolean", - "title": "IgnoreMissingComponents prevents kustomize from failing when components do not exist locally by not appending them to kustomization file" - }, "images": { "type": "array", "title": "Images is a list of Kustomize image override specifications", @@ -7355,10 +7274,6 @@ "description": "KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD\nuses the Kubernetes version of the target cluster.", "type": "string" }, - "labelIncludeTemplates": { - "type": "boolean", - "title": "LabelIncludeTemplates specifies whether to apply common labels to resource templates or not" - }, "labelWithoutSelector": { "type": "boolean", "title": "LabelWithoutSelector specifies whether to apply common labels to resource selectors or not" @@ -7507,7 +7422,7 @@ "title": "ControllerNamespace indicates the namespace in which the application controller is located" }, "health": { - "$ref": "#/definitions/v1alpha1AppHealthStatus" + "$ref": "#/definitions/v1alpha1HealthStatus" }, "history": { "type": "array", @@ -7579,34 +7494,34 @@ } }, "v1alpha1ApplicationTree": { - "description": "ApplicationTree represents the hierarchical structure of resources associated with an Argo CD application.", "type": "object", + "title": "ApplicationTree holds nodes which belongs to the application\nTODO: describe purpose of this type", "properties": { "hosts": { - "description": "Hosts provides a list of Kubernetes nodes that are running pods related to the application.", "type": "array", + "title": "Hosts holds list of Kubernetes nodes that run application related pods", "items": { "$ref": "#/definitions/v1alpha1HostInfo" } }, "nodes": { - "description": "Nodes contains a list of resources that are either directly managed by the application\nor are children of directly managed resources.", + "description": "Nodes contains list of nodes which either directly managed by the application and children of directly managed nodes.", "type": "array", "items": { "$ref": "#/definitions/v1alpha1ResourceNode" } }, "orphanedNodes": { - "description": "OrphanedNodes contains resources that exist in the same namespace as the application\nbut are not managed by it. This list is populated only if orphaned resource tracking\nis enabled in the application's project settings.", + "description": "OrphanedNodes contains if or orphaned nodes: nodes which are not managed by the app but in the same namespace. List is populated only if orphaned resources enabled in app project.", "type": "array", "items": { "$ref": "#/definitions/v1alpha1ResourceNode" } }, "shardsCount": { - "description": "ShardsCount represents the total number of shards the application tree is split into.\nThis is used to distribute resource processing across multiple shards.", "type": "integer", - "format": "int64" + "format": "int64", + "title": "ShardsCount contains total number of shards the application tree is split into" } } }, @@ -8060,9 +7975,6 @@ "v1alpha1GitFileGeneratorItem": { "type": "object", "properties": { - "exclude": { - "type": "boolean" - }, "path": { "type": "string" } @@ -8155,7 +8067,7 @@ }, "v1alpha1HealthStatus": { "type": "object", - "title": "HealthStatus contains information about the currently observed health state of a resource", + "title": "HealthStatus contains information about the currently observed health state of an application or resource", "properties": { "lastTransitionTime": { "$ref": "#/definitions/v1Time" @@ -8166,7 +8078,7 @@ }, "status": { "type": "string", - "title": "Status holds the status code of the resource" + "title": "Status holds the status code of the application or resource" } } }, @@ -8203,15 +8115,13 @@ } }, "v1alpha1HostInfo": { - "description": "HostInfo holds metadata and resource usage metrics for a specific host in the cluster.", "type": "object", + "title": "HostInfo holds host name and resources metrics\nTODO: describe purpose of this type\nTODO: describe members of this type", "properties": { "name": { - "description": "Name is the hostname or node name in the Kubernetes cluster.", "type": "string" }, "resourcesInfo": { - "description": "ResourcesInfo provides a list of resource usage details for different resource types on this host.", "type": "array", "items": { "$ref": "#/definitions/v1alpha1HostResourceInfo" @@ -8223,26 +8133,22 @@ } }, "v1alpha1HostResourceInfo": { - "description": "HostResourceInfo represents resource usage details for a specific resource type on a host.", "type": "object", + "title": "TODO: describe this type", "properties": { "capacity": { - "description": "Capacity represents the total available capacity of this resource on the host.", "type": "integer", "format": "int64" }, "requestedByApp": { - "description": "RequestedByApp indicates the total amount of this resource requested by the application running on the host.", "type": "integer", "format": "int64" }, "requestedByNeighbors": { - "description": "RequestedByNeighbors indicates the total amount of this resource requested by other workloads on the same host.", "type": "integer", "format": "int64" }, "resourceName": { - "description": "ResourceName specifies the type of resource (e.g., CPU, memory, storage).", "type": "string" } } @@ -8358,15 +8264,13 @@ } }, "v1alpha1KnownTypeField": { - "description": "KnownTypeField contains a mapping between a Custom Resource Definition (CRD) field\nand a well-known Kubernetes type. This mapping is primarily used for unit conversions\nin resources where the type is not explicitly defined (e.g., converting \"0.1\" to \"100m\" for CPU requests).", "type": "object", + "title": "KnownTypeField contains mapping between CRD field and known Kubernetes type.\nThis is mainly used for unit conversion in unknown resources (e.g. 0.1 == 100mi)\nTODO: Describe the members of this type", "properties": { "field": { - "type": "string", - "title": "Field represents the JSON path to the specific field in the CRD that requires type conversion.\nExample: \"spec.resources.requests.cpu\"" + "type": "string" }, "type": { - "description": "Type specifies the expected Kubernetes type for the field, such as \"cpu\" or \"memory\".\nThis helps in converting values between different formats (e.g., \"0.1\" to \"100m\" for CPU).", "type": "string" } } @@ -8776,13 +8680,6 @@ }, "template": { "$ref": "#/definitions/v1alpha1ApplicationSetTemplate" - }, - "values": { - "type": "object", - "title": "Values contains key/value pairs which are passed directly as parameters to the template", - "additionalProperties": { - "type": "string" - } } } }, @@ -8912,8 +8809,8 @@ "type": "string" }, "pullRequestState": { - "description": "PullRequestState is an additional MRs filter to get only those with a certain state. Default: \"\" (all states).\nValid values: opened, closed, merged, locked\".", - "type": "string" + "type": "string", + "title": "PullRequestState is an additional MRs filter to get only those with a certain state. Default: \"\" (all states)" }, "tokenRef": { "$ref": "#/definitions/v1alpha1SecretRef" @@ -8932,13 +8829,6 @@ "description": "Allow insecure tls, for self-signed certificates; default: false.", "type": "boolean" }, - "labels": { - "type": "array", - "title": "Labels is used to filter the PRs that you want to target", - "items": { - "type": "string" - } - }, "owner": { "description": "Gitea org or user to scan. Required.", "type": "string" @@ -8988,10 +8878,6 @@ "type": "object", "title": "RepoCreds holds the definition for repository credentials", "properties": { - "bearerToken": { - "type": "string", - "title": "BearerToken contains the bearer token used for Git BitBucket Data Center auth at the repo server" - }, "enableOCI": { "type": "boolean", "title": "EnableOCI specifies whether helm-oci support should be enabled for this repo" @@ -9054,10 +8940,6 @@ "type": "string", "title": "URL is the URL to which these credentials match" }, - "useAzureWorkloadIdentity": { - "type": "boolean", - "title": "UseAzureWorkloadIdentity specifies whether to use Azure Workload Identity for authentication" - }, "username": { "type": "string", "title": "Username for authenticating at the repo server" @@ -9083,10 +8965,6 @@ "type": "object", "title": "Repository is a repository holding application configurations", "properties": { - "bearerToken": { - "type": "string", - "title": "BearerToken contains the bearer token used for Git BitBucket Data Center auth at the repo server" - }, "connectionState": { "$ref": "#/definitions/v1alpha1ConnectionState" }, @@ -9176,10 +9054,6 @@ "description": "Type specifies the type of the repo. Can be either \"git\" or \"helm. \"git\" is assumed if empty or absent.", "type": "string" }, - "useAzureWorkloadIdentity": { - "type": "boolean", - "title": "UseAzureWorkloadIdentity specifies whether to use Azure Workload Identity for authentication" - }, "username": { "type": "string", "title": "Username contains the user name used for authenticating at the remote repository" @@ -9245,27 +9119,22 @@ } }, "v1alpha1ResourceAction": { - "description": "ResourceAction represents an individual action that can be performed on a resource.\nIt includes parameters, an optional disabled flag, an icon for display, and a name for the action.", "type": "object", + "title": "TODO: describe this type\nTODO: describe members of this type", "properties": { "disabled": { - "description": "Disabled indicates whether the action is disabled.", "type": "boolean" }, "displayName": { - "description": "DisplayName provides a user-friendly name for the action.", "type": "string" }, "iconClass": { - "description": "IconClass specifies the CSS class for the action's icon.", "type": "string" }, "name": { - "description": "Name is the name or identifier for the action.", "type": "string" }, "params": { - "description": "Params contains the parameters required to execute the action.", "type": "array", "items": { "$ref": "#/definitions/v1alpha1ResourceActionParam" @@ -9274,78 +9143,67 @@ } }, "v1alpha1ResourceActionParam": { - "description": "ResourceActionParam represents a parameter for a resource action.\nIt includes a name, value, type, and an optional default value for the parameter.", "type": "object", + "title": "TODO: describe this type\nTODO: describe members of this type", "properties": { "default": { - "description": "Default is the default value of the parameter, if any.", "type": "string" }, "name": { - "description": "Name is the name of the parameter.", "type": "string" }, "type": { - "description": "Type is the type of the parameter (e.g., string, integer).", "type": "string" }, "value": { - "description": "Value is the value of the parameter.", "type": "string" } } }, "v1alpha1ResourceDiff": { - "description": "ResourceDiff holds the diff between a live and target resource object in Argo CD.\nIt is used to compare the desired state (from Git/Helm) with the actual state in the cluster.", "type": "object", + "title": "ResourceDiff holds the diff of a live and target resource object\nTODO: describe members of this type", "properties": { "diff": { - "description": "Diff contains the JSON patch representing the difference between the live and target resource.\nDeprecated: Use NormalizedLiveState and PredictedLiveState instead to compute differences.", - "type": "string" + "type": "string", + "title": "Diff contains the JSON patch between target and live resource\nDeprecated: use NormalizedLiveState and PredictedLiveState to render the difference" }, "group": { - "description": "Group represents the API group of the resource (e.g., \"apps\" for Deployments).", "type": "string" }, "hook": { - "description": "Hook indicates whether this resource is a hook resource (e.g., pre-sync or post-sync hooks).", "type": "boolean" }, "kind": { - "description": "Kind represents the Kubernetes resource kind (e.g., \"Deployment\", \"Service\").", "type": "string" }, "liveState": { - "description": "LiveState contains the JSON-serialized resource manifest of the resource currently running in the cluster.", - "type": "string" + "type": "string", + "title": "TargetState contains the JSON live resource manifest" }, "modified": { - "description": "Modified indicates whether the live resource has changes compared to the target resource.", "type": "boolean" }, "name": { - "description": "Name is the name of the resource.", "type": "string" }, "namespace": { - "description": "Namespace specifies the namespace where the resource exists.", "type": "string" }, "normalizedLiveState": { - "description": "NormalizedLiveState contains the JSON-serialized live resource state after applying normalizations.\nNormalizations may include ignoring irrelevant fields like timestamps or defaults applied by Kubernetes.", - "type": "string" + "type": "string", + "title": "NormalizedLiveState contains JSON serialized live resource state with applied normalizations" }, "predictedLiveState": { - "description": "PredictedLiveState contains the JSON-serialized resource state that Argo CD predicts based on the\ncombination of the normalized live state and the desired target state.", - "type": "string" + "type": "string", + "title": "PredictedLiveState contains JSON serialized resource state that is calculated based on normalized and target resource state" }, "resourceVersion": { - "description": "ResourceVersion is the Kubernetes resource version, which helps in tracking changes.", "type": "string" }, "targetState": { - "description": "TargetState contains the JSON-serialized resource manifest as defined in the Git/Helm repository.", - "type": "string" + "type": "string", + "title": "TargetState contains the JSON serialized resource manifest defined in the Git/Helm" } } }, @@ -9387,39 +9245,35 @@ } }, "v1alpha1ResourceNetworkingInfo": { - "description": "ResourceNetworkingInfo holds networking-related information for a resource.", "type": "object", + "title": "ResourceNetworkingInfo holds networking resource related information\nTODO: describe members of this type", "properties": { "externalURLs": { - "description": "ExternalURLs holds a list of URLs that should be accessible externally.\nThis field is typically populated for Ingress resources based on their hostname rules.", + "description": "ExternalURLs holds list of URLs which should be available externally. List is populated for ingress resources using rules hostnames.", "type": "array", "items": { "type": "string" } }, "ingress": { - "description": "Ingress provides information about external access points (e.g., load balancer ingress) for this resource.", "type": "array", "items": { "$ref": "#/definitions/v1LoadBalancerIngress" } }, "labels": { - "description": "Labels holds the labels associated with this networking resource.", "type": "object", "additionalProperties": { "type": "string" } }, "targetLabels": { - "description": "TargetLabels represents labels associated with the target resources that this resource communicates with.", "type": "object", "additionalProperties": { "type": "string" } }, "targetRefs": { - "description": "TargetRefs contains references to other resources that this resource interacts with, such as Services or Pods.", "type": "array", "items": { "$ref": "#/definitions/v1alpha1ResourceRef" @@ -9428,8 +9282,8 @@ } }, "v1alpha1ResourceNode": { - "description": "ResourceNode contains information about a live Kubernetes resource and its relationships with other resources.", "type": "object", + "title": "ResourceNode contains information about live resource and its children\nTODO: describe members of this type", "properties": { "createdAt": { "$ref": "#/definitions/v1Time" @@ -9438,14 +9292,12 @@ "$ref": "#/definitions/v1alpha1HealthStatus" }, "images": { - "description": "Images lists container images associated with the resource.\nThis is primarily useful for pods and other workload resources.", "type": "array", "items": { "type": "string" } }, "info": { - "description": "Info provides additional metadata or annotations about the resource.", "type": "array", "items": { "$ref": "#/definitions/v1alpha1InfoItem" @@ -9455,14 +9307,12 @@ "$ref": "#/definitions/v1alpha1ResourceNetworkingInfo" }, "parentRefs": { - "description": "ParentRefs lists the parent resources that reference this resource.\nThis helps in understanding ownership and hierarchical relationships.", "type": "array", "items": { "$ref": "#/definitions/v1alpha1ResourceRef" } }, "resourceVersion": { - "description": "ResourceVersion indicates the version of the resource, used to track changes.", "type": "string" } }, @@ -9474,14 +9324,12 @@ }, "v1alpha1ResourceOverride": { "type": "object", - "title": "ResourceOverride holds configuration to customize resource diffing and health assessment", + "title": "ResourceOverride holds configuration to customize resource diffing and health assessment\nTODO: describe the members of this type", "properties": { "actions": { - "description": "Actions defines the set of actions that can be performed on the resource, as a Lua script.", "type": "string" }, "healthLua": { - "description": "HealthLua contains a Lua script that defines custom health checks for the resource.", "type": "string" }, "ignoreDifferences": { @@ -9491,14 +9339,12 @@ "$ref": "#/definitions/v1alpha1OverrideIgnoreDiff" }, "knownTypeFields": { - "description": "KnownTypeFields lists fields for which unit conversions should be applied.", "type": "array", "items": { "$ref": "#/definitions/v1alpha1KnownTypeField" } }, "useOpenLibs": { - "description": "UseOpenLibs indicates whether to use open-source libraries for the resource.", "type": "boolean" } } @@ -10148,10 +9994,6 @@ "type": "boolean", "title": "AllowEmpty allows apps have zero live resources (default: false)" }, - "enable": { - "type": "boolean", - "title": "Enable allows apps to explicitly control automated sync" - }, "prune": { "type": "boolean", "title": "Prune specifies whether to delete resources from the cluster that are not found in the sources anymore as part of automated sync (default: false)" @@ -10235,10 +10077,6 @@ "type": "object", "title": "SyncWindow contains the kind, time, duration and attributes that are used to assign the syncWindows to apps", "properties": { - "andOperator": { - "type": "boolean", - "title": "UseAndOperator use AND operator for matching applications, namespaces and clusters instead of the default OR operator" - }, "applications": { "type": "array", "title": "Applications contains a list of applications that the window will apply to", @@ -10253,10 +10091,6 @@ "type": "string" } }, - "description": { - "type": "string", - "title": "Description of the sync that will be applied to the schedule, can be used to add any information such as a ticket number for example" - }, "duration": { "type": "string", "title": "Duration is the amount of time the sync window will be open" diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index d9f3e2d9cb..3d140b97dc 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -10,7 +10,7 @@ import ( "syscall" "time" - "github.com/argoproj/pkg/v2/stats" + "github.com/argoproj/pkg/stats" "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -18,39 +18,35 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - commitclient "github.com/argoproj/argo-cd/v3/commitserver/apiclient" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/controller" - "github.com/argoproj/argo-cd/v3/controller/sharding" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - "github.com/argoproj/argo-cd/v3/pkg/ratelimiter" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/errors" - kubeutil "github.com/argoproj/argo-cd/v3/util/kube" - "github.com/argoproj/argo-cd/v3/util/settings" - "github.com/argoproj/argo-cd/v3/util/tls" - "github.com/argoproj/argo-cd/v3/util/trace" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + commitclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/controller" + "github.com/argoproj/argo-cd/v2/controller/sharding" + "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/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" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + kubeutil "github.com/argoproj/argo-cd/v2/util/kube" + "github.com/argoproj/argo-cd/v2/util/settings" + "github.com/argoproj/argo-cd/v2/util/tls" + "github.com/argoproj/argo-cd/v2/util/trace" ) const ( // CLIName is the name of the CLI cliName = common.ApplicationController // Default time in seconds for application resync period - defaultAppResyncPeriod = 120 - // Default time in seconds for application resync period jitter - defaultAppResyncPeriodJitter = 60 + defaultAppResyncPeriod = 180 // Default time in seconds for application hard resync period defaultAppHardResyncPeriod = 0 - // Default time in seconds for ignoring consecutive errors when comminicating with repo-server - defaultRepoErrorGracePeriod = defaultAppResyncPeriod + defaultAppResyncPeriodJitter ) func NewCommand() *cobra.Command { @@ -77,7 +73,6 @@ func NewCommand() *cobra.Command { metricsCacheExpiration time.Duration metricsAplicationLabels []string metricsAplicationConditions []string - metricsClusterLabels []string kubectlParallelismLimit int64 cacheSource func() (*appstatecache.Cache, error) redisClient *redis.Client @@ -103,7 +98,7 @@ func NewCommand() *cobra.Command { Short: "Run ArgoCD Application Controller", Long: "ArgoCD application controller is a Kubernetes controller that continuously monitors running applications and compares the current, live state against the desired target state (as specified in the repo). This command runs Application Controller in the foreground. It can be configured by following options.", DisableAutoGenTag: true, - RunE: func(c *cobra.Command, _ []string) error { + RunE: func(c *cobra.Command, args []string) error { ctx, cancel := context.WithCancel(c.Context()) defer cancel() @@ -155,8 +150,8 @@ func NewCommand() *cobra.Command { // repository server, if strict TLS validation was requested. if !repoServerPlaintext && repoServerStrictTLS { pool, err := tls.LoadX509CertPool( - env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)+"/controller/tls/tls.crt", - env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)+"/controller/tls/ca.crt", + fmt.Sprintf("%s/controller/tls/tls.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), + fmt.Sprintf("%s/controller/tls/ca.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), ) if err != nil { log.Fatalf("%v", err) @@ -209,7 +204,6 @@ func NewCommand() *cobra.Command { metricsCacheExpiration, metricsAplicationLabels, metricsAplicationConditions, - metricsClusterLabels, kubectlParallelismLimit, persistResourceHealth, clusterSharding, @@ -258,14 +252,14 @@ func NewCommand() *cobra.Command { clientConfig = cli.AddKubectlFlagsToCmd(&command) command.Flags().Int64Var(&appResyncPeriod, "app-resync", int64(env.ParseDurationFromEnv("ARGOCD_RECONCILIATION_TIMEOUT", defaultAppResyncPeriod*time.Second, 0, math.MaxInt64).Seconds()), "Time period in seconds for application resync.") command.Flags().Int64Var(&appHardResyncPeriod, "app-hard-resync", int64(env.ParseDurationFromEnv("ARGOCD_HARD_RECONCILIATION_TIMEOUT", defaultAppHardResyncPeriod*time.Second, 0, math.MaxInt64).Seconds()), "Time period in seconds for application hard resync.") - command.Flags().Int64Var(&appResyncJitter, "app-resync-jitter", int64(env.ParseDurationFromEnv("ARGOCD_RECONCILIATION_JITTER", defaultAppResyncPeriodJitter*time.Second, 0, math.MaxInt64).Seconds()), "Maximum time period in seconds to add as a delay jitter for application resync.") - command.Flags().Int64Var(&repoErrorGracePeriod, "repo-error-grace-period-seconds", int64(env.ParseDurationFromEnv("ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS", defaultRepoErrorGracePeriod*time.Second, 0, math.MaxInt64).Seconds()), "Grace period in seconds for ignoring consecutive errors while communicating with repo server.") + command.Flags().Int64Var(&appResyncJitter, "app-resync-jitter", int64(env.ParseDurationFromEnv("ARGOCD_RECONCILIATION_JITTER", 0*time.Second, 0, math.MaxInt64).Seconds()), "Maximum time period in seconds to add as a delay jitter for application resync.") + command.Flags().Int64Var(&repoErrorGracePeriod, "repo-error-grace-period-seconds", int64(env.ParseDurationFromEnv("ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS", defaultAppResyncPeriod*time.Second, 0, math.MaxInt64).Seconds()), "Grace period in seconds for ignoring consecutive errors while communicating with repo server.") command.Flags().StringVar(&repoServerAddress, "repo-server", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER", common.DefaultRepoServerAddr), "Repo server address.") command.Flags().IntVar(&repoServerTimeoutSeconds, "repo-server-timeout-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS", 60, 0, math.MaxInt64), "Repo server RPC call timeout seconds.") command.Flags().StringVar(&commitServerAddress, "commit-server", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER", common.DefaultCommitServerAddr), "Commit server address.") command.Flags().IntVar(&statusProcessors, "status-processors", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS", 20, 0, math.MaxInt32), "Number of application status processors") command.Flags().IntVar(&operationProcessors, "operation-processors", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_OPERATION_PROCESSORS", 10, 0, math.MaxInt32), "Number of application operation processors") - command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_LOGFORMAT", "json"), "Set the logging format. One of: json|text") + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error") 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") @@ -281,13 +275,12 @@ func NewCommand() *cobra.Command { command.Flags().BoolVar(&repoServerStrictTLS, "repo-server-strict-tls", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS", false), "Whether to use strict validation of the TLS cert presented by the repo server") command.Flags().StringSliceVar(&metricsAplicationLabels, "metrics-application-labels", []string{}, "List of Application labels that will be added to the argocd_application_labels metric") command.Flags().StringSliceVar(&metricsAplicationConditions, "metrics-application-conditions", []string{}, "List of Application conditions that will be added to the argocd_application_conditions metric") - command.Flags().StringSliceVar(&metricsClusterLabels, "metrics-cluster-labels", []string{}, "List of Cluster labels that will be added to the argocd_cluster_labels metric") command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to") command.Flags().BoolVar(&otlpInsecure, "otlp-insecure", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE", true), "OpenTelemetry collector insecure mode") command.Flags().StringToStringVar(&otlpHeaders, "otlp-headers", env.ParseStringToStringFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS", map[string]string{}, ","), "List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2)") command.Flags().StringSliceVar(&otlpAttrs, "otlp-attrs", env.StringsFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS", []string{}, ","), "List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value)") command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces that applications are allowed to be reconciled from") - command.Flags().BoolVar(&persistResourceHealth, "persist-resource-health", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH", false), "Enables storing the managed resources health in the Application CRD") + command.Flags().BoolVar(&persistResourceHealth, "persist-resource-health", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH", true), "Enables storing the managed resources health in the Application CRD") command.Flags().StringVar(&shardingAlgorithm, "sharding-method", env.StringFromEnv(common.EnvControllerShardingAlgorithm, common.DefaultShardingAlgorithm), "Enables choice of sharding method. Supported sharding methods are : [legacy, round-robin, consistent-hashing] ") // global queue rate limit config command.Flags().Int64Var(&workqueueRateLimit.BucketSize, "wq-bucket-size", env.ParseInt64FromEnv("WORKQUEUE_BUCKET_SIZE", 500, 1, math.MaxInt64), "Set Workqueue Rate Limiter Bucket Size, default 500") diff --git a/cmd/argocd-applicationset-controller/commands/applicationset_controller.go b/cmd/argocd-applicationset-controller/commands/applicationset_controller.go index c5383ed9a7..ce7b69c69b 100644 --- a/cmd/argocd-applicationset-controller/commands/applicationset_controller.go +++ b/cmd/argocd-applicationset-controller/commands/applicationset_controller.go @@ -8,22 +8,22 @@ import ( "runtime/debug" "time" - "github.com/argoproj/pkg/v2/stats" + "github.com/argoproj/pkg/stats" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - logutils "github.com/argoproj/argo-cd/v3/util/log" - "github.com/argoproj/argo-cd/v3/util/tls" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + logutils "github.com/argoproj/argo-cd/v2/util/log" + "github.com/argoproj/argo-cd/v2/util/tls" - "github.com/argoproj/argo-cd/v3/applicationset/controllers" - "github.com/argoproj/argo-cd/v3/applicationset/generators" - "github.com/argoproj/argo-cd/v3/applicationset/utils" - "github.com/argoproj/argo-cd/v3/applicationset/webhook" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/github_app" + "github.com/argoproj/argo-cd/v2/applicationset/controllers" + "github.com/argoproj/argo-cd/v2/applicationset/generators" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + "github.com/argoproj/argo-cd/v2/applicationset/webhook" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/github_app" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -36,21 +36,17 @@ import ( ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - appsetmetrics "github.com/argoproj/argo-cd/v3/applicationset/metrics" - "github.com/argoproj/argo-cd/v3/applicationset/services" - appv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/errors" - argosettings "github.com/argoproj/argo-cd/v3/util/settings" + 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" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/errors" + argosettings "github.com/argoproj/argo-cd/v2/util/settings" ) var gitSubmoduleEnabled = env.ParseBoolFromEnv(common.EnvGitSubmoduleEnabled, true) -const ( - cliName = common.ApplicationSetController -) - func NewCommand() *cobra.Command { var ( clientConfig clientcmd.ClientConfig @@ -83,10 +79,9 @@ func NewCommand() *cobra.Command { _ = clientgoscheme.AddToScheme(scheme) _ = appv1alpha1.AddToScheme(scheme) command := cobra.Command{ - Use: cliName, - Short: "Starts Argo CD ApplicationSet controller", - DisableAutoGenTag: true, - RunE: func(c *cobra.Command, _ []string) error { + Use: "controller", + Short: "Starts Argo CD ApplicationSet controller", + RunE: func(c *cobra.Command, args []string) error { ctx := c.Context() vers := common.GetVersion() @@ -125,7 +120,8 @@ func NewCommand() *cobra.Command { } // By default, watch all namespaces - var watchedNamespace string + var watchedNamespace string = "" + // If the applicationset-namespaces contains only one namespace it corresponds to the current namespace if len(applicationSetNamespaces) == 1 { watchedNamespace = (applicationSetNamespaces)[0] @@ -185,15 +181,16 @@ func NewCommand() *cobra.Command { if !repoServerPlaintext && repoServerStrictTLS { pool, err := tls.LoadX509CertPool( - env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)+"/reposerver/tls/tls.crt", - env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)+"/reposerver/tls/ca.crt", + fmt.Sprintf("%s/reposerver/tls/tls.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), + fmt.Sprintf("%s/reposerver/tls/ca.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), ) errors.CheckError(err) tlsConfig.Certificates = pool } repoClientset := apiclient.NewRepoServerClientset(argocdRepoServer, repoServerTimeoutSeconds, tlsConfig) - argoCDService := services.NewArgoCDService(argoCDDB, gitSubmoduleEnabled, repoClientset, enableNewGitFileGlobbing) + argoCDService, err := services.NewArgoCDService(argoCDDB.GetRepository, gitSubmoduleEnabled, repoClientset, enableNewGitFileGlobbing) + errors.CheckError(err) topLevelGenerators := generators.GetGenerators(ctx, mgr.GetClient(), k8sClient, namespace, argoCDService, dynamicClient, scmConfig) @@ -256,7 +253,7 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&policy, "policy", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_POLICY", ""), "Modify how application is synced between the generator and the cluster. Default is '' (empty), which means AppSets default to 'sync', but they may override that default. Setting an explicit value prevents AppSet-level overrides, unless --allow-policy-override is enabled. Explicit options are: 'sync' (create & update & delete), 'create-only', 'create-update' (no deletion), 'create-delete' (no update)") command.Flags().BoolVar(&enablePolicyOverride, "enable-policy-override", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_POLICY_OVERRIDE", policy == ""), "For security reason if 'policy' is set, it is not possible to override it at applicationSet level. 'allow-policy-override' allows user to define their own policy") command.Flags().BoolVar(&debugLog, "debug", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_DEBUG", false), "Print debug logs. Takes precedence over loglevel") - command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_LOGFORMAT", "json"), "Set the logging format. One of: json|text") + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error") 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)") diff --git a/cmd/argocd-cmp-server/commands/argocd_cmp_server.go b/cmd/argocd-cmp-server/commands/argocd_cmp_server.go index efb4960fae..9d1894695f 100644 --- a/cmd/argocd-cmp-server/commands/argocd_cmp_server.go +++ b/cmd/argocd-cmp-server/commands/argocd_cmp_server.go @@ -4,18 +4,18 @@ import ( "runtime/debug" "time" - "github.com/argoproj/pkg/v2/stats" + "github.com/argoproj/pkg/stats" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/cmpserver" - "github.com/argoproj/argo-cd/v3/cmpserver/plugin" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/errors" - traceutil "github.com/argoproj/argo-cd/v3/util/trace" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/cmpserver" + "github.com/argoproj/argo-cd/v2/cmpserver/plugin" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + traceutil "github.com/argoproj/argo-cd/v2/util/trace" ) const ( @@ -36,7 +36,7 @@ func NewCommand() *cobra.Command { Short: "Run ArgoCD ConfigManagementPlugin Server", Long: "ArgoCD ConfigManagementPlugin Server is an internal service which runs as sidecar container in reposerver deployment. The following configuration options are available:", DisableAutoGenTag: true, - RunE: func(c *cobra.Command, _ []string) error { + RunE: func(c *cobra.Command, args []string) error { ctx := c.Context() vers := common.GetVersion() @@ -89,7 +89,7 @@ func NewCommand() *cobra.Command { }, } - command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_CMP_SERVER_LOGFORMAT", "json"), "Set the logging format. One of: json|text") + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_CMP_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_CMP_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: trace|debug|info|warn|error") command.Flags().StringVar(&configFilePath, "config-dir-path", common.DefaultPluginConfigFilePath, "Config management plugin configuration file location, Default is '/home/argocd/cmp-server/config/'") command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_CMP_SERVER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to") diff --git a/cmd/argocd-commit-server/commands/argocd_commit_server.go b/cmd/argocd-commit-server/commands/argocd_commit_server.go index 7feed03381..5c07bc0c14 100644 --- a/cmd/argocd-commit-server/commands/argocd_commit_server.go +++ b/cmd/argocd-commit-server/commands/argocd_commit_server.go @@ -13,17 +13,17 @@ import ( "github.com/spf13/cobra" "google.golang.org/grpc/health/grpc_health_v1" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/commitserver" - "github.com/argoproj/argo-cd/v3/commitserver/apiclient" - "github.com/argoproj/argo-cd/v3/commitserver/metrics" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/askpass" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/healthz" - utilio "github.com/argoproj/argo-cd/v3/util/io" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/commitserver" + "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/commitserver/metrics" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/askpass" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/healthz" + ioutil "github.com/argoproj/argo-cd/v2/util/io" ) // NewCommand returns a new instance of an argocd-commit-server command @@ -38,7 +38,7 @@ func NewCommand() *cobra.Command { Use: "argocd-commit-server", Short: "Run Argo CD Commit Server", Long: "Argo CD Commit Server is an internal service which commits and pushes hydrated manifests to git. This command runs Commit Server in the foreground.", - RunE: func(_ *cobra.Command, _ []string) error { + RunE: func(cmd *cobra.Command, args []string) error { vers := common.GetVersion() vers.LogStartupInfo( "Argo CD Commit Server", @@ -71,7 +71,7 @@ func NewCommand() *cobra.Command { if err != nil { return err } - defer utilio.Close(conn) + defer ioutil.Close(conn) client := grpc_health_v1.NewHealthClient(conn) res, err := client.Check(r.Context(), &grpc_health_v1.HealthCheckRequest{}) if err != nil { @@ -106,7 +106,7 @@ func NewCommand() *cobra.Command { return nil }, } - command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LOGFORMAT", "json"), "Set the logging format. One of: json|text") + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error") command.Flags().StringVar(&listenHost, "address", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LISTEN_ADDRESS", common.DefaultAddressCommitServer), "Listen on given address for incoming connections") command.Flags().IntVar(&listenPort, "port", common.DefaultPortCommitServer, "Listen on given port for incoming connections") diff --git a/cmd/argocd-dex/commands/argocd_dex.go b/cmd/argocd-dex/commands/argocd_dex.go index 8afcb7955e..f674266738 100644 --- a/cmd/argocd-dex/commands/argocd_dex.go +++ b/cmd/argocd-dex/commands/argocd_dex.go @@ -7,7 +7,7 @@ import ( "runtime/debug" "syscall" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -15,13 +15,13 @@ import ( "k8s.io/client-go/tools/clientcmd" "sigs.k8s.io/yaml" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/dex" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/settings" - "github.com/argoproj/argo-cd/v3/util/tls" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/dex" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/settings" + "github.com/argoproj/argo-cd/v2/util/tls" ) const ( @@ -52,7 +52,7 @@ func NewRunDexCommand() *cobra.Command { command := cobra.Command{ Use: "rundex", Short: "Runs dex generating a config using settings from the Argo CD configmap and secret", - RunE: func(c *cobra.Command, _ []string) error { + RunE: func(c *cobra.Command, args []string) error { ctx := c.Context() vers := common.GetVersion() @@ -136,15 +136,16 @@ func NewRunDexCommand() *cobra.Command { errors.CheckError(err) } break + } else { + log.Infof("dex config unmodified") } - log.Infof("dex config unmodified") } } }, } clientConfig = cli.AddKubectlFlagsToCmd(&command) - command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_DEX_SERVER_LOGFORMAT", "json"), "Set the logging format. One of: json|text") + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_DEX_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_DEX_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error") command.Flags().BoolVar(&disableTLS, "disable-tls", env.ParseBoolFromEnv("ARGOCD_DEX_SERVER_DISABLE_TLS", false), "Disable TLS on the HTTP endpoint") return &command @@ -159,7 +160,7 @@ func NewGenDexConfigCommand() *cobra.Command { command := cobra.Command{ Use: "gendexcfg", Short: "Generates a dex config from Argo CD settings", - RunE: func(c *cobra.Command, _ []string) error { + RunE: func(c *cobra.Command, args []string) error { ctx := c.Context() cli.SetLogFormat(cmdutil.LogFormat) @@ -180,14 +181,14 @@ func NewGenDexConfigCommand() *cobra.Command { return nil } if out == "" { - dexCfg := make(map[string]any) + dexCfg := make(map[string]interface{}) err := yaml.Unmarshal(dexCfgBytes, &dexCfg) errors.CheckError(err) if staticClientsInterface, ok := dexCfg["staticClients"]; ok { - if staticClients, ok := staticClientsInterface.([]any); ok { + if staticClients, ok := staticClientsInterface.([]interface{}); ok { for i := range staticClients { staticClient := staticClients[i] - if mappings, ok := staticClient.(map[string]any); ok { + if mappings, ok := staticClient.(map[string]interface{}); ok { for key := range mappings { if key == "secret" { mappings[key] = "******" @@ -212,15 +213,15 @@ func NewGenDexConfigCommand() *cobra.Command { } clientConfig = cli.AddKubectlFlagsToCmd(&command) - command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_DEX_SERVER_LOGFORMAT", "json"), "Set the logging format. One of: json|text") + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_DEX_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_DEX_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error") command.Flags().StringVarP(&out, "out", "o", "", "Output to the specified file instead of stdout") command.Flags().BoolVar(&disableTLS, "disable-tls", env.ParseBoolFromEnv("ARGOCD_DEX_SERVER_DISABLE_TLS", false), "Disable TLS on the HTTP endpoint") return &command } -func iterateStringFields(obj any, callback func(name string, val string) string) { - if mapField, ok := obj.(map[string]any); ok { +func iterateStringFields(obj interface{}, callback func(name string, val string) string) { + if mapField, ok := obj.(map[string]interface{}); ok { for field, val := range mapField { if strVal, ok := val.(string); ok { mapField[field] = callback(field, strVal) @@ -228,7 +229,7 @@ func iterateStringFields(obj any, callback func(name string, val string) string) iterateStringFields(val, callback) } } - } else if arrayField, ok := obj.([]any); ok { + } else if arrayField, ok := obj.([]interface{}); ok { for i := range arrayField { iterateStringFields(arrayField[i], callback) } @@ -236,14 +237,15 @@ func iterateStringFields(obj any, callback func(name string, val string) string) } func redactor(dirtyString string) string { - config := make(map[string]any) + config := make(map[string]interface{}) err := yaml.Unmarshal([]byte(dirtyString), &config) errors.CheckError(err) iterateStringFields(config, func(name string, val string) string { if name == "clientSecret" || name == "secret" || name == "bindPW" { return "********" + } else { + return val } - return val }) data, err := yaml.Marshal(config) errors.CheckError(err) diff --git a/cmd/argocd-git-ask-pass/commands/argocd_git_ask_pass.go b/cmd/argocd-git-ask-pass/commands/argocd_git_ask_pass.go index b4780e2515..73673e977b 100644 --- a/cmd/argocd-git-ask-pass/commands/argocd_git_ask_pass.go +++ b/cmd/argocd-git-ask-pass/commands/argocd_git_ask_pass.go @@ -9,10 +9,10 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "github.com/argoproj/argo-cd/v3/util/askpass" - "github.com/argoproj/argo-cd/v3/util/errors" - grpc_util "github.com/argoproj/argo-cd/v3/util/grpc" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "github.com/argoproj/argo-cd/v2/util/askpass" + "github.com/argoproj/argo-cd/v2/util/errors" + grpc_util "github.com/argoproj/argo-cd/v2/util/grpc" + "github.com/argoproj/argo-cd/v2/util/io" ) const ( @@ -25,7 +25,7 @@ func NewCommand() *cobra.Command { Use: cliName, Short: "Argo CD git credential helper", DisableAutoGenTag: true, - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() if len(os.Args) != 2 { @@ -37,7 +37,7 @@ func NewCommand() *cobra.Command { } conn, err := grpc_util.BlockingDial(ctx, "unix", askpass.SocketPath, nil, grpc.WithTransportCredentials(insecure.NewCredentials())) errors.CheckError(err) - defer utilio.Close(conn) + defer io.Close(conn) client := askpass.NewAskPassServiceClient(conn) creds, err := client.GetCredentials(ctx, &askpass.CredentialsRequest{Nonce: nonce}) diff --git a/cmd/argocd-k8s-auth/commands/aws.go b/cmd/argocd-k8s-auth/commands/aws.go index 6052bdb4dc..1794a5bf57 100644 --- a/cmd/argocd-k8s-auth/commands/aws.go +++ b/cmd/argocd-k8s-auth/commands/aws.go @@ -16,7 +16,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" clientauthv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/util/errors" ) const ( @@ -41,7 +41,7 @@ func newAWSCommand() *cobra.Command { ) command := &cobra.Command{ Use: "aws", - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() presignedURLString, err := getSignedRequestWithRetry(ctx, time.Minute, 5*time.Second, clusterName, roleARN, profile, getSignedRequest) diff --git a/cmd/argocd-k8s-auth/commands/aws_test.go b/cmd/argocd-k8s-auth/commands/aws_test.go index e9dd42aa9e..7e31e50efb 100644 --- a/cmd/argocd-k8s-auth/commands/aws_test.go +++ b/cmd/argocd-k8s-auth/commands/aws_test.go @@ -1,7 +1,8 @@ package commands import ( - "errors" + "context" + "fmt" "testing" "time" @@ -10,13 +11,13 @@ import ( ) func TestGetSignedRequestWithRetry(t *testing.T) { - ctx := t.Context() + ctx := context.Background() t.Run("will return signed request on first attempt", func(t *testing.T) { // given t.Parallel() mock := &signedRequestMock{ - returnFunc: func(_ *signedRequestMock) (string, error) { + returnFunc: func(m *signedRequestMock) (string, error) { return "token", nil }, } @@ -34,7 +35,7 @@ func TestGetSignedRequestWithRetry(t *testing.T) { mock := &signedRequestMock{ returnFunc: func(m *signedRequestMock) (string, error) { if m.getSignedRequestCalls < 3 { - return "", errors.New("some error") + return "", fmt.Errorf("some error") } return "token", nil }, @@ -51,8 +52,8 @@ func TestGetSignedRequestWithRetry(t *testing.T) { // given t.Parallel() mock := &signedRequestMock{ - returnFunc: func(_ *signedRequestMock) (string, error) { - return "", errors.New("some error") + returnFunc: func(m *signedRequestMock) (string, error) { + return "", fmt.Errorf("some error") }, } @@ -61,7 +62,7 @@ func TestGetSignedRequestWithRetry(t *testing.T) { // then require.Error(t, err) - assert.Empty(t, signed) + assert.Equal(t, "", signed) }) } @@ -70,7 +71,7 @@ type signedRequestMock struct { returnFunc func(m *signedRequestMock) (string, error) } -func (m *signedRequestMock) getSignedRequestMock(_, _ string, _ string) (string, error) { +func (m *signedRequestMock) getSignedRequestMock(clusterName, roleARN string, profile string) (string, error) { m.getSignedRequestCalls++ return m.returnFunc(m) } diff --git a/cmd/argocd-k8s-auth/commands/azure.go b/cmd/argocd-k8s-auth/commands/azure.go index 357144c5ad..287b8d457a 100644 --- a/cmd/argocd-k8s-auth/commands/azure.go +++ b/cmd/argocd-k8s-auth/commands/azure.go @@ -7,7 +7,7 @@ import ( "github.com/Azure/kubelogin/pkg/token" "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/util/errors" ) var ( @@ -22,7 +22,7 @@ const ( func newAzureCommand() *cobra.Command { command := &cobra.Command{ Use: "azure", - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { o := token.OptionsWithEnv() if o.LoginMethod == "" { // no environment variable overrides // we'll use default of WorkloadIdentityLogin for the login flow diff --git a/cmd/argocd-k8s-auth/commands/gcp.go b/cmd/argocd-k8s-auth/commands/gcp.go index d45cffd20d..388d274072 100644 --- a/cmd/argocd-k8s-auth/commands/gcp.go +++ b/cmd/argocd-k8s-auth/commands/gcp.go @@ -7,7 +7,7 @@ import ( "github.com/spf13/cobra" "golang.org/x/oauth2/google" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/util/errors" ) // defaultGCPScopes: @@ -24,7 +24,7 @@ var defaultGCPScopes = []string{ func newGCPCommand() *cobra.Command { command := &cobra.Command{ Use: "gcp", - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() // Preferred way to retrieve GCP credentials diff --git a/cmd/argocd-notification/commands/controller.go b/cmd/argocd-notification/commands/controller.go index de29571fab..6f2dcc86a5 100644 --- a/cmd/argocd-notification/commands/controller.go +++ b/cmd/argocd-notification/commands/controller.go @@ -11,15 +11,15 @@ import ( "sync" "syscall" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/errors" - service "github.com/argoproj/argo-cd/v3/util/notification/argocd" - "github.com/argoproj/argo-cd/v3/util/tls" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + service "github.com/argoproj/argo-cd/v2/util/notification/argocd" + "github.com/argoproj/argo-cd/v2/util/tls" - notificationscontroller "github.com/argoproj/argo-cd/v3/notification_controller/controller" + notificationscontroller "github.com/argoproj/argo-cd/v2/notification_controller/controller" "github.com/argoproj/notifications-engine/pkg/controller" "github.com/prometheus/client_golang/prometheus" @@ -66,7 +66,7 @@ func NewCommand() *cobra.Command { command := cobra.Command{ Use: "controller", Short: "Starts Argo CD Notifications controller", - RunE: func(_ *cobra.Command, _ []string) error { + RunE: func(c *cobra.Command, args []string) error { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -129,8 +129,8 @@ func NewCommand() *cobra.Command { } if !tlsConfig.DisableTLS && tlsConfig.StrictValidation { pool, err := tls.LoadX509CertPool( - env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)+"/reposerver/tls/tls.crt", - env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)+"/reposerver/tls/ca.crt", + fmt.Sprintf("%s/reposerver/tls/tls.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), + fmt.Sprintf("%s/reposerver/tls/ca.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), ) if err != nil { return fmt.Errorf("failed to load repo-server certificate pool: %w", err) @@ -180,7 +180,7 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&appLabelSelector, "app-label-selector", "", "App label selector.") command.Flags().StringVar(&namespace, "namespace", "", "Namespace which controller handles. Current namespace if empty.") command.Flags().StringVar(&logLevel, "loglevel", env.StringFromEnv("ARGOCD_NOTIFICATIONS_CONTROLLER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error") - command.Flags().StringVar(&logFormat, "logformat", env.StringFromEnv("ARGOCD_NOTIFICATIONS_CONTROLLER_LOGFORMAT", "json"), "Set the logging format. One of: json|text") + command.Flags().StringVar(&logFormat, "logformat", env.StringFromEnv("ARGOCD_NOTIFICATIONS_CONTROLLER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") command.Flags().IntVar(&metricsPort, "metrics-port", defaultMetricsPort, "Metrics port") command.Flags().StringVar(&argocdRepoServer, "argocd-repo-server", common.DefaultRepoServerAddr, "Argo CD repo server address") command.Flags().BoolVar(&argocdRepoServerPlaintext, "argocd-repo-server-plaintext", env.ParseBoolFromEnv("ARGOCD_NOTIFICATION_CONTROLLER_REPO_SERVER_PLAINTEXT", false), "Use a plaintext client (non-TLS) to connect to repository server") diff --git a/cmd/argocd-repo-server/commands/argocd_repo_server.go b/cmd/argocd-repo-server/commands/argocd_repo_server.go index fd8e0bd0be..19d9a2a1e4 100644 --- a/cmd/argocd-repo-server/commands/argocd_repo_server.go +++ b/cmd/argocd-repo-server/commands/argocd_repo_server.go @@ -12,30 +12,30 @@ import ( "syscall" "time" - "github.com/argoproj/pkg/v2/stats" + "github.com/argoproj/pkg/stats" "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "google.golang.org/grpc/health/grpc_health_v1" "k8s.io/apimachinery/pkg/api/resource" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/reposerver" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - reposervercache "github.com/argoproj/argo-cd/v3/reposerver/cache" - "github.com/argoproj/argo-cd/v3/reposerver/metrics" - "github.com/argoproj/argo-cd/v3/reposerver/repository" - "github.com/argoproj/argo-cd/v3/util/askpass" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/gpg" - "github.com/argoproj/argo-cd/v3/util/healthz" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/tls" - traceutil "github.com/argoproj/argo-cd/v3/util/trace" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/reposerver" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + reposervercache "github.com/argoproj/argo-cd/v2/reposerver/cache" + "github.com/argoproj/argo-cd/v2/reposerver/metrics" + "github.com/argoproj/argo-cd/v2/reposerver/repository" + "github.com/argoproj/argo-cd/v2/util/askpass" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/gpg" + "github.com/argoproj/argo-cd/v2/util/healthz" + ioutil "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/tls" + traceutil "github.com/argoproj/argo-cd/v2/util/trace" ) const ( @@ -83,7 +83,7 @@ func NewCommand() *cobra.Command { Short: "Run ArgoCD Repository Server", Long: "ArgoCD Repository Server is an internal service which maintains a local cache of the Git repository holding the application manifests, and is responsible for generating and returning the Kubernetes manifests. This command runs Repository Server in the foreground. It can be configured by following options.", DisableAutoGenTag: true, - RunE: func(c *cobra.Command, _ []string) error { + RunE: func(c *cobra.Command, args []string) error { ctx := c.Context() vers := common.GetVersion() @@ -172,7 +172,7 @@ func NewCommand() *cobra.Command { if err != nil { return err } - defer utilio.Close(conn) + defer ioutil.Close(conn) client := grpc_health_v1.NewHealthClient(conn) res, err := client.Check(r.Context(), &grpc_health_v1.HealthCheckRequest{}) if err != nil { @@ -230,7 +230,7 @@ func NewCommand() *cobra.Command { return nil }, } - command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_REPO_SERVER_LOGFORMAT", "json"), "Set the logging format. One of: json|text") + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_REPO_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_REPO_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error") command.Flags().Int64Var(¶llelismLimit, "parallelismlimit", int64(env.ParseNumFromEnv("ARGOCD_REPO_SERVER_PARALLELISM_LIMIT", 0, 0, math.MaxInt32)), "Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit.") command.Flags().StringVar(&listenHost, "address", env.StringFromEnv("ARGOCD_REPO_SERVER_LISTEN_ADDRESS", common.DefaultAddressRepoServer), "Listen on given address for incoming connections") diff --git a/cmd/argocd-server/commands/argocd_server.go b/cmd/argocd-server/commands/argocd_server.go index 973cd0a182..0b89dad23e 100644 --- a/cmd/argocd-server/commands/argocd_server.go +++ b/cmd/argocd-server/commands/argocd_server.go @@ -12,7 +12,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" - "github.com/argoproj/pkg/v2/stats" + "github.com/argoproj/pkg/stats" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "k8s.io/client-go/dynamic" @@ -20,24 +20,24 @@ import ( "k8s.io/client-go/tools/clientcmd" "sigs.k8s.io/controller-runtime/pkg/client" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - reposervercache "github.com/argoproj/argo-cd/v3/reposerver/cache" - "github.com/argoproj/argo-cd/v3/server" - servercache "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/util/argo" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/dex" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/kube" - "github.com/argoproj/argo-cd/v3/util/templates" - "github.com/argoproj/argo-cd/v3/util/tls" - traceutil "github.com/argoproj/argo-cd/v3/util/trace" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "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" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + 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" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/kube" + "github.com/argoproj/argo-cd/v2/util/templates" + "github.com/argoproj/argo-cd/v2/util/tls" + traceutil "github.com/argoproj/argo-cd/v2/util/trace" ) const ( @@ -88,7 +88,6 @@ func NewCommand() *cobra.Command { enableProxyExtension bool webhookParallelism int hydratorEnabled bool - syncWithReplaceAllowed bool // ApplicationSet enableNewGitFileGlobbing bool @@ -104,7 +103,7 @@ func NewCommand() *cobra.Command { Short: "Run the ArgoCD API server", Long: "The API server is a gRPC/REST server which exposes the API consumed by the Web UI, CLI, and CI/CD systems. This command runs API server in the foreground. It can be configured by following options.", DisableAutoGenTag: true, - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() vers := common.GetVersion() @@ -171,8 +170,8 @@ func NewCommand() *cobra.Command { // repository server, if strict TLS validation was requested. if !repoServerPlaintext && repoServerStrictTLS { pool, err := tls.LoadX509CertPool( - env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)+"/server/tls/tls.crt", - env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)+"/server/tls/ca.crt", + fmt.Sprintf("%s/server/tls/tls.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), + fmt.Sprintf("%s/server/tls/ca.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), ) if err != nil { log.Fatalf("%v", err) @@ -180,26 +179,26 @@ func NewCommand() *cobra.Command { tlsConfig.Certificates = pool } - dexTLSConfig := &dex.DexTLSConfig{ + dexTlsConfig := &dex.DexTLSConfig{ DisableTLS: dexServerPlaintext, StrictValidation: dexServerStrictTLS, } if !dexServerPlaintext && dexServerStrictTLS { pool, err := tls.LoadX509CertPool( - env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath) + "/dex/tls/ca.crt", + fmt.Sprintf("%s/dex/tls/ca.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), ) if err != nil { log.Fatalf("%v", err) } - dexTLSConfig.RootCAs = pool + dexTlsConfig.RootCAs = pool cert, err := tls.LoadX509Cert( - env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath) + "/dex/tls/tls.crt", + fmt.Sprintf("%s/dex/tls/tls.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), ) if err != nil { log.Fatalf("%v", err) } - dexTLSConfig.Certificate = cert.Raw + dexTlsConfig.Certificate = cert.Raw } repoclientset := apiclient.NewRepoServerClientset(repoServerAddress, repoServerTimeoutSeconds, tlsConfig) @@ -230,7 +229,7 @@ func NewCommand() *cobra.Command { AppClientset: appClientSet, RepoClientset: repoclientset, DexServerAddr: dexServerAddress, - DexTLSConfig: dexTLSConfig, + DexTLSConfig: dexTlsConfig, DisableAuth: disableAuth, ContentTypes: contentTypesList, EnableGZip: enableGZip, @@ -246,7 +245,6 @@ func NewCommand() *cobra.Command { WebhookParallelism: webhookParallelism, EnableK8sEvent: enableK8sEvent, HydratorEnabled: hydratorEnabled, - SyncWithReplaceAllowed: syncWithReplaceAllowed, } appsetOpts := server.ApplicationSetOpts{ @@ -297,7 +295,7 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&staticAssetsDir, "staticassets", env.StringFromEnv("ARGOCD_SERVER_STATIC_ASSETS", "/shared/app"), "Directory path that contains additional static assets") command.Flags().StringVar(&baseHRef, "basehref", env.StringFromEnv("ARGOCD_SERVER_BASEHREF", "/"), "Value for base href in index.html. Used if Argo CD is running behind reverse proxy under subpath different from /") command.Flags().StringVar(&rootPath, "rootpath", env.StringFromEnv("ARGOCD_SERVER_ROOTPATH", ""), "Used if Argo CD is running behind reverse proxy under subpath different from /") - command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_SERVER_LOGFORMAT", "json"), "Set the logging format. One of: json|text") + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_SERVER_LOG_LEVEL", "info"), "Set the logging level. One of: debug|info|warn|error") command.Flags().IntVar(&glogLevel, "gloglevel", 0, "Set the glog logging level") command.Flags().StringVar(&repoServerAddress, "repo-server", env.StringFromEnv("ARGOCD_SERVER_REPO_SERVER", common.DefaultRepoServerAddr), "Repo server address") @@ -326,7 +324,6 @@ func NewCommand() *cobra.Command { command.Flags().IntVar(&webhookParallelism, "webhook-parallelism-limit", env.ParseNumFromEnv("ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT", 50, 1, 1000), "Number of webhook requests processed concurrently") command.Flags().StringSliceVar(&enableK8sEvent, "enable-k8s-event", env.StringsFromEnv("ARGOCD_ENABLE_K8S_EVENT", argo.DefaultEnableEventList(), ","), "Enable ArgoCD to use k8s event. For disabling all events, set the value as `none`. (e.g --enable-k8s-event=none), For enabling specific events, set the value as `event reason`. (e.g --enable-k8s-event=StatusRefreshed,ResourceCreated)") command.Flags().BoolVar(&hydratorEnabled, "hydrator-enabled", env.ParseBoolFromEnv("ARGOCD_HYDRATOR_ENABLED", false), "Feature flag to enable Hydrator. Default (\"false\")") - command.Flags().BoolVar(&syncWithReplaceAllowed, "sync-with-replace-allowed", env.ParseBoolFromEnv("ARGOCD_SYNC_WITH_REPLACE_ALLOWED", true), "Whether to allow users to select replace for syncs from UI/CLI") // 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 d4b4a14c50..1c7298e99a 100644 --- a/cmd/argocd/commands/account.go +++ b/cmd/argocd/commands/account.go @@ -10,25 +10,25 @@ import ( "text/tabwriter" "time" - timeutil "github.com/argoproj/pkg/v2/time" + timeutil "github.com/argoproj/pkg/time" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "golang.org/x/term" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/util/rbac" + "github.com/argoproj/argo-cd/v2/util/rbac" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - accountpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/account" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/localconfig" - sessionutil "github.com/argoproj/argo-cd/v3/util/session" - "github.com/argoproj/argo-cd/v3/util/templates" + "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" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/localconfig" + sessionutil "github.com/argoproj/argo-cd/v2/util/session" + "github.com/argoproj/argo-cd/v2/util/templates" ) func NewAccountCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { @@ -94,7 +94,7 @@ has appropriate RBAC permissions to change other accounts. } acdClient := headless.NewClientOrDie(clientOpts, c) conn, usrIf := acdClient.NewAccountClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) userInfo := getCurrentAccount(ctx, acdClient) @@ -173,7 +173,7 @@ func NewAccountGetUserInfoCommand(clientOpts *argocdclient.ClientOptions) *cobra } conn, client := headless.NewClientOrDie(clientOpts, c).NewSessionClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) response, err := client.GetUserInfo(ctx, &session.GetUserInfoRequest{}) errors.CheckError(err) @@ -229,7 +229,7 @@ Resources: %v } conn, client := headless.NewClientOrDie(clientOpts, c).NewAccountClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) response, err := client.CanI(ctx, &accountpkg.CanIRequest{ Action: args[0], @@ -267,7 +267,7 @@ func NewAccountListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman ctx := c.Context() conn, client := headless.NewClientOrDie(clientOpts, c).NewAccountClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) response, err := client.ListAccounts(ctx, &accountpkg.ListAccountRequest{}) @@ -291,7 +291,7 @@ func NewAccountListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman func getCurrentAccount(ctx context.Context, clientset argocdclient.Client) session.GetUserInfoResponse { conn, client := clientset.NewSessionClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) userInfo, err := client.GetUserInfo(ctx, &session.GetUserInfoRequest{}) errors.CheckError(err) return *userInfo @@ -320,7 +320,7 @@ argocd account get --account `, } conn, client := clientset.NewAccountClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) acc, err := client.GetAccount(ctx, &accountpkg.GetAccountRequest{Name: account}) @@ -388,7 +388,7 @@ argocd account generate-token --account `, clientset := headless.NewClientOrDie(clientOpts, c) conn, client := clientset.NewAccountClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) if account == "" { account = getCurrentAccount(ctx, clientset).Username } @@ -430,7 +430,7 @@ argocd account delete-token --account ID`, clientset := headless.NewClientOrDie(clientOpts, c) conn, client := clientset.NewAccountClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) if account == "" { account = getCurrentAccount(ctx, clientset).Username } diff --git a/cmd/argocd/commands/admin/admin.go b/cmd/argocd/commands/admin/admin.go index cdf04597e6..6c120bd425 100644 --- a/cmd/argocd/commands/admin/admin.go +++ b/cmd/argocd/commands/admin/admin.go @@ -6,28 +6,28 @@ import ( "strings" "github.com/spf13/cobra" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "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" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + "sigs.k8s.io/yaml" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/common" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - "github.com/argoproj/argo-cd/v3/util/errors" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/common" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/settings" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) const ( // YamlSeparator separates sections of a YAML file yamlSeparator = "---\n" - - applicationsetNamespacesCmdParamsKey = "applicationsetcontroller.namespaces" - applicationNamespacesCmdParamsKey = "application.namespaces" ) var ( @@ -38,19 +38,6 @@ var ( appplicationSetResource = schema.GroupVersionResource{Group: application.Group, Version: "v1alpha1", Resource: application.ApplicationSetPlural} ) -type argocdAdditionalNamespaces struct { - applicationNamespaces []string - applicationsetNamespaces []string -} - -type argoCDClientsets struct { - configMaps dynamic.ResourceInterface - secrets dynamic.ResourceInterface - applications dynamic.ResourceInterface - projects dynamic.ResourceInterface - applicationSets dynamic.ResourceInterface -} - // NewAdminCommand returns a new instance of an argocd command func NewAdminCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { pathOpts := clientcmd.NewDefaultPathOptions() @@ -82,31 +69,102 @@ $ argocd admin initial-password reset command.AddCommand(NewInitialPasswordCommand()) command.AddCommand(NewRedisInitialPasswordCommand()) - command.Flags().StringVar(&cmdutil.LogFormat, "logformat", "json", "Set the logging format. One of: json|text") + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", "text", "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error") return command } +type argoCDClientsets struct { + configMaps dynamic.ResourceInterface + secrets dynamic.ResourceInterface + applications dynamic.ResourceInterface + projects dynamic.ResourceInterface + applicationSets dynamic.ResourceInterface +} + func newArgoCDClientsets(config *rest.Config, namespace string) *argoCDClientsets { dynamicIf, err := dynamic.NewForConfig(config) errors.CheckError(err) - return &argoCDClientsets{ - configMaps: dynamicIf.Resource(configMapResource).Namespace(namespace), - secrets: dynamicIf.Resource(secretResource).Namespace(namespace), - applications: dynamicIf.Resource(applicationsResource).Namespace(namespace), + configMaps: dynamicIf.Resource(configMapResource).Namespace(namespace), + secrets: dynamicIf.Resource(secretResource).Namespace(namespace), + // To support applications and applicationsets in any namespace we will watch all namespaces and filter them afterwards + applications: dynamicIf.Resource(applicationsResource), projects: dynamicIf.Resource(appprojectsResource).Namespace(namespace), - applicationSets: dynamicIf.Resource(appplicationSetResource).Namespace(namespace), + applicationSets: dynamicIf.Resource(appplicationSetResource), } } +// getReferencedSecrets examines the argocd-cm config for any referenced repo secrets and returns a +// map of all referenced secrets. +func getReferencedSecrets(un unstructured.Unstructured) map[string]bool { + var cm apiv1.ConfigMap + err := runtime.DefaultUnstructuredConverter.FromUnstructured(un.Object, &cm) + errors.CheckError(err) + referencedSecrets := make(map[string]bool) + + // Referenced repository secrets + if reposRAW, ok := cm.Data["repositories"]; ok { + repos := make([]settings.Repository, 0) + err := yaml.Unmarshal([]byte(reposRAW), &repos) + errors.CheckError(err) + for _, cred := range repos { + if cred.PasswordSecret != nil { + referencedSecrets[cred.PasswordSecret.Name] = true + } + if cred.SSHPrivateKeySecret != nil { + referencedSecrets[cred.SSHPrivateKeySecret.Name] = true + } + if cred.UsernameSecret != nil { + referencedSecrets[cred.UsernameSecret.Name] = true + } + if cred.TLSClientCertDataSecret != nil { + referencedSecrets[cred.TLSClientCertDataSecret.Name] = true + } + if cred.TLSClientCertKeySecret != nil { + referencedSecrets[cred.TLSClientCertKeySecret.Name] = true + } + } + } + + // Referenced repository credentials secrets + if reposRAW, ok := cm.Data["repository.credentials"]; ok { + creds := make([]settings.RepositoryCredentials, 0) + err := yaml.Unmarshal([]byte(reposRAW), &creds) + errors.CheckError(err) + for _, cred := range creds { + if cred.PasswordSecret != nil { + referencedSecrets[cred.PasswordSecret.Name] = true + } + if cred.SSHPrivateKeySecret != nil { + referencedSecrets[cred.SSHPrivateKeySecret.Name] = true + } + if cred.UsernameSecret != nil { + referencedSecrets[cred.UsernameSecret.Name] = true + } + if cred.TLSClientCertDataSecret != nil { + referencedSecrets[cred.TLSClientCertDataSecret.Name] = true + } + if cred.TLSClientCertKeySecret != nil { + referencedSecrets[cred.TLSClientCertKeySecret.Name] = true + } + } + } + return referencedSecrets +} + // isArgoCDSecret returns whether or not the given secret is a part of Argo CD configuration // (e.g. argocd-secret, repo credentials, or cluster credentials) -func isArgoCDSecret(un unstructured.Unstructured) bool { +func isArgoCDSecret(repoSecretRefs map[string]bool, un unstructured.Unstructured) bool { secretName := un.GetName() if secretName == common.ArgoCDSecretName { return true } + if repoSecretRefs != nil { + if _, ok := repoSecretRefs[secretName]; ok { + return true + } + } if labels := un.GetLabels(); labels != nil { if _, ok := labels[common.LabelKeySecretType]; ok { return true @@ -134,8 +192,8 @@ func isArgoCDConfigMap(name string) bool { func specsEqual(left, right unstructured.Unstructured) bool { leftAnnotation := left.GetAnnotations() rightAnnotation := right.GetAnnotations() - delete(leftAnnotation, corev1.LastAppliedConfigAnnotation) - delete(rightAnnotation, corev1.LastAppliedConfigAnnotation) + delete(leftAnnotation, apiv1.LastAppliedConfigAnnotation) + delete(rightAnnotation, apiv1.LastAppliedConfigAnnotation) if !reflect.DeepEqual(leftAnnotation, rightAnnotation) { return false } @@ -169,14 +227,24 @@ func specsEqual(left, right unstructured.Unstructured) bool { return false } +type argocdAdditonalNamespaces struct { + applicationNamespaces []string + applicationsetNamespaces []string +} + +const ( + applicationsetNamespacesCmdParamsKey = "applicationsetcontroller.namespaces" + applicationNamespacesCmdParamsKey = "application.namespaces" +) + // Get additional namespaces from argocd-cmd-params -func getAdditionalNamespaces(ctx context.Context, configMapsClient dynamic.ResourceInterface) *argocdAdditionalNamespaces { +func getAdditionalNamespaces(ctx context.Context, argocdClientsets *argoCDClientsets) *argocdAdditonalNamespaces { applicationNamespaces := make([]string, 0) applicationsetNamespaces := make([]string, 0) - un, err := configMapsClient.Get(ctx, common.ArgoCDCmdParamsConfigMapName, metav1.GetOptions{}) + un, err := argocdClientsets.configMaps.Get(ctx, common.ArgoCDCmdParamsConfigMapName, v1.GetOptions{}) errors.CheckError(err) - var cm corev1.ConfigMap + var cm apiv1.ConfigMap err = runtime.DefaultUnstructuredConverter.FromUnstructured(un.Object, &cm) errors.CheckError(err) @@ -202,7 +270,7 @@ func getAdditionalNamespaces(ctx context.Context, configMapsClient dynamic.Resou applicationsetNamespaces = namespacesListFromString(strNamespaces) } - return &argocdAdditionalNamespaces{ + return &argocdAdditonalNamespaces{ applicationNamespaces: applicationNamespaces, applicationsetNamespaces: applicationsetNamespaces, } diff --git a/cmd/argocd/commands/admin/admin_test.go b/cmd/argocd/commands/admin/admin_test.go index 6b036ea292..85f59b5dee 100644 --- a/cmd/argocd/commands/admin/admin_test.go +++ b/cmd/argocd/commands/admin/admin_test.go @@ -1,21 +1,23 @@ package admin import ( + "context" "testing" "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" dynfake "k8s.io/client-go/dynamic/fake" ) func TestGetAdditionalNamespaces(t *testing.T) { - createArgoCDCmdCMWithKeys := func(data map[string]any) *unstructured.Unstructured { + createArgoCDCmdCMWithKeys := func(data map[string]interface{}) *unstructured.Unstructured { return &unstructured.Unstructured{ - Object: map[string]any{ + Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "name": "argocd-cmd-params-cm", "namespace": "argocd", }, @@ -25,34 +27,34 @@ func TestGetAdditionalNamespaces(t *testing.T) { } testCases := []struct { - CmdParamsKeys map[string]any - expected argocdAdditionalNamespaces + CmdParamsKeys map[string]interface{} + expected argocdAdditonalNamespaces description string }{ { description: "empty configmap should return no additional namespaces", - CmdParamsKeys: map[string]any{}, - expected: argocdAdditionalNamespaces{applicationNamespaces: []string{}, applicationsetNamespaces: []string{}}, + CmdParamsKeys: map[string]interface{}{}, + expected: argocdAdditonalNamespaces{applicationNamespaces: []string{}, applicationsetNamespaces: []string{}}, }, { description: "empty strings in respective keys in cm shoud return empty namespace list", - CmdParamsKeys: map[string]any{applicationsetNamespacesCmdParamsKey: "", applicationNamespacesCmdParamsKey: ""}, - expected: argocdAdditionalNamespaces{applicationNamespaces: []string{}, applicationsetNamespaces: []string{}}, + CmdParamsKeys: map[string]interface{}{applicationsetNamespacesCmdParamsKey: "", applicationNamespacesCmdParamsKey: ""}, + expected: argocdAdditonalNamespaces{applicationNamespaces: []string{}, applicationsetNamespaces: []string{}}, }, { description: "when only one of the keys in the cm is set only correct respective list of namespaces should be returned", - CmdParamsKeys: map[string]any{applicationNamespacesCmdParamsKey: "foo, bar*"}, - expected: argocdAdditionalNamespaces{applicationsetNamespaces: []string{}, applicationNamespaces: []string{"foo", "bar*"}}, + CmdParamsKeys: map[string]interface{}{applicationNamespacesCmdParamsKey: "foo, bar*"}, + expected: argocdAdditonalNamespaces{applicationsetNamespaces: []string{}, applicationNamespaces: []string{"foo", "bar*"}}, }, { description: "when only one of the keys in the cm is set only correct respective list of namespaces should be returned", - CmdParamsKeys: map[string]any{applicationsetNamespacesCmdParamsKey: "foo, bar*"}, - expected: argocdAdditionalNamespaces{applicationNamespaces: []string{}, applicationsetNamespaces: []string{"foo", "bar*"}}, + CmdParamsKeys: map[string]interface{}{applicationsetNamespacesCmdParamsKey: "foo, bar*"}, + expected: argocdAdditonalNamespaces{applicationNamespaces: []string{}, applicationsetNamespaces: []string{"foo", "bar*"}}, }, { description: "whitespaces are removed for both multiple and single namespace", - CmdParamsKeys: map[string]any{applicationNamespacesCmdParamsKey: " bar ", applicationsetNamespacesCmdParamsKey: " foo , bar* "}, - expected: argocdAdditionalNamespaces{applicationNamespaces: []string{"bar"}, applicationsetNamespaces: []string{"foo", "bar*"}}, + CmdParamsKeys: map[string]interface{}{applicationNamespacesCmdParamsKey: " bar ", applicationsetNamespacesCmdParamsKey: " foo , bar* "}, + expected: argocdAdditonalNamespaces{applicationNamespaces: []string{"bar"}, applicationsetNamespaces: []string{"foo", "bar*"}}, }, } @@ -60,10 +62,14 @@ func TestGetAdditionalNamespaces(t *testing.T) { fakeDynClient := dynfake.NewSimpleDynamicClient(runtime.NewScheme(), createArgoCDCmdCMWithKeys(c.CmdParamsKeys)) argoCDClientsets := &argoCDClientsets{ - configMaps: fakeDynClient.Resource(configMapResource).Namespace("argocd"), + configMaps: fakeDynClient.Resource(configMapResource).Namespace("argocd"), + applications: fakeDynClient.Resource(schema.GroupVersionResource{}), + applicationSets: fakeDynClient.Resource(schema.GroupVersionResource{}), + secrets: fakeDynClient.Resource(schema.GroupVersionResource{}), + projects: fakeDynClient.Resource(schema.GroupVersionResource{}), } - result := getAdditionalNamespaces(t.Context(), argoCDClientsets.configMaps) + result := getAdditionalNamespaces(context.TODO(), argoCDClientsets) assert.Equal(t, c.expected, *result) } } diff --git a/cmd/argocd/commands/admin/app.go b/cmd/argocd/commands/admin/app.go index e457ad1733..d3ec7a11f0 100644 --- a/cmd/argocd/commands/admin/app.go +++ b/cmd/argocd/commands/admin/app.go @@ -3,18 +3,16 @@ package admin import ( "context" "encoding/json" - stderrors "errors" "fmt" "net/http" "os" "sort" "time" - "github.com/argoproj/gitops-engine/pkg/health" "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/spf13/cobra" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "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/util/runtime" "k8s.io/client-go/kubernetes" @@ -22,28 +20,28 @@ import ( "k8s.io/client-go/tools/clientcmd" "sigs.k8s.io/yaml" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/controller" - "github.com/argoproj/argo-cd/v3/controller/cache" - "github.com/argoproj/argo-cd/v3/controller/metrics" - "github.com/argoproj/argo-cd/v3/controller/sharding" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - appinformers "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions" - reposerverclient "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/config" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" - kubeutil "github.com/argoproj/argo-cd/v3/util/kube" - "github.com/argoproj/argo-cd/v3/util/settings" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/controller" + "github.com/argoproj/argo-cd/v2/controller/cache" + "github.com/argoproj/argo-cd/v2/controller/metrics" + "github.com/argoproj/argo-cd/v2/controller/sharding" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + appinformers "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions" + reposerverclient "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" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/config" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/io" + kubeutil "github.com/argoproj/argo-cd/v2/util/kube" + "github.com/argoproj/argo-cd/v2/util/settings" ) func NewAppCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { @@ -100,7 +98,7 @@ func NewGenAppSpecCommand() *cobra.Command { argocd admin app generate-spec nginx-ingress --repo https://charts.helm.sh/stable --helm-chart nginx-ingress --revision 1.24.3 --dest-namespace default --dest-server https://kubernetes.default.svc # Generate declarative config for a Kustomize app - argocd admin app generate-spec kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image quay.io/argoprojlabs/argocd-e2e-container:0.1 + argocd admin app generate-spec kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1 # Generate declarative config for a app using a custom tool: argocd admin app generate-spec kasane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane @@ -109,7 +107,7 @@ func NewGenAppSpecCommand() *cobra.Command { apps, err := cmdutil.ConstructApps(fileURL, appName, labels, annotations, args, appOpts, c.Flags()) errors.CheckError(err) if len(apps) > 1 { - errors.CheckError(stderrors.New("failed to generate spec, more than one application is not supported")) + errors.CheckError(fmt.Errorf("failed to generate spec, more than one application is not supported")) } app := apps[0] if app.Name == "" { @@ -121,7 +119,7 @@ func NewGenAppSpecCommand() *cobra.Command { } out, closer, err := getOutWriter(inline, fileURL) errors.CheckError(err) - defer utilio.Close(closer) + defer io.Close(closer) errors.CheckError(PrintResources(outputFormat, out, app)) }, @@ -144,7 +142,7 @@ func NewGenAppSpecCommand() *cobra.Command { type appReconcileResult struct { Name string `json:"name"` - Health health.HealthStatusCode `json:"health"` + Health *v1alpha1.HealthStatus `json:"health"` Sync *v1alpha1.SyncStatus `json:"sync"` Conditions []v1alpha1.ApplicationCondition `json:"conditions"` } @@ -161,7 +159,7 @@ func (r *reconcileResults) getAppsMap() map[string]appReconcileResult { return res } -func printLine(format string, a ...any) { +func printLine(format string, a ...interface{}) { _, _ = fmt.Printf(format+"\n", a...) } @@ -188,12 +186,12 @@ func NewDiffReconcileResults() *cobra.Command { return command } -func toUnstructured(val any) (*unstructured.Unstructured, error) { +func toUnstructured(val interface{}) (*unstructured.Unstructured, error) { data, err := json.Marshal(val) if err != nil { return nil, fmt.Errorf("error while marhsalling value: %w", err) } - res := make(map[string]any) + res := make(map[string]interface{}) err = json.Unmarshal(data, &res) if err != nil { return nil, fmt.Errorf("error while unmarhsalling data: %w", err) @@ -286,7 +284,7 @@ func NewReconcileCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command overrides := clientcmd.ConfigOverrides{} repoServerName := clientOpts.RepoServerName repoServerServiceLabelSelector := common.LabelKeyComponentRepoServer + "=" + common.LabelValueComponentRepoServer - repoServerServices, err := kubeClientset.CoreV1().Services(namespace).List(context.Background(), metav1.ListOptions{LabelSelector: repoServerServiceLabelSelector}) + repoServerServices, err := kubeClientset.CoreV1().Services(namespace).List(context.Background(), v1.ListOptions{LabelSelector: repoServerServiceLabelSelector}) errors.CheckError(err) if len(repoServerServices.Items) > 0 { if repoServerServicelabel, ok := repoServerServices.Items[0].Labels[common.LabelKeyAppName]; ok && repoServerServicelabel != "" { @@ -339,7 +337,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, metav1.ListOptions{LabelSelector: selector}) + appsList, err := appClientset.ArgoprojV1alpha1().Applications(namespace).List(ctx, v1.ListOptions{LabelSelector: selector}) if err != nil { return nil, fmt.Errorf("error listing namespaced apps: %w", err) } @@ -349,7 +347,7 @@ func getReconcileResults(ctx context.Context, appClientset appclientset.Interfac items = append(items, appReconcileResult{ Name: app.Name, Conditions: app.Status.Conditions, - Health: app.Status.Health.Status, + Health: &app.Status.Health, Sync: &app.Status.Sync, }) } @@ -373,7 +371,7 @@ func reconcileApplications( appClientset, 1*time.Hour, appinformers.WithNamespace(namespace), - appinformers.WithTweakListOptions(func(_ *metav1.ListOptions) {}), + appinformers.WithTweakListOptions(func(options *v1.ListOptions) {}), ) appInformer := appInformerFactory.Argoproj().V1alpha1().Applications().Informer() @@ -381,14 +379,14 @@ func reconcileApplications( go appInformer.Run(ctx.Done()) go projInformer.Run(ctx.Done()) if !kubecache.WaitForCacheSync(ctx.Done(), appInformer.HasSynced, projInformer.HasSynced) { - return nil, stderrors.New("failed to sync cache") + return nil, fmt.Errorf("failed to sync cache") } appLister := appInformerFactory.Argoproj().V1alpha1().Applications().Lister() projLister := appInformerFactory.Argoproj().V1alpha1().AppProjects().Lister() - server, err := metrics.NewMetricsServer("", appLister, func(_ any) bool { + server, err := metrics.NewMetricsServer("", appLister, func(obj interface{}) bool { return true - }, func(_ *http.Request) error { + }, func(r *http.Request) error { return nil }, []string{}, []string{}) if err != nil { @@ -426,7 +424,7 @@ func reconcileApplications( ignoreNormalizerOpts, ) - appsList, err := appClientset.ArgoprojV1alpha1().Applications(namespace).List(ctx, metav1.ListOptions{LabelSelector: selector}) + appsList, err := appClientset.ArgoprojV1alpha1().Applications(namespace).List(ctx, v1.ListOptions{LabelSelector: selector}) if err != nil { return nil, fmt.Errorf("error listing namespaced apps: %w", err) } @@ -438,19 +436,14 @@ func reconcileApplications( var items []appReconcileResult prevServer := "" for _, app := range appsList.Items { - destCluster, err := argo.GetDestinationCluster(ctx, app.Spec.Destination, argoDB) - if err != nil { - return nil, fmt.Errorf("error getting destination cluster: %w", err) - } - - if prevServer != destCluster.Server { + if prevServer != app.Spec.Destination.Server { if prevServer != "" { - if clusterCache, err := stateCache.GetClusterCache(destCluster); err == nil { + if clusterCache, err := stateCache.GetClusterCache(prevServer); err == nil { clusterCache.Invalidate() } } - printLine("Reconciling apps of %s", destCluster.Server) - prevServer = destCluster.Server + printLine("Reconciling apps of %s", app.Spec.Destination.Server) + prevServer = app.Spec.Destination.Server } printLine(app.Name) @@ -479,5 +472,5 @@ func reconcileApplications( } func newLiveStateCache(argoDB db.ArgoDB, appInformer kubecache.SharedIndexInformer, settingsMgr *settings.SettingsManager, server *metrics.MetricsServer) cache.LiveStateCache { - return cache.NewLiveStateCache(argoDB, appInformer, settingsMgr, kubeutil.NewKubectl(), server, func(_ map[string]bool, _ corev1.ObjectReference) {}, &sharding.ClusterSharding{}, argo.NewResourceTracking()) + return cache.NewLiveStateCache(argoDB, appInformer, settingsMgr, kubeutil.NewKubectl(), server, func(managedByApp map[string]bool, ref apiv1.ObjectReference) {}, &sharding.ClusterSharding{}, argo.NewResourceTracking()) } diff --git a/cmd/argocd/commands/admin/app_test.go b/cmd/argocd/commands/admin/app_test.go index 604c4faf7b..964d23ccab 100644 --- a/cmd/argocd/commands/admin/app_test.go +++ b/cmd/argocd/commands/admin/app_test.go @@ -1,6 +1,7 @@ package admin import ( + "context" "testing" clustermocks "github.com/argoproj/gitops-engine/pkg/cache/mocks" @@ -15,22 +16,21 @@ import ( kubefake "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/tools/cache" - "github.com/argoproj/argo-cd/v3/common" - statecache "github.com/argoproj/argo-cd/v3/controller/cache" - cachemocks "github.com/argoproj/argo-cd/v3/controller/cache/mocks" - "github.com/argoproj/argo-cd/v3/controller/metrics" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appfake "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - argocdclient "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient/mocks" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/settings" + statecache "github.com/argoproj/argo-cd/v2/controller/cache" + cachemocks "github.com/argoproj/argo-cd/v2/controller/cache/mocks" + "github.com/argoproj/argo-cd/v2/controller/metrics" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appfake "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + argocdclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/settings" ) func TestGetReconcileResults(t *testing.T) { - ctx := t.Context() + ctx := context.Background() appClientset := appfake.NewSimpleClientset(&v1alpha1.Application{ ObjectMeta: metav1.ObjectMeta{ @@ -38,7 +38,7 @@ func TestGetReconcileResults(t *testing.T) { Namespace: "default", }, Status: v1alpha1.ApplicationStatus{ - Health: v1alpha1.AppHealthStatus{Status: health.HealthStatusHealthy}, + Health: v1alpha1.HealthStatus{Status: health.HealthStatusHealthy}, Sync: v1alpha1.SyncStatus{Status: v1alpha1.SyncStatusCodeOutOfSync}, }, }) @@ -48,37 +48,24 @@ func TestGetReconcileResults(t *testing.T) { expectedResults := []appReconcileResult{{ Name: "test", - Health: health.HealthStatusHealthy, + Health: &v1alpha1.HealthStatus{Status: health.HealthStatusHealthy}, Sync: &v1alpha1.SyncStatus{Status: v1alpha1.SyncStatusCodeOutOfSync}, }} assert.ElementsMatch(t, expectedResults, result) } func TestGetReconcileResults_Refresh(t *testing.T) { - ctx := t.Context() + ctx := context.Background() - argoCM := &corev1.ConfigMap{ + cm := corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: common.ArgoCDConfigMapName, + Name: "argocd-cm", Namespace: "default", Labels: map[string]string{ "app.kubernetes.io/part-of": "argocd", }, }, } - argoCDSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.ArgoCDSecretName, - Namespace: "default", - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string][]byte{ - "admin.password": nil, - "server.secretkey": nil, - }, - } proj := &v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{ Name: "default", @@ -104,7 +91,7 @@ func TestGetReconcileResults_Refresh(t *testing.T) { appClientset := appfake.NewSimpleClientset(app, proj) deployment := test.NewDeployment() - kubeClientset := kubefake.NewClientset(deployment, argoCM, argoCDSecret) + kubeClientset := kubefake.NewClientset(deployment, &cm) clusterCache := clustermocks.ClusterCache{} clusterCache.On("IsNamespaced", mock.Anything).Return(true, nil) clusterCache.On("GetGVKParser", mock.Anything).Return(nil) @@ -114,7 +101,7 @@ func TestGetReconcileResults_Refresh(t *testing.T) { }, nil) repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient} liveStateCache := cachemocks.LiveStateCache{} - liveStateCache.On("GetManagedLiveObjs", mock.Anything, mock.Anything, mock.Anything).Return(map[kube.ResourceKey]*unstructured.Unstructured{ + liveStateCache.On("GetManagedLiveObjs", mock.Anything, mock.Anything).Return(map[kube.ResourceKey]*unstructured.Unstructured{ kube.GetResourceKey(deployment): deployment, }, nil) liveStateCache.On("GetVersionsInfo", mock.Anything).Return("v1.2.3", nil, nil) @@ -123,7 +110,7 @@ func TestGetReconcileResults_Refresh(t *testing.T) { liveStateCache.On("IsNamespaced", mock.Anything, mock.Anything).Return(true, nil) result, err := reconcileApplications(ctx, kubeClientset, appClientset, "default", &repoServerClientset, "", - func(_ db.ArgoDB, _ cache.SharedIndexInformer, _ *settings.SettingsManager, _ *metrics.MetricsServer) statecache.LiveStateCache { + func(argoDB db.ArgoDB, appInformer cache.SharedIndexInformer, settingsMgr *settings.SettingsManager, server *metrics.MetricsServer) statecache.LiveStateCache { return &liveStateCache }, false, @@ -132,7 +119,7 @@ func TestGetReconcileResults_Refresh(t *testing.T) { require.NoError(t, err) - assert.Equal(t, health.HealthStatusMissing, result[0].Health) + assert.Equal(t, health.HealthStatusMissing, result[0].Health.Status) assert.Equal(t, v1alpha1.SyncStatusCodeOutOfSync, result[0].Sync.Status) } @@ -177,7 +164,7 @@ func TestDiffReconcileResults_DifferentApps(t *testing.T) { app2 1,9d0 < conditions: null -< health: "" +< health: null < name: app2 < sync: < comparedTo: @@ -188,7 +175,7 @@ app2 app3 0a1,9 > conditions: null -> health: "" +> health: null > name: app3 > sync: > comparedTo: diff --git a/cmd/argocd/commands/admin/backup.go b/cmd/argocd/commands/admin/backup.go index 9fb37a3097..b644b34e86 100644 --- a/cmd/argocd/commands/admin/backup.go +++ b/cmd/argocd/commands/admin/backup.go @@ -5,28 +5,24 @@ import ( "fmt" "io" "os" - "strings" - "time" "github.com/argoproj/gitops-engine/pkg/utils/kube" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apierr "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/client-go/dynamic" "k8s.io/client-go/tools/clientcmd" - - "k8s.io/client-go/util/retry" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/localconfig" - secutil "github.com/argoproj/argo-cd/v3/util/security" + "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" ) // NewExportCommand defines a new command for exporting Kubernetes and Argo CD resources. @@ -40,16 +36,13 @@ func NewExportCommand() *cobra.Command { command := cobra.Command{ Use: "export", Short: "Export all Argo CD data to stdout (default) or a file", - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() config, err := clientConfig.ClientConfig() errors.CheckError(err) - client, err := dynamic.NewForConfig(config) - errors.CheckError(err) namespace, _, err := clientConfig.Namespace() errors.CheckError(err) - acdClients := newArgoCDClientsets(config, namespace) var writer io.Writer if out == "-" { @@ -67,51 +60,44 @@ func NewExportCommand() *cobra.Command { }() } - if len(applicationNamespaces) == 0 || len(applicationsetNamespaces) == 0 { - defaultNs := getAdditionalNamespaces(ctx, acdClients.configMaps) - if len(applicationNamespaces) == 0 { - applicationNamespaces = defaultNs.applicationNamespaces - } - if len(applicationsetNamespaces) == 0 { - applicationsetNamespaces = defaultNs.applicationsetNamespaces - } - } - // To support applications and applicationsets in any namespace, we must list ALL namespaces and filter them afterwards - if len(applicationNamespaces) > 0 { - acdClients.applications = client.Resource(applicationsResource) - } - if len(applicationsetNamespaces) > 0 { - acdClients.applicationSets = client.Resource(appplicationSetResource) - } - - acdConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDConfigMapName, metav1.GetOptions{}) + acdClients := newArgoCDClientsets(config, namespace) + acdConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDConfigMapName, v1.GetOptions{}) errors.CheckError(err) export(writer, *acdConfigMap, namespace) - acdRBACConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDRBACConfigMapName, metav1.GetOptions{}) + acdRBACConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDRBACConfigMapName, v1.GetOptions{}) errors.CheckError(err) export(writer, *acdRBACConfigMap, namespace) - acdKnownHostsConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDKnownHostsConfigMapName, metav1.GetOptions{}) + acdKnownHostsConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDKnownHostsConfigMapName, v1.GetOptions{}) errors.CheckError(err) export(writer, *acdKnownHostsConfigMap, namespace) - acdTLSCertsConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDTLSCertsConfigMapName, metav1.GetOptions{}) + acdTLSCertsConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDTLSCertsConfigMapName, v1.GetOptions{}) errors.CheckError(err) export(writer, *acdTLSCertsConfigMap, namespace) - secrets, err := acdClients.secrets.List(ctx, metav1.ListOptions{}) + referencedSecrets := getReferencedSecrets(*acdConfigMap) + secrets, err := acdClients.secrets.List(ctx, v1.ListOptions{}) errors.CheckError(err) for _, secret := range secrets.Items { - if isArgoCDSecret(secret) { + if isArgoCDSecret(referencedSecrets, secret) { export(writer, secret, namespace) } } - - projects, err := acdClients.projects.List(ctx, metav1.ListOptions{}) + projects, err := acdClients.projects.List(ctx, v1.ListOptions{}) errors.CheckError(err) for _, proj := range projects.Items { export(writer, proj, namespace) } - applications, err := acdClients.applications.List(ctx, metav1.ListOptions{}) + additionalNamespaces := getAdditionalNamespaces(ctx, acdClients) + + if len(applicationNamespaces) == 0 { + applicationNamespaces = additionalNamespaces.applicationNamespaces + } + if len(applicationsetNamespaces) == 0 { + applicationsetNamespaces = additionalNamespaces.applicationsetNamespaces + } + + applications, err := acdClients.applications.List(ctx, v1.ListOptions{}) errors.CheckError(err) for _, app := range applications.Items { // Export application only if it is in one of the enabled namespaces @@ -119,9 +105,9 @@ func NewExportCommand() *cobra.Command { export(writer, app, namespace) } } - applicationSets, err := acdClients.applicationSets.List(ctx, metav1.ListOptions{}) - if err != nil && !apierrors.IsNotFound(err) { - if apierrors.IsForbidden(err) { + applicationSets, err := acdClients.applicationSets.List(ctx, v1.ListOptions{}) + if err != nil && !apierr.IsNotFound(err) { + if apierr.IsForbidden(err) { log.Warn(err) } else { errors.CheckError(err) @@ -139,18 +125,8 @@ func NewExportCommand() *cobra.Command { clientConfig = cli.AddKubectlFlagsToCmd(&command) command.Flags().StringVarP(&out, "out", "o", "-", "Output to the specified file instead of stdout") - command.Flags().StringSliceVarP(&applicationNamespaces, "application-namespaces", "", []string{}, fmt.Sprintf("Comma-separated list of namespace globs to export applications from, in addition to the control plane namespace (Argo CD namespace). "+ - "By default, all applications from the control plane namespace are always exported. "+ - "If this flag is provided, applications from the specified namespaces are exported along with the control plane namespace. "+ - "If not specified, the value from '%s' in %s is used (if defined in the ConfigMap). "+ - "If the ConfigMap value is not set, only applications from the control plane namespace are exported.", - applicationNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName)) - command.Flags().StringSliceVarP(&applicationsetNamespaces, "applicationset-namespaces", "", []string{}, fmt.Sprintf("Comma-separated list of namespace globs to export ApplicationSets from, in addition to the control plane namespace (Argo CD namespace). "+ - "By default, all ApplicationSets from the control plane namespace are always exported. "+ - "If this flag is provided, ApplicationSets from the specified namespaces are exported along with the control plane namespace. "+ - "If not specified, the value from '%s' in %s is used (if defined in the ConfigMap). "+ - "If the ConfigMap value is not set, only ApplicationSets from the control plane namespace are exported.", - applicationsetNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName)) + command.Flags().StringSliceVarP(&applicationNamespaces, "application-namespaces", "", []string{}, fmt.Sprintf("Comma separated list of namespace globs to export applications from. If not provided value from '%s' in %s will be used,if it's not defined only applications from Argo CD namespace will be exported", applicationNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName)) + command.Flags().StringSliceVarP(&applicationsetNamespaces, "applicationset-namespaces", "", []string{}, fmt.Sprintf("Comma separated list of namespace globs to export applicationsets from. If not provided value from '%s' in %s will be used,if it's not defined only applicationsets from Argo CD namespace will be exported", applicationsetNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName)) return &command } @@ -163,9 +139,7 @@ func NewImportCommand() *cobra.Command { verbose bool stopOperation bool ignoreTracking bool - overrideOnConflict bool promptsEnabled bool - skipResourcesWithLabel string applicationNamespaces []string applicationsetNamespaces []string ) @@ -188,8 +162,7 @@ func NewImportCommand() *cobra.Command { acdClients := newArgoCDClientsets(config, namespace) client, err := dynamic.NewForConfig(config) errors.CheckError(err) - fmt.Printf("import process started %s\n", namespace) - tt := time.Now() + var input []byte if in := args[0]; in == "-" { input, err = io.ReadAll(os.Stdin) @@ -202,57 +175,54 @@ func NewImportCommand() *cobra.Command { dryRunMsg = " (dry run)" } - if len(applicationNamespaces) == 0 || len(applicationsetNamespaces) == 0 { - defaultNs := getAdditionalNamespaces(ctx, acdClients.configMaps) - if len(applicationNamespaces) == 0 { - applicationNamespaces = defaultNs.applicationNamespaces - } - if len(applicationsetNamespaces) == 0 { - applicationsetNamespaces = defaultNs.applicationsetNamespaces - } + additionalNamespaces := getAdditionalNamespaces(ctx, acdClients) + + if len(applicationNamespaces) == 0 { + applicationNamespaces = additionalNamespaces.applicationNamespaces } - // To support applications and applicationsets in any namespace, we must list ALL namespaces and filter them afterwards - if len(applicationNamespaces) > 0 { - acdClients.applications = client.Resource(applicationsResource) - } - if len(applicationsetNamespaces) > 0 { - acdClients.applicationSets = client.Resource(appplicationSetResource) + if len(applicationsetNamespaces) == 0 { + applicationsetNamespaces = additionalNamespaces.applicationsetNamespaces } - // pruneObjects tracks live objects, and it's current resource version. any remaining + // pruneObjects tracks live objects and it's current resource version. any remaining // items in this map indicates the resource should be pruned since it no longer appears // in the backup pruneObjects := make(map[kube.ResourceKey]unstructured.Unstructured) - configMaps, err := acdClients.configMaps.List(ctx, metav1.ListOptions{}) - + configMaps, err := acdClients.configMaps.List(ctx, v1.ListOptions{}) errors.CheckError(err) + // referencedSecrets holds any secrets referenced in the argocd-cm configmap. These + // secrets need to be imported too + var referencedSecrets map[string]bool for _, cm := range configMaps.Items { if isArgoCDConfigMap(cm.GetName()) { pruneObjects[kube.ResourceKey{Group: "", Kind: "ConfigMap", Name: cm.GetName(), Namespace: cm.GetNamespace()}] = cm } + if cm.GetName() == common.ArgoCDConfigMapName { + referencedSecrets = getReferencedSecrets(cm) + } } - secrets, err := acdClients.secrets.List(ctx, metav1.ListOptions{}) + secrets, err := acdClients.secrets.List(ctx, v1.ListOptions{}) errors.CheckError(err) for _, secret := range secrets.Items { - if isArgoCDSecret(secret) { + if isArgoCDSecret(referencedSecrets, secret) { pruneObjects[kube.ResourceKey{Group: "", Kind: "Secret", Name: secret.GetName(), Namespace: secret.GetNamespace()}] = secret } } - applications, err := acdClients.applications.List(ctx, metav1.ListOptions{}) + applications, err := acdClients.applications.List(ctx, v1.ListOptions{}) errors.CheckError(err) for _, app := range applications.Items { if secutil.IsNamespaceEnabled(app.GetNamespace(), namespace, applicationNamespaces) { pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.ApplicationKind, Name: app.GetName(), Namespace: app.GetNamespace()}] = app } } - projects, err := acdClients.projects.List(ctx, metav1.ListOptions{}) + projects, err := acdClients.projects.List(ctx, v1.ListOptions{}) errors.CheckError(err) for _, proj := range projects.Items { pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.AppProjectKind, Name: proj.GetName(), Namespace: proj.GetNamespace()}] = proj } - applicationSets, err := acdClients.applicationSets.List(ctx, metav1.ListOptions{}) - if apierrors.IsForbidden(err) || apierrors.IsNotFound(err) { + applicationSets, err := acdClients.applicationSets.List(ctx, v1.ListOptions{}) + if apierr.IsForbidden(err) || apierr.IsNotFound(err) { log.Warnf("argoproj.io/ApplicationSet: %v\n", err) } else { errors.CheckError(err) @@ -264,9 +234,9 @@ func NewImportCommand() *cobra.Command { } } } + // Create or replace existing object backupObjects, err := kube.SplitYAML(input) - errors.CheckError(err) for _, bakObj := range backupObjects { gvk := bakObj.GroupVersionKind() @@ -277,13 +247,6 @@ func NewImportCommand() *cobra.Command { key := kube.ResourceKey{Group: gvk.Group, Kind: gvk.Kind, Name: bakObj.GetName(), Namespace: bakObj.GetNamespace()} liveObj, exists := pruneObjects[key] delete(pruneObjects, key) - - // If the resource in backup matches the skip label, do not import it - if isSkipLabelMatches(bakObj, skipResourcesWithLabel) { - fmt.Printf("Skipping %s/%s %s in namespace %s\n", bakObj.GroupVersionKind().Group, bakObj.GroupVersionKind().Kind, bakObj.GetName(), bakObj.GetNamespace()) - continue - } - var dynClient dynamic.ResourceInterface switch bakObj.GetKind() { case "Secret": @@ -293,17 +256,17 @@ func NewImportCommand() *cobra.Command { case application.AppProjectKind: dynClient = client.Resource(appprojectsResource).Namespace(bakObj.GetNamespace()) case application.ApplicationKind: + dynClient = client.Resource(applicationsResource).Namespace(bakObj.GetNamespace()) // If application is not in one of the allowed namespaces do not import it if !secutil.IsNamespaceEnabled(bakObj.GetNamespace(), namespace, applicationNamespaces) { continue } - dynClient = client.Resource(applicationsResource).Namespace(bakObj.GetNamespace()) case application.ApplicationSetKind: + dynClient = client.Resource(appplicationSetResource).Namespace(bakObj.GetNamespace()) // If applicationset is not in one of the allowed namespaces do not import it if !secutil.IsNamespaceEnabled(bakObj.GetNamespace(), namespace, applicationsetNamespaces) { continue } - dynClient = client.Resource(appplicationSetResource).Namespace(bakObj.GetNamespace()) } // If there is a live object, remove the tracking annotations/label that might conflict @@ -312,12 +275,11 @@ func NewImportCommand() *cobra.Command { updateTracking(bakObj, &liveObj) } - switch { - case !exists: + if !exists { isForbidden := false if !dryRun { - _, err = dynClient.Create(ctx, bakObj, metav1.CreateOptions{}) - if apierrors.IsForbidden(err) || apierrors.IsNotFound(err) { + _, err = dynClient.Create(ctx, bakObj, v1.CreateOptions{}) + if apierr.IsForbidden(err) || apierr.IsNotFound(err) { isForbidden = true log.Warnf("%s/%s %s: %v", gvk.Group, gvk.Kind, bakObj.GetName(), err) } else { @@ -327,31 +289,16 @@ func NewImportCommand() *cobra.Command { if !isForbidden { fmt.Printf("%s/%s %s in namespace %s created%s\n", gvk.Group, gvk.Kind, bakObj.GetName(), bakObj.GetNamespace(), dryRunMsg) } - case specsEqual(*bakObj, liveObj) && checkAppHasNoNeedToStopOperation(liveObj, stopOperation): + } else if specsEqual(*bakObj, liveObj) && checkAppHasNoNeedToStopOperation(liveObj, stopOperation) { if verbose { fmt.Printf("%s/%s %s unchanged%s\n", gvk.Group, gvk.Kind, bakObj.GetName(), dryRunMsg) } - default: + } else { isForbidden := false if !dryRun { newLive := updateLive(bakObj, &liveObj, stopOperation) - _, err = dynClient.Update(ctx, newLive, metav1.UpdateOptions{}) - if apierrors.IsConflict(err) { - fmt.Printf("Failed to update %s/%s %s in namespace %s: %v\n", gvk.Group, gvk.Kind, bakObj.GetName(), bakObj.GetNamespace(), err) - if overrideOnConflict { - err = retry.RetryOnConflict(retry.DefaultRetry, func() error { - fmt.Printf("Resource conflict: retrying update for Group: %s, Kind: %s, Name: %s, Namespace: %s\n", gvk.Group, gvk.Kind, bakObj.GetName(), bakObj.GetNamespace()) - liveObj, getErr := dynClient.Get(ctx, newLive.GetName(), metav1.GetOptions{}) - if getErr != nil { - errors.CheckError(getErr) - } - newLive.SetResourceVersion(liveObj.GetResourceVersion()) - _, err = dynClient.Update(ctx, newLive, metav1.UpdateOptions{}) - return err - }) - } - } - if apierrors.IsForbidden(err) || apierrors.IsNotFound(err) { + _, err = dynClient.Update(ctx, newLive, v1.UpdateOptions{}) + if apierr.IsForbidden(err) || apierr.IsNotFound(err) { isForbidden = true log.Warnf("%s/%s %s: %v", gvk.Group, gvk.Kind, bakObj.GetName(), err) } else { @@ -368,12 +315,6 @@ func NewImportCommand() *cobra.Command { // Delete objects not in backup for key, liveObj := range pruneObjects { - // If a live resource has a label to skip the import, it should never be pruned - if isSkipLabelMatches(&liveObj, skipResourcesWithLabel) { - fmt.Printf("Skipping pruning of %s/%s %s in namespace %s\n", key.Group, key.Kind, liveObj.GetName(), liveObj.GetNamespace()) - continue - } - if prune { var dynClient dynamic.ResourceInterface switch key.Kind { @@ -387,8 +328,8 @@ func NewImportCommand() *cobra.Command { if finalizers := liveObj.GetFinalizers(); len(finalizers) > 0 { newLive := liveObj.DeepCopy() newLive.SetFinalizers(nil) - _, err = dynClient.Update(ctx, newLive, metav1.UpdateOptions{}) - if err != nil && !apierrors.IsNotFound(err) { + _, err = dynClient.Update(ctx, newLive, v1.UpdateOptions{}) + if err != nil && !apierr.IsNotFound(err) { errors.CheckError(err) } } @@ -403,8 +344,8 @@ func NewImportCommand() *cobra.Command { if !dryRun { 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, metav1.DeleteOptions{}) - if apierrors.IsForbidden(err) || apierrors.IsNotFound(err) { + 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 { @@ -421,8 +362,6 @@ func NewImportCommand() *cobra.Command { fmt.Printf("%s/%s %s needs pruning\n", key.Group, key.Kind, key.Name) } } - duration := time.Since(tt) - fmt.Printf("Import process completed successfully in namespace %s at %s, duration: %s\n", namespace, time.Now().Format(time.RFC3339), duration) }, } @@ -430,13 +369,12 @@ func NewImportCommand() *cobra.Command { command.Flags().BoolVar(&dryRun, "dry-run", false, "Print what will be performed") command.Flags().BoolVar(&prune, "prune", false, "Prune secrets, applications and projects which do not appear in the backup") command.Flags().BoolVar(&ignoreTracking, "ignore-tracking", false, "Do not update the tracking annotation if the resource is already tracked") - command.Flags().BoolVar(&overrideOnConflict, "override-on-conflict", false, "Override the resource on conflict when updating resources") command.Flags().BoolVar(&verbose, "verbose", false, "Verbose output (versus only changed output)") command.Flags().BoolVar(&stopOperation, "stop-operation", false, "Stop any existing operations") - command.Flags().StringVarP(&skipResourcesWithLabel, "skip-resources-with-label", "", "", "Skip importing resources based on the label e.g. '--skip-resources-with-label my-label/example.io=true'") - 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.Flags().StringSliceVarP(&applicationNamespaces, "application-namespaces", "", []string{}, fmt.Sprintf("Comma separated list of namespace globs to which import of applications is allowed. If not provided value from '%s' in %s will be used,if it's not defined only applications without an explicit namespace will be imported to the Argo CD namespace", applicationNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName)) + command.Flags().StringSliceVarP(&applicationsetNamespaces, "applicationset-namespaces", "", []string{}, fmt.Sprintf("Comma separated list of namespace globs which import of applicationsets is allowed. If not provided value from '%s' in %s will be used,if it's not defined only applicationsets without an explicit namespace will be imported to the Argo CD namespace", applicationsetNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName)) command.PersistentFlags().BoolVar(&promptsEnabled, "prompts-enabled", localconfig.GetPromptsEnabled(true), "Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.") + return &command } @@ -445,7 +383,8 @@ func checkAppHasNoNeedToStopOperation(liveObj unstructured.Unstructured, stopOpe if !stopOperation { return true } - if liveObj.GetKind() == application.ApplicationKind { + switch liveObj.GetKind() { + case application.ApplicationKind: return liveObj.Object["operation"] == nil } return true @@ -468,7 +407,6 @@ func export(w io.Writer, un unstructured.Unstructured, argocdNamespace string) { un.SetLabels(labels) un.SetAnnotations(annotations) if namespace != argocdNamespace { - // Explicitly add the namespace for appset and apps in any namespace un.SetNamespace(namespace) } data, err := yaml.Marshal(un.Object) @@ -534,19 +472,3 @@ func updateTracking(bak, live *unstructured.Unstructured) { } } } - -// isSkipLabelMatches return if the resource should be skipped based on the labels -func isSkipLabelMatches(obj *unstructured.Unstructured, skipResourcesWithLabel string) bool { - if skipResourcesWithLabel == "" { - return false - } - parts := strings.SplitN(skipResourcesWithLabel, "=", 2) - if len(parts) != 2 || parts[0] == "" || parts[1] == "" { - return false - } - key, value := parts[0], parts[1] - if val, ok := obj.GetLabels()[key]; ok && val == value { - return true - } - return false -} diff --git a/cmd/argocd/commands/admin/backup_test.go b/cmd/argocd/commands/admin/backup_test.go index d1f638711b..b4fd07ad04 100644 --- a/cmd/argocd/commands/admin/backup_test.go +++ b/cmd/argocd/commands/admin/backup_test.go @@ -1,23 +1,19 @@ package admin import ( - "bytes" "testing" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/security" - "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) func newBackupObject(trackingValue string, trackingLabel bool, trackingAnnotation bool) *unstructured.Unstructured { - cm := corev1.ConfigMap{ + cm := v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "my-configmap", Namespace: "namespace", @@ -39,329 +35,6 @@ func newBackupObject(trackingValue string, trackingLabel bool, trackingAnnotatio return kube.MustToUnstructured(&cm) } -func newConfigmapObject() *unstructured.Unstructured { - cm := corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.ArgoCDConfigMapName, - Namespace: "argocd", - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - } - - return kube.MustToUnstructured(&cm) -} - -func newSecretsObject() *unstructured.Unstructured { - secret := corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.ArgoCDSecretName, - Namespace: "default", - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string][]byte{ - "admin.password": nil, - "server.secretkey": nil, - }, - } - - return kube.MustToUnstructured(&secret) -} - -func newAppProject() *unstructured.Unstructured { - appProject := v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: "argocd", - }, - Spec: v1alpha1.AppProjectSpec{ - Destinations: []v1alpha1.ApplicationDestination{ - { - Namespace: "*", - Server: "*", - }, - }, - ClusterResourceWhitelist: []metav1.GroupKind{ - { - Group: "*", - Kind: "*", - }, - }, - SourceRepos: []string{"*"}, - }, - } - - return kube.MustToUnstructured(&appProject) -} - -func newApplication(namespace string) *unstructured.Unstructured { - app := v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: "Application", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - Namespace: namespace, - }, - Spec: v1alpha1.ApplicationSpec{ - Source: &v1alpha1.ApplicationSource{}, - Project: "default", - Destination: v1alpha1.ApplicationDestination{ - Server: v1alpha1.KubernetesInternalAPIServerAddr, - Namespace: "default", - }, - }, - } - - return kube.MustToUnstructured(&app) -} - -func newApplicationSet(namespace string) *unstructured.Unstructured { - appSet := v1alpha1.ApplicationSet{ - TypeMeta: metav1.TypeMeta{ - Kind: "ApplicationSet", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "test-appset", - Namespace: namespace, - }, - Spec: v1alpha1.ApplicationSetSpec{ - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: "https://github.com/org/repo", - }, - }, - }, - }, - } - - return kube.MustToUnstructured(&appSet) -} - -// Test_exportResources tests for the resources exported when using the `argocd admin export` command -func Test_exportResources(t *testing.T) { - tests := []struct { - name string - object *unstructured.Unstructured - namespace string - enabledNamespaces []string - expectedFileContent string - expectExport bool - }{ - { - name: "ConfigMap should be in the exported manifest", - object: newConfigmapObject(), - expectExport: true, - expectedFileContent: `apiVersion: "" -kind: "" -metadata: - labels: - app.kubernetes.io/part-of: argocd - name: argocd-cm ---- -`, - }, - { - name: "Secret should be in the exported manifest", - object: newSecretsObject(), - expectExport: true, - expectedFileContent: `apiVersion: "" -data: - admin.password: null - server.secretkey: null -kind: "" -metadata: - labels: - app.kubernetes.io/part-of: argocd - name: argocd-secret - namespace: default ---- -`, - }, - { - name: "App Project should be in the exported manifest", - object: newAppProject(), - expectExport: true, - expectedFileContent: `apiVersion: "" -kind: "" -metadata: - name: default -spec: - clusterResourceWhitelist: - - group: '*' - kind: '*' - destinations: - - namespace: '*' - server: '*' - sourceRepos: - - '*' -status: {} ---- -`, - }, - { - name: "Application should be in the exported manifest when created in the default 'argocd' namespace", - object: newApplication("argocd"), - namespace: "argocd", - expectExport: true, - expectedFileContent: `apiVersion: "" -kind: Application -metadata: - name: test -spec: - destination: - namespace: default - server: https://kubernetes.default.svc - project: default - source: - repoURL: "" -status: - health: {} - sourceHydrator: {} - summary: {} - sync: - comparedTo: - destination: {} - source: - repoURL: "" - status: "" ---- -`, - }, - { - name: "Application should be in the exported manifest when created in the enabled namespaces", - object: newApplication("dev"), - namespace: "dev", - enabledNamespaces: []string{"dev", "prod"}, - expectExport: true, - expectedFileContent: `apiVersion: "" -kind: Application -metadata: - name: test - namespace: dev -spec: - destination: - namespace: default - server: https://kubernetes.default.svc - project: default - source: - repoURL: "" -status: - health: {} - sourceHydrator: {} - summary: {} - sync: - comparedTo: - destination: {} - source: - repoURL: "" - status: "" ---- -`, - }, - { - name: "Application should not be in the exported manifest when it's neither created in the default argod namespace nor in enabled namespace", - object: newApplication("staging"), - namespace: "staging", - enabledNamespaces: []string{"dev", "prod"}, - expectExport: false, - expectedFileContent: ``, - }, - { - name: "ApplicationSet should be in the exported manifest when created in the default 'argocd' namespace", - object: newApplicationSet("argocd"), - namespace: "argocd", - expectExport: true, - expectedFileContent: `apiVersion: "" -kind: ApplicationSet -metadata: - name: test-appset -spec: - generators: - - git: - repoURL: https://github.com/org/repo - revision: "" - template: - metadata: {} - spec: - destination: {} - project: "" - template: - metadata: {} - spec: - destination: {} - project: "" -status: {} ---- -`, - }, - { - name: "ApplicationSet should be in the exported manifest when created in the enabled namespaces", - object: newApplicationSet("dev"), - namespace: "dev", - enabledNamespaces: []string{"dev", "prod"}, - expectExport: true, - expectedFileContent: `apiVersion: "" -kind: ApplicationSet -metadata: - name: test-appset - namespace: dev -spec: - generators: - - git: - repoURL: https://github.com/org/repo - revision: "" - template: - metadata: {} - spec: - destination: {} - project: "" - template: - metadata: {} - spec: - destination: {} - project: "" -status: {} ---- -`, - }, - { - name: "ApplicationSet should not be in the exported manifest when neither created in the default 'argocd' namespace nor in enabled namespaces", - object: newApplicationSet("staging"), - namespace: "staging", - enabledNamespaces: []string{"dev", "prod"}, - expectExport: false, - expectedFileContent: ``, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var buf bytes.Buffer - - kind := tt.object.GetKind() - if kind == "Application" || kind == "ApplicationSet" { - if security.IsNamespaceEnabled(tt.namespace, "argocd", tt.enabledNamespaces) { - export(&buf, *tt.object, ArgoCDNamespace) - } - } else { - export(&buf, *tt.object, ArgoCDNamespace) - } - - content := buf.String() - if tt.expectExport { - assert.Equal(t, tt.expectedFileContent, content) - } else { - assert.Empty(t, content) - } - }) - } -} - func Test_updateTracking(t *testing.T) { type args struct { bak *unstructured.Unstructured @@ -412,76 +85,3 @@ func Test_updateTracking(t *testing.T) { }) } } - -func TestIsSkipLabelMatches(t *testing.T) { - tests := []struct { - name string - obj *unstructured.Unstructured - skipLabels string - expected bool - }{ - { - name: "Label matches", - obj: &unstructured.Unstructured{ - Object: map[string]any{ - "metadata": map[string]any{ - "labels": map[string]any{ - "test-label": "value", - }, - }, - }, - }, - skipLabels: "test-label=value", - expected: true, - }, - { - name: "Label does not match", - obj: &unstructured.Unstructured{ - Object: map[string]any{ - "metadata": map[string]any{ - "labels": map[string]any{ - "different-label": "value", - }, - }, - }, - }, - skipLabels: "test-label=value", - expected: false, - }, - { - name: "Empty skip labels", - obj: &unstructured.Unstructured{ - Object: map[string]any{ - "metadata": map[string]any{ - "labels": map[string]any{ - "test-label": "value", - }, - }, - }, - }, - skipLabels: "", - expected: false, - }, - { - name: "No labels value", - obj: &unstructured.Unstructured{ - Object: map[string]any{ - "metadata": map[string]any{ - "labels": map[string]any{ - "test-label": "value", - "another-label": "value2", - }, - }, - }, - }, - skipLabels: "test-label", - expected: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result := isSkipLabelMatches(tt.obj, tt.skipLabels) - assert.Equal(t, tt.expected, result) - }) - } -} diff --git a/cmd/argocd/commands/admin/cluster.go b/cmd/argocd/commands/admin/cluster.go index a0ce6910be..04d9a148b2 100644 --- a/cmd/argocd/commands/admin/cluster.go +++ b/cmd/argocd/commands/admin/cluster.go @@ -14,30 +14,30 @@ import ( "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" "k8s.io/utils/ptr" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/controller/sharding" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - "github.com/argoproj/argo-cd/v3/util/argo" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/clusterauth" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/glob" - kubeutil "github.com/argoproj/argo-cd/v3/util/kube" - "github.com/argoproj/argo-cd/v3/util/settings" - "github.com/argoproj/argo-cd/v3/util/text/label" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/controller/sharding" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + "github.com/argoproj/argo-cd/v2/util/argo" + 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/cli" + "github.com/argoproj/argo-cd/v2/util/clusterauth" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/glob" + kubeutil "github.com/argoproj/argo-cd/v2/util/kube" + "github.com/argoproj/argo-cd/v2/util/settings" + "github.com/argoproj/argo-cd/v2/util/text/label" ) func NewClusterCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clientcmd.PathOptions) *cobra.Command { @@ -78,7 +78,7 @@ type ClusterWithInfo struct { Namespaces []string } -func loadClusters(ctx context.Context, kubeClient kubernetes.Interface, appClient versioned.Interface, replicas int, shardingAlgorithm string, namespace string, portForwardRedis bool, cacheSrc func() (*appstatecache.Cache, error), shard int, redisName string, redisHaProxyName string, redisCompressionStr string) ([]ClusterWithInfo, error) { +func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClient *versioned.Clientset, replicas int, shardingAlgorithm string, namespace string, portForwardRedis bool, cacheSrc func() (*appstatecache.Cache, error), shard int, redisName string, redisHaProxyName string, redisCompressionStr string) ([]ClusterWithInfo, error) { settingsMgr := settings.NewSettingsManager(ctx, kubeClient, namespace) argoDB := db.NewDB(namespace, settingsMgr, kubeClient) @@ -86,7 +86,7 @@ func loadClusters(ctx context.Context, kubeClient kubernetes.Interface, appClien if err != nil { return nil, err } - appItems, err := appClient.ArgoprojV1alpha1().Applications(namespace).List(ctx, metav1.ListOptions{}) + appItems, err := appClient.ArgoprojV1alpha1().Applications(namespace).List(ctx, v1.ListOptions{}) if err != nil { return nil, err } @@ -123,6 +123,13 @@ func loadClusters(ctx context.Context, kubeClient kubernetes.Interface, appClien } apps := appItems.Items + for i, app := range apps { + err := argo.ValidateDestination(ctx, &app.Spec.Destination, argoDB) + if err != nil { + return nil, err + } + apps[i] = app + } clusters := make([]ClusterWithInfo, len(clustersList.Items)) batchSize := 10 @@ -147,11 +154,7 @@ func loadClusters(ctx context.Context, kubeClient kubernetes.Interface, appClien } nsSet := map[string]bool{} for _, app := range apps { - destCluster, err := argo.GetDestinationCluster(ctx, app.Spec.Destination, argoDB) - if err != nil { - return fmt.Errorf("error validating application destination: %w", err) - } - if destCluster.Server == cluster.Server { + if app.Spec.Destination.Server == cluster.Server { nsSet[app.Spec.Destination.Namespace] = true } } @@ -169,7 +172,7 @@ func loadClusters(ctx context.Context, kubeClient kubernetes.Interface, appClien func getControllerReplicas(ctx context.Context, kubeClient *kubernetes.Clientset, namespace string, appControllerName string) (int, error) { appControllerPodLabelSelector := common.LabelKeyAppName + "=" + appControllerName - controllerPods, err := kubeClient.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ + controllerPods, err := kubeClient.CoreV1().Pods(namespace).List(ctx, v1.ListOptions{ LabelSelector: appControllerPodLabelSelector, }) if err != nil { @@ -190,7 +193,7 @@ func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm command := cobra.Command{ Use: "shards", Short: "Print information about each controller shard and the estimated portion of Kubernetes resources it is responsible for.", - Run: func(cmd *cobra.Command, _ []string) { + Run: func(cmd *cobra.Command, args []string) { ctx := cmd.Context() log.SetLevel(log.WarnLevel) @@ -228,7 +231,7 @@ func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm // parse all added flags so far to get the redis-compression flag that was added by AddCacheFlagsToCmd() above // we can ignore unchecked error here as the command will be parsed again and checked when command.Execute() is run later - //nolint:errcheck + // nolint:errcheck command.ParseFlags(os.Args[1:]) return &command } @@ -271,21 +274,23 @@ func runClusterNamespacesCommand(ctx context.Context, clientConfig clientcmd.Cli if err != nil { return fmt.Errorf("error listing clusters: %w", err) } - appItems, err := appClient.ArgoprojV1alpha1().Applications(namespace).List(ctx, metav1.ListOptions{}) + appItems, err := appClient.ArgoprojV1alpha1().Applications(namespace).List(ctx, v1.ListOptions{}) if err != nil { return fmt.Errorf("error listing application: %w", err) } apps := appItems.Items + for i, app := range apps { + if err := argo.ValidateDestination(ctx, &app.Spec.Destination, argoDB); err != nil { + return fmt.Errorf("error validating application destination: %w", err) + } + apps[i] = app + } + clusters := map[string][]string{} for _, cluster := range clustersList.Items { nsSet := map[string]bool{} for _, app := range apps { - destCluster, err := argo.GetDestinationCluster(ctx, app.Spec.Destination, argoDB) - if err != nil { - return fmt.Errorf("error validating application destination: %w", err) - } - - if destCluster.Server != cluster.Server { + if app.Spec.Destination.Server != cluster.Server { continue } // Use namespaces of actually deployed resources, since some application use dummy target namespace @@ -314,12 +319,12 @@ func NewClusterNamespacesCommand() *cobra.Command { command := cobra.Command{ Use: "namespaces", Short: "Print information namespaces which Argo CD manages in each cluster.", - Run: func(cmd *cobra.Command, _ []string) { + Run: func(cmd *cobra.Command, args []string) { ctx := cmd.Context() log.SetLevel(log.WarnLevel) - err := runClusterNamespacesCommand(ctx, clientConfig, func(_ *versioned.Clientset, _ db.ArgoDB, clusters map[string][]string) error { + err := runClusterNamespacesCommand(ctx, clientConfig, func(appClient *versioned.Clientset, _ db.ArgoDB, clusters map[string][]string) error { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) _, _ = fmt.Fprintf(w, "CLUSTER\tNAMESPACES\n") @@ -478,7 +483,7 @@ argocd admin cluster stats --shard=1 #In a multi-cluster environment to print stats for a specific cluster say(target-cluster) argocd admin cluster stats target-cluster`, - Run: func(cmd *cobra.Command, _ []string) { + Run: func(cmd *cobra.Command, args []string) { ctx := cmd.Context() log.SetLevel(log.WarnLevel) @@ -514,7 +519,7 @@ argocd admin cluster stats target-cluster`, // parse all added flags so far to get the redis-compression flag that was added by AddCacheFlagsToCmd() above // we can ignore unchecked error here as the command will be parsed again and checked when command.Execute() is run later - //nolint:errcheck + // nolint:errcheck command.ParseFlags(os.Args[1:]) return &command } @@ -545,7 +550,7 @@ argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kub c.HelpFunc()(c, args) os.Exit(1) } - serverURL := args[0] + serverUrl := args[0] output := args[1] conf, err := clientConfig.ClientConfig() errors.CheckError(err) @@ -554,7 +559,7 @@ argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kub kubeclientset, err := kubernetes.NewForConfig(conf) errors.CheckError(err) - cluster, err := db.NewDB(namespace, settings.NewSettingsManager(ctx, kubeclientset, namespace), kubeclientset).GetCluster(ctx, serverURL) + cluster, err := db.NewDB(namespace, settings.NewSettingsManager(ctx, kubeclientset, namespace), kubeclientset).GetCluster(ctx, serverUrl) errors.CheckError(err) rawConfig, err := cluster.RawRestConfig() errors.CheckError(err) @@ -612,14 +617,13 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command var awsAuthConf *v1alpha1.AWSAuthConfig var execProviderConf *v1alpha1.ExecProviderConfig - switch { - case clusterOpts.AwsClusterName != "": + if clusterOpts.AwsClusterName != "" { awsAuthConf = &v1alpha1.AWSAuthConfig{ ClusterName: clusterOpts.AwsClusterName, RoleARN: clusterOpts.AwsRoleArn, Profile: clusterOpts.AwsProfile, } - case clusterOpts.ExecProviderCommand != "": + } else if clusterOpts.ExecProviderCommand != "" { execProviderConf = &v1alpha1.ExecProviderConfig{ Command: clusterOpts.ExecProviderCommand, Args: clusterOpts.ExecProviderArgs, @@ -627,10 +631,10 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command APIVersion: clusterOpts.ExecProviderAPIVersion, InstallHint: clusterOpts.ExecProviderInstallHint, } - case generateToken: + } else if generateToken { bearerToken, err = GenerateToken(clusterOpts, conf) errors.CheckError(err) - case bearerToken == "": + } else if bearerToken == "" { bearerToken = "bearer-token" } if clusterOpts.Name != "" { @@ -663,7 +667,7 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command secName, err := db.URIToSecretName("cluster", clst.Server) errors.CheckError(err) - secret, err := kubeClientset.CoreV1().Secrets(ArgoCDNamespace).Get(ctx, secName, metav1.GetOptions{}) + secret, err := kubeClientset.CoreV1().Secrets(ArgoCDNamespace).Get(ctx, secName, v1.GetOptions{}) errors.CheckError(err) errors.CheckError(PrintResources(outputFormat, os.Stdout, secret)) diff --git a/cmd/argocd/commands/admin/cluster_test.go b/cmd/argocd/commands/admin/cluster_test.go deleted file mode 100644 index 5550dd4331..0000000000 --- a/cmd/argocd/commands/admin/cluster_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package admin - -import ( - "testing" - "time" - - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - fakeapps "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - "github.com/argoproj/argo-cd/v3/util/cache/appstate" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes/fake" - "k8s.io/utils/ptr" -) - -func Test_loadClusters(t *testing.T) { - argoCDCM := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "argocd-cm", - Namespace: "argocd", - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string]string{}, - } - argoCDSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "argocd-secret", - Namespace: "argocd", - }, - Data: map[string][]byte{ - "server.secretkey": []byte("test"), - }, - } - app := &v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - Namespace: "argocd", - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "test", - }, - }, - } - ctx := t.Context() - kubeClient := fake.NewClientset(argoCDCM, argoCDSecret) - appClient := fakeapps.NewSimpleClientset(app) - cacheSrc := func() (*appstate.Cache, error) { - return appstate.NewCache(cacheutil.NewCache(cacheutil.NewInMemoryCache(time.Minute)), time.Minute), nil - } - clusters, err := loadClusters(ctx, kubeClient, appClient, 3, "", "argocd", false, cacheSrc, 0, "", "", "") - require.NoError(t, err) - for i := range clusters { - // This changes, nil it to avoid testing it. - //nolint:staticcheck - clusters[i].ConnectionState.ModifiedAt = nil - } - - expected := []ClusterWithInfo{{ - Cluster: v1alpha1.Cluster{ - ID: "", - Server: "https://kubernetes.default.svc", - Name: "in-cluster", - ConnectionState: v1alpha1.ConnectionState{ - Status: "Successful", - }, - ServerVersion: ".", - Shard: ptr.To(int64(0)), - }, - Namespaces: []string{"test"}, - }} - assert.Equal(t, expected, clusters) -} diff --git a/cmd/argocd/commands/admin/dashboard.go b/cmd/argocd/commands/admin/dashboard.go index 02cb4e797f..5ac701beaa 100644 --- a/cmd/argocd/commands/admin/dashboard.go +++ b/cmd/argocd/commands/admin/dashboard.go @@ -6,13 +6,13 @@ import ( "github.com/spf13/cobra" "k8s.io/client-go/tools/clientcmd" - "github.com/argoproj/argo-cd/v3/util/cli" + "github.com/argoproj/argo-cd/v2/util/cli" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/initialize" - "github.com/argoproj/argo-cd/v3/common" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/initialize" + "github.com/argoproj/argo-cd/v2/common" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/util/errors" ) func NewDashboardCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { @@ -24,7 +24,7 @@ func NewDashboardCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command cmd := &cobra.Command{ Use: "dashboard", Short: "Starts Argo CD Web UI locally", - Run: func(cmd *cobra.Command, _ []string) { + Run: func(cmd *cobra.Command, args []string) { ctx := cmd.Context() clientOpts.Core = true diff --git a/cmd/argocd/commands/admin/generatespec_utils.go b/cmd/argocd/commands/admin/generatespec_utils.go index 71b2883a98..f9d902111a 100644 --- a/cmd/argocd/commands/admin/generatespec_utils.go +++ b/cmd/argocd/commands/admin/generatespec_utils.go @@ -8,22 +8,22 @@ import ( "os" "github.com/argoproj/gitops-engine/pkg/utils/kube" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "sigs.k8s.io/yaml" - utilio "github.com/argoproj/argo-cd/v3/util/io" + ioutil "github.com/argoproj/argo-cd/v2/util/io" ) func getOutWriter(inline bool, filePath string) (io.Writer, io.Closer, error) { if !inline { - return os.Stdout, utilio.NopCloser, nil + return os.Stdout, ioutil.NopCloser, nil } if filePath == "" { - return nil, nil, errors.New("the file path must be specified using flag '--file'") + return nil, nil, errors.New("The file path must be specified using flag '--file'") } - err := os.Rename(filePath, filePath+".back") + err := os.Rename(filePath, fmt.Sprintf("%s.back", filePath)) if err != nil { return nil, nil, err } @@ -36,9 +36,9 @@ func getOutWriter(inline bool, filePath string) (io.Writer, io.Closer, error) { } // PrintResources prints a single resource in YAML or JSON format to stdout according to the output format -func PrintResources(output string, out io.Writer, resources ...any) error { +func PrintResources(output string, out io.Writer, resources ...interface{}) error { for i, resource := range resources { - if secret, ok := resource.(*corev1.Secret); ok { + if secret, ok := resource.(*v1.Secret); ok { convertSecretData(secret) } filteredResource, err := omitFields(resource) @@ -47,7 +47,7 @@ func PrintResources(output string, out io.Writer, resources ...any) error { } resources[i] = filteredResource } - var obj any = resources + var obj interface{} = resources if len(resources) == 1 { obj = resources[0] } @@ -74,13 +74,13 @@ func PrintResources(output string, out io.Writer, resources ...any) error { } // omit fields such as status, creationTimestamp and metadata.namespace in k8s objects -func omitFields(resource any) (any, error) { +func omitFields(resource interface{}) (interface{}, error) { jsonBytes, err := json.Marshal(resource) if err != nil { return nil, err } - toMap := make(map[string]any) + toMap := make(map[string]interface{}) err = json.Unmarshal(jsonBytes, &toMap) if err != nil { return nil, err @@ -88,7 +88,7 @@ func omitFields(resource any) (any, error) { delete(toMap, "status") if v, ok := toMap["metadata"]; ok { - if metadata, ok := v.(map[string]any); ok { + if metadata, ok := v.(map[string]interface{}); ok { delete(metadata, "creationTimestamp") delete(metadata, "namespace") } @@ -97,7 +97,7 @@ func omitFields(resource any) (any, error) { } // convertSecretData converts kubernetes secret's data to stringData -func convertSecretData(secret *corev1.Secret) { +func convertSecretData(secret *v1.Secret) { secret.Kind = kube.SecretKind secret.APIVersion = "v1" secret.StringData = map[string]string{} diff --git a/cmd/argocd/commands/admin/generatespec_utils_test.go b/cmd/argocd/commands/admin/generatespec_utils_test.go index 5598f89018..9c5735df58 100644 --- a/cmd/argocd/commands/admin/generatespec_utils_test.go +++ b/cmd/argocd/commands/admin/generatespec_utils_test.go @@ -2,21 +2,22 @@ package admin import ( "bytes" + "fmt" "os" "testing" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "github.com/argoproj/argo-cd/v2/util/io" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestGetOutWriter_InlineOff(t *testing.T) { out, closer, err := getOutWriter(false, "") require.NoError(t, err) - defer utilio.Close(closer) + defer io.Close(closer) assert.Equal(t, os.Stdout, out) } @@ -24,21 +25,21 @@ func TestGetOutWriter_InlineOff(t *testing.T) { func TestGetOutWriter_InlineOn(t *testing.T) { tmpFile := t.TempDir() defer func() { - _ = os.Remove(tmpFile + ".back") + _ = os.Remove(fmt.Sprintf("%s.back", tmpFile)) }() out, closer, err := getOutWriter(true, tmpFile) require.NoError(t, err) - defer utilio.Close(closer) + defer io.Close(closer) assert.Equal(t, tmpFile, out.(*os.File).Name()) - _, err = os.Stat(tmpFile + ".back") + _, err = os.Stat(fmt.Sprintf("%s.back", tmpFile)) require.NoError(t, err, "Back file must be created") } func TestPrintResources_Secret_YAML(t *testing.T) { out := bytes.Buffer{} - err := PrintResources("yaml", &out, &corev1.Secret{ + err := PrintResources("yaml", &out, &v1.Secret{ ObjectMeta: metav1.ObjectMeta{Name: "my-secret"}, Data: map[string][]byte{"my-secret-key": []byte("my-secret-data")}, }) diff --git a/cmd/argocd/commands/admin/initial_password.go b/cmd/argocd/commands/admin/initial_password.go index 6b019f5f5a..bcd699d3d0 100644 --- a/cmd/argocd/commands/admin/initial_password.go +++ b/cmd/argocd/commands/admin/initial_password.go @@ -5,12 +5,12 @@ import ( "fmt" "github.com/spf13/cobra" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/errors" ) const initialPasswordSecretName = "argocd-initial-admin-secret" @@ -21,14 +21,14 @@ func NewInitialPasswordCommand() *cobra.Command { command := cobra.Command{ Use: "initial-password", Short: "Prints initial password to log in to Argo CD for the first time", - Run: func(_ *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { config, err := clientConfig.ClientConfig() errors.CheckError(err) namespace, _, err := clientConfig.Namespace() errors.CheckError(err) kubeClientset := kubernetes.NewForConfigOrDie(config) - secret, err := kubeClientset.CoreV1().Secrets(namespace).Get(context.Background(), initialPasswordSecretName, metav1.GetOptions{}) + secret, err := kubeClientset.CoreV1().Secrets(namespace).Get(context.Background(), initialPasswordSecretName, v1.GetOptions{}) errors.CheckError(err) if initialPass, ok := secret.Data["password"]; ok { diff --git a/cmd/argocd/commands/admin/notifications.go b/cmd/argocd/commands/admin/notifications.go index 08837db9c5..32ae589270 100644 --- a/cmd/argocd/commands/admin/notifications.go +++ b/cmd/argocd/commands/admin/notifications.go @@ -1,23 +1,24 @@ package admin import ( + "fmt" "log" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/env" - service "github.com/argoproj/argo-cd/v3/util/notification/argocd" - "github.com/argoproj/argo-cd/v3/util/notification/settings" - "github.com/argoproj/argo-cd/v3/util/tls" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/env" + service "github.com/argoproj/argo-cd/v2/util/notification/argocd" + settings "github.com/argoproj/argo-cd/v2/util/notification/settings" + "github.com/argoproj/argo-cd/v2/util/tls" "github.com/argoproj/notifications-engine/pkg/cmd" "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) var applications = schema.GroupVersionResource{Group: application.Group, Version: "v1alpha1", Resource: application.ApplicationPlural} @@ -50,8 +51,8 @@ func NewNotificationsCommand() *cobra.Command { } if !tlsConfig.DisableTLS && tlsConfig.StrictValidation { pool, err := tls.LoadX509CertPool( - env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)+"/reposerver/tls/tls.crt", - env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)+"/reposerver/tls/ca.crt", + fmt.Sprintf("%s/reposerver/tls/tls.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), + fmt.Sprintf("%s/reposerver/tls/ca.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), ) if err != nil { log.Fatalf("Failed to load tls certs: %v", err) diff --git a/cmd/argocd/commands/admin/project.go b/cmd/argocd/commands/admin/project.go index 9381ed4ad2..3570afbb1a 100644 --- a/cmd/argocd/commands/admin/project.go +++ b/cmd/argocd/commands/admin/project.go @@ -2,24 +2,23 @@ package admin import ( "context" - stderrors "errors" "fmt" "os" "path/filepath" "strings" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - appclient "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/templates" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + appclient "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/templates" "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/spf13/cobra" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/clientcmd" ) @@ -66,7 +65,7 @@ func NewGenProjectSpecCommand() *cobra.Command { out, closer, err := getOutWriter(inline, fileURL) errors.CheckError(err) - defer utilio.Close(closer) + defer io.Close(closer) errors.CheckError(PrintResources(outputFormat, out, proj)) }, @@ -97,16 +96,16 @@ func getModification(modification string, resource string, scope string, permiss switch modification { case "set": if scope == "" { - return nil, stderrors.New("flag --group cannot be empty if permission should be set in role") + return nil, fmt.Errorf("Flag --group cannot be empty if permission should be set in role") } if permission == "" { - return nil, stderrors.New("flag --permission cannot be empty if permission should be set in role") + return nil, fmt.Errorf("Flag --permission cannot be empty if permission should be set in role") } return func(proj string, action string) string { return fmt.Sprintf("%s, %s, %s/%s, %s", resource, action, proj, scope, permission) }, nil case "remove": - return func(_ string, _ string) string { + return func(proj string, action string) string { return "" }, nil } @@ -123,7 +122,7 @@ func saveProject(ctx context.Context, updated v1alpha1.AppProject, orig v1alpha1 } _ = cli.PrintDiff(updated.Name, target, live) if !dryRun { - _, err = projectsIf.Update(ctx, &updated, metav1.UpdateOptions{}) + _, err = projectsIf.Update(ctx, &updated, v1.UpdateOptions{}) if err != nil { return fmt.Errorf("error while updating project: %w", err) } @@ -199,7 +198,7 @@ func NewUpdatePolicyRuleCommand() *cobra.Command { } func updateProjects(ctx context.Context, projIf appclient.AppProjectInterface, projectGlob string, rolePattern string, action string, modification func(string, string) string, dryRun bool) error { - projects, err := projIf.List(ctx, metav1.ListOptions{}) + projects, err := projIf.List(ctx, v1.ListOptions{}) if err != nil { return fmt.Errorf("error listing the projects: %w", err) } @@ -223,14 +222,13 @@ func updateProjects(ctx context.Context, projIf appclient.AppProjectInterface, p break } policyPermission := modification(proj.Name, action) - switch { - case actionPolicyIndex == -1 && policyPermission != "": + if actionPolicyIndex == -1 && policyPermission != "" { updated = true role.Policies = append(role.Policies, formatPolicy(proj.Name, role.Name, policyPermission)) - case actionPolicyIndex > -1 && policyPermission == "": + } else if actionPolicyIndex > -1 && policyPermission == "" { updated = true role.Policies = append(role.Policies[:actionPolicyIndex], role.Policies[actionPolicyIndex+1:]...) - case actionPolicyIndex > -1 && policyPermission != "": + } else if actionPolicyIndex > -1 && policyPermission != "" { updated = true role.Policies[actionPolicyIndex] = formatPolicy(proj.Name, role.Name, policyPermission) } diff --git a/cmd/argocd/commands/admin/project_allowlist.go b/cmd/argocd/commands/admin/project_allowlist.go index 7caca31d92..9f436f2f3a 100644 --- a/cmd/argocd/commands/admin/project_allowlist.go +++ b/cmd/argocd/commands/admin/project_allowlist.go @@ -17,10 +17,10 @@ import ( "k8s.io/client-go/tools/clientcmd" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/util/errors" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/cli" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cli" // load the gcp plugin (required to authenticate against GKE clusters). _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" @@ -29,7 +29,7 @@ import ( // load the azure plugin (required to authenticate with AKS clusters). _ "k8s.io/client-go/plugin/pkg/client/auth/azure" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) // NewProjectAllowListGenCommand generates a project from clusterRole @@ -136,17 +136,17 @@ func generateProjectAllowList(serverResources []*metav1.APIResourceList, cluster continue } - ruleAPIGroup := rule.APIGroups[0] + ruleApiGroup := rule.APIGroups[0] for _, ruleResource := range rule.Resources { for _, apiResourcesList := range serverResources { gv, err := schema.ParseGroupVersion(apiResourcesList.GroupVersion) if err != nil { gv = schema.GroupVersion{} } - if ruleAPIGroup == gv.Group { + if ruleApiGroup == gv.Group { for _, apiResource := range apiResourcesList.APIResources { if apiResource.Name == ruleResource { - resourceList = append(resourceList, metav1.GroupKind{Group: ruleAPIGroup, Kind: apiResource.Kind}) + resourceList = append(resourceList, metav1.GroupKind{Group: ruleApiGroup, Kind: apiResource.Kind}) } } } diff --git a/cmd/argocd/commands/admin/project_test.go b/cmd/argocd/commands/admin/project_test.go index 3e0b7c10e9..341cd48f5c 100644 --- a/cmd/argocd/commands/admin/project_test.go +++ b/cmd/argocd/commands/admin/project_test.go @@ -1,14 +1,15 @@ package admin import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" ) const ( @@ -20,7 +21,7 @@ func newProj(name string, roleNames ...string) *v1alpha1.AppProject { for i := range roleNames { roles = append(roles, v1alpha1.ProjectRole{Name: roleNames[i]}) } - return &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{ + return &v1alpha1.AppProject{ObjectMeta: v1.ObjectMeta{ Name: name, Namespace: namespace, }, Spec: v1alpha1.AppProjectSpec{ @@ -29,7 +30,7 @@ func newProj(name string, roleNames ...string) *v1alpha1.AppProject { } func TestUpdateProjects_FindMatchingProject(t *testing.T) { - ctx := t.Context() + ctx := context.Background() clientset := fake.NewSimpleClientset(newProj("foo", "test"), newProj("bar", "test")) @@ -38,17 +39,17 @@ func TestUpdateProjects_FindMatchingProject(t *testing.T) { err = updateProjects(ctx, clientset.ArgoprojV1alpha1().AppProjects(namespace), "ba*", "*", "set", modification, false) require.NoError(t, err) - fooProj, err := clientset.ArgoprojV1alpha1().AppProjects(namespace).Get(ctx, "foo", metav1.GetOptions{}) + fooProj, err := clientset.ArgoprojV1alpha1().AppProjects(namespace).Get(ctx, "foo", v1.GetOptions{}) require.NoError(t, err) assert.Empty(t, fooProj.Spec.Roles[0].Policies) - barProj, err := clientset.ArgoprojV1alpha1().AppProjects(namespace).Get(ctx, "bar", metav1.GetOptions{}) + barProj, err := clientset.ArgoprojV1alpha1().AppProjects(namespace).Get(ctx, "bar", v1.GetOptions{}) require.NoError(t, err) - assert.Equal(t, []string{"p, proj:bar:test, *, set, bar/*, allow"}, barProj.Spec.Roles[0].Policies) + assert.EqualValues(t, []string{"p, proj:bar:test, *, set, bar/*, allow"}, barProj.Spec.Roles[0].Policies) } func TestUpdateProjects_FindMatchingRole(t *testing.T) { - ctx := t.Context() + ctx := context.Background() clientset := fake.NewSimpleClientset(newProj("proj", "foo", "bar")) @@ -57,9 +58,9 @@ func TestUpdateProjects_FindMatchingRole(t *testing.T) { err = updateProjects(ctx, clientset.ArgoprojV1alpha1().AppProjects(namespace), "*", "fo*", "set", modification, false) require.NoError(t, err) - proj, err := clientset.ArgoprojV1alpha1().AppProjects(namespace).Get(ctx, "proj", metav1.GetOptions{}) + proj, err := clientset.ArgoprojV1alpha1().AppProjects(namespace).Get(ctx, "proj", v1.GetOptions{}) require.NoError(t, err) - assert.Equal(t, []string{"p, proj:proj:foo, *, set, proj/*, allow"}, proj.Spec.Roles[0].Policies) + assert.EqualValues(t, []string{"p, proj:proj:foo, *, set, proj/*, allow"}, proj.Spec.Roles[0].Policies) assert.Empty(t, proj.Spec.Roles[1].Policies) } @@ -74,7 +75,7 @@ func TestGetModification_RemovePolicy(t *testing.T) { modification, err := getModification("remove", "*", "*", "allow") require.NoError(t, err) policy := modification("proj", "myaction") - assert.Empty(t, policy) + assert.Equal(t, "", policy) } func TestGetModification_NotSupported(t *testing.T) { diff --git a/cmd/argocd/commands/admin/redis_initial_password.go b/cmd/argocd/commands/admin/redis_initial_password.go index 96c29017c7..f54741773f 100644 --- a/cmd/argocd/commands/admin/redis_initial_password.go +++ b/cmd/argocd/commands/admin/redis_initial_password.go @@ -8,15 +8,16 @@ import ( "github.com/spf13/cobra" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/errors" ) func generateRandomPassword() (string, error) { @@ -40,7 +41,7 @@ func NewRedisInitialPasswordCommand() *cobra.Command { command := cobra.Command{ Use: "redis-initial-password", Short: "Ensure the Redis password exists, creating a new one if necessary.", - Run: func(_ *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { namespace, _, err := clientConfig.Namespace() errors.CheckError(err) @@ -74,18 +75,19 @@ func NewRedisInitialPasswordCommand() *cobra.Command { Type: corev1.SecretTypeOpaque, } _, err = kubeClientset.CoreV1().Secrets(namespace).Create(context.Background(), secret, metav1.CreateOptions{}) - if err != nil && !apierrors.IsAlreadyExists(err) { + if err != nil && !apierr.IsAlreadyExists(err) { errors.CheckError(err) } fmt.Printf("Argo CD Redis secret state confirmed: secret name %s.\n", redisInitialCredentials) - secret, err = kubeClientset.CoreV1().Secrets(namespace).Get(context.Background(), redisInitialCredentials, metav1.GetOptions{}) + secret, err = kubeClientset.CoreV1().Secrets(namespace).Get(context.Background(), redisInitialCredentials, v1.GetOptions{}) errors.CheckError(err) if _, ok := secret.Data[redisInitialCredentialsKey]; ok { fmt.Println("Password secret is configured properly.") } else { - errors.Fatal(errors.ErrorGeneric, fmt.Sprintf("key %s doesn't exist in secret %s. \n", redisInitialCredentialsKey, redisInitialCredentials)) + err := fmt.Errorf("key %s doesn't exist in secret %s. \n", redisInitialCredentialsKey, redisInitialCredentials) + errors.CheckError(err) } }, } diff --git a/cmd/argocd/commands/admin/repo.go b/cmd/argocd/commands/admin/repo.go index e3e00368a2..84933ab0c0 100644 --- a/cmd/argocd/commands/admin/repo.go +++ b/cmd/argocd/commands/admin/repo.go @@ -1,22 +1,22 @@ package admin import ( - stderrors "errors" + "fmt" "os" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/git" - "github.com/argoproj/argo-cd/v3/util/settings" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( @@ -54,9 +54,6 @@ func NewGenRepoSpecCommand() *cobra.Command { # Add a private Git repository via HTTPS using username/password and TLS client certificates: argocd admin repo generate-spec https://git.example.com/repos/repo --username git --password secret --tls-client-cert-path ~/mycert.crt --tls-client-cert-key-path ~/mycert.key - # Add a private Git BitBucket Data Center repository via HTTPS using bearer token: - argocd admin repo generate-spec https://bitbucket.example.com/scm/proj/repo --bearer-token secret-token - # Add a private Git repository via HTTPS using username/password without verifying the server's TLS certificate argocd admin repo generate-spec https://git.example.com/repos/repo --username git --password secret --insecure-skip-server-verification @@ -95,7 +92,7 @@ func NewGenRepoSpecCommand() *cobra.Command { } repoOpts.Repo.SSHPrivateKey = string(keyData) } else { - err := stderrors.New("--ssh-private-key-path is only supported for SSH repositories") + err := fmt.Errorf("--ssh-private-key-path is only supported for SSH repositories") errors.CheckError(err) } } @@ -103,7 +100,7 @@ func NewGenRepoSpecCommand() *cobra.Command { // tls-client-cert-path and tls-client-cert-key-key-path must always be // specified together if (repoOpts.TlsClientCertPath != "" && repoOpts.TlsClientCertKeyPath == "") || (repoOpts.TlsClientCertPath == "" && repoOpts.TlsClientCertKeyPath != "") { - err := stderrors.New("--tls-client-cert-path and --tls-client-cert-key-path must be specified together") + err := fmt.Errorf("--tls-client-cert-path and --tls-client-cert-key-path must be specified together") errors.CheckError(err) } @@ -117,7 +114,7 @@ func NewGenRepoSpecCommand() *cobra.Command { repoOpts.Repo.TLSClientCertData = string(tlsCertData) repoOpts.Repo.TLSClientCertKey = string(tlsCertKey) } else { - err := stderrors.New("--tls-client-cert-path is only supported for HTTPS repositories") + err := fmt.Errorf("--tls-client-cert-path is only supported for HTTPS repositories") errors.CheckError(err) } } @@ -129,10 +126,9 @@ func NewGenRepoSpecCommand() *cobra.Command { repoOpts.Repo.Insecure = repoOpts.InsecureSkipServerVerification repoOpts.Repo.EnableLFS = repoOpts.EnableLfs repoOpts.Repo.EnableOCI = repoOpts.EnableOci - repoOpts.Repo.UseAzureWorkloadIdentity = repoOpts.UseAzureWorkloadIdentity if repoOpts.Repo.Type == "helm" && repoOpts.Repo.Name == "" { - errors.CheckError(stderrors.New("must specify --name for repos of type 'helm'")) + errors.CheckError(fmt.Errorf("must specify --name for repos of type 'helm'")) } // If the user set a username, but didn't supply password via --password, @@ -141,19 +137,12 @@ func NewGenRepoSpecCommand() *cobra.Command { repoOpts.Repo.Password = cli.PromptPassword(repoOpts.Repo.Password) } - err := cmdutil.ValidateBearerTokenAndPasswordCombo(repoOpts.Repo.BearerToken, repoOpts.Repo.Password) - errors.CheckError(err) - err = cmdutil.ValidateBearerTokenForHTTPSRepoOnly(repoOpts.Repo.BearerToken, git.IsHTTPSURL(repoOpts.Repo.Repo)) - errors.CheckError(err) - err = cmdutil.ValidateBearerTokenForGitOnly(repoOpts.Repo.BearerToken, repoOpts.Repo.Type) - errors.CheckError(err) - - argoCDCM := &corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ + argoCDCM := &apiv1.ConfigMap{ + TypeMeta: v1.TypeMeta{ Kind: "ConfigMap", APIVersion: "v1", }, - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: ArgoCDNamespace, Labels: map[string]string{ @@ -165,10 +154,10 @@ func NewGenRepoSpecCommand() *cobra.Command { settingsMgr := settings.NewSettingsManager(ctx, kubeClientset, ArgoCDNamespace) argoDB := db.NewDB(ArgoCDNamespace, settingsMgr, kubeClientset) - _, err = argoDB.CreateRepository(ctx, &repoOpts.Repo) + _, err := argoDB.CreateRepository(ctx, &repoOpts.Repo) errors.CheckError(err) - secret, err := kubeClientset.CoreV1().Secrets(ArgoCDNamespace).Get(ctx, db.RepoURLToSecretName(repoSecretPrefix, repoOpts.Repo.Repo, repoOpts.Repo.Project), metav1.GetOptions{}) + secret, err := kubeClientset.CoreV1().Secrets(ArgoCDNamespace).Get(ctx, db.RepoURLToSecretName(repoSecretPrefix, repoOpts.Repo.Repo, repoOpts.Repo.Project), v1.GetOptions{}) errors.CheckError(err) errors.CheckError(PrintResources(outputFormat, os.Stdout, secret)) diff --git a/cmd/argocd/commands/admin/settings.go b/cmd/argocd/commands/admin/settings.go index a239de54b0..85baf9bfd1 100644 --- a/cmd/argocd/commands/admin/settings.go +++ b/cmd/argocd/commands/admin/settings.go @@ -3,7 +3,6 @@ package admin import ( "bytes" "context" - stderrors "errors" "fmt" "os" "reflect" @@ -16,21 +15,20 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/tools/clientcmd" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/common" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/lua" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/lua" + "github.com/argoproj/argo-cd/v2/util/settings" ) type settingsOpts struct { @@ -53,7 +51,7 @@ func collectLogs(callback func()) string { return out.String() } -func setSettingsMeta(obj metav1.Object) { +func setSettingsMeta(obj v1.Object) { obj.SetNamespace("default") labels := obj.GetLabels() if labels == nil { @@ -65,20 +63,19 @@ func setSettingsMeta(obj metav1.Object) { func (opts *settingsOpts) createSettingsManager(ctx context.Context) (*settings.SettingsManager, error) { var argocdCM *corev1.ConfigMap - switch { - case opts.argocdCMPath == "" && !opts.loadClusterSettings: - return nil, stderrors.New("either --argocd-cm-path must be provided or --load-cluster-settings must be set to true") - case opts.argocdCMPath == "": + if opts.argocdCMPath == "" && !opts.loadClusterSettings { + return nil, fmt.Errorf("either --argocd-cm-path must be provided or --load-cluster-settings must be set to true") + } else if opts.argocdCMPath == "" { realClientset, ns, err := opts.getK8sClient() if err != nil { return nil, err } - argocdCM, err = realClientset.CoreV1().ConfigMaps(ns).Get(ctx, common.ArgoCDConfigMapName, metav1.GetOptions{}) + argocdCM, err = realClientset.CoreV1().ConfigMaps(ns).Get(ctx, common.ArgoCDConfigMapName, v1.GetOptions{}) if err != nil { return nil, err } - default: + } else { data, err := os.ReadFile(opts.argocdCMPath) if err != nil { return nil, err @@ -91,8 +88,7 @@ func (opts *settingsOpts) createSettingsManager(ctx context.Context) (*settings. setSettingsMeta(argocdCM) var argocdSecret *corev1.Secret - switch { - case opts.argocdSecretPath != "": + if opts.argocdSecretPath != "" { data, err := os.ReadFile(opts.argocdSecretPath) if err != nil { return nil, err @@ -102,18 +98,18 @@ func (opts *settingsOpts) createSettingsManager(ctx context.Context) (*settings. return nil, err } setSettingsMeta(argocdSecret) - case opts.loadClusterSettings: + } else if opts.loadClusterSettings { realClientset, ns, err := opts.getK8sClient() if err != nil { return nil, err } - argocdSecret, err = realClientset.CoreV1().Secrets(ns).Get(ctx, common.ArgoCDSecretName, metav1.GetOptions{}) + argocdSecret, err = realClientset.CoreV1().Secrets(ns).Get(ctx, common.ArgoCDSecretName, v1.GetOptions{}) if err != nil { return nil, err } - default: + } else { argocdSecret = &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: common.ArgoCDSecretName, }, Data: map[string][]byte{ @@ -163,7 +159,7 @@ func NewSettingsCommand() *cobra.Command { command.AddCommand(NewValidateSettingsCommand(&opts)) command.AddCommand(NewResourceOverridesCommand(&opts)) - command.AddCommand(NewRBACCommand()) + command.AddCommand(NewRBACCommand(&opts)) opts.clientConfig = cli.AddKubectlFlagsToCmd(command) command.PersistentFlags().StringVar(&opts.argocdCMPath, "argocd-cm-path", "", "Path to local argocd-cm.yaml file") @@ -215,7 +211,7 @@ var validatorsByGroup = map[string]settingValidator{ } var summary string if ssoProvider != "" { - summary = ssoProvider + " is configured" + summary = fmt.Sprintf("%s is configured", ssoProvider) if general.URL == "" { summary = summary + " ('url' field is missing)" } @@ -248,6 +244,19 @@ var validatorsByGroup = map[string]settingValidator{ } return summary, err }, + "repositories": joinValidators(func(manager *settings.SettingsManager) (string, error) { + repos, err := manager.GetRepositories() + if err != nil { + return "", err + } + return fmt.Sprintf("%d repositories", len(repos)), nil + }, func(manager *settings.SettingsManager) (string, error) { + creds, err := manager.GetRepositoryCredentials() + if err != nil { + return "", err + } + return fmt.Sprintf("%d repository credentials", len(creds)), nil + }), "accounts": func(manager *settings.SettingsManager) (string, error) { accounts, err := manager.GetAccounts() if err != nil { @@ -285,7 +294,7 @@ argocd admin settings validate --argocd-cm-path ./argocd-cm.yaml #Validates accounts and plugins settings in Kubernetes cluster of current kubeconfig context argocd admin settings validate --group accounts --group plugins --load-cluster-settings`, - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() settingsManager, err := cmdCtx.createSettingsManager(ctx) @@ -501,15 +510,15 @@ argocd admin settings resource-overrides health ./deploy.yaml --argocd-cm-path . os.Exit(1) } - executeResourceOverrideCommand(ctx, cmdCtx, args, func(res unstructured.Unstructured, _ v1alpha1.ResourceOverride, overrides map[string]v1alpha1.ResourceOverride) { + executeResourceOverrideCommand(ctx, cmdCtx, args, func(res unstructured.Unstructured, override v1alpha1.ResourceOverride, overrides map[string]v1alpha1.ResourceOverride) { gvk := res.GroupVersionKind() resHealth, err := healthutil.GetResourceHealth(&res, lua.ResourceHealthOverrides(overrides)) - switch { - case err != nil: + + if err != nil { errors.CheckError(err) - case resHealth == nil: + } else if resHealth == nil { fmt.Printf("Health script is not configured for '%s/%s'\n", gvk.Group, gvk.Kind) - default: + } else { _, _ = fmt.Printf("STATUS: %s\n", resHealth.Status) _, _ = fmt.Printf("MESSAGE: %s\n", resHealth.Message) } @@ -564,8 +573,6 @@ argocd admin settings resource-overrides action list /tmp/deploy.yaml --argocd-c } func NewResourceActionRunCommand(cmdCtx commandContext) *cobra.Command { - var resourceActionParameters []string - command := &cobra.Command{ Use: "run-action RESOURCE_YAML_PATH ACTION", Aliases: []string{"action"}, @@ -582,23 +589,6 @@ argocd admin settings resource-overrides action /tmp/deploy.yaml restart --argoc } action := args[1] - // Parse resource action parameters - parsedParams := make([]*applicationpkg.ResourceActionParameters, 0) - if len(resourceActionParameters) > 0 { - for _, param := range resourceActionParameters { - parts := strings.SplitN(param, "=", 2) - if len(parts) != 2 { - log.Fatalf("Invalid parameter format: %s", param) - } - name := parts[0] - value := parts[1] - parsedParams = append(parsedParams, &applicationpkg.ResourceActionParameters{ - Name: &name, - Value: &value, - }) - } - } - executeResourceOverrideCommand(ctx, cmdCtx, args, func(res unstructured.Unstructured, override v1alpha1.ResourceOverride, overrides map[string]v1alpha1.ResourceOverride) { gvk := res.GroupVersionKind() if override.Actions == "" { @@ -610,7 +600,7 @@ argocd admin settings resource-overrides action /tmp/deploy.yaml restart --argoc action, err := luaVM.GetResourceAction(&res, action) errors.CheckError(err) - modifiedRes, err := luaVM.ExecuteResourceAction(&res, action.ActionLua, parsedParams) + modifiedRes, err := luaVM.ExecuteResourceAction(&res, action.ActionLua) errors.CheckError(err) for _, impactedResource := range modifiedRes { @@ -635,7 +625,5 @@ argocd admin settings resource-overrides action /tmp/deploy.yaml restart --argoc }) }, } - - command.Flags().StringArrayVar(&resourceActionParameters, "param", []string{}, "Action parameters (e.g. --param key1=value1)") return command } diff --git a/cmd/argocd/commands/admin/settings_rbac.go b/cmd/argocd/commands/admin/settings_rbac.go index e9469a61e6..66fad77b23 100644 --- a/cmd/argocd/commands/admin/settings_rbac.go +++ b/cmd/argocd/commands/admin/settings_rbac.go @@ -14,10 +14,11 @@ import ( "k8s.io/client-go/tools/clientcmd" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/assets" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/rbac" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/assets" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/rbac" ) type actionTraitMap map[string]rbacTrait @@ -108,7 +109,7 @@ var extensionActions = actionTraitMap{ } // NewRBACCommand is the command for 'rbac' -func NewRBACCommand() *cobra.Command { +func NewRBACCommand(cmdCtx commandContext) *cobra.Command { command := &cobra.Command{ Use: "rbac", Short: "Validate and test RBAC configuration", @@ -116,13 +117,13 @@ func NewRBACCommand() *cobra.Command { c.HelpFunc()(c, args) }, } - command.AddCommand(NewRBACCanCommand()) + command.AddCommand(NewRBACCanCommand(cmdCtx)) command.AddCommand(NewRBACValidateCommand()) return command } // NewRBACCanCommand is the command for 'rbac can' -func NewRBACCanCommand() *cobra.Command { +func NewRBACCanCommand(cmdCtx commandContext) *cobra.Command { var ( policyFile string defaultRole string @@ -208,7 +209,30 @@ argocd admin settings rbac can someuser create application 'default/app' --defau defaultRole = newDefaultRole } - res := checkPolicy(subject, action, resource, subResource, builtinPolicy, userPolicy, defaultRole, matchMode, strict) + // Logs RBAC will be enforced only if an internal var serverRBACLogEnforceEnable + // (representing server.rbac.log.enforce.enable env var in argocd-cm) + // is defined and has a "true" value + // Otherwise, no RBAC enforcement for logs will take place (meaning, 'can' request on a logs resource will result in "yes", + // even if there is no explicit RBAC allow, or if there is an explicit RBAC deny) + var isLogRbacEnforced func() bool + if nsOverride && policyFile == "" { + if resolveRBACResourceName(resource) == rbac.ResourceLogs { + isLogRbacEnforced = func() bool { + if opts, ok := cmdCtx.(*settingsOpts); ok { + opts.loadClusterSettings = true + opts.clientConfig = clientConfig + settingsMgr, err := opts.createSettingsManager(ctx) + errors.CheckError(err) + logEnforceEnable, err := settingsMgr.GetServerRBACLogEnforceEnable() + errors.CheckError(err) + return logEnforceEnable + } + return false + } + } + } + res := checkPolicy(subject, action, resource, subResource, builtinPolicy, userPolicy, defaultRole, matchMode, strict, isLogRbacEnforced) + if res { if !quiet { fmt.Println("Yes") @@ -374,7 +398,7 @@ func getPolicyConfigMap(ctx context.Context, client kubernetes.Interface, namesp // checkPolicy checks whether given subject is allowed to execute specified // action against specified resource -func checkPolicy(subject, action, resource, subResource, builtinPolicy, userPolicy, defaultRole, matchMode string, strict bool) bool { +func checkPolicy(subject, action, resource, subResource, builtinPolicy, userPolicy, defaultRole, matchMode string, strict bool, isLogRbacEnforced func() bool) bool { enf := rbac.NewEnforcer(nil, "argocd", "argocd-rbac-cm", nil) enf.SetDefaultRole(defaultRole) enf.SetMatchMode(matchMode) @@ -416,6 +440,11 @@ func checkPolicy(subject, action, resource, subResource, builtinPolicy, userPoli subResource = "*/*" } } + if realResource == rbac.ResourceLogs { + if isLogRbacEnforced != nil && !isLogRbacEnforced() { + return true + } + } return enf.Enforce(subject, realResource, action, subResource) } diff --git a/cmd/argocd/commands/admin/settings_rbac_test.go b/cmd/argocd/commands/admin/settings_rbac_test.go index 8b905a11ff..52a6deb2bf 100644 --- a/cmd/argocd/commands/admin/settings_rbac_test.go +++ b/cmd/argocd/commands/admin/settings_rbac_test.go @@ -1,6 +1,7 @@ package admin import ( + "context" "os" "testing" @@ -13,9 +14,9 @@ import ( "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "github.com/argoproj/argo-cd/v3/util/rbac" + "github.com/argoproj/argo-cd/v2/util/rbac" - "github.com/argoproj/argo-cd/v3/util/assets" + "github.com/argoproj/argo-cd/v2/util/assets" ) type FakeClientConfig struct { @@ -115,7 +116,7 @@ func Test_validateRBACResourceAction(t *testing.T) { } func Test_PolicyFromCSV(t *testing.T) { - ctx := t.Context() + ctx := context.Background() uPol, dRole, matchMode := getPolicy(ctx, "testdata/rbac/policy.csv", nil, "") require.NotEmpty(t, uPol) @@ -124,19 +125,27 @@ func Test_PolicyFromCSV(t *testing.T) { } func Test_PolicyFromYAML(t *testing.T) { - ctx := t.Context() + ctx := context.Background() uPol, dRole, matchMode := getPolicy(ctx, "testdata/rbac/argocd-rbac-cm.yaml", nil, "") require.NotEmpty(t, uPol) require.Equal(t, "role:unknown", dRole) require.Empty(t, matchMode) require.True(t, checkPolicy("my-org:team-qa", "update", "project", "foo", - "", uPol, dRole, matchMode, true)) + "", uPol, dRole, matchMode, true, nil)) +} + +func trueLogRbacEnforce() bool { + return true +} + +func falseLogRbacEnforce() bool { + return false } func Test_PolicyFromK8s(t *testing.T) { data, err := os.ReadFile("testdata/rbac/policy.csv") - ctx := t.Context() + ctx := context.Background() require.NoError(t, err) kubeclientset := fake.NewClientset(&corev1.ConfigMap{ @@ -152,72 +161,114 @@ func Test_PolicyFromK8s(t *testing.T) { uPol, dRole, matchMode := getPolicy(ctx, "", kubeclientset, "argocd") require.NotEmpty(t, uPol) require.Equal(t, "role:unknown", dRole) - require.Empty(t, matchMode) + require.Equal(t, "", matchMode) t.Run("get applications", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "applications", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true) + ok := checkPolicy("role:user", "get", "applications", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, nil) require.True(t, ok) }) t.Run("get clusters", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "clusters", "*", assets.BuiltinPolicyCSV, uPol, dRole, "", true) + ok := checkPolicy("role:user", "get", "clusters", "*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, nil) require.True(t, ok) }) t.Run("get certificates", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "certificates", "*", assets.BuiltinPolicyCSV, uPol, dRole, "", true) + ok := checkPolicy("role:user", "get", "certificates", "*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, nil) require.False(t, ok) }) t.Run("get certificates by default role", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "certificates", "*", assets.BuiltinPolicyCSV, uPol, "role:readonly", "glob", true) + ok := checkPolicy("role:user", "get", "certificates", "*", assets.BuiltinPolicyCSV, uPol, "role:readonly", "glob", true, nil) require.True(t, ok) }) t.Run("get certificates by default role without builtin policy", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "certificates", "*", "", uPol, "role:readonly", "glob", true) + ok := checkPolicy("role:user", "get", "certificates", "*", "", uPol, "role:readonly", "glob", true, nil) require.False(t, ok) }) t.Run("use regex match mode instead of glob", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "certificates", ".*", assets.BuiltinPolicyCSV, uPol, "role:readonly", "regex", true) + ok := checkPolicy("role:user", "get", "certificates", ".*", assets.BuiltinPolicyCSV, uPol, "role:readonly", "regex", true, nil) require.False(t, ok) }) t.Run("get logs", func(t *testing.T) { - ok := checkPolicy("role:test", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true) + ok := checkPolicy("role:test", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, nil) require.True(t, ok) }) + // no function is provided to check if logs rbac is enforced or not, so the policy permissions are queried to determine if no-such-user can get logs t.Run("no-such-user get logs", func(t *testing.T) { - ok := checkPolicy("no-such-user", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true) + ok := checkPolicy("no-such-user", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, nil) require.False(t, ok) }) + // logs rbac policy is enforced, and no-such-user is not granted logs permission in user policy, so the result should be false (cannot get logs) + t.Run("no-such-user get logs rbac enforced", func(t *testing.T) { + ok := checkPolicy("no-such-user", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, trueLogRbacEnforce) + require.False(t, ok) + }) + // no-such-user is not granted logs permission in user policy, but logs rbac policy is not enforced, so logs permission is open to all + t.Run("no-such-user get logs rbac not enforced", func(t *testing.T) { + ok := checkPolicy("no-such-user", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, falseLogRbacEnforce) + require.True(t, ok) + }) + // no function is provided to check if logs rbac is enforced or not, so the policy permissions are queried to determine if log-deny-user can get logs t.Run("log-deny-user get logs", func(t *testing.T) { - ok := checkPolicy("log-deny-user", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true) + ok := checkPolicy("log-deny-user", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, nil) require.False(t, ok) }) + // logs rbac policy is enforced, and log-deny-user is denied logs permission in user policy, so the result should be false (cannot get logs) + t.Run("log-deny-user get logs rbac enforced", func(t *testing.T) { + ok := checkPolicy("log-deny-user", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, trueLogRbacEnforce) + require.False(t, ok) + }) + // log-deny-user is denied logs permission in user policy, but logs rbac policy is not enforced, so logs permission is open to all + t.Run("log-deny-user get logs rbac not enforced", func(t *testing.T) { + ok := checkPolicy("log-deny-user", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, falseLogRbacEnforce) + require.True(t, ok) + }) + // no function is provided to check if logs rbac is enforced or not, so the policy permissions are queried to determine if log-allow-user can get logs t.Run("log-allow-user get logs", func(t *testing.T) { - ok := checkPolicy("log-allow-user", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true) + ok := checkPolicy("log-allow-user", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, nil) + require.True(t, ok) + }) + // logs rbac policy is enforced, and log-allow-user is granted logs permission in user policy, so the result should be true (can get logs) + t.Run("log-allow-user get logs rbac enforced", func(t *testing.T) { + ok := checkPolicy("log-allow-user", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, trueLogRbacEnforce) + require.True(t, ok) + }) + // log-allow-user is granted logs permission in user policy, and logs rbac policy is not enforced, so logs permission is open to all + t.Run("log-allow-user get logs rbac not enforced", func(t *testing.T) { + ok := checkPolicy("log-allow-user", "get", "logs", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, falseLogRbacEnforce) require.True(t, ok) }) t.Run("get logs", func(t *testing.T) { - ok := checkPolicy("role:test", "get", "logs", "*", assets.BuiltinPolicyCSV, uPol, dRole, "", true) + ok := checkPolicy("role:test", "get", "logs", "*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, nil) require.True(t, ok) }) t.Run("get logs", func(t *testing.T) { - ok := checkPolicy("role:test", "get", "logs", "", assets.BuiltinPolicyCSV, uPol, dRole, "", true) + ok := checkPolicy("role:test", "get", "logs", "", assets.BuiltinPolicyCSV, uPol, dRole, "", true, nil) require.True(t, ok) }) t.Run("create exec", func(t *testing.T) { - ok := checkPolicy("role:test", "create", "exec", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true) + ok := checkPolicy("role:test", "create", "exec", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, nil) require.True(t, ok) }) t.Run("create applicationsets", func(t *testing.T) { - ok := checkPolicy("role:user", "create", "applicationsets", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true) + ok := checkPolicy("role:user", "create", "applicationsets", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, nil) + require.True(t, ok) + }) + // trueLogRbacEnforce or falseLogRbacEnforce should not affect non-logs resources + t.Run("create applicationsets with trueLogRbacEnforce", func(t *testing.T) { + ok := checkPolicy("role:user", "create", "applicationsets", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, trueLogRbacEnforce) + require.True(t, ok) + }) + t.Run("create applicationsets with falseLogRbacEnforce", func(t *testing.T) { + ok := checkPolicy("role:user", "create", "applicationsets", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, trueLogRbacEnforce) require.True(t, ok) }) t.Run("delete applicationsets", func(t *testing.T) { - ok := checkPolicy("role:user", "delete", "applicationsets", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true) + ok := checkPolicy("role:user", "delete", "applicationsets", "*/*", assets.BuiltinPolicyCSV, uPol, dRole, "", true, nil) require.True(t, ok) }) } func Test_PolicyFromK8sUsingRegex(t *testing.T) { - ctx := t.Context() + ctx := context.Background() policy := ` p, role:user, clusters, get, .+, allow @@ -251,49 +302,49 @@ p, role:readonly, certificates, get, .*, allow p, role:, certificates, get, .*, allow` t.Run("get applications", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "applications", ".*/.*", builtInPolicy, uPol, dRole, "regex", true) + ok := checkPolicy("role:user", "get", "applications", ".*/.*", builtInPolicy, uPol, dRole, "regex", true, nil) require.True(t, ok) }) t.Run("get clusters", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "clusters", ".*", builtInPolicy, uPol, dRole, "regex", true) + ok := checkPolicy("role:user", "get", "clusters", ".*", builtInPolicy, uPol, dRole, "regex", true, nil) require.True(t, ok) }) t.Run("get certificates", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "certificates", ".*", builtInPolicy, uPol, dRole, "regex", true) + ok := checkPolicy("role:user", "get", "certificates", ".*", builtInPolicy, uPol, dRole, "regex", true, nil) require.False(t, ok) }) t.Run("get certificates by default role", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "certificates", ".*", builtInPolicy, uPol, "role:readonly", "regex", true) + ok := checkPolicy("role:user", "get", "certificates", ".*", builtInPolicy, uPol, "role:readonly", "regex", true, nil) require.True(t, ok) }) t.Run("get certificates by default role without builtin policy", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "certificates", ".*", "", uPol, "role:readonly", "regex", true) + ok := checkPolicy("role:user", "get", "certificates", ".*", "", uPol, "role:readonly", "regex", true, nil) require.False(t, ok) }) t.Run("use glob match mode instead of regex", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "certificates", ".+", builtInPolicy, uPol, dRole, "glob", true) + ok := checkPolicy("role:user", "get", "certificates", ".+", builtInPolicy, uPol, dRole, "glob", true, nil) require.False(t, ok) }) t.Run("get logs via glob match mode", func(t *testing.T) { - ok := checkPolicy("role:user", "get", "logs", ".*/.*", builtInPolicy, uPol, dRole, "glob", true) + ok := checkPolicy("role:user", "get", "logs", ".*/.*", builtInPolicy, uPol, dRole, "glob", true, nil) require.True(t, ok) }) t.Run("create exec", func(t *testing.T) { - ok := checkPolicy("role:user", "create", "exec", ".*/.*", builtInPolicy, uPol, dRole, "regex", true) + ok := checkPolicy("role:user", "create", "exec", ".*/.*", builtInPolicy, uPol, dRole, "regex", true, nil) require.True(t, ok) }) t.Run("create applicationsets", func(t *testing.T) { - ok := checkPolicy("role:user", "create", "applicationsets", ".*/.*", builtInPolicy, uPol, dRole, "regex", true) + ok := checkPolicy("role:user", "create", "applicationsets", ".*/.*", builtInPolicy, uPol, dRole, "regex", true, nil) require.True(t, ok) }) t.Run("delete applicationsets", func(t *testing.T) { - ok := checkPolicy("role:user", "delete", "applicationsets", ".*/.*", builtInPolicy, uPol, dRole, "regex", true) + ok := checkPolicy("role:user", "delete", "applicationsets", ".*/.*", builtInPolicy, uPol, dRole, "regex", true, nil) require.True(t, ok) }) } func TestNewRBACCanCommand(t *testing.T) { - command := NewRBACCanCommand() + command := NewRBACCanCommand(&settingsOpts{}) require.NotNil(t, command) assert.Equal(t, "can", command.Name()) diff --git a/cmd/argocd/commands/admin/settings_test.go b/cmd/argocd/commands/admin/settings_test.go index 7418d61cb6..0b37b0bd32 100644 --- a/cmd/argocd/commands/admin/settings_test.go +++ b/cmd/argocd/commands/admin/settings_test.go @@ -1,18 +1,20 @@ package admin import ( + "bytes" "context" + "fmt" "io" "os" "testing" - "github.com/argoproj/argo-cd/v3/common" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + utils "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/settings" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" ) @@ -31,7 +33,7 @@ func captureStdout(callback func()) (string, error) { }() callback() - utilio.Close(w) + utils.Close(w) data, err := io.ReadAll(r) if err != nil { @@ -43,7 +45,7 @@ func captureStdout(callback func()) (string, error) { func newSettingsManager(data map[string]string) *settings.SettingsManager { ctx := context.Background() - clientset := fake.NewClientset(&corev1.ConfigMap{ + clientset := fake.NewClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: common.ArgoCDConfigMapName, @@ -52,7 +54,7 @@ func newSettingsManager(data map[string]string) *settings.SettingsManager { }, }, Data: data, - }, &corev1.Secret{ + }, &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: common.ArgoCDSecretName, @@ -67,6 +69,8 @@ func newSettingsManager(data map[string]string) *settings.SettingsManager { type fakeCmdContext struct { mgr *settings.SettingsManager + // nolint:unused + out bytes.Buffer } func newCmdContext(data map[string]string) *fakeCmdContext { @@ -85,7 +89,7 @@ type validatorTestCase struct { } func TestCreateSettingsManager(t *testing.T) { - ctx := t.Context() + ctx := context.Background() f, closer, err := tempFile(`apiVersion: v1 kind: ConfigMap @@ -94,7 +98,7 @@ metadata: data: url: https://myargocd.com`) require.NoError(t, err) - defer utilio.Close(closer) + defer utils.Close(closer) opts := settingsOpts{argocdCMPath: f} settingsManager, err := opts.createSettingsManager(ctx) @@ -154,6 +158,15 @@ clientSecret: aaaabbbbccccddddeee`, }, containsSummary: "updated-options", }, + "Repositories": { + validator: "repositories", + data: map[string]string{ + "repositories": ` +- url: https://github.com/argoproj/my-private-repository1 +- url: https://github.com/argoproj/my-private-repository2`, + }, + containsSummary: "2 repositories", + }, "Accounts": { validator: "accounts", data: map[string]string{ @@ -243,7 +256,7 @@ func tempFile(content string) (string, io.Closer, error) { panic(err) } }() - return f.Name(), utilio.NewCloser(func() error { + return f.Name(), utils.NewCloser(func() error { return os.Remove(f.Name()) }), nil } @@ -257,14 +270,14 @@ func TestValidateSettingsCommand_NoErrors(t *testing.T) { require.NoError(t, err) for k := range validatorsByGroup { - assert.Contains(t, out, "âś… "+k) + assert.Contains(t, out, fmt.Sprintf("âś… %s", k)) } } func TestResourceOverrideIgnoreDifferences(t *testing.T) { f, closer, err := tempFile(testDeploymentYAML) require.NoError(t, err) - defer utilio.Close(closer) + defer utils.Close(closer) t.Run("NoOverridesConfigured", func(t *testing.T) { cmd := NewResourceOverridesCommand(newCmdContext(map[string]string{})) @@ -297,7 +310,7 @@ func TestResourceOverrideIgnoreDifferences(t *testing.T) { func TestResourceOverrideHealth(t *testing.T) { f, closer, err := tempFile(testCustomResourceYAML) require.NoError(t, err) - defer utilio.Close(closer) + defer utils.Close(closer) t.Run("NoHealthAssessment", func(t *testing.T) { cmd := NewResourceOverridesCommand(newCmdContext(map[string]string{ @@ -348,11 +361,11 @@ func TestResourceOverrideHealth(t *testing.T) { func TestResourceOverrideAction(t *testing.T) { f, closer, err := tempFile(testDeploymentYAML) require.NoError(t, err) - defer utilio.Close(closer) + defer utils.Close(closer) cronJobFile, closer, err := tempFile(testCronJobYAML) require.NoError(t, err) - defer utilio.Close(closer) + defer utils.Close(closer) t.Run("NoActions", func(t *testing.T) { cmd := NewResourceOverridesCommand(newCmdContext(map[string]string{ diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index ed24152a62..3cfc5f13f1 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -3,7 +3,7 @@ package commands import ( "context" "encoding/json" - stderrors "errors" + std_errors "errors" "fmt" "io" "os" @@ -12,7 +12,6 @@ import ( "sort" "strconv" "strings" - "sync" "text/tabwriter" "time" "unicode/utf8" @@ -22,7 +21,7 @@ import ( "github.com/argoproj/gitops-engine/pkg/sync/hook" "github.com/argoproj/gitops-engine/pkg/sync/ignore" "github.com/argoproj/gitops-engine/pkg/utils/kube" - grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/retry" + grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry" "github.com/mattn/go-isatty" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -36,30 +35,30 @@ import ( "k8s.io/utils/ptr" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/controller" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - clusterpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster" - projectpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/project" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/settings" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - repoapiclient "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/reposerver/repository" - "github.com/argoproj/argo-cd/v3/util/argo" - argodiff "github.com/argoproj/argo-cd/v3/util/argo/diff" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/git" - "github.com/argoproj/argo-cd/v3/util/grpc" - utilio "github.com/argoproj/argo-cd/v3/util/io" - logutils "github.com/argoproj/argo-cd/v3/util/log" - "github.com/argoproj/argo-cd/v3/util/manifeststream" - "github.com/argoproj/argo-cd/v3/util/templates" - "github.com/argoproj/argo-cd/v3/util/text/label" + "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" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + clusterpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster" + projectpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/project" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/settings" + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + repoapiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/reposerver/repository" + "github.com/argoproj/argo-cd/v2/util/argo" + argodiff "github.com/argoproj/argo-cd/v2/util/argo/diff" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/grpc" + argoio "github.com/argoproj/argo-cd/v2/util/io" + logutils "github.com/argoproj/argo-cd/v2/util/log" + "github.com/argoproj/argo-cd/v2/util/manifeststream" + "github.com/argoproj/argo-cd/v2/util/templates" + "github.com/argoproj/argo-cd/v2/util/text/label" ) // NewApplicationCommand returns a new instance of an `argocd app` command @@ -144,7 +143,7 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. argocd app create nginx-ingress --repo https://charts.helm.sh/stable --helm-chart nginx-ingress --revision 1.24.3 --dest-namespace default --dest-server https://kubernetes.default.svc # Create a Kustomize app - argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image quay.io/argoprojlabs/argocd-e2e-container:0.1 + argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1 # Create a MultiSource app while yaml file contains an application with multiple sources argocd app create guestbook --file @@ -170,7 +169,7 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. app.Finalizers = append(app.Finalizers, "resources-finalizer.argocd.argoproj.io") } conn, appIf := argocdClient.NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) appCreateRequest := application.ApplicationCreateRequest{ Application: app, Upsert: &upsert, @@ -189,16 +188,15 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. errors.CheckError(err) var action string - switch { - case existing == nil: + if existing == nil { action = "created" - case !hasAppChanged(existing, created, upsert): + } else if !hasAppChanged(existing, created, upsert) { action = "unchanged" - default: + } else { action = "updated" } - fmt.Printf("application '%s' %s\n", created.Name, action) + fmt.Printf("application '%s' %s\n", created.ObjectMeta.Name, action) } }, } @@ -268,7 +266,7 @@ func hasAppChanged(appReq, appRes *argoappv1.Application, upsert bool) bool { if reflect.DeepEqual(appRes.Spec, appReq.Spec) && reflect.DeepEqual(appRes.Labels, appReq.Labels) && - reflect.DeepEqual(appRes.Annotations, appReq.Annotations) && + reflect.DeepEqual(appRes.ObjectMeta.Annotations, appReq.Annotations) && reflect.DeepEqual(appRes.Finalizers, appReq.Finalizers) { return false } @@ -276,8 +274,8 @@ func hasAppChanged(appReq, appRes *argoappv1.Application, upsert bool) bool { return true } -func parentChildDetails(ctx context.Context, appIf application.ApplicationServiceClient, appName string, appNs string) (map[string]argoappv1.ResourceNode, map[string][]string, map[string]struct{}) { - mapUIDToNode := make(map[string]argoappv1.ResourceNode) +func parentChildDetails(appIf application.ApplicationServiceClient, ctx context.Context, appName string, appNs string) (map[string]argoappv1.ResourceNode, map[string][]string, map[string]struct{}) { + mapUidToNode := make(map[string]argoappv1.ResourceNode) mapParentToChild := make(map[string][]string) parentNode := make(map[string]struct{}) @@ -285,7 +283,7 @@ func parentChildDetails(ctx context.Context, appIf application.ApplicationServic errors.CheckError(err) for _, node := range resourceTree.Nodes { - mapUIDToNode[node.UID] = node + mapUidToNode[node.UID] = node if len(node.ParentRefs) > 0 { _, ok := mapParentToChild[node.ParentRefs[0].UID] @@ -298,12 +296,12 @@ func parentChildDetails(ctx context.Context, appIf application.ApplicationServic parentNode[node.UID] = struct{}{} } } - return mapUIDToNode, mapParentToChild, parentNode + return mapUidToNode, mapParentToChild, parentNode } -func printHeader(ctx context.Context, acdClient argocdclient.Client, app *argoappv1.Application, windows *argoappv1.SyncWindows, showOperation bool, showParams bool, sourcePosition int) { - appURL := getAppURL(ctx, acdClient, app.Name) - printAppSummaryTable(app, appURL, windows) +func printHeader(acdClient argocdclient.Client, app *argoappv1.Application, ctx context.Context, windows *argoappv1.SyncWindows, showOperation bool, showParams bool, sourcePosition int) { + aURL := appURL(ctx, acdClient, app.Name) + printAppSummaryTable(app, aURL, windows) if len(app.Status.Conditions) > 0 { fmt.Println() @@ -338,7 +336,6 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com refresh bool hardRefresh bool output string - timeout uint showParams bool showOperation bool appNamespace string @@ -384,91 +381,49 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com `), Run: func(c *cobra.Command, args []string) { - ctx, cancel := context.WithCancel(c.Context()) - defer cancel() + ctx := c.Context() if len(args) == 0 { c.HelpFunc()(c, args) os.Exit(1) } acdClient := headless.NewClientOrDie(clientOpts, c) conn, appIf := acdClient.NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) - if timeout != 0 { - time.AfterFunc(time.Duration(timeout)*time.Second, func() { - if ctx.Err() != nil { - fmt.Println("Timeout function: context already cancelled:", ctx.Err()) - } else { - fmt.Println("Timeout function: cancelling context manually") - cancel() - } - }) - } - getAppStateWithRetry := func() (*argoappv1.Application, error) { - type getResponse struct { - app *argoappv1.Application - err error - } - - ch := make(chan getResponse, 1) - - go func() { - app, err := appIf.Get(ctx, &application.ApplicationQuery{ - Name: &appName, - Refresh: getRefreshType(refresh, hardRefresh), - AppNamespace: &appNs, - }) - ch <- getResponse{app: app, err: err} - }() - - select { - case result := <-ch: - return result.app, result.err - case <-ctx.Done(): - // Timeout occurred, try again without refresh flag - // Create new context for retry request - ctx := context.Background() - app, err := appIf.Get(ctx, &application.ApplicationQuery{ - Name: &appName, - AppNamespace: &appNs, - }) - return app, err - } - } - - app, err := getAppStateWithRetry() + app, err := appIf.Get(ctx, &application.ApplicationQuery{ + Name: &appName, + Refresh: getRefreshType(refresh, hardRefresh), + AppNamespace: &appNs, + }) errors.CheckError(err) - if ctx.Err() != nil { - ctx = context.Background() // Reset context for subsequent requests - } if sourceName != "" && sourcePosition != -1 { - errors.Fatal(errors.ErrorGeneric, "Only one of source-position and source-name can be specified.") + errors.CheckError(fmt.Errorf("Only one of source-position and source-name can be specified.")) } if sourceName != "" { sourceNameToPosition := getSourceNameToPositionMap(app) - pos, ok := sourceNameToPosition[sourceName] - if !ok { + if pos, ok := sourceNameToPosition[sourceName]; !ok { log.Fatalf("Unknown source name '%s'", sourceName) + } else { + sourcePosition = int(pos) } - sourcePosition = int(pos) } // check for source position if --show-params is set if app.Spec.HasMultipleSources() && showParams { if sourcePosition <= 0 { - errors.Fatal(errors.ErrorGeneric, "Source position should be specified and must be greater than 0 for applications with multiple sources") + errors.CheckError(fmt.Errorf("Source position should be specified and must be greater than 0 for applications with multiple sources")) } if len(app.Spec.GetSources()) < sourcePosition { - errors.Fatal(errors.ErrorGeneric, "Source position should be less than the number of sources in the application") + errors.CheckError(fmt.Errorf("Source position should be less than the number of sources in the application")) } } pConn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(pConn) + defer argoio.Close(pConn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: app.Spec.Project}) errors.CheckError(err) @@ -479,7 +434,7 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com err := PrintResource(app, output) errors.CheckError(err) case "wide", "": - printHeader(ctx, acdClient, app, windows, showOperation, showParams, sourcePosition) + printHeader(acdClient, app, ctx, windows, showOperation, showParams, sourcePosition) if len(app.Status.Resources) > 0 { fmt.Println() w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) @@ -487,18 +442,18 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com _ = w.Flush() } case "tree": - printHeader(ctx, acdClient, app, windows, showOperation, showParams, sourcePosition) - mapUIDToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appName, appNs) - if len(mapUIDToNode) > 0 { + printHeader(acdClient, app, ctx, windows, showOperation, showParams, sourcePosition) + mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appName, appNs) + if len(mapUidToNode) > 0 { fmt.Println() - printTreeView(mapUIDToNode, mapParentToChild, parentNode, mapNodeNameToResourceState) + printTreeView(mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState) } case "tree=detailed": - printHeader(ctx, acdClient, app, windows, showOperation, showParams, sourcePosition) - mapUIDToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appName, appNs) - if len(mapUIDToNode) > 0 { + printHeader(acdClient, app, ctx, windows, showOperation, showParams, sourcePosition) + mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appName, appNs) + if len(mapUidToNode) > 0 { fmt.Println() - printTreeViewDetailed(mapUIDToNode, mapParentToChild, parentNode, mapNodeNameToResourceState) + printTreeViewDetailed(mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState) } default: errors.CheckError(fmt.Errorf("unknown output format: %s", output)) @@ -506,7 +461,6 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com }, } command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide|tree") - command.Flags().UintVar(&timeout, "timeout", defaultCheckTimeoutSeconds, "Time out after this many seconds") command.Flags().BoolVar(&showOperation, "show-operation", false, "Show application operation") command.Flags().BoolVar(&showParams, "show-params", false, "Show application parameters and overrides") command.Flags().BoolVar(&refresh, "refresh", false, "Refresh application data when retrieving") @@ -531,7 +485,6 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co filter string container string previous bool - matchCase bool ) command := &cobra.Command{ Use: "logs APPNAME", @@ -567,9 +520,6 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co # Filter logs to show only those containing a specific string argocd app logs my-app --filter "error" - # Filter logs to show only those containing a specific string and match case - argocd app logs my-app --filter "error" --match-case - # Get logs for a specific container within the pods argocd app logs my-app -c my-container @@ -586,7 +536,7 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } acdClient := headless.NewClientOrDie(clientOpts, c) conn, appIf := acdClient.NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) appName, appNs := argo.ParseFromQualifiedName(args[0], "") retry := true @@ -603,7 +553,6 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co SinceSeconds: ptr.To(sinceSeconds), UntilTime: &untilTime, Filter: &filter, - MatchCase: ptr.To(matchCase), Container: ptr.To(container), Previous: ptr.To(previous), AppNamespace: &appNs, @@ -614,7 +563,7 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co for { msg, err := stream.Recv() if err != nil { - if stderrors.Is(err, io.EOF) { + if std_errors.Is(err, io.EOF) { return } st, ok := status.FromError(err) @@ -628,10 +577,11 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } log.Fatalf("stream read failed: %v", err) } - if msg.GetLast() { + if !msg.GetLast() { + fmt.Println(msg.GetContent()) + } else { return } - fmt.Println(msg.GetContent()) } // Done with receive message } // Done with retry }, @@ -648,7 +598,6 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co command.Flags().StringVar(&filter, "filter", "", "Show logs contain this string") command.Flags().StringVarP(&container, "container", "c", "", "Optional container name") command.Flags().BoolVarP(&previous, "previous", "p", false, "Specify if the previously terminated container logs should be returned") - command.Flags().BoolVarP(&matchCase, "match-case", "m", false, "Specify if the filter should be case-sensitive") return command } @@ -709,7 +658,7 @@ func printAppSummaryTable(app *argoappv1.Application, appURL string, windows *ar } var syncPolicy string - if app.Spec.SyncPolicy != nil && app.Spec.SyncPolicy.IsAutomatedSyncEnabled() { + if app.Spec.SyncPolicy != nil && app.Spec.SyncPolicy.Automated != nil { syncPolicy = "Automated" if app.Spec.SyncPolicy.Automated.Prune { syncPolicy += " (Prune)" @@ -721,15 +670,18 @@ func printAppSummaryTable(app *argoappv1.Application, appURL string, windows *ar syncStatusStr := string(app.Status.Sync.Status) switch app.Status.Sync.Status { case argoappv1.SyncStatusCodeSynced: - syncStatusStr += " to " + app.Spec.GetSource().TargetRevision + syncStatusStr += fmt.Sprintf(" to %s", app.Spec.GetSource().TargetRevision) case argoappv1.SyncStatusCodeOutOfSync: - syncStatusStr += " from " + app.Spec.GetSource().TargetRevision + syncStatusStr += fmt.Sprintf(" from %s", app.Spec.GetSource().TargetRevision) } if !git.IsCommitSHA(app.Spec.GetSource().TargetRevision) && !git.IsTruncatedCommitSHA(app.Spec.GetSource().TargetRevision) && len(app.Status.Sync.Revision) > 7 { syncStatusStr += fmt.Sprintf(" (%s)", app.Status.Sync.Revision[0:7]) } fmt.Printf(printOpFmtStr, "Sync Status:", syncStatusStr) healthStr := string(app.Status.Health.Status) + if app.Status.Health.Message != "" { + healthStr = fmt.Sprintf("%s (%s)", app.Status.Health.Status, app.Status.Health.Message) + } fmt.Printf(printOpFmtStr, "Health Status:", healthStr) } @@ -773,10 +725,10 @@ func appURLDefault(acdClient argocdclient.Client, appName string) string { return fmt.Sprintf("%s://%s/applications/%s", scheme, server, appName) } -// getAppURL returns the URL of an application -func getAppURL(ctx context.Context, acdClient argocdclient.Client, appName string) string { +// appURL returns the URL of an application +func appURL(ctx context.Context, acdClient argocdclient.Client, appName string) string { conn, settingsIf := acdClient.NewSettingsClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) argoSettings, err := settingsIf.Get(ctx, &settings.SettingsQuery{}) errors.CheckError(err) @@ -877,30 +829,30 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) argocdClient := headless.NewClientOrDie(clientOpts, c) conn, appIf := argocdClient.NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) errors.CheckError(err) sourceName = appOpts.SourceName if sourceName != "" && sourcePosition != -1 { - errors.Fatal(errors.ErrorGeneric, "Only one of source-position and source-name can be specified.") + errors.CheckError(fmt.Errorf("Only one of source-position and source-name can be specified.")) } if sourceName != "" { sourceNameToPosition := getSourceNameToPositionMap(app) - pos, ok := sourceNameToPosition[sourceName] - if !ok { + if pos, ok := sourceNameToPosition[sourceName]; !ok { log.Fatalf("Unknown source name '%s'", sourceName) + } else { + sourcePosition = int(pos) } - sourcePosition = int(pos) } if app.Spec.HasMultipleSources() { if sourcePosition <= 0 { - errors.Fatal(errors.ErrorGeneric, "Source position should be specified and must be greater than 0 for applications with multiple sources") + errors.CheckError(fmt.Errorf("Source position should be specified and must be greater than 0 for applications with multiple sources")) } if len(app.Spec.GetSources()) < sourcePosition { - errors.Fatal(errors.ErrorGeneric, "Source position should be less than the number of sources in the application") + errors.CheckError(fmt.Errorf("Source position should be less than the number of sources in the application")) } } @@ -935,7 +887,6 @@ type unsetOpts struct { kustomizeNamespace bool kustomizeImages []string kustomizeReplicas []string - ignoreMissingComponents bool parameters []string valuesFiles []string valuesLiteral bool @@ -952,7 +903,6 @@ func (o *unsetOpts) KustomizeIsZero() bool { !o.nameSuffix && !o.kustomizeVersion && !o.kustomizeNamespace && - !o.ignoreMissingComponents && len(o.kustomizeImages) == 0 && len(o.kustomizeReplicas) == 0 } @@ -992,30 +942,30 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) errors.CheckError(err) sourceName = appOpts.SourceName if sourceName != "" && sourcePosition != -1 { - errors.Fatal(errors.ErrorGeneric, "Only one of source-position and source-name can be specified.") + errors.CheckError(fmt.Errorf("Only one of source-position and source-name can be specified.")) } if sourceName != "" { sourceNameToPosition := getSourceNameToPositionMap(app) - pos, ok := sourceNameToPosition[sourceName] - if !ok { + if pos, ok := sourceNameToPosition[sourceName]; !ok { log.Fatalf("Unknown source name '%s'", sourceName) + } else { + sourcePosition = int(pos) } - sourcePosition = int(pos) } if app.Spec.HasMultipleSources() { if sourcePosition <= 0 { - errors.Fatal(errors.ErrorGeneric, "Source position should be specified and must be greater than 0 for applications with multiple sources") + errors.CheckError(fmt.Errorf("Source position should be specified and must be greater than 0 for applications with multiple sources")) } if len(app.Spec.GetSources()) < sourcePosition { - errors.Fatal(errors.ErrorGeneric, "Source position should be less than the number of sources in the application") + errors.CheckError(fmt.Errorf("Source position should be less than the number of sources in the application")) } } @@ -1058,7 +1008,6 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C command.Flags().BoolVar(&opts.kustomizeNamespace, "kustomize-namespace", false, "Kustomize namespace") command.Flags().StringArrayVar(&opts.kustomizeImages, "kustomize-image", []string{}, "Kustomize images name (e.g. --kustomize-image node --kustomize-image mysql)") command.Flags().StringArrayVar(&opts.kustomizeReplicas, "kustomize-replica", []string{}, "Kustomize replicas name (e.g. --kustomize-replica my-deployment --kustomize-replica my-statefulset)") - command.Flags().BoolVar(&opts.ignoreMissingComponents, "ignore-missing-components", false, "Unset the kustomize ignore-missing-components option (revert to false)") command.Flags().StringArrayVar(&opts.pluginEnvs, "plugin-env", []string{}, "Unset plugin env variables (e.g --plugin-env name)") command.Flags().BoolVar(&opts.passCredentials, "pass-credentials", false, "Unset passCredentials") command.Flags().BoolVar(&opts.ref, "ref", false, "Unset ref on the source") @@ -1099,11 +1048,6 @@ func unset(source *argoappv1.ApplicationSource, opts unsetOpts) (updated bool, n source.Kustomize.Namespace = "" } - if opts.ignoreMissingComponents && source.Kustomize.IgnoreMissingComponents { - source.Kustomize.IgnoreMissingComponents = false - updated = true - } - for _, kustomizeImage := range opts.kustomizeImages { for i, item := range source.Kustomize.Images { if argoappv1.KustomizeImage(kustomizeImage).Match(item) { @@ -1256,7 +1200,7 @@ func groupObjsByKey(localObs []*unstructured.Unstructured, liveObjs []*unstructu objByKey := make(map[kube.ResourceKey]*unstructured.Unstructured) for i := range localObs { obj := localObs[i] - if !hook.IsHook(obj) && !ignore.Ignore(obj) { + if !(hook.IsHook(obj) || ignore.Ignore(obj)) { objByKey[kube.GetResourceKey(obj)] = obj } } @@ -1301,20 +1245,20 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } if len(sourceNames) > 0 && len(sourcePositions) > 0 { - errors.Fatal(errors.ErrorGeneric, "Only one of source-positions and source-names can be specified.") + errors.CheckError(fmt.Errorf("Only one of source-positions and source-names can be specified.")) } if len(sourcePositions) > 0 && len(revisions) != len(sourcePositions) { - errors.Fatal(errors.ErrorGeneric, "While using --revisions and --source-positions, length of values for both flags should be same.") + errors.CheckError(fmt.Errorf("While using --revisions and --source-positions, length of values for both flags should be same.")) } if len(sourceNames) > 0 && len(revisions) != len(sourceNames) { - errors.Fatal(errors.ErrorGeneric, "While using --revisions and --source-names, length of values for both flags should be same.") + errors.CheckError(fmt.Errorf("While using --revisions and --source-names, length of values for both flags should be same.")) } clientset := headless.NewClientOrDie(clientOpts, c) conn, appIf := clientset.NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) app, err := appIf.Get(ctx, &application.ApplicationQuery{ Name: &appName, @@ -1327,23 +1271,22 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co sourceNameToPosition := getSourceNameToPositionMap(app) for _, name := range sourceNames { - pos, ok := sourceNameToPosition[name] - if !ok { + if pos, ok := sourceNameToPosition[name]; !ok { log.Fatalf("Unknown source name '%s'", name) + } else { + sourcePositions = append(sourcePositions, pos) } - sourcePositions = append(sourcePositions, pos) } } resources, err := appIf.ManagedResources(ctx, &application.ResourcesQuery{ApplicationName: &appName, AppNamespace: &appNs}) errors.CheckError(err) conn, settingsIf := clientset.NewSettingsClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) argoSettings, err := settingsIf.Get(ctx, &settings.SettingsQuery{}) errors.CheckError(err) diffOption := &DifferenceOption{} - switch { - case app.Spec.HasMultipleSources() && len(revisions) > 0 && len(sourcePositions) > 0: + if app.Spec.HasMultipleSources() && len(revisions) > 0 && len(sourcePositions) > 0 { numOfSources := int64(len(app.Spec.GetSources())) for _, pos := range sourcePositions { if pos <= 0 || pos > numOfSources { @@ -1363,7 +1306,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co diffOption.res = res diffOption.revisions = revisions diffOption.sourcePositions = sourcePositions - case revision != "": + } else if revision != "" { q := application.ApplicationManifestQuery{ Name: &appName, Revision: &revision, @@ -1373,7 +1316,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co errors.CheckError(err) diffOption.res = res diffOption.revision = revision - case local != "": + } else if local != "" { if serverSideGenerate { client, err := appIf.GetManifestsWithFiles(ctx, grpc_retry.Disable()) errors.CheckError(err) @@ -1388,7 +1331,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } else { fmt.Fprintf(os.Stderr, "Warning: local diff without --server-side-generate is deprecated and does not work with plugins. Server-side generation will be the default in v2.7.") conn, clusterIf := clientset.NewClusterClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) cluster, err := clusterIf.Get(ctx, &clusterpkg.ClusterQuery{Name: app.Spec.Destination.Name, Server: app.Spec.Destination.Server}) errors.CheckError(err) @@ -1397,7 +1340,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co diffOption.cluster = cluster } } - proj := getProject(ctx, c, clientOpts, app.Spec.Project) + proj := getProject(c, clientOpts, ctx, app.Spec.Project) foundDiffs := findandPrintDiff(ctx, app, proj.Project, resources, argoSettings, diffOption, ignoreNormalizerOpts) if foundDiffs && exitCode { os.Exit(diffExitCode) @@ -1439,11 +1382,10 @@ func findandPrintDiff(ctx context.Context, app *argoappv1.Application, proj *arg liveObjs, err := cmdutil.LiveObjects(resources.Items) errors.CheckError(err) items := make([]objKeyLiveTarget, 0) - switch { - case diffOptions.local != "": + if diffOptions.local != "" { localObjs := groupObjsByKey(getLocalObjects(ctx, app, proj, diffOptions.local, diffOptions.localRepoRoot, argoSettings.AppLabelKey, diffOptions.cluster.Info.ServerVersion, diffOptions.cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.TrackingMethod), liveObjs, app.Spec.Destination.Namespace) items = groupObjsForDiff(resources, localObjs, items, argoSettings, app.InstanceName(argoSettings.ControllerNamespace), app.Spec.Destination.Namespace) - case diffOptions.revision != "" || len(diffOptions.revisions) > 0: + } else if diffOptions.revision != "" || len(diffOptions.revisions) > 0 { var unstructureds []*unstructured.Unstructured for _, mfst := range diffOptions.res.Manifests { obj, err := argoappv1.UnmarshalToUnstructured(mfst) @@ -1452,7 +1394,7 @@ func findandPrintDiff(ctx context.Context, app *argoappv1.Application, proj *arg } groupedObjs := groupObjsByKey(unstructureds, liveObjs, app.Spec.Destination.Namespace) items = groupObjsForDiff(resources, groupedObjs, items, argoSettings, app.InstanceName(argoSettings.ControllerNamespace), app.Spec.Destination.Namespace) - case diffOptions.serversideRes != nil: + } else if diffOptions.serversideRes != nil { var unstructureds []*unstructured.Unstructured for _, mfst := range diffOptions.serversideRes.Manifests { obj, err := argoappv1.UnmarshalToUnstructured(mfst) @@ -1461,7 +1403,7 @@ func findandPrintDiff(ctx context.Context, app *argoappv1.Application, proj *arg } groupedObjs := groupObjsByKey(unstructureds, liveObjs, app.Spec.Destination.Namespace) items = groupObjsForDiff(resources, groupedObjs, items, argoSettings, app.InstanceName(argoSettings.ControllerNamespace), app.Spec.Destination.Namespace) - default: + } else { for i := range resources.Items { res := resources.Items[i] live := &unstructured.Unstructured{} @@ -1589,8 +1531,8 @@ func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra. } acdClient := headless.NewClientOrDie(clientOpts, c) conn, appIf := acdClient.NewApplicationClientOrDie() - defer utilio.Close(conn) - isTerminal := isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) + defer argoio.Close(conn) + var isTerminal bool = isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) promptFlag := c.Flag("yes") if promptFlag.Changed && promptFlag.Value.String() == "true" { noPrompt = true @@ -1673,7 +1615,7 @@ func printApplicationNames(apps []argoappv1.Application) { func printApplicationTable(apps []argoappv1.Application, output *string) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) var fmtStr string - headers := []any{"NAME", "CLUSTER", "NAMESPACE", "PROJECT", "STATUS", "HEALTH", "SYNCPOLICY", "CONDITIONS"} + headers := []interface{}{"NAME", "CLUSTER", "NAMESPACE", "PROJECT", "STATUS", "HEALTH", "SYNCPOLICY", "CONDITIONS"} if *output == "wide" { fmtStr = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" headers = append(headers, "REPO", "PATH", "TARGET") @@ -1682,7 +1624,7 @@ func printApplicationTable(apps []argoappv1.Application, output *string) { } _, _ = fmt.Fprintf(w, fmtStr, headers...) for _, app := range apps { - vals := []any{ + vals := []interface{}{ app.QualifiedName(), getServer(&app), app.Spec.Destination.Namespace, @@ -1722,11 +1664,11 @@ func NewApplicationListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co argocd app list -l app.kubernetes.io/instance argocd app list -l '!app.kubernetes.io/instance' argocd app list -l 'app.kubernetes.io/instance notin (my-app,other-app)'`, - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) apps, err := appIf.List(ctx, &application.ApplicationQuery{ Selector: ptr.To(selector), AppNamespace: &appNamespace, @@ -1768,7 +1710,7 @@ func NewApplicationListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } func formatSyncPolicy(app argoappv1.Application) string { - if app.Spec.SyncPolicy == nil || !app.Spec.SyncPolicy.IsAutomatedSyncEnabled() { + if app.Spec.SyncPolicy == nil || app.Spec.SyncPolicy.Automated == nil { return "Manual" } policy := "Auto" @@ -1796,10 +1738,6 @@ func formatConditionsSummary(app argoappv1.Application) string { items = append(items, cndType) } } - - // Sort the keys by name - sort.Strings(items) - summary := "" if len(items) > 0 { slices.Sort(items) @@ -1825,7 +1763,7 @@ func parseSelectedResources(resources []string) ([]*argoappv1.SyncOperationResou } nameFields := strings.Split(resourceName, resourceFieldNamespaceDelimiter) if len(nameFields) != resourceFieldNameWithNamespaceCount { - return "", "", fmt.Errorf("resource with namespace should have GROUP%sKIND%sNAMESPACE%sNAME, but instead got: %s", resourceFieldDelimiter, resourceFieldDelimiter, resourceFieldNamespaceDelimiter, resource) + return "", "", fmt.Errorf("Resource with namespace should have GROUP%sKIND%sNAMESPACE%sNAME, but instead got: %s", resourceFieldDelimiter, resourceFieldDelimiter, resourceFieldNamespaceDelimiter, resource) } namespace := nameFields[0] name := nameFields[1] @@ -1846,7 +1784,7 @@ func parseSelectedResources(resources []string) ([]*argoappv1.SyncOperationResou } fields := strings.Split(resource, resourceFieldDelimiter) if len(fields) != resourceFieldCount { - return nil, fmt.Errorf("resource should have GROUP%sKIND%sNAME, but instead got: %s", resourceFieldDelimiter, resourceFieldDelimiter, resource) + return nil, fmt.Errorf("Resource should have GROUP%sKIND%sNAME, but instead got: %s", resourceFieldDelimiter, resourceFieldDelimiter, resource) } name, namespace, err := nameRetriever(fields[2], resource) if err != nil { @@ -1923,7 +1861,7 @@ func NewApplicationWaitCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co appNames := args acdClient := headless.NewClientOrDie(clientOpts, c) closer, appIf := acdClient.NewApplicationClientOrDie() - defer utilio.Close(closer) + defer argoio.Close(closer) if selector != "" { list, err := appIf.List(ctx, &application.ApplicationQuery{Selector: ptr.To(selector)}) errors.CheckError(err) @@ -2082,7 +2020,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co acdClient := headless.NewClientOrDie(clientOpts, c) conn, appIf := acdClient.NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) selectedLabels, err := label.Parse(labels) errors.CheckError(err) @@ -2095,11 +2033,11 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co sourceNameToPosition := getSourceNameToPositionMap(app) for _, name := range sourceNames { - pos, ok := sourceNameToPosition[name] - if !ok { + if pos, ok := sourceNameToPosition[name]; !ok { log.Fatalf("Unknown source name '%s'", name) + } else { + sourcePositions = append(sourcePositions, pos) } - sourcePositions = append(sourcePositions, pos) } } @@ -2116,7 +2054,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co if len(list.Items) == 0 { errMsg := "No matching apps found for filter:" if selector != "" { - errMsg += " selector " + selector + errMsg += fmt.Sprintf(" selector %s", selector) } if len(projects) != 0 { errMsg += fmt.Sprintf(" projects %v", projects) @@ -2204,7 +2142,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } if local != "" { - if app.Spec.SyncPolicy != nil && app.Spec.SyncPolicy.IsAutomatedSyncEnabled() && !dryRun { + if app.Spec.SyncPolicy != nil && app.Spec.SyncPolicy.Automated != nil && !dryRun { log.Fatal("Cannot use local sync when Automatic Sync Policy is enabled except with --dry-run") } @@ -2212,15 +2150,15 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co conn, settingsIf := acdClient.NewSettingsClientOrDie() argoSettings, err := settingsIf.Get(ctx, &settings.SettingsQuery{}) errors.CheckError(err) - utilio.Close(conn) + argoio.Close(conn) conn, clusterIf := acdClient.NewClusterClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) cluster, err := clusterIf.Get(ctx, &clusterpkg.ClusterQuery{Name: app.Spec.Destination.Name, Server: app.Spec.Destination.Server}) errors.CheckError(err) - utilio.Close(conn) + argoio.Close(conn) - proj := getProject(ctx, c, clientOpts, app.Spec.Project) + proj := getProject(c, clientOpts, ctx, app.Spec.Project) localObjsStrings = getLocalObjectsString(ctx, app, proj.Project, local, localRepoRoot, argoSettings.AppLabelKey, cluster.Info.ServerVersion, cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.TrackingMethod) errors.CheckError(err) diffOption.local = local @@ -2290,25 +2228,26 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co }) errors.CheckError(err) conn, settingsIf := acdClient.NewSettingsClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) argoSettings, err := settingsIf.Get(ctx, &settings.SettingsQuery{}) errors.CheckError(err) foundDiffs := false fmt.Printf("====== Previewing differences between live and desired state of application %s ======\n", appQualifiedName) - proj := getProject(ctx, c, clientOpts, app.Spec.Project) + proj := getProject(c, clientOpts, ctx, app.Spec.Project) foundDiffs = findandPrintDiff(ctx, app, proj.Project, resources, argoSettings, diffOption, ignoreNormalizerOpts) - if !foundDiffs { + if foundDiffs { + if !diffChangesConfirm { + yesno := cli.AskToProceed(fmt.Sprintf("Please review changes to application %s shown above. Do you want to continue the sync process? (y/n): ", appQualifiedName)) + if !yesno { + os.Exit(0) + } + } + } else { fmt.Printf("====== No Differences found ======\n") // if no differences found, then no need to sync return } - if !diffChangesConfirm { - yesno := cli.AskToProceed(fmt.Sprintf("Please review changes to application %s shown above. Do you want to continue the sync process? (y/n): ", appQualifiedName)) - if !yesno { - os.Exit(0) - } - } } _, err = appIf.Sync(ctx, &syncReq) errors.CheckError(err) @@ -2399,9 +2338,9 @@ func (rs *resourceState) Key() string { return fmt.Sprintf("%s/%s/%s/%s", rs.Group, rs.Kind, rs.Namespace, rs.Name) } -func (rs *resourceState) FormatItems() []any { +func (rs *resourceState) FormatItems() []interface{} { timeStr := time.Now().Format("2006-01-02T15:04:05-07:00") - return []any{timeStr, rs.Group, rs.Kind, rs.Namespace, rs.Name, rs.Status, rs.Health, rs.Hook, rs.Message} + return []interface{}{timeStr, rs.Group, rs.Kind, rs.Namespace, rs.Name, rs.Status, rs.Health, rs.Hook, rs.Message} } // Merge merges the new state with any different contents from another resourceState. @@ -2517,21 +2456,28 @@ func checkResourceStatus(watch watchOpts, healthStatus string, syncStatus string if watch.delete { return false } - - healthBeingChecked := watch.suspended || watch.health || watch.degraded healthCheckPassed := true - if healthBeingChecked { - healthCheckPassed = false - if watch.health { - healthCheckPassed = healthCheckPassed || healthStatus == string(health.HealthStatusHealthy) - } - if watch.suspended { - healthCheckPassed = healthCheckPassed || healthStatus == string(health.HealthStatusSuspended) - } - if watch.degraded { - healthCheckPassed = healthCheckPassed || healthStatus == string(health.HealthStatusDegraded) - } + if watch.suspended && watch.health && watch.degraded { + healthCheckPassed = healthStatus == string(health.HealthStatusHealthy) || + healthStatus == string(health.HealthStatusSuspended) || + healthStatus == string(health.HealthStatusDegraded) + } else if watch.suspended && watch.degraded { + healthCheckPassed = healthStatus == string(health.HealthStatusDegraded) || + healthStatus == string(health.HealthStatusSuspended) + } else if watch.degraded && watch.health { + healthCheckPassed = healthStatus == string(health.HealthStatusHealthy) || + healthStatus == string(health.HealthStatusDegraded) + // below are good + } else if watch.suspended && watch.health { + healthCheckPassed = healthStatus == string(health.HealthStatusHealthy) || + healthStatus == string(health.HealthStatusSuspended) + } else if watch.suspended { + healthCheckPassed = healthStatus == string(health.HealthStatusSuspended) + } else if watch.health { + healthCheckPassed = healthStatus == string(health.HealthStatusHealthy) + } else if watch.degraded { + healthCheckPassed = healthStatus == string(health.HealthStatusDegraded) } synced := !watch.sync || syncStatus == string(argoappv1.SyncStatusCodeSynced) @@ -2544,43 +2490,18 @@ func checkResourceStatus(watch watchOpts, healthStatus string, syncStatus string // constructs the necessary data structures to print the app as a tree. func resourceParentChild(ctx context.Context, acdClient argocdclient.Client, appName string, appNs string) (map[string]argoappv1.ResourceNode, map[string][]string, map[string]struct{}, map[string]*resourceState) { _, appIf := acdClient.NewApplicationClientOrDie() - mapUIDToNode, mapParentToChild, parentNode := parentChildDetails(ctx, appIf, appName, appNs) + mapUidToNode, mapParentToChild, parentNode := parentChildDetails(appIf, ctx, appName, appNs) app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: ptr.To(appName), AppNamespace: ptr.To(appNs)}) errors.CheckError(err) mapNodeNameToResourceState := make(map[string]*resourceState) for _, res := range getResourceStates(app, nil) { mapNodeNameToResourceState[res.Kind+"/"+res.Name] = res } - return mapUIDToNode, mapParentToChild, parentNode, mapNodeNameToResourceState + return mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState } const waitFormatString = "%s\t%5s\t%10s\t%10s\t%20s\t%8s\t%7s\t%10s\t%s\n" -// AppWithLock encapsulates the application and its lock -type AppWithLock struct { - mu sync.Mutex - app *argoappv1.Application -} - -// NewAppWithLock creates a new AppWithLock instance -func NewAppWithLock() *AppWithLock { - return &AppWithLock{} -} - -// SetApp safely updates the application -func (a *AppWithLock) SetApp(app *argoappv1.Application) { - a.mu.Lock() - defer a.mu.Unlock() - a.app = app -} - -// GetApp safely retrieves the application -func (a *AppWithLock) GetApp() *argoappv1.Application { - a.mu.Lock() - defer a.mu.Unlock() - return a.app -} - // waitOnApplicationStatus watches an application and blocks until either the desired watch conditions // are fulfilled or we reach the timeout. Returns the app once desired conditions have been filled. // Additionally return the operationState at time of fulfilment (which may be different than returned app). @@ -2588,15 +2509,11 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, ctx, cancel := context.WithCancel(ctx) defer cancel() - appWithLock := NewAppWithLock() // refresh controls whether or not we refresh the app before printing the final status. // We only want to do this when an operation is in progress, since operations are the only // time when the sync status lags behind when an operation completes refresh := false - // appURL is declared here so that it can be used in the printFinalStatus function when the context is cancelled - appURL := getAppURL(ctx, acdClient, appName) - // printSummary controls whether we print the app summary table, OperationState, and ResourceState // We don't want to print these when output type is json or yaml, as the output would become unparsable. printSummary := output != "json" && output != "yaml" @@ -2619,7 +2536,7 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, if printSummary { fmt.Println() - printAppSummaryTable(app, appURL, nil) + printAppSummaryTable(app, appURL(ctx, acdClient, appName), nil) fmt.Println() if watch.operation { printOperationResult(app.Status.OperationState) @@ -2638,17 +2555,16 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, _ = w.Flush() } case "tree": - mapUIDToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appRealName, appNs) - if len(mapUIDToNode) > 0 { + mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appRealName, appNs) + if len(mapUidToNode) > 0 { fmt.Println() - printTreeView(mapUIDToNode, mapParentToChild, parentNode, mapNodeNameToResourceState) + printTreeView(mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState) } case "tree=detailed": - - mapUIDToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appRealName, appNs) - if len(mapUIDToNode) > 0 { + mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appRealName, appNs) + if len(mapUidToNode) > 0 { fmt.Println() - printTreeViewDetailed(mapUIDToNode, mapParentToChild, parentNode, mapNodeNameToResourceState) + printTreeViewDetailed(mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState) } default: errors.CheckError(fmt.Errorf("unknown output format: %s", output)) @@ -2658,24 +2574,19 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, if timeout != 0 { time.AfterFunc(time.Duration(timeout)*time.Second, func() { - conn, appClient := acdClient.NewApplicationClientOrDie() - defer conn.Close() - // We want to print the final status of the app even if the conditions are not met - if printSummary { - fmt.Println() - fmt.Println("This is the state of the app after wait timed out:") - } - // Setting refresh = false because we don't want printFinalStatus to execute a refresh - refresh = false - // Updating the app object to the latest state + _, appClient := acdClient.NewApplicationClientOrDie() app, err := appClient.Get(ctx, &application.ApplicationQuery{ Name: &appRealName, AppNamespace: &appNs, }) errors.CheckError(err) - // Update the app object - appWithLock.SetApp(app) - // Cancel the context to stop the watch + + if printSummary { + fmt.Println() + fmt.Println("This is the state of the app after `wait` timed out:") + } + + printFinalStatus(app) cancel() if printSummary { @@ -2692,13 +2603,12 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, prevStates := make(map[string]*resourceState) conn, appClient := acdClient.NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) app, err := appClient.Get(ctx, &application.ApplicationQuery{ Name: &appRealName, AppNamespace: &appNs, }) errors.CheckError(err) - appWithLock.SetApp(app) // Update the app object // printFinalStatus() will refresh and update the app object, potentially causing the app's // status.operationState to be different than the version when we break out of the event loop. @@ -2706,12 +2616,11 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, // finalOperationState captures the operationState as it was seen when we met the conditions of // the wait, so the caller can rely on it to determine the outcome of the operation. // See: https://github.com/argoproj/argo-cd/issues/5592 - finalOperationState := appWithLock.GetApp().Status.OperationState + finalOperationState := app.Status.OperationState - appEventCh := acdClient.WatchApplicationWithRetry(ctx, appName, appWithLock.GetApp().ResourceVersion) + appEventCh := acdClient.WatchApplicationWithRetry(ctx, appName, app.ResourceVersion) for appEvent := range appEventCh { - appWithLock.SetApp(&appEvent.Application) - app = appWithLock.GetApp() + app = &appEvent.Application finalOperationState = app.Status.OperationState operationInProgress := false @@ -2782,7 +2691,7 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, } _ = w.Flush() } - _ = printFinalStatus(appWithLock.GetApp()) + _ = printFinalStatus(app) return nil, finalOperationState, fmt.Errorf("timed out (%ds) waiting for app %q match desired state", timeout, appName) } @@ -2822,7 +2731,7 @@ func setParameterOverrides(app *argoappv1.Application, parameters []string, sour } // Print list of history ID's for an application. -func printApplicationHistoryIDs(revHistory []argoappv1.RevisionHistory) { +func printApplicationHistoryIds(revHistory []argoappv1.RevisionHistory) { for _, depInfo := range revHistory { fmt.Println(depInfo.ID) } @@ -2830,7 +2739,7 @@ func printApplicationHistoryIDs(revHistory []argoappv1.RevisionHistory) { // Print a history table for an application. func printApplicationHistoryTable(revHistory []argoappv1.RevisionHistory) { - maxAllowedRevisions := 7 + MAX_ALLOWED_REVISIONS := 7 w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) type history struct { id int64 @@ -2843,8 +2752,8 @@ func printApplicationHistoryTable(revHistory []argoappv1.RevisionHistory) { if depInfo.Sources != nil { for i, sourceInfo := range depInfo.Sources { rev := sourceInfo.TargetRevision - if len(depInfo.Revisions) == len(depInfo.Sources) && len(depInfo.Revisions[i]) >= maxAllowedRevisions { - rev = fmt.Sprintf("%s (%s)", rev, depInfo.Revisions[i][0:maxAllowedRevisions]) + if len(depInfo.Revisions) == len(depInfo.Sources) && len(depInfo.Revisions[i]) >= MAX_ALLOWED_REVISIONS { + rev = fmt.Sprintf("%s (%s)", rev, depInfo.Revisions[i][0:MAX_ALLOWED_REVISIONS]) } if _, ok := varHistory[sourceInfo.RepoURL]; !ok { varHistoryKeys = append(varHistoryKeys, sourceInfo.RepoURL) @@ -2857,8 +2766,8 @@ func printApplicationHistoryTable(revHistory []argoappv1.RevisionHistory) { } } else { rev := depInfo.Source.TargetRevision - if len(depInfo.Revision) >= maxAllowedRevisions { - rev = fmt.Sprintf("%s (%s)", rev, depInfo.Revision[0:maxAllowedRevisions]) + if len(depInfo.Revision) >= MAX_ALLOWED_REVISIONS { + rev = fmt.Sprintf("%s (%s)", rev, depInfo.Revision[0:MAX_ALLOWED_REVISIONS]) } if _, ok := varHistory[depInfo.Source.RepoURL]; !ok { varHistoryKeys = append(varHistoryKeys, depInfo.Source.RepoURL) @@ -2901,7 +2810,7 @@ func NewApplicationHistoryCommand(clientOpts *argocdclient.ClientOptions) *cobra os.Exit(1) } conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) app, err := appIf.Get(ctx, &application.ApplicationQuery{ Name: &appName, @@ -2910,7 +2819,7 @@ func NewApplicationHistoryCommand(clientOpts *argocdclient.ClientOptions) *cobra errors.CheckError(err) if output == "id" { - printApplicationHistoryIDs(app.Status.History) + printApplicationHistoryIds(app.Status.History) } else { printApplicationHistoryTable(app.Status.History) } @@ -2926,7 +2835,7 @@ func findRevisionHistory(application *argoappv1.Application, historyId int64) (* if historyId == -1 { l := len(application.Status.History) if l < 2 { - return nil, fmt.Errorf("application '%s' should have at least two successful deployments", application.Name) + return nil, fmt.Errorf("Application '%s' should have at least two successful deployments", application.ObjectMeta.Name) } return &application.Status.History[l-2], nil } @@ -2935,7 +2844,7 @@ func findRevisionHistory(application *argoappv1.Application, historyId int64) (* return &di, nil } } - return nil, fmt.Errorf("application '%s' does not have deployment id '%d' in history", application.Name, historyId) + return nil, fmt.Errorf("Application '%s' does not have deployment id '%d' in history\n", application.ObjectMeta.Name, historyId) } // NewApplicationRollbackCommand returns a new instance of an `argocd app rollback` command @@ -2964,7 +2873,7 @@ func NewApplicationRollbackCommand(clientOpts *argocdclient.ClientOptions) *cobr } acdClient := headless.NewClientOrDie(clientOpts, c) conn, appIf := acdClient.NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) app, err := appIf.Get(ctx, &application.ApplicationQuery{ Name: &appName, AppNamespace: &appNs, @@ -3063,15 +2972,15 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob } if len(sourceNames) > 0 && len(sourcePositions) > 0 { - errors.Fatal(errors.ErrorGeneric, "Only one of source-positions and source-names can be specified.") + errors.CheckError(fmt.Errorf("Only one of source-positions and source-names can be specified.")) } if len(sourcePositions) > 0 && len(revisions) != len(sourcePositions) { - errors.Fatal(errors.ErrorGeneric, "While using --revisions and --source-positions, length of values for both flags should be same.") + errors.CheckError(fmt.Errorf("While using --revisions and --source-positions, length of values for both flags should be same.")) } if len(sourceNames) > 0 && len(revisions) != len(sourceNames) { - errors.Fatal(errors.ErrorGeneric, "While using --revisions and --source-names, length of values for both flags should be same.") + errors.CheckError(fmt.Errorf("While using --revisions and --source-names, length of values for both flags should be same.")) } for _, pos := range sourcePositions { @@ -3083,7 +2992,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob appName, appNs := argo.ParseFromQualifiedName(args[0], "") clientset := headless.NewClientOrDie(clientOpts, c) conn, appIf := clientset.NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) app, err := appIf.Get(context.Background(), &application.ApplicationQuery{ Name: &appName, @@ -3095,11 +3004,11 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob sourceNameToPosition := getSourceNameToPositionMap(app) for _, name := range sourceNames { - pos, ok := sourceNameToPosition[name] - if !ok { + if pos, ok := sourceNameToPosition[name]; !ok { log.Fatalf("Unknown source name '%s'", name) + } else { + sourcePositions = append(sourcePositions, pos) } - sourcePositions = append(sourcePositions, pos) } } @@ -3112,22 +3021,21 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob var unstructureds []*unstructured.Unstructured switch source { case "git": - switch { - case local != "": + if local != "" { settingsConn, settingsIf := clientset.NewSettingsClientOrDie() - defer utilio.Close(settingsConn) + defer argoio.Close(settingsConn) argoSettings, err := settingsIf.Get(context.Background(), &settings.SettingsQuery{}) errors.CheckError(err) clusterConn, clusterIf := clientset.NewClusterClientOrDie() - defer utilio.Close(clusterConn) + defer argoio.Close(clusterConn) cluster, err := clusterIf.Get(context.Background(), &clusterpkg.ClusterQuery{Name: app.Spec.Destination.Name, Server: app.Spec.Destination.Server}) errors.CheckError(err) - proj := getProject(ctx, c, clientOpts, app.Spec.Project) - //nolint:staticcheck + proj := getProject(c, clientOpts, ctx, app.Spec.Project) + // nolint:staticcheck unstructureds = getLocalObjects(context.Background(), app, proj.Project, local, localRepoRoot, argoSettings.AppLabelKey, cluster.ServerVersion, cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.TrackingMethod) - case len(revisions) > 0 && len(sourcePositions) > 0: + } else if len(revisions) > 0 && len(sourcePositions) > 0 { q := application.ApplicationManifestQuery{ Name: &appName, AppNamespace: &appNs, @@ -3143,7 +3051,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob errors.CheckError(err) unstructureds = append(unstructureds, obj) } - case revision != "": + } else if revision != "" { q := application.ApplicationManifestQuery{ Name: &appName, AppNamespace: &appNs, @@ -3157,7 +3065,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob errors.CheckError(err) unstructureds = append(unstructureds, obj) } - default: + } else { targetObjs, err := targetObjects(resources.Items) errors.CheckError(err) unstructureds = targetObjs @@ -3202,7 +3110,7 @@ func NewApplicationTerminateOpCommand(clientOpts *argocdclient.ClientOptions) *c } appName, appNs := argo.ParseFromQualifiedName(args[0], "") conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) _, err := appIf.TerminateOperation(ctx, &application.OperationTerminateRequest{ Name: &appName, AppNamespace: &appNs, @@ -3229,7 +3137,7 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) app, err := appIf.Get(ctx, &application.ApplicationQuery{ Name: &appName, AppNamespace: &appNs, @@ -3241,7 +3149,7 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co appData, err = yaml.JSONToYAML(appData) errors.CheckError(err) - cli.InteractiveEdit(appName+"-*-edit.yaml", appData, func(input []byte) error { + cli.InteractiveEdit(fmt.Sprintf("%s-*-edit.yaml", appName), appData, func(input []byte) error { input, err = yaml.YAMLToJSON(input) if err != nil { return fmt.Errorf("error converting YAML to JSON: %w", err) @@ -3299,7 +3207,7 @@ func NewApplicationPatchCommand(clientOpts *argocdclient.ClientOptions) *cobra.C } appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) patchedApp, err := appIf.Patch(ctx, &application.ApplicationPatchRequest{ Name: &appName, @@ -3341,7 +3249,7 @@ func NewApplicationAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cob argocdClient := headless.NewClientOrDie(clientOpts, c) conn, appIf := argocdClient.NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) @@ -3354,7 +3262,7 @@ func NewApplicationAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cob errors.CheckError(err) if c.Flags() == nil { - errors.Fatal(errors.ErrorGeneric, "ApplicationSource needs atleast repoUrl, path or chart or ref field. No source to add.") + errors.CheckError(fmt.Errorf("ApplicationSource needs atleast repoUrl, path or chart or ref field. No source to add.")) } if len(app.Spec.Sources) > 0 { @@ -3374,9 +3282,9 @@ func NewApplicationAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cob }) errors.CheckError(err) - fmt.Printf("Application '%s' updated successfully\n", app.Name) + fmt.Printf("Application '%s' updated successfully\n", app.ObjectMeta.Name) } else { - errors.Fatal(errors.ErrorGeneric, fmt.Sprintf("Cannot add source: application %s does not have spec.sources defined", appName)) + errors.CheckError(fmt.Errorf("Cannot add source: application %s does not have spec.sources defined", appName)) } }, } @@ -3409,12 +3317,12 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) * } if sourceName == "" && sourcePosition <= 0 { - errors.Fatal(errors.ErrorGeneric, "Value of source-position must be greater than 0") + errors.CheckError(fmt.Errorf("Value of source-position must be greater than 0")) } argocdClient := headless.NewClientOrDie(clientOpts, c) conn, appIf := argocdClient.NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) @@ -3426,28 +3334,28 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) * errors.CheckError(err) if sourceName != "" && sourcePosition != -1 { - errors.Fatal(errors.ErrorGeneric, "Only one of source-position and source-name can be specified.") + errors.CheckError(fmt.Errorf("Only one of source-position and source-name can be specified.")) } if sourceName != "" { sourceNameToPosition := getSourceNameToPositionMap(app) - pos, ok := sourceNameToPosition[sourceName] - if !ok { + if pos, ok := sourceNameToPosition[sourceName]; !ok { log.Fatalf("Unknown source name '%s'", sourceName) + } else { + sourcePosition = int(pos) } - sourcePosition = int(pos) } if !app.Spec.HasMultipleSources() { - errors.Fatal(errors.ErrorGeneric, "Application does not have multiple sources configured") + errors.CheckError(fmt.Errorf("Application does not have multiple sources configured")) } if len(app.Spec.GetSources()) == 1 { - errors.Fatal(errors.ErrorGeneric, "Cannot remove the only source remaining in the app") + errors.CheckError(fmt.Errorf("Cannot remove the only source remaining in the app")) } if len(app.Spec.GetSources()) < sourcePosition { - errors.Fatal(errors.ErrorGeneric, fmt.Sprintf("Application does not have source at %d\n", sourcePosition)) + errors.CheckError(fmt.Errorf("Application does not have source at %d\n", sourcePosition)) } app.Spec.Sources = append(app.Spec.Sources[:sourcePosition-1], app.Spec.Sources[sourcePosition:]...) @@ -3462,7 +3370,7 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) * }) errors.CheckError(err) - fmt.Printf("Application '%s' updated successfully\n", app.Name) + fmt.Printf("Application '%s' updated successfully\n", app.ObjectMeta.Name) } else { fmt.Println("The command to delete the source was cancelled") } @@ -3489,7 +3397,7 @@ func NewApplicationConfirmDeletionCommand(clientOpts *argocdclient.ClientOptions argocdClient := headless.NewClientOrDie(clientOpts, c) conn, appIf := argocdClient.NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) @@ -3514,7 +3422,7 @@ func NewApplicationConfirmDeletionCommand(clientOpts *argocdclient.ClientOptions }) errors.CheckError(err) - fmt.Printf("Application '%s' updated successfully\n", app.Name) + 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") diff --git a/cmd/argocd/commands/app_actions.go b/cmd/argocd/commands/app_actions.go index b445011bae..f795585d07 100644 --- a/cmd/argocd/commands/app_actions.go +++ b/cmd/argocd/commands/app_actions.go @@ -8,23 +8,23 @@ import ( "strconv" "text/tabwriter" - "github.com/argoproj/argo-cd/v3/util/templates" + "github.com/argoproj/argo-cd/v2/util/templates" - "github.com/argoproj/argo-cd/v3/cmd/util" + "github.com/argoproj/argo-cd/v2/cmd/util" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "k8s.io/utils/ptr" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + v1alpha1 "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/errors" + "github.com/argoproj/argo-cd/v2/util/io" ) type DisplayedAction struct { @@ -83,8 +83,8 @@ func NewApplicationResourceActionsListCommand(clientOpts *argocdclient.ClientOpt } appName, appNs := argo.ParseFromQualifiedName(args[0], "") conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() - defer utilio.Close(conn) - resources, err := getActionableResourcesForApplication(ctx, appIf, &appNs, &appName) + defer io.Close(conn) + resources, err := getActionableResourcesForApplication(appIf, ctx, &appNs, &appName) errors.CheckError(err) filteredObjects, err := util.FilterResources(command.Flags().Changed("group"), resources, group, kind, namespace, resourceName, true) errors.CheckError(err) @@ -175,8 +175,8 @@ func NewApplicationResourceActionsRunCommand(clientOpts *argocdclient.ClientOpti actionName := args[1] conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() - defer utilio.Close(conn) - resources, err := getActionableResourcesForApplication(ctx, appIf, &appNs, &appName) + defer io.Close(conn) + resources, err := getActionableResourcesForApplication(appIf, ctx, &appNs, &appName) errors.CheckError(err) filteredObjects, err := util.FilterResources(command.Flags().Changed("group"), resources, group, kind, namespace, resourceName, all) errors.CheckError(err) @@ -207,7 +207,7 @@ func NewApplicationResourceActionsRunCommand(clientOpts *argocdclient.ClientOpti return command } -func getActionableResourcesForApplication(ctx context.Context, appIf applicationpkg.ApplicationServiceClient, appNs *string, appName *string) ([]*v1alpha1.ResourceDiff, error) { +func getActionableResourcesForApplication(appIf applicationpkg.ApplicationServiceClient, ctx context.Context, appNs *string, appName *string) ([]*v1alpha1.ResourceDiff, error) { resources, err := appIf.ManagedResources(ctx, &applicationpkg.ResourcesQuery{ ApplicationName: appName, AppNamespace: appNs, diff --git a/cmd/argocd/commands/app_resource_test.go b/cmd/argocd/commands/app_resource_test.go index 4de6e0cbf3..171da12b47 100644 --- a/cmd/argocd/commands/app_resource_test.go +++ b/cmd/argocd/commands/app_resource_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestPrintTreeViewAppResources(t *testing.T) { diff --git a/cmd/argocd/commands/app_resources.go b/cmd/argocd/commands/app_resources.go index f2a6cd4a32..e7cc47fa8b 100644 --- a/cmd/argocd/commands/app_resources.go +++ b/cmd/argocd/commands/app_resources.go @@ -5,21 +5,21 @@ import ( "os" "text/tabwriter" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "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" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/errors" + argoio "github.com/argoproj/argo-cd/v2/util/io" ) func NewApplicationPatchResourceCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { @@ -58,7 +58,7 @@ func NewApplicationPatchResourceCommand(clientOpts *argocdclient.ClientOptions) appName, appNs := argo.ParseFromQualifiedName(args[0], "") conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) resources, err := appIf.ManagedResources(ctx, &applicationpkg.ResourcesQuery{ ApplicationName: &appName, AppNamespace: &appNs, @@ -123,7 +123,7 @@ func NewApplicationDeleteResourceCommand(clientOpts *argocdclient.ClientOptions) appName, appNs := argo.ParseFromQualifiedName(args[0], "") conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) resources, err := appIf.ManagedResources(ctx, &applicationpkg.ResourcesQuery{ ApplicationName: &appName, AppNamespace: &appNs, @@ -164,12 +164,12 @@ func NewApplicationDeleteResourceCommand(clientOpts *argocdclient.ClientOptions) } func parentChildInfo(nodes []v1alpha1.ResourceNode) (map[string]v1alpha1.ResourceNode, map[string][]string, map[string]struct{}) { - mapUIDToNode := make(map[string]v1alpha1.ResourceNode) + mapUidToNode := make(map[string]v1alpha1.ResourceNode) mapParentToChild := make(map[string][]string) parentNode := make(map[string]struct{}) for _, node := range nodes { - mapUIDToNode[node.UID] = node + mapUidToNode[node.UID] = node if len(node.ParentRefs) > 0 { _, ok := mapParentToChild[node.ParentRefs[0].UID] @@ -182,7 +182,7 @@ func parentChildInfo(nodes []v1alpha1.ResourceNode) (map[string]v1alpha1.Resourc parentNode[node.UID] = struct{}{} } } - return mapUIDToNode, mapParentToChild, parentNode + return mapUidToNode, mapParentToChild, parentNode } func printDetailedTreeViewAppResourcesNotOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, w *tabwriter.Writer) { @@ -211,33 +211,32 @@ func printTreeViewAppResourcesOrphaned(nodeMapping map[string]v1alpha1.ResourceN func printResources(listAll bool, orphaned bool, appResourceTree *v1alpha1.ApplicationTree, output string) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) - switch output { - case "tree=detailed": + if output == "tree=detailed" { fmt.Fprintf(w, "GROUP\tKIND\tNAMESPACE\tNAME\tORPHANED\tAGE\tHEALTH\tREASON\n") if !orphaned || listAll { - mapUIDToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.Nodes) - printDetailedTreeViewAppResourcesNotOrphaned(mapUIDToNode, mapParentToChild, parentNode, w) + mapUidToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.Nodes) + printDetailedTreeViewAppResourcesNotOrphaned(mapUidToNode, mapParentToChild, parentNode, w) } if orphaned || listAll { - mapUIDToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.OrphanedNodes) - printDetailedTreeViewAppResourcesOrphaned(mapUIDToNode, mapParentToChild, parentNode, w) + mapUidToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.OrphanedNodes) + printDetailedTreeViewAppResourcesOrphaned(mapUidToNode, mapParentToChild, parentNode, w) } - case "tree": + } else if output == "tree" { fmt.Fprintf(w, "GROUP\tKIND\tNAMESPACE\tNAME\tORPHANED\n") if !orphaned || listAll { - mapUIDToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.Nodes) - printTreeViewAppResourcesNotOrphaned(mapUIDToNode, mapParentToChild, parentNode, w) + mapUidToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.Nodes) + printTreeViewAppResourcesNotOrphaned(mapUidToNode, mapParentToChild, parentNode, w) } if orphaned || listAll { - mapUIDToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.OrphanedNodes) - printTreeViewAppResourcesOrphaned(mapUIDToNode, mapParentToChild, parentNode, w) + mapUidToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.OrphanedNodes) + printTreeViewAppResourcesOrphaned(mapUidToNode, mapParentToChild, parentNode, w) } - default: - headers := []any{"GROUP", "KIND", "NAMESPACE", "NAME", "ORPHANED"} + } else { + headers := []interface{}{"GROUP", "KIND", "NAMESPACE", "NAME", "ORPHANED"} fmtStr := "%s\t%s\t%s\t%s\t%s\n" _, _ = fmt.Fprintf(w, fmtStr, headers...) if !orphaned || listAll { @@ -272,7 +271,7 @@ func NewApplicationListResourcesCommand(clientOpts *argocdclient.ClientOptions) listAll := !c.Flag("orphaned").Changed appName, appNs := argo.ParseFromQualifiedName(args[0], "") conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) appResourceTree, err := appIf.ResourceTree(ctx, &applicationpkg.ResourcesQuery{ ApplicationName: &appName, AppNamespace: &appNs, diff --git a/cmd/argocd/commands/app_test.go b/cmd/argocd/commands/app_test.go index 3e8b3182b9..57aede02a5 100644 --- a/cmd/argocd/commands/app_test.go +++ b/cmd/argocd/commands/app_test.go @@ -12,6 +12,32 @@ import ( "testing" "time" + "google.golang.org/grpc" + "k8s.io/apimachinery/pkg/watch" + + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + + v1 "k8s.io/api/core/v1" + + "sigs.k8s.io/yaml" + + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + accountpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/account" + applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + applicationsetpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/applicationset" + certificatepkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/certificate" + clusterpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster" + gpgkeypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/gpgkey" + notificationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/notification" + projectpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/project" + repocredspkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repocreds" + repositorypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository" + sessionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" + settingspkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/settings" + versionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/version" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/gitops-engine/pkg/health" "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/coreos/go-oidc/v3/oidc" @@ -20,32 +46,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/oauth2" - "google.golang.org/grpc" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" - "k8s.io/apimachinery/pkg/watch" - "sigs.k8s.io/yaml" - - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - accountpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/account" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - applicationsetpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/applicationset" - certificatepkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/certificate" - clusterpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster" - gpgkeypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/gpgkey" - notificationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/notification" - projectpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/project" - repocredspkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repocreds" - repositorypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repository" - sessionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" - settingspkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/settings" - versionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/version" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" + k8swatch "k8s.io/apimachinery/pkg/watch" ) func Test_getInfos(t *testing.T) { @@ -116,7 +121,7 @@ func TestFindRevisionHistoryWithoutPassedId(t *testing.T) { status := v1alpha1.ApplicationStatus{ Resources: nil, Sync: v1alpha1.SyncStatus{}, - Health: v1alpha1.AppHealthStatus{}, + Health: v1alpha1.HealthStatus{}, History: histories, Conditions: nil, ReconciledAt: nil, @@ -224,7 +229,7 @@ func TestFindRevisionHistoryWithoutPassedIdWithMultipleSources(t *testing.T) { status := v1alpha1.ApplicationStatus{ Resources: nil, Sync: v1alpha1.SyncStatus{}, - Health: v1alpha1.AppHealthStatus{}, + Health: v1alpha1.HealthStatus{}, History: histories, Conditions: nil, ReconciledAt: nil, @@ -277,7 +282,7 @@ func TestFindRevisionHistoryWithoutPassedIdAndEmptyHistoryList(t *testing.T) { status := v1alpha1.ApplicationStatus{ Resources: nil, Sync: v1alpha1.SyncStatus{}, - Health: v1alpha1.AppHealthStatus{}, + Health: v1alpha1.HealthStatus{}, History: histories, Conditions: nil, ReconciledAt: nil, @@ -295,7 +300,7 @@ func TestFindRevisionHistoryWithoutPassedIdAndEmptyHistoryList(t *testing.T) { require.Error(t, err, "Find revision history should fail with errors") require.Nil(t, history, "History should be empty") - require.EqualError(t, err, "application '' should have at least two successful deployments", "Find revision history should fail with correct error message") + require.EqualError(t, err, "Application '' should have at least two successful deployments", "Find revision history should fail with correct error message") } func TestFindRevisionHistoryWithPassedId(t *testing.T) { @@ -308,7 +313,7 @@ func TestFindRevisionHistoryWithPassedId(t *testing.T) { status := v1alpha1.ApplicationStatus{ Resources: nil, Sync: v1alpha1.SyncStatus{}, - Health: v1alpha1.AppHealthStatus{}, + Health: v1alpha1.HealthStatus{}, History: histories, Conditions: nil, ReconciledAt: nil, @@ -338,7 +343,7 @@ func TestFindRevisionHistoryWithPassedIdThatNotExist(t *testing.T) { status := v1alpha1.ApplicationStatus{ Resources: nil, Sync: v1alpha1.SyncStatus{}, - Health: v1alpha1.AppHealthStatus{}, + Health: v1alpha1.HealthStatus{}, History: histories, Conditions: nil, ReconciledAt: nil, @@ -356,26 +361,26 @@ func TestFindRevisionHistoryWithPassedIdThatNotExist(t *testing.T) { require.Error(t, err, "Find revision history should fail with errors") require.Nil(t, history, "History should be not found") - require.EqualError(t, err, "application '' does not have deployment id '4' in history", "Find revision history should fail with correct error message") + require.EqualError(t, err, "Application '' does not have deployment id '4' in history\n", "Find revision history should fail with correct error message") } func Test_groupObjsByKey(t *testing.T) { localObjs := []*unstructured.Unstructured{ { - Object: map[string]any{ + Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Pod", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "name": "pod-name", "namespace": "default", }, }, }, { - Object: map[string]any{ + Object: map[string]interface{}{ "apiVersion": "apiextensions.k8s.io/v1", "kind": "CustomResourceDefinition", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "name": "certificates.cert-manager.io", }, }, @@ -383,20 +388,20 @@ func Test_groupObjsByKey(t *testing.T) { } liveObjs := []*unstructured.Unstructured{ { - Object: map[string]any{ + Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Pod", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "name": "pod-name", "namespace": "default", }, }, }, { - Object: map[string]any{ + Object: map[string]interface{}{ "apiVersion": "apiextensions.k8s.io/v1", "kind": "CustomResourceDefinition", - "metadata": map[string]any{ + "metadata": map[string]interface{}{ "name": "certificates.cert-manager.io", }, }, @@ -692,8 +697,9 @@ func TestPrintAppSummaryTable(t *testing.T) { Sync: v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, }, - Health: v1alpha1.AppHealthStatus{ - Status: health.HealthStatusProgressing, + Health: v1alpha1.HealthStatus{ + Status: health.HealthStatusProgressing, + Message: "health-message", }, }, } @@ -746,7 +752,7 @@ SyncWindow: Sync Denied Assigned Windows: allow:0 0 * * *:24h,deny:0 0 * * *:24h,allow:0 0 * * *:24h Sync Policy: Automated (Prune) Sync Status: OutOfSync from master -Health Status: Progressing +Health Status: Progressing (health-message) ` assert.Equalf(t, expectation, output, "Incorrect print app summary output %q, should be %q", output, expectation) } @@ -786,8 +792,9 @@ func TestPrintAppSummaryTable_MultipleSources(t *testing.T) { Sync: v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, }, - Health: v1alpha1.AppHealthStatus{ - Status: health.HealthStatusProgressing, + Health: v1alpha1.HealthStatus{ + Status: health.HealthStatusProgressing, + Message: "health-message", }, }, } @@ -843,7 +850,7 @@ SyncWindow: Sync Denied Assigned Windows: allow:0 0 * * *:24h,deny:0 0 * * *:24h,allow:0 0 * * *:24h Sync Policy: Automated (Prune) Sync Status: OutOfSync from master -Health Status: Progressing +Health Status: Progressing (health-message) ` assert.Equalf(t, expectation, output, "Incorrect print app summary output %q, should be %q", output, expectation) } @@ -1028,9 +1035,10 @@ func TestTargetObjects_invalid(t *testing.T) { } func TestCheckForDeleteEvent(t *testing.T) { + ctx := context.Background() fakeClient := new(fakeAcdClient) - checkForDeleteEvent(t.Context(), fakeClient, "testApp") + checkForDeleteEvent(ctx, fakeClient, "testApp") } func TestPrintApplicationNames(t *testing.T) { @@ -1050,10 +1058,9 @@ func TestPrintApplicationNames(t *testing.T) { func Test_unset(t *testing.T) { kustomizeSource := &v1alpha1.ApplicationSource{ Kustomize: &v1alpha1.ApplicationSourceKustomize{ - IgnoreMissingComponents: true, - NamePrefix: "some-prefix", - NameSuffix: "some-suffix", - Version: "123", + NamePrefix: "some-prefix", + NameSuffix: "some-suffix", + Version: "123", Images: v1alpha1.KustomizeImages{ "old1=new:tag", "old2=new:tag", @@ -1110,7 +1117,7 @@ func Test_unset(t *testing.T) { assert.Equal(t, "some-prefix", kustomizeSource.Kustomize.NamePrefix) updated, nothingToUnset := unset(kustomizeSource, unsetOpts{namePrefix: true}) - assert.Empty(t, kustomizeSource.Kustomize.NamePrefix) + assert.Equal(t, "", kustomizeSource.Kustomize.NamePrefix) assert.True(t, updated) assert.False(t, nothingToUnset) updated, nothingToUnset = unset(kustomizeSource, unsetOpts{namePrefix: true}) @@ -1119,7 +1126,7 @@ func Test_unset(t *testing.T) { assert.Equal(t, "some-suffix", kustomizeSource.Kustomize.NameSuffix) updated, nothingToUnset = unset(kustomizeSource, unsetOpts{nameSuffix: true}) - assert.Empty(t, kustomizeSource.Kustomize.NameSuffix) + assert.Equal(t, "", kustomizeSource.Kustomize.NameSuffix) assert.True(t, updated) assert.False(t, nothingToUnset) updated, nothingToUnset = unset(kustomizeSource, unsetOpts{nameSuffix: true}) @@ -1128,7 +1135,7 @@ func Test_unset(t *testing.T) { assert.Equal(t, "123", kustomizeSource.Kustomize.Version) updated, nothingToUnset = unset(kustomizeSource, unsetOpts{kustomizeVersion: true}) - assert.Empty(t, kustomizeSource.Kustomize.Version) + assert.Equal(t, "", kustomizeSource.Kustomize.Version) assert.True(t, updated) assert.False(t, nothingToUnset) updated, nothingToUnset = unset(kustomizeSource, unsetOpts{kustomizeVersion: true}) @@ -1153,15 +1160,6 @@ func Test_unset(t *testing.T) { assert.False(t, updated) assert.False(t, nothingToUnset) - assert.True(t, kustomizeSource.Kustomize.IgnoreMissingComponents) - updated, nothingToUnset = unset(kustomizeSource, unsetOpts{ignoreMissingComponents: true}) - assert.False(t, kustomizeSource.Kustomize.IgnoreMissingComponents) - assert.True(t, updated) - assert.False(t, nothingToUnset) - updated, nothingToUnset = unset(kustomizeSource, unsetOpts{ignoreMissingComponents: true}) - assert.False(t, updated) - assert.False(t, nothingToUnset) - assert.Len(t, helmSource.Helm.Parameters, 2) updated, nothingToUnset = unset(helmSource, unsetOpts{parameters: []string{"name-1"}}) assert.Len(t, helmSource.Helm.Parameters, 1) @@ -1182,7 +1180,7 @@ func Test_unset(t *testing.T) { assert.Equal(t, "some: yaml", helmSource.Helm.ValuesString()) updated, nothingToUnset = unset(helmSource, unsetOpts{valuesLiteral: true}) - assert.Empty(t, helmSource.Helm.ValuesString()) + assert.Equal(t, "", helmSource.Helm.ValuesString()) assert.True(t, updated) assert.False(t, nothingToUnset) updated, nothingToUnset = unset(helmSource, unsetOpts{valuesLiteral: true}) @@ -1560,7 +1558,7 @@ func TestPrintApplicationTableNotWide(t *testing.T) { Sync: v1alpha1.SyncStatus{ Status: "OutOfSync", }, - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: "Healthy", }, }, @@ -1596,7 +1594,7 @@ func TestPrintApplicationTableWide(t *testing.T) { Sync: v1alpha1.SyncStatus{ Status: "OutOfSync", }, - Health: v1alpha1.AppHealthStatus{ + Health: v1alpha1.HealthStatus{ Status: "Healthy", }, }, @@ -1869,7 +1867,7 @@ func testApp(name, project string, labels map[string]string, annotations map[str func TestWaitOnApplicationStatus_JSON_YAML_WideOutput(t *testing.T) { acdClient := &customAcdClient{&fakeAcdClient{}} - ctx := t.Context() + ctx := context.Background() var selectResource []*v1alpha1.SyncOperationResource watch := watchOpts{ sync: false, @@ -1920,72 +1918,7 @@ Source: SyncWindow: Sync Allowed Sync Policy: Automated (Prune) Sync Status: OutOfSync from master -Health Status: Progressing - -Operation: Sync -Sync Revision: revision -Phase: -Start: 0001-01-01 00:00:00 +0000 UTC -Finished: 2020-11-10 23:00:00 +0000 UTC -Duration: 2333448h16m18.871345152s -Message: test - -GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE - Service default service-name1 Synced Healthy -apps Deployment default test Synced Healthy -` - expectation = fmt.Sprintf(expectation, timeStr, timeStr) - expectationParts := strings.Split(expectation, "\n") - slices.Sort(expectationParts) - expectationSorted := strings.Join(expectationParts, "\n") - outputParts := strings.Split(output, "\n") - slices.Sort(outputParts) - outputSorted := strings.Join(outputParts, "\n") - // Need to compare sorted since map entries may not keep a specific order during serialization, leading to flakiness. - assert.Equalf(t, expectationSorted, outputSorted, "Incorrect output %q, should be %q (items order doesn't matter)", output, expectation) -} - -func TestWaitOnApplicationStatus_JSON_YAML_WideOutput_With_Timeout(t *testing.T) { - acdClient := &customAcdClient{&fakeAcdClient{simulateTimeout: 15}} - ctx := t.Context() - var selectResource []*v1alpha1.SyncOperationResource - watch := watchOpts{ - sync: false, - health: false, - operation: true, - suspended: false, - } - watch = getWatchOpts(watch) - - output, _ := captureOutput(func() error { - _, _, _ = waitOnApplicationStatus(ctx, acdClient, "app-name", 5, watch, selectResource, "") - return nil - }) - timeStr := time.Now().Format("2006-01-02T15:04:05-07:00") - - expectation := `TIMESTAMP GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE -%s Service default service-name1 Synced Healthy -%s apps Deployment default test Synced Healthy - -The command timed out waiting for the conditions to be met. - -This is the state of the app after wait timed out: - -Name: argocd/test -Project: default -Server: local -Namespace: argocd -URL: http://localhost:8080/applications/app-name -Source: -- Repo: test - Target: master - Path: /test - Helm Values: path1,path2 - Name Prefix: prefix -SyncWindow: Sync Allowed -Sync Policy: Automated (Prune) -Sync Status: OutOfSync from master -Health Status: Progressing +Health Status: Progressing (health-message) Operation: Sync Sync Revision: revision @@ -2014,7 +1947,7 @@ type customAcdClient struct { *fakeAcdClient } -func (c *customAcdClient) WatchApplicationWithRetry(ctx context.Context, _ string, _ string) chan *v1alpha1.ApplicationWatchEvent { +func (c *customAcdClient) WatchApplicationWithRetry(ctx context.Context, appName string, revision string) chan *v1alpha1.ApplicationWatchEvent { appEventsCh := make(chan *v1alpha1.ApplicationWatchEvent) _, appClient := c.NewApplicationClientOrDie() app, _ := appClient.Get(ctx, &applicationpkg.ApplicationQuery{}) @@ -2028,7 +1961,6 @@ func (c *customAcdClient) WatchApplicationWithRetry(ctx context.Context, _ strin } go func() { - time.Sleep(time.Duration(c.simulateTimeout) * time.Second) appEventsCh <- &v1alpha1.ApplicationWatchEvent{ Type: watch.Bookmark, Application: newApp, @@ -2055,19 +1987,19 @@ func (c *fakeConnection) Close() error { type fakeSettingsServiceClient struct{} -func (f fakeSettingsServiceClient) Get(_ context.Context, _ *settingspkg.SettingsQuery, _ ...grpc.CallOption) (*settingspkg.Settings, error) { +func (f fakeSettingsServiceClient) Get(ctx context.Context, in *settingspkg.SettingsQuery, opts ...grpc.CallOption) (*settingspkg.Settings, error) { return &settingspkg.Settings{ URL: "http://localhost:8080", }, nil } -func (f fakeSettingsServiceClient) GetPlugins(_ context.Context, _ *settingspkg.SettingsQuery, _ ...grpc.CallOption) (*settingspkg.SettingsPluginsResponse, error) { +func (f fakeSettingsServiceClient) GetPlugins(ctx context.Context, in *settingspkg.SettingsQuery, opts ...grpc.CallOption) (*settingspkg.SettingsPluginsResponse, error) { return nil, nil } type fakeAppServiceClient struct{} -func (c *fakeAppServiceClient) Get(_ context.Context, _ *applicationpkg.ApplicationQuery, _ ...grpc.CallOption) (*v1alpha1.Application, error) { +func (c *fakeAppServiceClient) Get(ctx context.Context, in *applicationpkg.ApplicationQuery, opts ...grpc.CallOption) (*v1alpha1.Application, error) { time := metav1.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC) return &v1alpha1.Application{ ObjectMeta: metav1.ObjectMeta{ @@ -2127,124 +2059,123 @@ func (c *fakeAppServiceClient) Get(_ context.Context, _ *applicationpkg.Applicat Sync: v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, }, - Health: v1alpha1.AppHealthStatus{ - Status: health.HealthStatusProgressing, + Health: v1alpha1.HealthStatus{ + Status: health.HealthStatusProgressing, + Message: "health-message", }, }, }, nil } -func (c *fakeAppServiceClient) List(_ context.Context, _ *applicationpkg.ApplicationQuery, _ ...grpc.CallOption) (*v1alpha1.ApplicationList, error) { +func (c *fakeAppServiceClient) List(ctx context.Context, in *applicationpkg.ApplicationQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationList, error) { return nil, nil } -func (c *fakeAppServiceClient) ListResourceEvents(_ context.Context, _ *applicationpkg.ApplicationResourceEventsQuery, _ ...grpc.CallOption) (*corev1.EventList, error) { +func (c *fakeAppServiceClient) ListResourceEvents(ctx context.Context, in *applicationpkg.ApplicationResourceEventsQuery, opts ...grpc.CallOption) (*v1.EventList, error) { return nil, nil } -func (c *fakeAppServiceClient) Watch(_ context.Context, _ *applicationpkg.ApplicationQuery, _ ...grpc.CallOption) (applicationpkg.ApplicationService_WatchClient, error) { +func (c *fakeAppServiceClient) Watch(ctx context.Context, in *applicationpkg.ApplicationQuery, opts ...grpc.CallOption) (applicationpkg.ApplicationService_WatchClient, error) { return nil, nil } -func (c *fakeAppServiceClient) Create(_ context.Context, _ *applicationpkg.ApplicationCreateRequest, _ ...grpc.CallOption) (*v1alpha1.Application, error) { +func (c *fakeAppServiceClient) Create(ctx context.Context, in *applicationpkg.ApplicationCreateRequest, opts ...grpc.CallOption) (*v1alpha1.Application, error) { return nil, nil } -func (c *fakeAppServiceClient) GetApplicationSyncWindows(_ context.Context, _ *applicationpkg.ApplicationSyncWindowsQuery, _ ...grpc.CallOption) (*applicationpkg.ApplicationSyncWindowsResponse, error) { +func (c *fakeAppServiceClient) GetApplicationSyncWindows(ctx context.Context, in *applicationpkg.ApplicationSyncWindowsQuery, opts ...grpc.CallOption) (*applicationpkg.ApplicationSyncWindowsResponse, error) { return nil, nil } -func (c *fakeAppServiceClient) RevisionMetadata(_ context.Context, _ *applicationpkg.RevisionMetadataQuery, _ ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error) { +func (c *fakeAppServiceClient) RevisionMetadata(ctx context.Context, in *applicationpkg.RevisionMetadataQuery, opts ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error) { return nil, nil } -func (c *fakeAppServiceClient) RevisionChartDetails(_ context.Context, _ *applicationpkg.RevisionMetadataQuery, _ ...grpc.CallOption) (*v1alpha1.ChartDetails, error) { +func (c *fakeAppServiceClient) RevisionChartDetails(ctx context.Context, in *applicationpkg.RevisionMetadataQuery, opts ...grpc.CallOption) (*v1alpha1.ChartDetails, error) { return nil, nil } -func (c *fakeAppServiceClient) GetManifests(_ context.Context, _ *applicationpkg.ApplicationManifestQuery, _ ...grpc.CallOption) (*apiclient.ManifestResponse, error) { +func (c *fakeAppServiceClient) GetManifests(ctx context.Context, in *applicationpkg.ApplicationManifestQuery, opts ...grpc.CallOption) (*apiclient.ManifestResponse, error) { return nil, nil } -func (c *fakeAppServiceClient) GetManifestsWithFiles(_ context.Context, _ ...grpc.CallOption) (applicationpkg.ApplicationService_GetManifestsWithFilesClient, error) { +func (c *fakeAppServiceClient) GetManifestsWithFiles(ctx context.Context, opts ...grpc.CallOption) (applicationpkg.ApplicationService_GetManifestsWithFilesClient, error) { return nil, nil } -func (c *fakeAppServiceClient) Update(_ context.Context, _ *applicationpkg.ApplicationUpdateRequest, _ ...grpc.CallOption) (*v1alpha1.Application, error) { +func (c *fakeAppServiceClient) Update(ctx context.Context, in *applicationpkg.ApplicationUpdateRequest, opts ...grpc.CallOption) (*v1alpha1.Application, error) { return nil, nil } -func (c *fakeAppServiceClient) UpdateSpec(_ context.Context, _ *applicationpkg.ApplicationUpdateSpecRequest, _ ...grpc.CallOption) (*v1alpha1.ApplicationSpec, error) { +func (c *fakeAppServiceClient) UpdateSpec(ctx context.Context, in *applicationpkg.ApplicationUpdateSpecRequest, opts ...grpc.CallOption) (*v1alpha1.ApplicationSpec, error) { return nil, nil } -func (c *fakeAppServiceClient) Patch(_ context.Context, _ *applicationpkg.ApplicationPatchRequest, _ ...grpc.CallOption) (*v1alpha1.Application, error) { +func (c *fakeAppServiceClient) Patch(ctx context.Context, in *applicationpkg.ApplicationPatchRequest, opts ...grpc.CallOption) (*v1alpha1.Application, error) { return nil, nil } -func (c *fakeAppServiceClient) Delete(_ context.Context, _ *applicationpkg.ApplicationDeleteRequest, _ ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) { +func (c *fakeAppServiceClient) Delete(ctx context.Context, in *applicationpkg.ApplicationDeleteRequest, opts ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) { return nil, nil } -func (c *fakeAppServiceClient) Sync(_ context.Context, _ *applicationpkg.ApplicationSyncRequest, _ ...grpc.CallOption) (*v1alpha1.Application, error) { +func (c *fakeAppServiceClient) Sync(ctx context.Context, in *applicationpkg.ApplicationSyncRequest, opts ...grpc.CallOption) (*v1alpha1.Application, error) { return nil, nil } -func (c *fakeAppServiceClient) ManagedResources(_ context.Context, _ *applicationpkg.ResourcesQuery, _ ...grpc.CallOption) (*applicationpkg.ManagedResourcesResponse, error) { +func (c *fakeAppServiceClient) ManagedResources(ctx context.Context, in *applicationpkg.ResourcesQuery, opts ...grpc.CallOption) (*applicationpkg.ManagedResourcesResponse, error) { return nil, nil } -func (c *fakeAppServiceClient) ResourceTree(_ context.Context, _ *applicationpkg.ResourcesQuery, _ ...grpc.CallOption) (*v1alpha1.ApplicationTree, error) { +func (c *fakeAppServiceClient) ResourceTree(ctx context.Context, in *applicationpkg.ResourcesQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationTree, error) { return nil, nil } -func (c *fakeAppServiceClient) WatchResourceTree(_ context.Context, _ *applicationpkg.ResourcesQuery, _ ...grpc.CallOption) (applicationpkg.ApplicationService_WatchResourceTreeClient, error) { +func (c *fakeAppServiceClient) WatchResourceTree(ctx context.Context, in *applicationpkg.ResourcesQuery, opts ...grpc.CallOption) (applicationpkg.ApplicationService_WatchResourceTreeClient, error) { return nil, nil } -func (c *fakeAppServiceClient) Rollback(_ context.Context, _ *applicationpkg.ApplicationRollbackRequest, _ ...grpc.CallOption) (*v1alpha1.Application, error) { +func (c *fakeAppServiceClient) Rollback(ctx context.Context, in *applicationpkg.ApplicationRollbackRequest, opts ...grpc.CallOption) (*v1alpha1.Application, error) { return nil, nil } -func (c *fakeAppServiceClient) TerminateOperation(_ context.Context, _ *applicationpkg.OperationTerminateRequest, _ ...grpc.CallOption) (*applicationpkg.OperationTerminateResponse, error) { +func (c *fakeAppServiceClient) TerminateOperation(ctx context.Context, in *applicationpkg.OperationTerminateRequest, opts ...grpc.CallOption) (*applicationpkg.OperationTerminateResponse, error) { return nil, nil } -func (c *fakeAppServiceClient) GetResource(_ context.Context, _ *applicationpkg.ApplicationResourceRequest, _ ...grpc.CallOption) (*applicationpkg.ApplicationResourceResponse, error) { +func (c *fakeAppServiceClient) GetResource(ctx context.Context, in *applicationpkg.ApplicationResourceRequest, opts ...grpc.CallOption) (*applicationpkg.ApplicationResourceResponse, error) { return nil, nil } -func (c *fakeAppServiceClient) PatchResource(_ context.Context, _ *applicationpkg.ApplicationResourcePatchRequest, _ ...grpc.CallOption) (*applicationpkg.ApplicationResourceResponse, error) { +func (c *fakeAppServiceClient) PatchResource(ctx context.Context, in *applicationpkg.ApplicationResourcePatchRequest, opts ...grpc.CallOption) (*applicationpkg.ApplicationResourceResponse, error) { return nil, nil } -func (c *fakeAppServiceClient) ListResourceActions(_ context.Context, _ *applicationpkg.ApplicationResourceRequest, _ ...grpc.CallOption) (*applicationpkg.ResourceActionsListResponse, error) { +func (c *fakeAppServiceClient) ListResourceActions(ctx context.Context, in *applicationpkg.ApplicationResourceRequest, opts ...grpc.CallOption) (*applicationpkg.ResourceActionsListResponse, error) { return nil, nil } -func (c *fakeAppServiceClient) RunResourceAction(_ context.Context, _ *applicationpkg.ResourceActionRunRequest, _ ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) { +func (c *fakeAppServiceClient) RunResourceAction(ctx context.Context, in *applicationpkg.ResourceActionRunRequest, opts ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) { return nil, nil } -func (c *fakeAppServiceClient) DeleteResource(_ context.Context, _ *applicationpkg.ApplicationResourceDeleteRequest, _ ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) { +func (c *fakeAppServiceClient) DeleteResource(ctx context.Context, in *applicationpkg.ApplicationResourceDeleteRequest, opts ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) { return nil, nil } -func (c *fakeAppServiceClient) PodLogs(_ context.Context, _ *applicationpkg.ApplicationPodLogsQuery, _ ...grpc.CallOption) (applicationpkg.ApplicationService_PodLogsClient, error) { +func (c *fakeAppServiceClient) PodLogs(ctx context.Context, in *applicationpkg.ApplicationPodLogsQuery, opts ...grpc.CallOption) (applicationpkg.ApplicationService_PodLogsClient, error) { return nil, nil } -func (c *fakeAppServiceClient) ListLinks(_ context.Context, _ *applicationpkg.ListAppLinksRequest, _ ...grpc.CallOption) (*applicationpkg.LinksResponse, error) { +func (c *fakeAppServiceClient) ListLinks(ctx context.Context, in *applicationpkg.ListAppLinksRequest, opts ...grpc.CallOption) (*applicationpkg.LinksResponse, error) { return nil, nil } -func (c *fakeAppServiceClient) ListResourceLinks(_ context.Context, _ *applicationpkg.ApplicationResourceRequest, _ ...grpc.CallOption) (*applicationpkg.LinksResponse, error) { +func (c *fakeAppServiceClient) ListResourceLinks(ctx context.Context, in *applicationpkg.ApplicationResourceRequest, opts ...grpc.CallOption) (*applicationpkg.LinksResponse, error) { return nil, nil } -type fakeAcdClient struct { - simulateTimeout uint -} +type fakeAcdClient struct{} func (c *fakeAcdClient) ClientOptions() argocdclient.ClientOptions { return argocdclient.ClientOptions{} @@ -2358,15 +2289,15 @@ func (c *fakeAcdClient) NewAccountClientOrDie() (io.Closer, accountpkg.AccountSe return nil, nil } -func (c *fakeAcdClient) WatchApplicationWithRetry(_ context.Context, _ string, _ string) chan *v1alpha1.ApplicationWatchEvent { +func (c *fakeAcdClient) WatchApplicationWithRetry(ctx context.Context, appName string, revision string) chan *v1alpha1.ApplicationWatchEvent { appEventsCh := make(chan *v1alpha1.ApplicationWatchEvent) go func() { modifiedEvent := new(v1alpha1.ApplicationWatchEvent) - modifiedEvent.Type = watch.Modified + modifiedEvent.Type = k8swatch.Modified appEventsCh <- modifiedEvent deletedEvent := new(v1alpha1.ApplicationWatchEvent) - deletedEvent.Type = watch.Deleted + deletedEvent.Type = k8swatch.Deleted appEventsCh <- deletedEvent }() return appEventsCh diff --git a/cmd/argocd/commands/applicationset.go b/cmd/argocd/commands/applicationset.go index 97ce8c5d8e..3dcc905182 100644 --- a/cmd/argocd/commands/applicationset.go +++ b/cmd/argocd/commands/applicationset.go @@ -11,18 +11,18 @@ import ( "github.com/spf13/cobra" "google.golang.org/grpc/codes" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/admin" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/applicationset" - arogappsetv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/grpc" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/templates" + "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/errors" + "github.com/argoproj/argo-cd/v2/util/grpc" + argoio "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/templates" ) var appSetExample = templates.Examples(` @@ -80,7 +80,7 @@ func NewApplicationSetGetCommand(clientOpts *argocdclient.ClientOptions) *cobra. } acdClient := headless.NewClientOrDie(clientOpts, c) conn, appIf := acdClient.NewApplicationSetClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) appSetName, appSetNs := argo.ParseFromQualifiedName(args[0], "") @@ -135,8 +135,8 @@ func NewApplicationSetCreateCommand(clientOpts *argocdclient.ClientOptions) *cob os.Exit(1) } argocdClient := headless.NewClientOrDie(clientOpts, c) - fileURL := args[0] - appsets, err := cmdutil.ConstructApplicationSet(fileURL) + fileUrl := args[0] + appsets, err := cmdutil.ConstructApplicationSet(fileUrl) errors.CheckError(err) if len(appsets) == 0 { @@ -146,11 +146,12 @@ func NewApplicationSetCreateCommand(clientOpts *argocdclient.ClientOptions) *cob for _, appset := range appsets { if appset.Name == "" { - errors.Fatal(errors.ErrorGeneric, fmt.Sprintf("Error creating ApplicationSet %s. ApplicationSet does not have Name field set", appset)) + err := fmt.Errorf("Error creating ApplicationSet %s. ApplicationSet does not have Name field set", appset) + errors.CheckError(err) } conn, appIf := argocdClient.NewApplicationSetClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) // Get app before creating to see if it is being updated or no change existing, err := appIf.Get(ctx, &applicationset.ApplicationSetGetQuery{Name: appset.Name, AppsetNamespace: appset.Namespace}) @@ -172,16 +173,15 @@ func NewApplicationSetCreateCommand(clientOpts *argocdclient.ClientOptions) *cob } var action string - switch { - case existing == nil: + if existing == nil { action = "created" - case !hasAppSetChanged(existing, created, upsert): + } else if !hasAppSetChanged(existing, created, upsert) { action = "unchanged" - default: + } else { action = "updated" } - c.PrintErrf("ApplicationSet '%s' %s%s\n", created.Name, action, dryRunMsg) + c.PrintErrf("ApplicationSet '%s' %s%s\n", created.ObjectMeta.Name, action, dryRunMsg) switch output { case "yaml", "json": @@ -227,8 +227,8 @@ func NewApplicationSetGenerateCommand(clientOpts *argocdclient.ClientOptions) *c os.Exit(1) } argocdClient := headless.NewClientOrDie(clientOpts, c) - fileURL := args[0] - appsets, err := cmdutil.ConstructApplicationSet(fileURL) + fileUrl := args[0] + appsets, err := cmdutil.ConstructApplicationSet(fileUrl) errors.CheckError(err) if len(appsets) != 1 { @@ -237,11 +237,12 @@ func NewApplicationSetGenerateCommand(clientOpts *argocdclient.ClientOptions) *c } appset := appsets[0] if appset.Name == "" { - errors.Fatal(errors.ErrorGeneric, fmt.Sprintf("Error generating apps for ApplicationSet %s. ApplicationSet does not have Name field set", appset)) + err := fmt.Errorf("Error generating apps for ApplicationSet %s. ApplicationSet does not have Name field set", appset) + errors.CheckError(err) } conn, appIf := argocdClient.NewApplicationSetClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) req := applicationset.ApplicationSetGenerateRequest{ ApplicationSet: appset, @@ -256,7 +257,7 @@ func NewApplicationSetGenerateCommand(clientOpts *argocdclient.ClientOptions) *c switch output { case "yaml", "json": - var resources []any + var resources []interface{} for i := range appsList { app := appsList[i] // backfill api version and kind because k8s client always return empty values for these fields @@ -292,11 +293,11 @@ func NewApplicationSetListCommand(clientOpts *argocdclient.ClientOptions) *cobra # List all ApplicationSets argocd appset list `), - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationSetClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) appsets, err := appIf.List(ctx, &applicationset.ApplicationSetListQuery{Selector: selector, Projects: projects, AppsetNamespace: appSetNamespace}) errors.CheckError(err) @@ -341,8 +342,8 @@ func NewApplicationSetDeleteCommand(clientOpts *argocdclient.ClientOptions) *cob os.Exit(1) } conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationSetClientOrDie() - defer utilio.Close(conn) - isTerminal := isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) + defer argoio.Close(conn) + var isTerminal bool = isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) numOfApps := len(args) promptFlag := c.Flag("yes") if promptFlag.Changed && promptFlag.Value.String() == "true" { @@ -395,7 +396,7 @@ func printApplicationSetNames(apps []arogappsetv1.ApplicationSet) { func printApplicationSetTable(apps []arogappsetv1.ApplicationSet, output *string) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) var fmtStr string - headers := []any{"NAME", "PROJECT", "SYNCPOLICY", "CONDITIONS"} + headers := []interface{}{"NAME", "PROJECT", "SYNCPOLICY", "CONDITIONS"} if *output == "wide" { fmtStr = "%s\t%s\t%s\t%s\t%s\t%s\t%s\n" headers = append(headers, "REPO", "PATH", "TARGET") @@ -410,7 +411,7 @@ func printApplicationSetTable(apps []arogappsetv1.ApplicationSet, output *string conditions = append(conditions, condition) } } - vals := []any{ + vals := []interface{}{ app.QualifiedName(), app.Spec.Template.Spec.Project, app.Spec.SyncPolicy, @@ -458,7 +459,7 @@ func printAppSetSummaryTable(appSet *arogappsetv1.ApplicationSet) { syncPolicyStr string syncPolicy = appSet.Spec.Template.Spec.SyncPolicy ) - if syncPolicy != nil && syncPolicy.IsAutomatedSyncEnabled() { + if syncPolicy != nil && syncPolicy.Automated != nil { syncPolicyStr = "Automated" if syncPolicy.Automated.Prune { syncPolicyStr += " (Prune)" @@ -495,7 +496,7 @@ func hasAppSetChanged(appReq, appRes *arogappsetv1.ApplicationSet, upsert bool) if reflect.DeepEqual(appRes.Spec, appReq.Spec) && reflect.DeepEqual(appRes.Labels, appReq.Labels) && - reflect.DeepEqual(appRes.Annotations, appReq.Annotations) && + reflect.DeepEqual(appRes.ObjectMeta.Annotations, appReq.Annotations) && reflect.DeepEqual(appRes.Finalizers, appReq.Finalizers) { return false } diff --git a/cmd/argocd/commands/applicationset_test.go b/cmd/argocd/commands/applicationset_test.go index c44f2297a5..fd6f07b5d7 100644 --- a/cmd/argocd/commands/applicationset_test.go +++ b/cmd/argocd/commands/applicationset_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestPrintApplicationSetNames(t *testing.T) { diff --git a/cmd/argocd/commands/bcrypt.go b/cmd/argocd/commands/bcrypt.go index 7b0b1a75af..d2557ef411 100644 --- a/cmd/argocd/commands/bcrypt.go +++ b/cmd/argocd/commands/bcrypt.go @@ -16,7 +16,7 @@ func NewBcryptCmd() *cobra.Command { Short: "Generate bcrypt hash for any password", Example: `# Generate bcrypt hash for any password argocd account bcrypt --password YOUR_PASSWORD`, - Run: func(cmd *cobra.Command, _ []string) { + Run: func(cmd *cobra.Command, args []string) { bytePassword := []byte(password) // Hashing the password hash, err := bcrypt.GenerateFromPassword(bytePassword, bcrypt.DefaultCost) diff --git a/cmd/argocd/commands/cert.go b/cmd/argocd/commands/cert.go index 3cd9b3b21c..d123a9ae66 100644 --- a/cmd/argocd/commands/cert.go +++ b/cmd/argocd/commands/cert.go @@ -2,7 +2,6 @@ package commands import ( "crypto/x509" - stderrors "errors" "fmt" "os" "sort" @@ -11,14 +10,14 @@ import ( "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - certificatepkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/certificate" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - certutil "github.com/argoproj/argo-cd/v3/util/cert" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "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" + certutil "github.com/argoproj/argo-cd/v2/util/cert" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/io" ) // NewCertCommand returns a new instance of an `argocd repo` command @@ -69,7 +68,7 @@ func NewCertAddTLSCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command ctx := c.Context() conn, certIf := headless.NewClientOrDie(clientOpts, c).NewCertClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) if len(args) != 1 { c.HelpFunc()(c, args) @@ -106,8 +105,9 @@ func NewCertAddTLSCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command if subjectMap[x509cert.Subject.String()] != nil { fmt.Printf("ERROR: Cert with subject '%s' already seen in the input stream.\n", x509cert.Subject.String()) continue + } else { + subjectMap[x509cert.Subject.String()] = x509cert } - subjectMap[x509cert.Subject.String()] = x509cert } serverName := args[0] @@ -148,11 +148,11 @@ func NewCertAddSSHCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command command := &cobra.Command{ Use: "add-ssh --batch", Short: "Add SSH known host entries for repository servers", - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() conn, certIf := headless.NewClientOrDie(clientOpts, c).NewCertClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) var sshKnownHostsLists []string var err error @@ -167,13 +167,13 @@ func NewCertAddSSHCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command sshKnownHostsLists, err = certutil.ParseSSHKnownHostsFromStream(os.Stdin) } } else { - err = stderrors.New("you need to specify --batch or specify --help for usage instructions") + err = fmt.Errorf("You need to specify --batch or specify --help for usage instructions") } errors.CheckError(err) if len(sshKnownHostsLists) == 0 { - errors.Fatal(errors.ErrorGeneric, "No valid SSH known hosts data found.") + errors.CheckError(fmt.Errorf("No valid SSH known hosts data found.")) } for _, knownHostsEntry := range sshKnownHostsLists { @@ -226,7 +226,7 @@ func NewCertRemoveCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command os.Exit(1) } conn, certIf := headless.NewClientOrDie(clientOpts, c).NewCertClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) hostNamePattern := args[0] // Prevent the user from specifying a wildcard as hostname as precaution @@ -234,7 +234,8 @@ func NewCertRemoveCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command // remove all certificates, but it's less likely that it happens by // accident. if hostNamePattern == "*" { - errors.Fatal(errors.ErrorGeneric, "A single wildcard is not allowed as REPOSERVER name.") + err := fmt.Errorf("A single wildcard is not allowed as REPOSERVER name.") + errors.CheckError(err) } promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) @@ -275,7 +276,7 @@ func NewCertListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { command := &cobra.Command{ Use: "list", Short: "List configured certificates", - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() if certType != "" { @@ -289,7 +290,7 @@ func NewCertListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { } conn, certIf := headless.NewClientOrDie(clientOpts, c).NewCertClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) certificates, err := certIf.ListCertificates(ctx, &certificatepkg.RepositoryCertificateQuery{HostNamePattern: hostNamePattern, CertType: certType}) errors.CheckError(err) @@ -317,12 +318,11 @@ func printCertTable(certs []appsv1.RepositoryCertificate, sortOrder string) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) fmt.Fprintf(w, "HOSTNAME\tTYPE\tSUBTYPE\tINFO\n") - switch sortOrder { - case "hostname", "": + if sortOrder == "hostname" || sortOrder == "" { sort.Slice(certs, func(i, j int) bool { return certs[i].ServerName < certs[j].ServerName }) - case "type": + } else if sortOrder == "type" { sort.Slice(certs, func(i, j int) bool { return certs[i].CertType < certs[j].CertType }) diff --git a/cmd/argocd/commands/cluster.go b/cmd/argocd/commands/cluster.go index e41a8f8e6d..65a3981dab 100644 --- a/cmd/argocd/commands/cluster.go +++ b/cmd/argocd/commands/cluster.go @@ -8,9 +8,6 @@ import ( "strings" "text/tabwriter" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "github.com/mattn/go-isatty" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -18,17 +15,17 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/common" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - clusterpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/clusterauth" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/text/label" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/common" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + clusterpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster" + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/clusterauth" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/text/label" ) const ( @@ -91,7 +88,7 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie ) command := &cobra.Command{ Use: "add CONTEXT", - Short: cliName + " cluster add CONTEXT", + Short: fmt.Sprintf("%s cluster add CONTEXT", cliName), Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -120,14 +117,13 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie managerBearerToken := "" var awsAuthConf *argoappv1.AWSAuthConfig var execProviderConf *argoappv1.ExecProviderConfig - switch { - case clusterOpts.AwsClusterName != "": + if clusterOpts.AwsClusterName != "" { awsAuthConf = &argoappv1.AWSAuthConfig{ ClusterName: clusterOpts.AwsClusterName, RoleARN: clusterOpts.AwsRoleArn, Profile: clusterOpts.AwsProfile, } - case clusterOpts.ExecProviderCommand != "": + } else if clusterOpts.ExecProviderCommand != "" { execProviderConf = &argoappv1.ExecProviderConfig{ Command: clusterOpts.ExecProviderCommand, Args: clusterOpts.ExecProviderArgs, @@ -135,7 +131,7 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie APIVersion: clusterOpts.ExecProviderAPIVersion, InstallHint: clusterOpts.ExecProviderInstallHint, } - default: + } else { // Install RBAC resources for managing the cluster if clusterOpts.ServiceAccount != "" { managerBearerToken, err = clusterauth.GetServiceAccountBearerToken(clientset, clusterOpts.SystemNamespace, clusterOpts.ServiceAccount, common.BearerTokenTimeout) @@ -162,7 +158,7 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie errors.CheckError(err) conn, clusterIf := headless.NewClientOrDie(clientOpts, c).NewClusterClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) if clusterOpts.Name != "" { contextName = clusterOpts.Name } @@ -170,14 +166,13 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie if clusterOpts.InClusterEndpoint() { clst.Server = argoappv1.KubernetesInternalAPIServerAddr } else if clusterOpts.ClusterEndpoint == string(cmdutil.KubePublicEndpoint) { - endpoint, caData, err := cmdutil.GetKubePublicEndpoint(clientset) + endpoint, err := cmdutil.GetKubePublicEndpoint(clientset) if err != nil || len(endpoint) == 0 { log.Warnf("Failed to find the cluster endpoint from kube-public data: %v", err) log.Infof("Falling back to the endpoint '%s' as listed in the kubeconfig context", clst.Server) endpoint = clst.Server } clst.Server = endpoint - clst.Config.CAData = caData } if clusterOpts.Shard >= 0 { @@ -215,7 +210,7 @@ func getRestConfig(pathOpts *clientcmd.PathOptions, ctxName string) (*rest.Confi clstContext := config.Contexts[ctxName] if clstContext == nil { - return nil, fmt.Errorf("context %s does not exist in kubeconfig", ctxName) + return nil, fmt.Errorf("Context %s does not exist in kubeconfig", ctxName) } overrides := clientcmd.ConfigOverrides{ @@ -254,7 +249,7 @@ func NewClusterSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command // name of the cluster whose fields have to be updated. clusterName = args[0] conn, clusterIf := headless.NewClientOrDie(clientOpts, c).NewClusterClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) // checks the fields that needs to be updated updatedFields := checkFieldsToUpdate(clusterOptions, labels, annotations) namespaces := clusterOptions.Namespaces @@ -283,12 +278,7 @@ func NewClusterSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command }, } _, err := clusterIf.Update(ctx, &clusterUpdateRequest) - if err != nil { - if status.Code(err) == codes.PermissionDenied { - log.Error("Ensure that the cluster is present and you have the necessary permissions to update the cluster") - } - errors.CheckError(err) - } + errors.CheckError(err) fmt.Printf("Cluster '%s' updated.\n", clusterName) } else { fmt.Print("Specify the cluster field to be updated.\n") @@ -336,7 +326,7 @@ argocd cluster get in-cluster`, os.Exit(1) } conn, clusterIf := headless.NewClientOrDie(clientOpts, c).NewClusterClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) clusters := make([]argoappv1.Cluster, 0) for _, clusterSelector := range args { clst, err := clusterIf.Get(ctx, getQueryBySelector(clusterSelector)) @@ -380,12 +370,12 @@ func printClusterDetails(clusters []argoappv1.Cluster) { fmt.Printf("Cluster information\n\n") fmt.Printf(" Server URL: %s\n", cluster.Server) fmt.Printf(" Server Name: %s\n", strWithDefault(cluster.Name, "-")) - //nolint:staticcheck + // nolint:staticcheck fmt.Printf(" Server Version: %s\n", cluster.ServerVersion) fmt.Printf(" Namespaces: %s\n", formatNamespaces(cluster)) fmt.Printf("\nTLS configuration\n\n") - fmt.Printf(" Client cert: %v\n", string(cluster.Config.CertData) != "") - fmt.Printf(" Cert validation: %v\n", !cluster.Config.Insecure) + fmt.Printf(" Client cert: %v\n", string(cluster.Config.TLSClientConfig.CertData) != "") + fmt.Printf(" Cert validation: %v\n", !cluster.Config.TLSClientConfig.Insecure) fmt.Printf("\nAuthentication\n\n") fmt.Printf(" Basic authentication: %v\n", cluster.Config.Username != "") fmt.Printf(" oAuth authentication: %v\n", cluster.Config.BearerToken != "") @@ -412,9 +402,9 @@ argocd cluster rm cluster-name`, os.Exit(1) } conn, clusterIf := headless.NewClientOrDie(clientOpts, c).NewClusterClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) numOfClusters := len(args) - var isConfirmAll bool + var isConfirmAll bool = false for _, clusterSelector := range args { clusterQuery := getQueryBySelector(clusterSelector) @@ -475,7 +465,7 @@ func printClusterTable(clusters []argoappv1.Cluster) { if len(c.Namespaces) > 0 { server = fmt.Sprintf("%s (%d namespaces)", c.Server, len(c.Namespaces)) } - //nolint:staticcheck + // nolint:staticcheck _, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", server, c.Name, c.ServerVersion, c.ConnectionState.Status, c.ConnectionState.Message, c.Project) } _ = w.Flush() @@ -506,11 +496,11 @@ func NewClusterListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman command := &cobra.Command{ Use: "list", Short: "List configured clusters", - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() conn, clusterIf := headless.NewClientOrDie(clientOpts, c).NewClusterClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) clusters, err := clusterIf.List(ctx, &clusterpkg.ClusterQuery{}) errors.CheckError(err) switch output { @@ -551,7 +541,7 @@ argocd cluster list -o server func NewClusterRotateAuthCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { command := &cobra.Command{ Use: "rotate-auth SERVER/NAME", - Short: cliName + " cluster rotate-auth SERVER/NAME", + Short: fmt.Sprintf("%s cluster rotate-auth SERVER/NAME", cliName), Example: `argocd cluster rotate-auth https://12.34.567.89 argocd cluster rotate-auth cluster-name`, Run: func(c *cobra.Command, args []string) { @@ -562,7 +552,7 @@ argocd cluster rotate-auth cluster-name`, os.Exit(1) } conn, clusterIf := headless.NewClientOrDie(clientOpts, c).NewClusterClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) cluster := args[0] clusterQuery := getQueryBySelector(cluster) diff --git a/cmd/argocd/commands/cluster_test.go b/cmd/argocd/commands/cluster_test.go index 8307f36428..311713a30f 100644 --- a/cmd/argocd/commands/cluster_test.go +++ b/cmd/argocd/commands/cluster_test.go @@ -9,24 +9,24 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func Test_getQueryBySelector(t *testing.T) { query := getQueryBySelector("my-cluster") assert.Equal(t, "my-cluster", query.Name) - assert.Empty(t, query.Server) + assert.Equal(t, "", query.Server) query = getQueryBySelector("http://my-server") - assert.Empty(t, query.Name) + assert.Equal(t, "", query.Name) assert.Equal(t, "http://my-server", query.Server) query = getQueryBySelector("https://my-server") - assert.Empty(t, query.Name) + assert.Equal(t, "", query.Name) assert.Equal(t, "https://my-server", query.Server) } -func Test_printClusterTable(_ *testing.T) { +func Test_printClusterTable(t *testing.T) { printClusterTable([]v1alpha1.Cluster{ { Server: "my-server", @@ -93,7 +93,7 @@ func Test_getRestConfig(t *testing.T) { }, nil, true, - "context not-exist does not exist in kubeconfig", + "Context not-exist does not exist in kubeconfig", }, } for _, tt := range tests { diff --git a/cmd/argocd/commands/common.go b/cmd/argocd/commands/common.go index 9b924e063b..849b9a48f0 100644 --- a/cmd/argocd/commands/common.go +++ b/cmd/argocd/commands/common.go @@ -17,7 +17,7 @@ const ( ) // PrintResource prints a single resource in YAML or JSON format to stdout according to the output format -func PrintResource(resource any, output string) error { +func PrintResource(resource interface{}, output string) error { switch output { case "json": jsonBytes, err := json.MarshalIndent(resource, "", " ") @@ -38,7 +38,7 @@ func PrintResource(resource any, output string) error { } // PrintResourceList marshals & prints a list of resources to stdout according to the output format -func PrintResourceList(resources any, output string, single bool) error { +func PrintResourceList(resources interface{}, output string, single bool) error { kt := reflect.ValueOf(resources) // Sometimes, we want to marshal the first resource of a slice or array as single item if kt.Kind() == reflect.Slice || kt.Kind() == reflect.Array { diff --git a/cmd/argocd/commands/common_test.go b/cmd/argocd/commands/common_test.go index 8e0834253a..8a3a2446a6 100644 --- a/cmd/argocd/commands/common_test.go +++ b/cmd/argocd/commands/common_test.go @@ -16,7 +16,7 @@ baz: foo foo: bar ` -const expectJSONSingle = `{ +const expectJsonSingle = `{ "bar": "", "baz": "foo", "foo": "bar" @@ -33,7 +33,7 @@ two: foo: bar ` -const expectJSONList = `{ +const expectJsonList = `{ "one": { "bar": "", "baz": "foo", @@ -88,7 +88,7 @@ func Test_PrintResource(t *testing.T) { return err }) require.NoError(t, err) - assert.JSONEq(t, expectJSONSingle, str) + assert.JSONEq(t, expectJsonSingle, str) err = PrintResource(testResource, "unknown") require.Error(t, err) @@ -123,7 +123,7 @@ func Test_PrintResourceList(t *testing.T) { return err }) require.NoError(t, err) - assert.JSONEq(t, expectJSONList, str) + assert.JSONEq(t, expectJsonList, str) str, err = captureOutput(func() error { err := PrintResourceList(testResource2, "yaml", true) @@ -137,7 +137,7 @@ func Test_PrintResourceList(t *testing.T) { return err }) require.NoError(t, err) - assert.JSONEq(t, expectJSONSingle, str) + assert.JSONEq(t, expectJsonSingle, str) err = PrintResourceList(testResource, "unknown", false) require.Error(t, err) diff --git a/cmd/argocd/commands/configure.go b/cmd/argocd/commands/configure.go index d5fa4f2a2d..15c4bef41e 100644 --- a/cmd/argocd/commands/configure.go +++ b/cmd/argocd/commands/configure.go @@ -6,9 +6,9 @@ import ( "github.com/spf13/cobra" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/localconfig" + 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 @@ -24,7 +24,7 @@ argocd configure --prompts-enabled=true # Disable optional interactive prompts argocd configure --prompts-enabled=false`, - Run: func(_ *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { localCfg, err := localconfig.ReadLocalConfig(globalClientOpts.ConfigPath) errors.CheckError(err) diff --git a/cmd/argocd/commands/configure_test.go b/cmd/argocd/commands/configure_test.go index a538ffb225..cb084f88ab 100644 --- a/cmd/argocd/commands/configure_test.go +++ b/cmd/argocd/commands/configure_test.go @@ -4,12 +4,12 @@ import ( "os" "testing" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/util/localconfig" + "github.com/argoproj/argo-cd/v2/util/localconfig" ) func TestNewConfigureCommand_PromptsEnabled_DefaultTrue(t *testing.T) { diff --git a/cmd/argocd/commands/context.go b/cmd/argocd/commands/context.go index 38be5e8808..2c4b37ba2f 100644 --- a/cmd/argocd/commands/context.go +++ b/cmd/argocd/commands/context.go @@ -1,7 +1,6 @@ package commands import ( - stderrors "errors" "fmt" "os" "path" @@ -11,9 +10,9 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/localconfig" + 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" ) // NewContextCommand returns a new instance of an `argocd ctx` command @@ -86,12 +85,12 @@ func deleteContext(context, configPath string) error { localCfg, err := localconfig.ReadLocalConfig(configPath) errors.CheckError(err) if localCfg == nil { - return stderrors.New("nothing to logout from") + return fmt.Errorf("Nothing to logout from") } serverName, ok := localCfg.RemoveContext(context) if !ok { - return fmt.Errorf("context %s does not exist", context) + return fmt.Errorf("Context %s does not exist", context) } _ = localCfg.RemoveUser(context) _ = localCfg.RemoveServer(serverName) @@ -105,7 +104,7 @@ func deleteContext(context, configPath string) error { } err = localconfig.ValidateLocalConfig(*localCfg) if err != nil { - return stderrors.New("error in logging out") + return fmt.Errorf("Error in logging out") } err = localconfig.WriteLocalConfig(*localCfg, configPath) errors.CheckError(err) diff --git a/cmd/argocd/commands/context_test.go b/cmd/argocd/commands/context_test.go index 0e31a3a7ec..e9f953a22c 100644 --- a/cmd/argocd/commands/context_test.go +++ b/cmd/argocd/commands/context_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/util/localconfig" + "github.com/argoproj/argo-cd/v2/util/localconfig" ) const testConfig = `contexts: @@ -70,7 +70,7 @@ func TestContextDelete(t *testing.T) { localConfig, err = localconfig.ReadLocalConfig(testConfigFilePath) require.NoError(t, err) - assert.Empty(t, localConfig.CurrentContext) + assert.Equal(t, "", localConfig.CurrentContext) assert.NotContains(t, localConfig.Contexts, localconfig.ContextRef{Name: "localhost:8080", Server: "localhost:8080", User: "localhost:8080"}) assert.NotContains(t, localConfig.Servers, localconfig.Server{PlainText: true, Server: "localhost:8080"}) assert.NotContains(t, localConfig.Users, localconfig.User{AuthToken: "vErrYS3c3tReFRe$hToken", Name: "localhost:8080"}) diff --git a/cmd/argocd/commands/gpg.go b/cmd/argocd/commands/gpg.go index 3150c5cfe8..bc50655cfa 100644 --- a/cmd/argocd/commands/gpg.go +++ b/cmd/argocd/commands/gpg.go @@ -1,7 +1,6 @@ package commands import ( - stderrors "errors" "fmt" "os" "strings" @@ -9,14 +8,14 @@ import ( "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - gpgkeypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/gpgkey" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/templates" + "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" + "github.com/argoproj/argo-cd/v2/util/errors" + argoio "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/templates" ) // NewGPGCommand returns a new instance of an `argocd repo` command @@ -54,11 +53,11 @@ func NewGPGListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { argocd gpg list -o yaml `), - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() conn, gpgIf := headless.NewClientOrDie(clientOpts, c).NewGPGKeyClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) keys, err := gpgIf.List(ctx, &gpgkeypkg.GnuPGPublicKeyQuery{}) errors.CheckError(err) switch output { @@ -97,10 +96,10 @@ func NewGPGGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { ctx := c.Context() if len(args) != 1 { - errors.Fatal(errors.ErrorGeneric, "Missing KEYID argument") + errors.CheckError(fmt.Errorf("Missing KEYID argument")) } conn, gpgIf := headless.NewClientOrDie(clientOpts, c).NewGPGKeyClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) key, err := gpgIf.Get(ctx, &gpgkeypkg.GnuPGPublicKeyQuery{KeyID: args[0]}) errors.CheckError(err) switch output { @@ -133,18 +132,18 @@ func NewGPGAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { argocd gpg add --from /path/to/keyfile `), - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() if fromFile == "" { - errors.CheckError(stderrors.New("--from is mandatory")) + errors.CheckError(fmt.Errorf("--from is mandatory")) } keyData, err := os.ReadFile(fromFile) if err != nil { errors.CheckError(err) } conn, gpgIf := headless.NewClientOrDie(clientOpts, c).NewGPGKeyClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) resp, err := gpgIf.Create(ctx, &gpgkeypkg.GnuPGPublicKeyCreateRequest{Publickey: &appsv1.GnuPGPublicKey{KeyData: string(keyData)}}) errors.CheckError(err) fmt.Printf("Created %d key(s) from input file", len(resp.Created.Items)) @@ -167,13 +166,13 @@ func NewGPGDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command ctx := c.Context() if len(args) != 1 { - errors.Fatal(errors.ErrorGeneric, "Missing KEYID argument") + errors.CheckError(fmt.Errorf("Missing KEYID argument")) } keyId := args[0] conn, gpgIf := headless.NewClientOrDie(clientOpts, c).NewGPGKeyClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to remove '%s'? [y/n] ", keyId)) diff --git a/cmd/argocd/commands/headless/headless.go b/cmd/argocd/commands/headless/headless.go index 07630b406f..64505fd9c0 100644 --- a/cmd/argocd/commands/headless/headless.go +++ b/cmd/argocd/commands/headless/headless.go @@ -15,7 +15,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" runtimeUtil "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/dynamic" @@ -25,20 +25,20 @@ import ( "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/initialize" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - repoapiclient "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/server" - servercache "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/util/cache" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/cli" - utilio "github.com/argoproj/argo-cd/v3/util/io" - kubeutil "github.com/argoproj/argo-cd/v3/util/kube" - "github.com/argoproj/argo-cd/v3/util/localconfig" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/initialize" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + repoapiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/server" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "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/cli" + "github.com/argoproj/argo-cd/v2/util/io" + kubeutil "github.com/argoproj/argo-cd/v2/util/kube" + "github.com/argoproj/argo-cd/v2/util/localconfig" ) type forwardCacheClient struct { @@ -88,7 +88,7 @@ func (c *forwardCacheClient) Rename(oldKey string, newKey string, expiration tim }) } -func (c *forwardCacheClient) Get(key string, obj any) error { +func (c *forwardCacheClient) Get(key string, obj interface{}) error { return c.doLazy(func(client cache.CacheClient) error { return client.Get(key, obj) }) @@ -122,14 +122,14 @@ type forwardRepoClientset struct { kubeClientset kubernetes.Interface } -func (c *forwardRepoClientset) NewRepoServerClient() (utilio.Closer, repoapiclient.RepoServerServiceClient, error) { +func (c *forwardRepoClientset) NewRepoServerClient() (io.Closer, repoapiclient.RepoServerServiceClient, error) { c.init.Do(func() { overrides := clientcmd.ConfigOverrides{ CurrentContext: c.context, } repoServerName := c.repoServerName repoServererviceLabelSelector := common.LabelKeyComponentRepoServer + "=" + common.LabelValueComponentRepoServer - repoServerServices, err := c.kubeClientset.CoreV1().Services(c.namespace).List(context.Background(), metav1.ListOptions{LabelSelector: repoServererviceLabelSelector}) + repoServerServices, err := c.kubeClientset.CoreV1().Services(c.namespace).List(context.Background(), metaV1.ListOptions{LabelSelector: repoServererviceLabelSelector}) if err != nil { c.err = err return @@ -164,7 +164,7 @@ func testAPI(ctx context.Context, clientOpts *apiclient.ClientOptions) error { if err != nil { return fmt.Errorf("failed to create version client: %w", err) } - defer utilio.Close(closer) + defer io.Close(closer) _, err = versionClient.Version(ctx, &empty.Empty{}) if err != nil { return fmt.Errorf("failed to get version: %w", err) @@ -212,13 +212,13 @@ func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOpti address = ptr.To("localhost") } if port == nil || *port == 0 { - addr := *address + ":0" + addr := fmt.Sprintf("%s:0", *address) ln, err := net.Listen("tcp", addr) if err != nil { return fmt.Errorf("failed to listen on %q: %w", addr, err) } port = &ln.Addr().(*net.TCPAddr).Port - utilio.Close(ln) + io.Close(ln) } restConfig, err := clientConfig.ClientConfig() diff --git a/cmd/argocd/commands/initialize/cmd.go b/cmd/argocd/commands/initialize/cmd.go index 1cc0b45e06..8f9da9f687 100644 --- a/cmd/argocd/commands/initialize/cmd.go +++ b/cmd/argocd/commands/initialize/cmd.go @@ -4,7 +4,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/argoproj/argo-cd/v3/util/cli" + "github.com/argoproj/argo-cd/v2/util/cli" ) func RetrieveContextIfChanged(contextFlag *pflag.Flag) string { diff --git a/cmd/argocd/commands/initialize/cmd_test.go b/cmd/argocd/commands/initialize/cmd_test.go index 597fc965cc..59f2efb55a 100644 --- a/cmd/argocd/commands/initialize/cmd_test.go +++ b/cmd/argocd/commands/initialize/cmd_test.go @@ -40,7 +40,7 @@ func Test_FlagContextNotChanged(t *testing.T) { Annotations: nil, }) - assert.Empty(t, res) + assert.Equal(t, "", res) } func Test_FlagContextChanged(t *testing.T) { @@ -76,5 +76,5 @@ func Test_FlagContextNil(t *testing.T) { Annotations: nil, }) - assert.Empty(t, res) + assert.Equal(t, "", res) } diff --git a/cmd/argocd/commands/login.go b/cmd/argocd/commands/login.go index 07854f2aaf..72b89dae17 100644 --- a/cmd/argocd/commands/login.go +++ b/cmd/argocd/commands/login.go @@ -13,25 +13,25 @@ import ( "time" "github.com/coreos/go-oidc/v3/oidc" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" log "github.com/sirupsen/logrus" "github.com/skratchdot/open-golang/open" "github.com/spf13/cobra" "golang.org/x/oauth2" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - sessionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" - settingspkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/settings" - claimsutil "github.com/argoproj/argo-cd/v3/util/claims" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/errors" - grpc_util "github.com/argoproj/argo-cd/v3/util/grpc" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/localconfig" - oidcutil "github.com/argoproj/argo-cd/v3/util/oidc" - "github.com/argoproj/argo-cd/v3/util/rand" - oidcconfig "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + sessionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" + settingspkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/settings" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/errors" + grpc_util "github.com/argoproj/argo-cd/v2/util/grpc" + "github.com/argoproj/argo-cd/v2/util/io" + jwtutil "github.com/argoproj/argo-cd/v2/util/jwt" + "github.com/argoproj/argo-cd/v2/util/localconfig" + oidcutil "github.com/argoproj/argo-cd/v2/util/oidc" + "github.com/argoproj/argo-cd/v2/util/rand" + oidcconfig "github.com/argoproj/argo-cd/v2/util/settings" ) // NewLoginCommand returns a new instance of `argocd login` command @@ -67,12 +67,11 @@ argocd login cd.argoproj.io --core`, os.Exit(1) } - switch { - case globalClientOpts.PortForward: + if globalClientOpts.PortForward { server = "port-forward" - case globalClientOpts.Core: + } else if globalClientOpts.Core { server = "kubernetes" - default: + } else { server = args[0] if !skipTestTLS { @@ -126,7 +125,7 @@ argocd login cd.argoproj.io --core`, if !globalClientOpts.Core { acdClient := headless.NewClientOrDie(&clientOpts, c) setConn, setIf := acdClient.NewSettingsClientOrDie() - defer utilio.Close(setConn) + defer io.Close(setConn) if !sso { tokenString = passwordLogin(ctx, acdClient, username, password) } else { @@ -143,9 +142,7 @@ argocd login cd.argoproj.io --core`, claims := jwt.MapClaims{} _, _, err := parser.ParseUnverified(tokenString, &claims) errors.CheckError(err) - argoClaims, err := claimsutil.MapClaimsToArgoClaims(claims) - errors.CheckError(err) - fmt.Printf("'%s' logged in successfully\n", userDisplayName(argoClaims)) + fmt.Printf("'%s' logged in successfully\n", userDisplayName(claims)) } // login successful. Persist the config @@ -192,17 +189,14 @@ argocd login cd.argoproj.io --core`, return command } -func userDisplayName(claims *claimsutil.ArgoClaims) string { - if claims == nil { - return "" +func userDisplayName(claims jwt.MapClaims) string { + if email := jwtutil.StringField(claims, "email"); email != "" { + return email } - if claims.Email != "" { - return claims.Email + if name := jwtutil.StringField(claims, "name"); name != "" { + return name } - if claims.Name != "" { - return claims.Name - } - return claims.GetUserIdentifier() + return jwtutil.StringField(claims, "sub") } // oauth2Login opens a browser, runs a temporary HTTP server to delegate OAuth2 login flow and @@ -360,7 +354,7 @@ func oauth2Login( func passwordLogin(ctx context.Context, acdClient argocdclient.Client, username, password string) string { username, password = cli.PromptCredentials(username, password) sessConn, sessionIf := acdClient.NewSessionClientOrDie() - defer utilio.Close(sessConn) + defer io.Close(sessConn) sessionRequest := sessionpkg.SessionCreateRequest{ Username: username, Password: password, diff --git a/cmd/argocd/commands/login_test.go b/cmd/argocd/commands/login_test.go index 43cbf1febf..420b484674 100644 --- a/cmd/argocd/commands/login_test.go +++ b/cmd/argocd/commands/login_test.go @@ -5,12 +5,10 @@ import ( "os" "testing" - claimsutil "github.com/argoproj/argo-cd/v3/util/claims" - utilio "github.com/argoproj/argo-cd/v3/util/io" + utils "github.com/argoproj/argo-cd/v2/util/io" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func captureStdout(callback func()) (string, error) { @@ -27,7 +25,7 @@ func captureStdout(callback func()) (string, error) { }() callback() - utilio.Close(w) + utils.Close(w) data, err := io.ReadAll(r) if err != nil { @@ -37,45 +35,26 @@ func captureStdout(callback func()) (string, error) { } func Test_userDisplayName_email(t *testing.T) { - claims, err := claimsutil.MapClaimsToArgoClaims(jwt.MapClaims{"iss": "qux", "sub": "foo", "email": "firstname.lastname@example.com", "groups": []string{"baz"}}) - require.NoError(t, err) + claims := jwt.MapClaims{"iss": "qux", "sub": "foo", "email": "firstname.lastname@example.com", "groups": []string{"baz"}} actualName := userDisplayName(claims) expectedName := "firstname.lastname@example.com" assert.Equal(t, expectedName, actualName) } func Test_userDisplayName_name(t *testing.T) { - claims, err := claimsutil.MapClaimsToArgoClaims(jwt.MapClaims{"iss": "qux", "sub": "foo", "name": "Firstname Lastname", "groups": []string{"baz"}}) - require.NoError(t, err) + claims := jwt.MapClaims{"iss": "qux", "sub": "foo", "name": "Firstname Lastname", "groups": []string{"baz"}} actualName := userDisplayName(claims) expectedName := "Firstname Lastname" assert.Equal(t, expectedName, actualName) } func Test_userDisplayName_sub(t *testing.T) { - claims, err := claimsutil.MapClaimsToArgoClaims(jwt.MapClaims{"iss": "qux", "sub": "foo", "groups": []string{"baz"}}) - require.NoError(t, err) + claims := jwt.MapClaims{"iss": "qux", "sub": "foo", "groups": []string{"baz"}} actualName := userDisplayName(claims) expectedName := "foo" assert.Equal(t, expectedName, actualName) } -func Test_userDisplayName_federatedClaims(t *testing.T) { - claims, err := claimsutil.MapClaimsToArgoClaims(jwt.MapClaims{ - "iss": "qux", - "sub": "foo", - "groups": []string{"baz"}, - "federated_claims": map[string]any{ - "connector_id": "dex", - "user_id": "ldap-123", - }, - }) - require.NoError(t, err) - actualName := userDisplayName(claims) - expectedName := "ldap-123" - assert.Equal(t, expectedName, actualName) -} - func Test_ssoAuthFlow_ssoLaunchBrowser_false(t *testing.T) { out, _ := captureStdout(func() { ssoAuthFlow("http://test-sso-browser-flow.com", false) diff --git a/cmd/argocd/commands/logout.go b/cmd/argocd/commands/logout.go index 4f39df8841..29dce70965 100644 --- a/cmd/argocd/commands/logout.go +++ b/cmd/argocd/commands/logout.go @@ -7,10 +7,10 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/localconfig" + "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" ) // NewLogoutCommand returns a new instance of `argocd logout` command diff --git a/cmd/argocd/commands/logout_test.go b/cmd/argocd/commands/logout_test.go index 3ff28b2455..2a5c2da7b8 100644 --- a/cmd/argocd/commands/logout_test.go +++ b/cmd/argocd/commands/logout_test.go @@ -7,8 +7,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/util/localconfig" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/util/localconfig" ) func TestLogout(t *testing.T) { diff --git a/cmd/argocd/commands/plugin.go b/cmd/argocd/commands/plugin.go deleted file mode 100644 index 47e5a40e1a..0000000000 --- a/cmd/argocd/commands/plugin.go +++ /dev/null @@ -1,143 +0,0 @@ -package commands - -import ( - "errors" - "fmt" - "os" - "os/exec" - "path/filepath" - "strings" - - "github.com/argoproj/argo-cd/v3/util/cli" - - log "github.com/sirupsen/logrus" -) - -// DefaultPluginHandler implements the PluginHandler interface -type DefaultPluginHandler struct { - ValidPrefixes []string - lookPath func(file string) (string, error) - run func(cmd *exec.Cmd) error -} - -// NewDefaultPluginHandler instantiates the DefaultPluginHandler -func NewDefaultPluginHandler(validPrefixes []string) *DefaultPluginHandler { - return &DefaultPluginHandler{ - ValidPrefixes: validPrefixes, - lookPath: exec.LookPath, - run: func(cmd *exec.Cmd) error { - return cmd.Run() - }, - } -} - -// HandleCommandExecutionError processes the error returned from executing the command. -// It handles both standard Argo CD commands and plugin commands. We don't require to return -// error but we are doing it to cover various test scenarios. -func (h *DefaultPluginHandler) HandleCommandExecutionError(err error, isArgocdCLI bool, args []string) error { - // the log level needs to be setup manually here since the initConfig() - // set by the cobra.OnInitialize() was never executed because cmd.Execute() - // gave us a non-nil error. - initConfig() - cli.SetLogFormat("text") - // If it's an unknown command error, attempt to handle it as a plugin. - // Unfortunately, cobra doesn't handle this error, so we need to assume - // that error consists of substring "unknown command". - // https://github.com/spf13/cobra/pull/2167 - if isArgocdCLI && strings.Contains(err.Error(), "unknown command") { - pluginPath, pluginErr := h.handlePluginCommand(args[1:]) - // IMP: If a plugin doesn't exist, the returned path will be empty along with nil error - // This means the command is neither a normal Argo CD Command nor a plugin. - if pluginErr != nil { - // If plugin handling fails, report the plugin error and exit - fmt.Printf("Error: %v\n", pluginErr) - return pluginErr - } else if pluginPath == "" { - fmt.Printf("Error: %v\nRun 'argocd --help' for usage.\n", err) - return err - } - } else { - // If it's any other error (not an unknown command), report it directly and exit - fmt.Printf("Error: %v\n", err) - return err - } - - return nil -} - -// handlePluginCommand is responsible for finding and executing a plugin when a command isn't recognized as a built-in command -func (h *DefaultPluginHandler) handlePluginCommand(cmdArgs []string) (string, error) { - foundPluginPath := "" - path, found := h.lookForPlugin(cmdArgs[0]) - if !found { - return foundPluginPath, nil - } - - foundPluginPath = path - - // Execute the plugin that is found - if err := h.executePlugin(foundPluginPath, cmdArgs[1:], os.Environ()); err != nil { - return foundPluginPath, err - } - - return foundPluginPath, nil -} - -// lookForPlugin looks for a plugin in the PATH that starts with argocd prefix -func (h *DefaultPluginHandler) lookForPlugin(filename string) (string, bool) { - for _, prefix := range h.ValidPrefixes { - pluginName := fmt.Sprintf("%s-%s", prefix, filename) - path, err := h.lookPath(pluginName) - if err != nil { - // error if a plugin is found in a relative path - if errors.Is(err, exec.ErrDot) { - log.Errorf("Plugin '%s' found in relative path: %v", pluginName, err) - } else { - log.Warnf("error looking for plugin '%s': %v", pluginName, err) - } - continue - } - - if len(path) == 0 { - return "", false - } - - return path, true - } - - return "", false -} - -// executePlugin implements PluginHandler and executes a plugin found -func (h *DefaultPluginHandler) executePlugin(executablePath string, cmdArgs, environment []string) error { - cmd := h.command(executablePath, cmdArgs...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Stdin = os.Stdin - cmd.Env = environment - - err := h.run(cmd) - if err != nil { - return err - } - - return nil -} - -// command creates a new command for all OSs -func (h *DefaultPluginHandler) command(name string, arg ...string) *exec.Cmd { - cmd := &exec.Cmd{ - Path: name, - Args: append([]string{name}, arg...), - } - if filepath.Base(name) == name { - lp, err := h.lookPath(name) - if lp != "" && err != nil { - // Update cmd.Path even if err is non-nil. - // If err is ErrDot (especially on Windows), lp may include a resolved - // extension (like .exe or .bat) that should be preserved. - cmd.Path = lp - } - } - return cmd -} diff --git a/cmd/argocd/commands/plugin_test.go b/cmd/argocd/commands/plugin_test.go deleted file mode 100644 index 2f8ae88d08..0000000000 --- a/cmd/argocd/commands/plugin_test.go +++ /dev/null @@ -1,311 +0,0 @@ -package commands - -import ( - "bytes" - "errors" - "os" - "os/exec" - "path/filepath" - "testing" - - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -// setupPluginPath sets the PATH to the directory where plugins are stored for testing purpose -func setupPluginPath(t *testing.T) { - t.Helper() - wd, err := os.Getwd() - require.NoError(t, err) - testdataPath := filepath.Join(wd, "testdata") - t.Setenv("PATH", testdataPath) -} - -// TestNormalCommandWithPlugin ensures that a standard ArgoCD command executes correctly -// even when a plugin with the same name exists in the PATH -func TestNormalCommandWithPlugin(t *testing.T) { - setupPluginPath(t) - - _ = NewDefaultPluginHandler([]string{"argocd"}) - args := []string{"argocd", "version", "--short", "--client"} - buf := new(bytes.Buffer) - cmd := NewVersionCmd(&argocdclient.ClientOptions{}, nil) - cmd.SetArgs(args[1:]) - cmd.SetOut(buf) - cmd.SilenceErrors = true - cmd.SilenceUsage = true - - err := cmd.Execute() - require.NoError(t, err) - output := buf.String() - assert.Equal(t, "argocd: v99.99.99+unknown\n", output) -} - -// TestPluginExecution verifies that a plugin found in the PATH executes successfully following the correct naming conventions -func TestPluginExecution(t *testing.T) { - setupPluginPath(t) - - pluginHandler := NewDefaultPluginHandler([]string{"argocd"}) - cmd := NewCommand() - cmd.SilenceErrors = true - cmd.SilenceUsage = true - - tests := []struct { - name string - args []string - expectedPluginErr string - }{ - { - name: "'argocd-foo' binary exists in the PATH", - args: []string{"argocd", "foo"}, - expectedPluginErr: "", - }, - { - name: "'argocd-demo_plugin' binary exists in the PATH", - args: []string{"argocd", "demo_plugin"}, - expectedPluginErr: "", - }, - { - name: "'my-plugin' binary exists in the PATH", - args: []string{"argocd", "my-plugin"}, - expectedPluginErr: "unknown command \"my-plugin\" for \"argocd\"", - }, - { - name: "'argocd_my-plugin' binary exists in the PATH", - args: []string{"argocd", "my-plugin"}, - expectedPluginErr: "unknown command \"my-plugin\" for \"argocd\"", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - cmd.SetArgs(tt.args[1:]) - - err := cmd.Execute() - require.Error(t, err) - - // since the command is not a valid argocd command, check for plugin execution - pluginErr := pluginHandler.HandleCommandExecutionError(err, true, tt.args) - if tt.expectedPluginErr == "" { - require.NoError(t, pluginErr) - } else { - require.EqualError(t, pluginErr, tt.expectedPluginErr) - } - }) - } -} - -// TestNormalCommandError checks for an error when executing a normal ArgoCD command with invalid flags -func TestNormalCommandError(t *testing.T) { - setupPluginPath(t) - - pluginHandler := NewDefaultPluginHandler([]string{"argocd"}) - args := []string{"argocd", "version", "--non-existent-flag"} - cmd := NewVersionCmd(&argocdclient.ClientOptions{}, nil) - cmd.SetArgs(args[1:]) - cmd.SilenceErrors = true - cmd.SilenceUsage = true - - err := cmd.Execute() - require.Error(t, err) - - pluginErr := pluginHandler.HandleCommandExecutionError(err, true, args) - assert.EqualError(t, pluginErr, "unknown flag: --non-existent-flag") -} - -// TestUnknownCommandNoPlugin tests the scenario when the command is neither a normal ArgoCD command -// nor exists as a plugin -func TestUnknownCommandNoPlugin(t *testing.T) { - pluginHandler := NewDefaultPluginHandler([]string{"argocd"}) - cmd := NewCommand() - cmd.SilenceErrors = true - cmd.SilenceUsage = true - args := []string{"argocd", "non-existent"} - cmd.SetArgs(args[1:]) - - err := cmd.Execute() - require.Error(t, err) - - pluginErr := pluginHandler.HandleCommandExecutionError(err, true, args) - require.Error(t, pluginErr) - assert.Equal(t, err, pluginErr) -} - -// TestPluginNoExecutePermission verifies the behavior when a plugin doesn't have executable permissions -func TestPluginNoExecutePermission(t *testing.T) { - setupPluginPath(t) - - pluginHandler := NewDefaultPluginHandler([]string{"argocd"}) - cmd := NewCommand() - cmd.SilenceErrors = true - cmd.SilenceUsage = true - args := []string{"argocd", "no-permission"} - cmd.SetArgs(args[1:]) - - err := cmd.Execute() - require.Error(t, err) - - pluginErr := pluginHandler.HandleCommandExecutionError(err, true, args) - require.Error(t, pluginErr) - assert.EqualError(t, pluginErr, "unknown command \"no-permission\" for \"argocd\"") -} - -// TestPluginExecutionError checks for errors that occur during plugin execution -func TestPluginExecutionError(t *testing.T) { - setupPluginPath(t) - - pluginHandler := NewDefaultPluginHandler([]string{"argocd"}) - cmd := NewCommand() - cmd.SilenceErrors = true - cmd.SilenceUsage = true - args := []string{"argocd", "error"} - cmd.SetArgs(args[1:]) - - err := cmd.Execute() - require.Error(t, err) - - pluginErr := pluginHandler.HandleCommandExecutionError(err, true, args) - require.Error(t, pluginErr) - assert.EqualError(t, pluginErr, "exit status 1") -} - -// TestPluginInRelativePathIgnored ensures that plugins in a relative path, even if the path is included in PATH, -// are ignored and not executed. -func TestPluginInRelativePathIgnored(t *testing.T) { - setupPluginPath(t) - - relativePath := "./relative-plugins" - err := os.MkdirAll(relativePath, 0o755) - require.NoError(t, err) - defer os.RemoveAll(relativePath) - - relativePluginPath := filepath.Join(relativePath, "argocd-ignore-plugin") - err = os.WriteFile(relativePluginPath, []byte("#!/bin/bash\necho 'This should not execute'\n"), 0o755) - require.NoError(t, err) - - t.Setenv("PATH", os.Getenv("PATH")+string(os.PathListSeparator)+relativePath) - - pluginHandler := NewDefaultPluginHandler([]string{"argocd"}) - cmd := NewCommand() - cmd.SilenceErrors = true - cmd.SilenceUsage = true - args := []string{"argocd", "ignore-plugin"} - cmd.SetArgs(args[1:]) - - err = cmd.Execute() - require.Error(t, err) - - pluginErr := pluginHandler.HandleCommandExecutionError(err, true, args) - require.Error(t, pluginErr) - assert.EqualError(t, pluginErr, "unknown command \"ignore-plugin\" for \"argocd\"") -} - -// TestPluginFlagParsing checks that the flags are parsed correctly by the plugin handler -func TestPluginFlagParsing(t *testing.T) { - setupPluginPath(t) - - pluginHandler := NewDefaultPluginHandler([]string{"argocd"}) - - tests := []struct { - name string - args []string - shouldFail bool - expectedErrMsg string - }{ - { - name: "Valid flags", - args: []string{"argocd", "test-plugin", "--flag1", "value1", "--flag2", "value2"}, - shouldFail: false, - expectedErrMsg: "", - }, - { - name: "Unknown flag", - args: []string{"argocd", "test-plugin", "--flag3", "invalid"}, - shouldFail: true, - expectedErrMsg: "exit status 1", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - cmd := NewCommand() - cmd.SilenceErrors = true - cmd.SilenceUsage = true - - cmd.SetArgs(tt.args[1:]) - - err := cmd.Execute() - require.Error(t, err) - - pluginErr := pluginHandler.HandleCommandExecutionError(err, true, tt.args) - - if tt.shouldFail { - require.Error(t, pluginErr) - assert.Equal(t, tt.expectedErrMsg, pluginErr.Error(), "Unexpected error message") - } else { - require.NoError(t, pluginErr, "Expected no error for valid flags") - } - }) - } -} - -// TestPluginStatusCode checks for a correct status code that a plugin binary would generate -func TestPluginStatusCode(t *testing.T) { - setupPluginPath(t) - - pluginHandler := NewDefaultPluginHandler([]string{"argocd"}) - - tests := []struct { - name string - args []string - wantStatus int - throwErr bool - }{ - { - name: "plugin generates the successful exit code", - args: []string{"argocd", "status-code-plugin", "--flag1", "value1"}, - wantStatus: 0, - throwErr: false, - }, - { - name: "plugin generates an error status code", - args: []string{"argocd", "status-code-plugin", "--flag3", "value3"}, - wantStatus: 1, - throwErr: true, - }, - { - name: "plugin generates a status code for an invalid command", - args: []string{"argocd", "status-code-plugin", "invalid"}, - wantStatus: 127, - throwErr: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - cmd := NewCommand() - cmd.SilenceErrors = true - cmd.SilenceUsage = true - - cmd.SetArgs(tt.args[1:]) - - err := cmd.Execute() - require.Error(t, err) - - pluginErr := pluginHandler.HandleCommandExecutionError(err, true, tt.args) - if !tt.throwErr { - require.NoError(t, pluginErr) - } else { - require.Error(t, pluginErr) - var exitErr *exec.ExitError - if errors.As(pluginErr, &exitErr) { - assert.Equal(t, tt.wantStatus, exitErr.ExitCode(), "unexpected exit code") - } else { - t.Fatalf("expected an exit error, got: %v", pluginErr) - } - } - }) - } -} diff --git a/cmd/argocd/commands/project.go b/cmd/argocd/commands/project.go index 3477d3eecb..b3dc9498d6 100644 --- a/cmd/argocd/commands/project.go +++ b/cmd/argocd/commands/project.go @@ -17,18 +17,18 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - projectpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/project" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/git" - "github.com/argoproj/argo-cd/v3/util/gpg" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/templates" + "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" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/gpg" + argoio "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/templates" ) type policyOpts struct { @@ -122,7 +122,7 @@ func NewProjectCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm errors.CheckError(err) conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) _, err = projIf.Create(ctx, &projectpkg.ProjectCreateRequest{Project: proj, Upsert: upsert}) errors.CheckError(err) }, @@ -159,7 +159,7 @@ func NewProjectSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command } projName := args[0] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -202,7 +202,7 @@ func NewProjectAddSignatureKeyCommand(clientOpts *argocdclient.ClientOptions) *c } conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -240,7 +240,7 @@ func NewProjectRemoveSignatureKeyCommand(clientOpts *argocdclient.ClientOptions) signatureKey := args[1] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -254,10 +254,11 @@ func NewProjectRemoveSignatureKeyCommand(clientOpts *argocdclient.ClientOptions) } if index == -1 { log.Fatal("Specified signature key is not configured for project") + } else { + proj.Spec.SignatureKeys = append(proj.Spec.SignatureKeys[:index], proj.Spec.SignatureKeys[index+1:]...) + _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) + errors.CheckError(err) } - proj.Spec.SignatureKeys = append(proj.Spec.SignatureKeys[:index], proj.Spec.SignatureKeys[index+1:]...) - _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) - errors.CheckError(err) }, } @@ -296,7 +297,7 @@ func NewProjectAddDestinationCommand(clientOpts *argocdclient.ClientOptions) *co namespace := args[2] destination := buildApplicationDestination(args[1], namespace, nameInsteadServer) conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -337,7 +338,7 @@ func NewProjectRemoveDestinationCommand(clientOpts *argocdclient.ClientOptions) server := args[1] namespace := args[2] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -351,10 +352,11 @@ func NewProjectRemoveDestinationCommand(clientOpts *argocdclient.ClientOptions) } if index == -1 { log.Fatal("Specified destination does not exist in project") + } else { + proj.Spec.Destinations = append(proj.Spec.Destinations[:index], proj.Spec.Destinations[index+1:]...) + _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) + errors.CheckError(err) } - proj.Spec.Destinations = append(proj.Spec.Destinations[:index], proj.Spec.Destinations[index+1:]...) - _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) - errors.CheckError(err) }, } @@ -385,7 +387,7 @@ func NewProjectAddOrphanedIgnoreCommand(clientOpts *argocdclient.ClientOptions) group := args[1] kind := args[2] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -435,7 +437,7 @@ func NewProjectRemoveOrphanedIgnoreCommand(clientOpts *argocdclient.ClientOption group := args[1] kind := args[2] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -454,10 +456,11 @@ func NewProjectRemoveOrphanedIgnoreCommand(clientOpts *argocdclient.ClientOption } if index == -1 { log.Fatal("Specified resource does not exist in the orphaned ignore of project") + } else { + proj.Spec.OrphanedResources.Ignore = append(proj.Spec.OrphanedResources.Ignore[:index], proj.Spec.OrphanedResources.Ignore[index+1:]...) + _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) + errors.CheckError(err) } - proj.Spec.OrphanedResources.Ignore = append(proj.Spec.OrphanedResources.Ignore[:index], proj.Spec.OrphanedResources.Ignore[index+1:]...) - _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) - errors.CheckError(err) }, } command.Flags().StringVar(&name, "name", "", "Resource name pattern") @@ -483,13 +486,13 @@ func NewProjectAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cobra.C projName := args[0] url := args[1] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) for _, item := range proj.Spec.SourceRepos { - if item == "*" { + if item == "*" && item == url { fmt.Printf("Source repository '*' already allowed in project\n") return } @@ -525,7 +528,7 @@ func NewProjectAddSourceNamespace(clientOpts *argocdclient.ClientOptions) *cobra projName := args[0] srcNamespace := args[1] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -563,7 +566,7 @@ func NewProjectRemoveSourceNamespace(clientOpts *argocdclient.ClientOptions) *co projName := args[0] srcNamespace := args[1] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -599,21 +602,22 @@ func modifyResourcesList(list *[]metav1.GroupKind, add bool, listDesc string, gr fmt.Printf("Group '%s' and kind '%s' is added to %s resources\n", group, kind, listDesc) *list = append(*list, metav1.GroupKind{Group: group, Kind: kind}) return true - } - index := -1 - for i, item := range *list { - if item.Group == group && item.Kind == kind { - index = i - break + } else { + index := -1 + for i, item := range *list { + if item.Group == group && item.Kind == kind { + index = i + break + } } + if index == -1 { + fmt.Printf("Group '%s' and kind '%s' not in %s resources\n", group, kind, listDesc) + return false + } + *list = append((*list)[:index], (*list)[index+1:]...) + fmt.Printf("Group '%s' and kind '%s' is removed from %s resources\n", group, kind, listDesc) + return true } - if index == -1 { - fmt.Printf("Group '%s' and kind '%s' not in %s resources\n", group, kind, listDesc) - return false - } - *list = append((*list)[:index], (*list)[index+1:]...) - fmt.Printf("Group '%s' and kind '%s' is removed from %s resources\n", group, kind, listDesc) - return true } func modifyResourceListCmd(cmdUse, cmdDesc, examples string, clientOpts *argocdclient.ClientOptions, allow bool, namespacedList bool) *cobra.Command { @@ -639,7 +643,7 @@ func modifyResourceListCmd(cmdUse, cmdDesc, examples string, clientOpts *argocdc } projName, group, kind := args[0], args[1], args[2] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -737,7 +741,7 @@ func NewProjectRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) *cobr projName := args[0] url := args[1] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -782,7 +786,7 @@ func NewProjectDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) for _, name := range args { canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to delete %s? [y/n]", name)) if canDelete { @@ -827,11 +831,11 @@ func NewProjectListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman # List all available projects in yaml format argocd proj list -o yaml `), - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) projects, err := projIf.List(ctx, &projectpkg.ProjectQuery{}) errors.CheckError(err) switch output { @@ -1023,7 +1027,7 @@ func NewProjectGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command os.Exit(1) } projName := args[0] - detailedProject := getProject(ctx, c, clientOpts, projName) + detailedProject := getProject(c, clientOpts, ctx, projName) switch output { case "yaml", "json": @@ -1040,9 +1044,9 @@ func NewProjectGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command return command } -func getProject(ctx context.Context, c *cobra.Command, clientOpts *argocdclient.ClientOptions, projName string) *projectpkg.DetailedProjectsResponse { +func getProject(c *cobra.Command, clientOpts *argocdclient.ClientOptions, ctx context.Context, projName string) *projectpkg.DetailedProjectsResponse { conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) detailedProject, err := projIf.GetDetailedProject(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) return detailedProject @@ -1065,7 +1069,7 @@ func NewProjectEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman } projName := args[0] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) projData, err := json.Marshal(proj.Spec) @@ -1073,7 +1077,7 @@ func NewProjectEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman projData, err = yaml.JSONToYAML(projData) errors.CheckError(err) - cli.InteractiveEdit(projName+"-*-edit.yaml", projData, func(input []byte) error { + cli.InteractiveEdit(fmt.Sprintf("%s-*-edit.yaml", projName), projData, func(input []byte) error { input, err = yaml.YAMLToJSON(input) if err != nil { return fmt.Errorf("error converting YAML to JSON: %w", err) @@ -1110,11 +1114,12 @@ func NewProjectAddDestinationServiceAccountCommand(clientOpts *argocdclient.Clie Namespace: namespace, DefaultServiceAccount: fmt.Sprintf("%s:%s", serviceAccountNamespace, serviceAccount), } - } - return v1alpha1.ApplicationDestinationServiceAccount{ - Server: destination, - Namespace: namespace, - DefaultServiceAccount: serviceAccount, + } else { + return v1alpha1.ApplicationDestinationServiceAccount{ + Server: destination, + Namespace: namespace, + DefaultServiceAccount: serviceAccount, + } } } @@ -1150,7 +1155,7 @@ func NewProjectAddDestinationServiceAccountCommand(clientOpts *argocdclient.Clie destinationServiceAccount := buildApplicationDestinationServiceAccount(server, namespace, serviceAccount, serviceAccountNamespace) conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -1192,7 +1197,7 @@ func NewProjectRemoveDestinationServiceAccountCommand(clientOpts *argocdclient.C namespace := args[2] serviceAccount := args[3] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -1205,11 +1210,12 @@ func NewProjectRemoveDestinationServiceAccountCommand(clientOpts *argocdclient.C destServiceAccount.DefaultServiceAccount == serviceAccount }, ) - if originalLength == len(proj.Spec.DestinationServiceAccounts) { + if originalLength != len(proj.Spec.DestinationServiceAccounts) { + _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) + errors.CheckError(err) + } else { log.Fatal("Specified destination service account does not exist in project") } - _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) - errors.CheckError(err) }, } diff --git a/cmd/argocd/commands/project_role.go b/cmd/argocd/commands/project_role.go index f8715c3c38..a0da6793fa 100644 --- a/cmd/argocd/commands/project_role.go +++ b/cmd/argocd/commands/project_role.go @@ -7,20 +7,19 @@ import ( "text/tabwriter" "time" - timeutil "github.com/argoproj/pkg/v2/time" - jwtgo "github.com/golang-jwt/jwt/v5" + timeutil "github.com/argoproj/pkg/time" + jwtgo "github.com/golang-jwt/jwt/v4" "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - projectpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/project" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - claimsutil "github.com/argoproj/argo-cd/v3/util/claims" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/jwt" - "github.com/argoproj/argo-cd/v3/util/templates" + "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" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/jwt" + "github.com/argoproj/argo-cd/v2/util/templates" ) const ( @@ -91,7 +90,7 @@ ID ISSUED-AT EXPIRES-AT projName := args[0] roleName := args[1] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -150,7 +149,7 @@ ID ISSUED-AT EXPIRES-AT projName := args[0] roleName := args[1] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -192,7 +191,7 @@ func NewProjectRoleCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. command := &cobra.Command{ Use: "create PROJECT ROLE-NAME", Short: "Create a project role", - Example: templates.Examples(` + Example: templates.Examples(` # Create a project role in the "my-project" project with the name "my-role". argocd proj role create my-project my-role --description "My project role description" `), @@ -207,7 +206,7 @@ func NewProjectRoleCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. projName := args[0] roleName := args[1] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -244,7 +243,7 @@ func NewProjectRoleDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra. projName := args[0] roleName := args[1] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) @@ -308,7 +307,7 @@ Create token succeeded for proj:test-project:test-role. projName := args[0] roleName := args[1] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) if expiresIn == "" { expiresIn = "0s" } @@ -322,24 +321,18 @@ Create token succeeded for proj:test-project:test-role. }) errors.CheckError(err) - var claims jwtgo.MapClaims - _, _, err = jwtgo.NewParser().ParseUnverified(tokenResponse.Token, &claims) - if err != nil { + token, err := jwtgo.Parse(tokenResponse.Token, nil) + if token == nil { err = fmt.Errorf("received malformed token %w", err) errors.CheckError(err) return } - argoClaims, err := claimsutil.MapClaimsToArgoClaims(claims) - if err != nil { - errors.CheckError(fmt.Errorf("invalid argo claims: %w", err)) - return - } - + claims := token.Claims.(jwtgo.MapClaims) issuedAt, _ := jwt.IssuedAt(claims) expiresAt := int64(jwt.Float64Field(claims, "exp")) - id := argoClaims.ID - subject := argoClaims.GetUserIdentifier() + id := jwt.StringField(claims, "jti") + subject := jwt.StringField(claims, "sub") if !outputTokenOnly { fmt.Printf("Create token succeeded for %s.\n", subject) @@ -383,7 +376,7 @@ fa9d3517-c52d-434c-9bff-215b38508842 2023-10-08T11:08:18+01:00 Never roleName := args[1] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -466,7 +459,7 @@ $ argocd proj role delete-token test-project test-role 1696769937 promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to delete '%s' project token? [y/n]", tokenId)) if canDelete { @@ -503,7 +496,7 @@ func NewProjectRoleListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co command := &cobra.Command{ Use: "list PROJECT", Short: "List all the roles in a project", - Example: templates.Examples(` + Example: templates.Examples(` # This command will list all the roles in argocd-project in a default table format. argocd proj role list PROJECT @@ -521,7 +514,7 @@ func NewProjectRoleListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } projName := args[0] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) project, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -567,7 +560,7 @@ ID ISSUED-AT EXPIRES-AT projName := args[0] roleName := args[1] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -611,7 +604,7 @@ func NewProjectRoleAddGroupCommand(clientOpts *argocdclient.ClientOptions) *cobr } projName, roleName, groupName := args[0], args[1], args[2] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) updated, err := proj.AddGroupToRole(roleName, groupName) @@ -642,7 +635,7 @@ func NewProjectRoleRemoveGroupCommand(clientOpts *argocdclient.ClientOptions) *c } projName, roleName, groupName := args[0], args[1], args[2] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) updated, err := proj.RemoveGroupFromRole(roleName, groupName) diff --git a/cmd/argocd/commands/projectwindows.go b/cmd/argocd/commands/projectwindows.go index 239b9e2c85..589064b240 100644 --- a/cmd/argocd/commands/projectwindows.go +++ b/cmd/argocd/commands/projectwindows.go @@ -9,13 +9,13 @@ import ( "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - projectpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/project" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "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" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/io" ) // NewProjectWindowsCommand returns a new instance of the `argocd proj windows` command @@ -30,7 +30,7 @@ argocd proj windows add my-project \ --duration 3600 \ --prune -#Delete a sync window from a project +#Delete a sync window from a project argocd proj windows delete #List project sync windows @@ -56,8 +56,8 @@ func NewProjectWindowsDisableManualSyncCommand(clientOpts *argocdclient.ClientOp Short: "Disable manual sync for a sync window", Long: "Disable manual sync for a sync window. Requires ID which can be found by running \"argocd proj windows list PROJECT\"", Example: ` -#Disable manual sync for a sync window for the Project -argocd proj windows disable-manual-sync PROJECT ID +#Disable manual sync for a sync window for the Project +argocd proj windows disable-manual-sync PROJECT ID #Disabling manual sync for a windows set on the default project with Id 0 argocd proj windows disable-manual-sync default 0`, @@ -74,7 +74,7 @@ argocd proj windows disable-manual-sync default 0`, errors.CheckError(err) conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -100,7 +100,7 @@ func NewProjectWindowsEnableManualSyncCommand(clientOpts *argocdclient.ClientOpt Long: "Enable manual sync for a sync window. Requires ID which can be found by running \"argocd proj windows list PROJECT\"", Example: ` #Enabling manual sync for a general case -argocd proj windows enable-manual-sync PROJECT ID +argocd proj windows enable-manual-sync PROJECT ID #Enabling manual sync for a windows set on the default project with Id 2 argocd proj windows enable-manual-sync default 2 @@ -120,7 +120,7 @@ argocd proj windows enable-manual-sync my-app-project --message "Manual sync ini errors.CheckError(err) conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -149,8 +149,6 @@ func NewProjectWindowsAddWindowCommand(clientOpts *argocdclient.ClientOptions) * clusters []string manualSync bool timeZone string - andOperator bool - description string ) command := &cobra.Command{ Use: "add PROJECT", @@ -161,8 +159,7 @@ argocd proj windows add PROJECT \ --kind allow \ --schedule "0 22 * * *" \ --duration 1h \ - --applications "*" \ - --description "Ticket 123" + --applications "*" #Add a deny sync window with the ability to manually sync. argocd proj windows add PROJECT \ @@ -172,8 +169,7 @@ argocd proj windows add PROJECT \ --applications "prod-\\*,website" \ --namespaces "default,\\*-prod" \ --clusters "prod,staging" \ - --manual-sync \ - --description "Ticket 123" + --manual-sync `, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -184,12 +180,12 @@ argocd proj windows add PROJECT \ } projName := args[0] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) - err = proj.Spec.AddWindow(kind, schedule, duration, applications, namespaces, clusters, manualSync, timeZone, andOperator, description) + err = proj.Spec.AddWindow(kind, schedule, duration, applications, namespaces, clusters, manualSync, timeZone) errors.CheckError(err) _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) @@ -204,8 +200,6 @@ argocd proj windows add PROJECT \ command.Flags().StringSliceVar(&clusters, "clusters", []string{}, "Clusters that the schedule will be applied to. Comma separated, wildcards supported (e.g. --clusters prod,staging)") command.Flags().BoolVar(&manualSync, "manual-sync", false, "Allow manual syncs for both deny and allow windows") command.Flags().StringVar(&timeZone, "time-zone", "UTC", "Time zone of the sync window") - command.Flags().BoolVar(&andOperator, "use-and-operator", false, "Use AND operator for matching applications, namespaces and clusters instead of the default OR operator") - command.Flags().StringVar(&description, "description", "", `Sync window description`) return command } @@ -216,7 +210,7 @@ func NewProjectWindowsDeleteCommand(clientOpts *argocdclient.ClientOptions) *cob Use: "delete PROJECT ID", Short: "Delete a sync window from a project. Requires ID which can be found by running \"argocd proj windows list PROJECT\"", Example: ` -#Delete a sync window from a project (default) with ID 0 +#Delete a sync window from a project (default) with ID 0 argocd proj windows delete default 0 #Delete a sync window from a project (new-project) with ID 1 @@ -234,7 +228,7 @@ argocd proj windows delete new-project 1`, errors.CheckError(err) conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -264,7 +258,6 @@ func NewProjectWindowsUpdateCommand(clientOpts *argocdclient.ClientOptions) *cob namespaces []string clusters []string timeZone string - description string ) command := &cobra.Command{ Use: "update PROJECT ID", @@ -287,14 +280,14 @@ argocd proj windows update PROJECT ID \ errors.CheckError(err) conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) for i, window := range proj.Spec.SyncWindows { if id == i { - err := window.Update(schedule, duration, applications, namespaces, clusters, timeZone, description) + err := window.Update(schedule, duration, applications, namespaces, clusters, timeZone) if err != nil { errors.CheckError(err) } @@ -311,7 +304,6 @@ argocd proj windows update PROJECT ID \ command.Flags().StringSliceVar(&namespaces, "namespaces", []string{}, "Namespaces that the schedule will be applied to. Comma separated, wildcards supported (e.g. --namespaces default,\\*-prod)") command.Flags().StringSliceVar(&clusters, "clusters", []string{}, "Clusters that the schedule will be applied to. Comma separated, wildcards supported (e.g. --clusters prod,staging)") command.Flags().StringVar(&timeZone, "time-zone", "UTC", "Time zone of the sync window. (e.g. --time-zone \"America/New_York\")") - command.Flags().StringVar(&description, "description", "", "Sync window description") return command } @@ -339,7 +331,7 @@ argocd proj windows list test-project`, } projName := args[0] conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -362,13 +354,13 @@ argocd proj windows list test-project`, func printSyncWindows(proj *v1alpha1.AppProject) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) var fmtStr string - headers := []any{"ID", "STATUS", "KIND", "SCHEDULE", "DURATION", "APPLICATIONS", "NAMESPACES", "CLUSTERS", "MANUALSYNC", "TIMEZONE"} + headers := []interface{}{"ID", "STATUS", "KIND", "SCHEDULE", "DURATION", "APPLICATIONS", "NAMESPACES", "CLUSTERS", "MANUALSYNC", "TIMEZONE"} fmtStr = strings.Repeat("%s\t", len(headers)) + "\n" fmt.Fprintf(w, fmtStr, headers...) if proj.Spec.SyncWindows.HasWindows() { for i, window := range proj.Spec.SyncWindows { isActive, _ := window.Active() - vals := []any{ + vals := []interface{}{ strconv.Itoa(i), formatBoolOutput(isActive), window.Kind, @@ -377,9 +369,8 @@ func printSyncWindows(proj *v1alpha1.AppProject) { formatListOutput(window.Applications), formatListOutput(window.Namespaces), formatListOutput(window.Clusters), - formatBoolEnabledOutput(window.ManualSync), + formatManualOutput(window.ManualSync), window.TimeZone, - formatBoolEnabledOutput(window.UseAndOperator), } fmt.Fprintf(w, fmtStr, vals...) } @@ -407,7 +398,7 @@ func formatBoolOutput(active bool) string { return o } -func formatBoolEnabledOutput(active bool) string { +func formatManualOutput(active bool) string { var o string if active { o = "Enabled" diff --git a/cmd/argocd/commands/relogin.go b/cmd/argocd/commands/relogin.go index 5eec14a581..effb0239c0 100644 --- a/cmd/argocd/commands/relogin.go +++ b/cmd/argocd/commands/relogin.go @@ -8,13 +8,13 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - settingspkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/settings" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/localconfig" - "github.com/argoproj/argo-cd/v3/util/session" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + settingspkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/settings" + "github.com/argoproj/argo-cd/v2/util/errors" + argoio "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/localconfig" + "github.com/argoproj/argo-cd/v2/util/session" ) // NewReloginCommand returns a new instance of `argocd relogin` command @@ -65,7 +65,7 @@ func NewReloginCommand(globalClientOpts *argocdclient.ClientOptions) *cobra.Comm } else { fmt.Println("Reinitiating SSO login") setConn, setIf := acdClient.NewSettingsClientOrDie() - defer utilio.Close(setConn) + defer argoio.Close(setConn) httpClient, err := acdClient.HTTPClient() errors.CheckError(err) ctx = oidc.ClientContext(ctx, httpClient) diff --git a/cmd/argocd/commands/relogin_test.go b/cmd/argocd/commands/relogin_test.go index e8a2c554dc..9b6e1e7d83 100644 --- a/cmd/argocd/commands/relogin_test.go +++ b/cmd/argocd/commands/relogin_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" ) func TestNewReloginCommand(t *testing.T) { @@ -24,7 +24,7 @@ func TestNewReloginCommand(t *testing.T) { // Assert command flags passwordFlag := cmd.Flags().Lookup("password") assert.NotNil(t, passwordFlag, "Expected flag --password to be defined") - assert.Empty(t, passwordFlag.Value.String(), "Unexpected default value for --password flag") + assert.Equal(t, "", passwordFlag.Value.String(), "Unexpected default value for --password flag") ssoPortFlag := cmd.Flags().Lookup("sso-port") port, err := strconv.Atoi(ssoPortFlag.Value.String()) @@ -55,7 +55,7 @@ func TestNewReloginCommandWithGlobalClientOptions(t *testing.T) { // Assert command flags passwordFlag := cmd.Flags().Lookup("password") assert.NotNil(t, passwordFlag, "Expected flag --password to be defined") - assert.Empty(t, passwordFlag.Value.String(), "Unexpected default value for --password flag") + assert.Equal(t, "", passwordFlag.Value.String(), "Unexpected default value for --password flag") ssoPortFlag := cmd.Flags().Lookup("sso-port") port, err := strconv.Atoi(ssoPortFlag.Value.String()) diff --git a/cmd/argocd/commands/repo.go b/cmd/argocd/commands/repo.go index 3619cc1b62..3aba1b2e65 100644 --- a/cmd/argocd/commands/repo.go +++ b/cmd/argocd/commands/repo.go @@ -1,7 +1,6 @@ package commands import ( - stderrors "errors" "fmt" "os" "strconv" @@ -10,16 +9,16 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - repositorypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repository" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/git" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "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" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/io" ) // NewRepoCommand returns a new instance of an `argocd repo` command @@ -119,14 +118,15 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { } repoOpts.Repo.SSHPrivateKey = string(keyData) } else { - errors.Fatal(errors.ErrorGeneric, "--ssh-private-key-path is only supported for SSH repositories.") + err := fmt.Errorf("--ssh-private-key-path is only supported for SSH repositories.") + errors.CheckError(err) } } // tls-client-cert-path and tls-client-cert-key-key-path must always be // specified together if (repoOpts.TlsClientCertPath != "" && repoOpts.TlsClientCertKeyPath == "") || (repoOpts.TlsClientCertPath == "" && repoOpts.TlsClientCertKeyPath != "") { - err := stderrors.New("--tls-client-cert-path and --tls-client-cert-key-path must be specified together") + err := fmt.Errorf("--tls-client-cert-path and --tls-client-cert-key-path must be specified together") errors.CheckError(err) } @@ -140,7 +140,7 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { repoOpts.Repo.TLSClientCertData = string(tlsCertData) repoOpts.Repo.TLSClientCertKey = string(tlsCertKey) } else { - err := stderrors.New("--tls-client-cert-path is only supported for HTTPS repositories") + err := fmt.Errorf("--tls-client-cert-path is only supported for HTTPS repositories") errors.CheckError(err) } } @@ -152,7 +152,7 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { errors.CheckError(err) repoOpts.Repo.GithubAppPrivateKey = string(githubAppPrivateKey) } else { - err := stderrors.New("--github-app-private-key-path is only supported for HTTPS repositories") + err := fmt.Errorf("--github-app-private-key-path is only supported for HTTPS repositories") errors.CheckError(err) } } @@ -163,7 +163,7 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { errors.CheckError(err) repoOpts.Repo.GCPServiceAccountKey = string(gcpServiceAccountKey) } else { - err := stderrors.New("--gcp-service-account-key-path is only supported for HTTPS repositories") + err := fmt.Errorf("--gcp-service-account-key-path is only supported for HTTPS repositories") errors.CheckError(err) } } @@ -181,14 +181,13 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { repoOpts.Repo.Proxy = repoOpts.Proxy repoOpts.Repo.NoProxy = repoOpts.NoProxy repoOpts.Repo.ForceHttpBasicAuth = repoOpts.ForceHttpBasicAuth - repoOpts.Repo.UseAzureWorkloadIdentity = repoOpts.UseAzureWorkloadIdentity if repoOpts.Repo.Type == "helm" && repoOpts.Repo.Name == "" { - errors.Fatal(errors.ErrorGeneric, "Must specify --name for repos of type 'helm'") + errors.CheckError(fmt.Errorf("Must specify --name for repos of type 'helm'")) } conn, repoIf := headless.NewClientOrDie(clientOpts, c).NewRepoClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) // If the user set a username, but didn't supply password via --password, // then we prompt for it @@ -196,13 +195,6 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { repoOpts.Repo.Password = cli.PromptPassword(repoOpts.Repo.Password) } - err := cmdutil.ValidateBearerTokenAndPasswordCombo(repoOpts.Repo.BearerToken, repoOpts.Repo.Password) - errors.CheckError(err) - err = cmdutil.ValidateBearerTokenForGitOnly(repoOpts.Repo.BearerToken, repoOpts.Repo.Type) - errors.CheckError(err) - err = cmdutil.ValidateBearerTokenForHTTPSRepoOnly(repoOpts.Repo.BearerToken, git.IsHTTPSURL(repoOpts.Repo.Repo)) - errors.CheckError(err) - // We let the server check access to the repository before adding it. If // it is a private repo, but we cannot access with with the credentials // that were supplied, we bail out. @@ -216,7 +208,6 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { Name: repoOpts.Repo.Name, Username: repoOpts.Repo.Username, Password: repoOpts.Repo.Password, - BearerToken: repoOpts.Repo.BearerToken, SshPrivateKey: repoOpts.Repo.SSHPrivateKey, TlsClientCertData: repoOpts.Repo.TLSClientCertData, TlsClientCertKey: repoOpts.Repo.TLSClientCertKey, @@ -230,9 +221,8 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { Project: repoOpts.Repo.Project, GcpServiceAccountKey: repoOpts.Repo.GCPServiceAccountKey, ForceHttpBasicAuth: repoOpts.Repo.ForceHttpBasicAuth, - UseAzureWorkloadIdentity: repoOpts.Repo.UseAzureWorkloadIdentity, } - _, err = repoIf.ValidateAccess(ctx, &repoAccessReq) + _, err := repoIf.ValidateAccess(ctx, &repoAccessReq) errors.CheckError(err) repoCreateReq := repositorypkg.RepoCreateRequest{ @@ -264,7 +254,7 @@ func NewRepoRemoveCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command os.Exit(1) } conn, repoIf := headless.NewClientOrDie(clientOpts, c).NewRepoClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) for _, repoURL := range args { @@ -316,18 +306,18 @@ func NewRepoListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { command := &cobra.Command{ Use: "list", Short: "List configured repositories", - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() conn, repoIf := headless.NewClientOrDie(clientOpts, c).NewRepoClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) forceRefresh := false switch refresh { case "": case "hard": forceRefresh = true default: - err := stderrors.New("--refresh must be one of: 'hard'") + err := fmt.Errorf("--refresh must be one of: 'hard'") errors.CheckError(err) } repos, err := repoIf.ListRepositories(ctx, &repositorypkg.RepoQuery{ForceRefresh: forceRefresh}) @@ -372,14 +362,14 @@ func NewRepoGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { // Repository URL repoURL := args[0] conn, repoIf := headless.NewClientOrDie(clientOpts, c).NewRepoClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) forceRefresh := false switch refresh { case "": case "hard": forceRefresh = true default: - err := stderrors.New("--refresh must be one of: 'hard'") + err := fmt.Errorf("--refresh must be one of: 'hard'") errors.CheckError(err) } repo, err := repoIf.Get(ctx, &repositorypkg.RepoQuery{Repo: repoURL, ForceRefresh: forceRefresh, AppProject: project}) diff --git a/cmd/argocd/commands/repocreds.go b/cmd/argocd/commands/repocreds.go index 213a7c7d8d..215895d5fc 100644 --- a/cmd/argocd/commands/repocreds.go +++ b/cmd/argocd/commands/repocreds.go @@ -1,7 +1,6 @@ package commands import ( - stderrors "errors" "fmt" "os" "text/tabwriter" @@ -9,25 +8,24 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/common" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - repocredspkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repocreds" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/git" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/templates" + "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" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/templates" ) // NewRepoCredsCommand returns a new instance of an `argocd repocreds` command func NewRepoCredsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { command := &cobra.Command{ Use: "repocreds", - Short: "Manage credential templates for repositories", + Short: "Manage repository connection parameters", Example: templates.Examples(` # Add credentials with user/pass authentication to use for all repositories under the specified URL argocd repocreds add URL --username USERNAME --password PASSWORD @@ -66,9 +64,6 @@ func NewRepoCredsAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma repocredsAddExamples := ` # Add credentials with user/pass authentication to use for all repositories under https://git.example.com/repos argocd repocreds add https://git.example.com/repos/ --username git --password secret - # Add credentials with bearer token authentication to use for all BitBucket Data Center repositories under https://bitbucket.example.com/scm - argocd repocreds add https://bitbucket.example.com/scm/ --bearer-token secret-token - # Add credentials with SSH private key authentication to use for all repositories under ssh://git@git.example.com/repos argocd repocreds add ssh://git@git.example.com/repos/ --ssh-private-key-path ~/.ssh/id_rsa @@ -109,14 +104,16 @@ func NewRepoCredsAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma } repo.SSHPrivateKey = string(keyData) } else { - errors.Fatal(errors.ErrorGeneric, "--ssh-private-key-path is only supported for SSH repositories.") + err := fmt.Errorf("--ssh-private-key-path is only supported for SSH repositories.") + errors.CheckError(err) } } // tls-client-cert-path and tls-client-cert-key-key-path must always be // specified together if (tlsClientCertPath != "" && tlsClientCertKeyPath == "") || (tlsClientCertPath == "" && tlsClientCertKeyPath != "") { - errors.Fatal(errors.ErrorGeneric, "--tls-client-cert-path and --tls-client-cert-key-path must be specified together") + err := fmt.Errorf("--tls-client-cert-path and --tls-client-cert-key-path must be specified together") + errors.CheckError(err) } // Specifying tls-client-cert-path is only valid for HTTPS repositories @@ -129,7 +126,7 @@ func NewRepoCredsAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma repo.TLSClientCertData = string(tlsCertData) repo.TLSClientCertKey = string(tlsCertKey) } else { - err := stderrors.New("--tls-client-cert-path is only supported for HTTPS repositories") + err := fmt.Errorf("--tls-client-cert-path is only supported for HTTPS repositories") errors.CheckError(err) } } @@ -141,7 +138,7 @@ func NewRepoCredsAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma errors.CheckError(err) repo.GithubAppPrivateKey = string(githubAppPrivateKey) } else { - err := stderrors.New("--github-app-private-key-path is only supported for HTTPS repositories") + err := fmt.Errorf("--github-app-private-key-path is only supported for HTTPS repositories") errors.CheckError(err) } } @@ -153,13 +150,13 @@ func NewRepoCredsAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma errors.CheckError(err) repo.GCPServiceAccountKey = string(gcpServiceAccountKey) } else { - err := stderrors.New("--gcp-service-account-key-path is only supported for HTTPS repositories") + err := fmt.Errorf("--gcp-service-account-key-path is only supported for HTTPS repositories") errors.CheckError(err) } } conn, repoIf := headless.NewClientOrDie(clientOpts, c).NewRepoCredsClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) // If the user set a username, but didn't supply password via --password, // then we prompt for it @@ -167,13 +164,6 @@ func NewRepoCredsAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma repo.Password = cli.PromptPassword(repo.Password) } - err := cmdutil.ValidateBearerTokenAndPasswordCombo(repo.BearerToken, repo.Password) - errors.CheckError(err) - err = cmdutil.ValidateBearerTokenForGitOnly(repo.BearerToken, repo.Type) - errors.CheckError(err) - err = cmdutil.ValidateBearerTokenForHTTPSRepoOnly(repo.BearerToken, git.IsHTTPSURL(repo.URL)) - errors.CheckError(err) - repoCreateReq := repocredspkg.RepoCredsCreateRequest{ Creds: &repo, Upsert: upsert, @@ -186,7 +176,6 @@ func NewRepoCredsAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma } command.Flags().StringVar(&repo.Username, "username", "", "username to the repository") command.Flags().StringVar(&repo.Password, "password", "", "password to the repository") - command.Flags().StringVar(&repo.BearerToken, "bearer-token", "", "bearer token to the Git repository") command.Flags().StringVar(&sshPrivateKeyPath, "ssh-private-key-path", "", "path to the private ssh key (e.g. ~/.ssh/id_rsa)") command.Flags().StringVar(&tlsClientCertPath, "tls-client-cert-path", "", "path to the TLS client cert (must be PEM format)") command.Flags().StringVar(&tlsClientCertKeyPath, "tls-client-cert-key-path", "", "path to the TLS client cert's key path (must be PEM format)") @@ -199,7 +188,6 @@ func NewRepoCredsAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma command.Flags().StringVar(&repo.Type, "type", common.DefaultRepoType, "type of the repository, \"git\" or \"helm\"") command.Flags().StringVar(&gcpServiceAccountKeyPath, "gcp-service-account-key-path", "", "service account key for the Google Cloud Platform") command.Flags().BoolVar(&repo.ForceHttpBasicAuth, "force-http-basic-auth", false, "whether to force basic auth when connecting via HTTP") - command.Flags().BoolVar(&repo.UseAzureWorkloadIdentity, "use-azure-workload-identity", false, "whether to use azure workload identity for authentication") command.Flags().StringVar(&repo.Proxy, "proxy-url", "", "If provided, this URL will be used to connect via proxy") return command } @@ -221,7 +209,7 @@ func NewRepoCredsRemoveCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co os.Exit(1) } conn, repoIf := headless.NewClientOrDie(clientOpts, c).NewRepoCredsClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) @@ -279,11 +267,11 @@ func NewRepoCredsListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm # List all repo urls in url format argocd repocreds list -o url `), - Run: func(c *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { ctx := c.Context() conn, repoIf := headless.NewClientOrDie(clientOpts, c).NewRepoCredsClientOrDie() - defer utilio.Close(conn) + defer io.Close(conn) repos, err := repoIf.ListRepositoryCredentials(ctx, &repocredspkg.RepoCredsQuery{}) errors.CheckError(err) switch output { diff --git a/cmd/argocd/commands/root.go b/cmd/argocd/commands/root.go index ba8f0d5840..7323c444e4 100644 --- a/cmd/argocd/commands/root.go +++ b/cmd/argocd/commands/root.go @@ -3,21 +3,20 @@ package commands import ( "fmt" - "github.com/argoproj/argo-cd/v3/util/cache" - "github.com/spf13/cobra" "k8s.io/client-go/tools/clientcmd" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/admin" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/initialize" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/common" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/config" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/localconfig" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/admin" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/initialize" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/common" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/config" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/localconfig" ) func init() { @@ -67,7 +66,7 @@ func NewCommand() *cobra.Command { defaultLocalConfigPath, err := localconfig.DefaultLocalConfigPath() errors.CheckError(err) command.PersistentFlags().StringVar(&clientOpts.ConfigPath, "config", config.GetFlag("config", defaultLocalConfigPath), "Path to Argo CD config") - command.PersistentFlags().StringVar(&clientOpts.ServerAddr, "server", config.GetFlag("server", env.StringFromEnv(common.EnvServer, "")), "Argo CD server address") + command.PersistentFlags().StringVar(&clientOpts.ServerAddr, "server", config.GetFlag("server", ""), "Argo CD server address") command.PersistentFlags().BoolVar(&clientOpts.PlainText, "plaintext", config.GetBoolFlag("plaintext"), "Disable TLS") command.PersistentFlags().BoolVar(&clientOpts.Insecure, "insecure", config.GetBoolFlag("insecure"), "Skip server certificate and domain verification") command.PersistentFlags().StringVar(&clientOpts.CertFile, "server-crt", config.GetFlag("server-crt", ""), "Server certificate file") @@ -76,7 +75,7 @@ func NewCommand() *cobra.Command { command.PersistentFlags().StringVar(&clientOpts.AuthToken, "auth-token", config.GetFlag("auth-token", env.StringFromEnv(common.EnvAuthToken, "")), fmt.Sprintf("Authentication token; set this or the %s environment variable", common.EnvAuthToken)) command.PersistentFlags().BoolVar(&clientOpts.GRPCWeb, "grpc-web", config.GetBoolFlag("grpc-web"), "Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2.") command.PersistentFlags().StringVar(&clientOpts.GRPCWebRootPath, "grpc-web-root-path", config.GetFlag("grpc-web-root-path", ""), "Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root.") - command.PersistentFlags().StringVar(&cmdutil.LogFormat, "logformat", config.GetFlag("logformat", "json"), "Set the logging format. One of: json|text") + command.PersistentFlags().StringVar(&cmdutil.LogFormat, "logformat", config.GetFlag("logformat", "text"), "Set the logging format. One of: text|json") command.PersistentFlags().StringVar(&cmdutil.LogLevel, "loglevel", config.GetFlag("loglevel", "info"), "Set the logging level. One of: debug|info|warn|error") command.PersistentFlags().StringSliceVarP(&clientOpts.Headers, "header", "H", config.GetStringSliceFlag("header", []string{}), "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)") command.PersistentFlags().BoolVar(&clientOpts.PortForward, "port-forward", config.GetBoolFlag("port-forward"), "Connect to a random argocd-server port using port forwarding") diff --git a/cmd/argocd/commands/testdata/argocd-demo_plugin b/cmd/argocd/commands/testdata/argocd-demo_plugin deleted file mode 100755 index 5c3ef35c5e..0000000000 --- a/cmd/argocd/commands/testdata/argocd-demo_plugin +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -if [[ "$1" == "version" ]] -then - echo "1.0.0" - exit 0 -fi - -if [[ "$1" == "config" ]] -then - echo "$KUBECONFIG" - exit 0 -fi - -echo "I am a plugin named argocd-demo_plugin" diff --git a/cmd/argocd/commands/testdata/argocd-error b/cmd/argocd/commands/testdata/argocd-error deleted file mode 100755 index 365c3b851e..0000000000 --- a/cmd/argocd/commands/testdata/argocd-error +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -if [[ "$1" == "version" ]] -then - echo "1.0.0" - exit 0 -fi - -if [[ "$1" == "config" ]] -then - echo "$KUBECONFIG" - exit 0 -fi - -# Default behavior: simulate an error -echo "Error: I am a plugin named argocd-error, and I encountered an error." >&2 -exit 1 diff --git a/cmd/argocd/commands/testdata/argocd-foo b/cmd/argocd/commands/testdata/argocd-foo deleted file mode 100755 index 8a01221de4..0000000000 --- a/cmd/argocd/commands/testdata/argocd-foo +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -if [[ "$1" == "version" ]] -then - echo "1.0.0" - exit 0 -fi - -if [[ "$1" == "config" ]] -then - echo "$KUBECONFIG" - exit 0 -fi - -echo "I am a plugin named argocd-foo" diff --git a/cmd/argocd/commands/testdata/argocd-no-permission b/cmd/argocd/commands/testdata/argocd-no-permission deleted file mode 100644 index 11332ad234..0000000000 --- a/cmd/argocd/commands/testdata/argocd-no-permission +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -echo "I can't be executed since I don't have executable permissions" diff --git a/cmd/argocd/commands/testdata/argocd-status-code-plugin b/cmd/argocd/commands/testdata/argocd-status-code-plugin deleted file mode 100755 index 3aaa1fabc4..0000000000 --- a/cmd/argocd/commands/testdata/argocd-status-code-plugin +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -case "$1" in - "--flag1") - echo "Flag1 detected: $2" - exit 0 - ;; - "--flag3") - echo "Unknown argument: --flag3" >&2 - exit 1 - ;; - *) - echo "Plugin not found or invalid command" >&2 - exit 127 - ;; -esac diff --git a/cmd/argocd/commands/testdata/argocd-test-plugin b/cmd/argocd/commands/testdata/argocd-test-plugin deleted file mode 100755 index 377d83c0ba..0000000000 --- a/cmd/argocd/commands/testdata/argocd-test-plugin +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -# Ensure we receive the expected flags and values -while [[ "$#" -gt 0 ]]; do - case $1 in - --flag1) FLAG1="$2"; shift ;; - --flag2) FLAG2="$2"; shift ;; - --help) echo "Usage: argocd test-plugin --flag1 value1 --flag2 value2"; exit 0 ;; - *) echo "Unknown argument: $1"; exit 1 ;; - esac - shift -done - -# Output the parsed flag values -echo "Flag1: ${FLAG1}" -echo "Flag2: ${FLAG2}" diff --git a/cmd/argocd/commands/testdata/argocd-version b/cmd/argocd/commands/testdata/argocd-version deleted file mode 100755 index 9639838cf8..0000000000 --- a/cmd/argocd/commands/testdata/argocd-version +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -echo "Fetching the version of Argo CD..." -argocd version --short --client diff --git a/cmd/argocd/commands/testdata/argocd_my-plugin b/cmd/argocd/commands/testdata/argocd_my-plugin deleted file mode 100755 index e63e98e780..0000000000 --- a/cmd/argocd/commands/testdata/argocd_my-plugin +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -echo "Hello from argocd_my-plugin" - -if [ "$#" -gt 0 ]; then - echo "Arguments received: $@" -fi diff --git a/cmd/argocd/commands/testdata/my-plugin b/cmd/argocd/commands/testdata/my-plugin deleted file mode 100755 index 42265877be..0000000000 --- a/cmd/argocd/commands/testdata/my-plugin +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -echo "Hello from my-plugin" - -if [ "$#" -gt 0 ]; then - echo "Arguments received: $@" -fi diff --git a/cmd/argocd/commands/tree.go b/cmd/argocd/commands/tree.go index ae87b82770..904b2e7d68 100644 --- a/cmd/argocd/commands/tree.go +++ b/cmd/argocd/commands/tree.go @@ -9,7 +9,7 @@ import ( "github.com/argoproj/gitops-engine/pkg/health" "k8s.io/apimachinery/pkg/util/duration" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) const ( @@ -36,7 +36,7 @@ func treeViewAppGet(prefix string, uidToNodeMap map[string]v1alpha1.ResourceNode _, _ = fmt.Fprintf(w, "%s%s\t%s\t%s\t%s\n", printPrefix(prefix), parent.Kind+"/"+parent.Name, "", healthStatus, "") } chs := parentToChildMap[parent.UID] - for i, childUID := range chs { + for i, childUid := range chs { var p string switch i { case len(chs) - 1: @@ -44,7 +44,7 @@ func treeViewAppGet(prefix string, uidToNodeMap map[string]v1alpha1.ResourceNode default: p = prefix + firstElemPrefix } - treeViewAppGet(p, uidToNodeMap, parentToChildMap, uidToNodeMap[childUID], mapNodeNameToResourceState, w) + treeViewAppGet(p, uidToNodeMap, parentToChildMap, uidToNodeMap[childUid], mapNodeNameToResourceState, w) } } diff --git a/cmd/argocd/commands/tree_test.go b/cmd/argocd/commands/tree_test.go index 1dc7f47a91..c0d2129fed 100644 --- a/cmd/argocd/commands/tree_test.go +++ b/cmd/argocd/commands/tree_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestTreeViewAppGet(t *testing.T) { diff --git a/cmd/argocd/commands/utils/prompt.go b/cmd/argocd/commands/utils/prompt.go index f3193cf4ac..4cda58aef5 100644 --- a/cmd/argocd/commands/utils/prompt.go +++ b/cmd/argocd/commands/utils/prompt.go @@ -1,7 +1,7 @@ package utils import ( - "github.com/argoproj/argo-cd/v3/util/cli" + "github.com/argoproj/argo-cd/v2/util/cli" ) type Prompt struct { diff --git a/cmd/argocd/commands/version.go b/cmd/argocd/commands/version.go index 47766d0240..8c69c4195c 100644 --- a/cmd/argocd/commands/version.go +++ b/cmd/argocd/commands/version.go @@ -8,12 +8,12 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/common" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/version" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/common" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/version" + "github.com/argoproj/argo-cd/v2/util/errors" + argoio "github.com/argoproj/argo-cd/v2/util/io" ) // NewVersionCmd returns a new `version` command to be used as a sub-command to root @@ -39,13 +39,13 @@ func NewVersionCmd(clientOpts *argocdclient.ClientOptions, serverVersion *versio # Print only client and server core version strings in YAML format argocd version --short -o yaml `, - Run: func(cmd *cobra.Command, _ []string) { + Run: func(cmd *cobra.Command, args []string) { ctx := cmd.Context() cv := common.GetVersion() switch output { case "yaml", "json": - v := make(map[string]any) + v := make(map[string]interface{}) if short { v["client"] = map[string]string{cliName: cv.Version} @@ -94,7 +94,7 @@ func NewVersionCmd(clientOpts *argocdclient.ClientOptions, serverVersion *versio func getServerVersion(ctx context.Context, options *argocdclient.ClientOptions, c *cobra.Command) *version.VersionMessage { conn, versionIf := headless.NewClientOrDie(options, c).NewVersionClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) v, err := versionIf.Version(ctx, &empty.Empty{}) errors.CheckError(err) diff --git a/cmd/argocd/commands/version_test.go b/cmd/argocd/commands/version_test.go index 890f187ade..fb85a491ec 100644 --- a/cmd/argocd/commands/version_test.go +++ b/cmd/argocd/commands/version_test.go @@ -7,8 +7,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/version" + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/version" ) func TestShortVersionClient(t *testing.T) { diff --git a/cmd/main.go b/cmd/main.go index fb3efd9547..92eb27049c 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,38 +1,30 @@ package main import ( - "errors" "os" - "os/exec" "path/filepath" - "github.com/spf13/cobra" - "k8s.io/klog/v2" + "github.com/argoproj/argo-cd/v2/cmd/util" - appcontroller "github.com/argoproj/argo-cd/v3/cmd/argocd-application-controller/commands" - applicationset "github.com/argoproj/argo-cd/v3/cmd/argocd-applicationset-controller/commands" - cmpserver "github.com/argoproj/argo-cd/v3/cmd/argocd-cmp-server/commands" - commitserver "github.com/argoproj/argo-cd/v3/cmd/argocd-commit-server/commands" - dex "github.com/argoproj/argo-cd/v3/cmd/argocd-dex/commands" - gitaskpass "github.com/argoproj/argo-cd/v3/cmd/argocd-git-ask-pass/commands" - k8sauth "github.com/argoproj/argo-cd/v3/cmd/argocd-k8s-auth/commands" - notification "github.com/argoproj/argo-cd/v3/cmd/argocd-notification/commands" - reposerver "github.com/argoproj/argo-cd/v3/cmd/argocd-repo-server/commands" - apiserver "github.com/argoproj/argo-cd/v3/cmd/argocd-server/commands" - cli "github.com/argoproj/argo-cd/v3/cmd/argocd/commands" - "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/util/log" + "github.com/spf13/cobra" + + appcontroller "github.com/argoproj/argo-cd/v2/cmd/argocd-application-controller/commands" + applicationset "github.com/argoproj/argo-cd/v2/cmd/argocd-applicationset-controller/commands" + cmpserver "github.com/argoproj/argo-cd/v2/cmd/argocd-cmp-server/commands" + commitserver "github.com/argoproj/argo-cd/v2/cmd/argocd-commit-server/commands" + dex "github.com/argoproj/argo-cd/v2/cmd/argocd-dex/commands" + gitaskpass "github.com/argoproj/argo-cd/v2/cmd/argocd-git-ask-pass/commands" + k8sauth "github.com/argoproj/argo-cd/v2/cmd/argocd-k8s-auth/commands" + notification "github.com/argoproj/argo-cd/v2/cmd/argocd-notification/commands" + reposerver "github.com/argoproj/argo-cd/v2/cmd/argocd-repo-server/commands" + apiserver "github.com/argoproj/argo-cd/v2/cmd/argocd-server/commands" + cli "github.com/argoproj/argo-cd/v2/cmd/argocd/commands" ) const ( binaryNameEnv = "ARGOCD_BINARY_NAME" ) -func init() { - // Make sure klog uses the configured log level and format. - klog.SetLogger(log.NewLogrusLogger(log.NewWithCurrentConfig())) -} - func main() { var command *cobra.Command @@ -41,12 +33,11 @@ func main() { binaryName = val } - isArgocdCLI := false - + isCLI := false switch binaryName { case "argocd", "argocd-linux-amd64", "argocd-darwin-amd64", "argocd-windows-amd64.exe": command = cli.NewCommand() - isArgocdCLI = true + isCLI = true case "argocd-server": command = apiserver.NewCommand() case "argocd-application-controller": @@ -55,7 +46,7 @@ func main() { command = reposerver.NewCommand() case "argocd-cmp-server": command = cmpserver.NewCommand() - isArgocdCLI = true + isCLI = true case "argocd-commit-server": command = commitserver.NewCommand() case "argocd-dex": @@ -64,41 +55,19 @@ func main() { command = notification.NewCommand() case "argocd-git-ask-pass": command = gitaskpass.NewCommand() - isArgocdCLI = true + isCLI = true case "argocd-applicationset-controller": command = applicationset.NewCommand() case "argocd-k8s-auth": command = k8sauth.NewCommand() - isArgocdCLI = true + isCLI = true default: command = cli.NewCommand() - isArgocdCLI = true + isCLI = true } - util.SetAutoMaxProcs(isArgocdCLI) + util.SetAutoMaxProcs(isCLI) - if isArgocdCLI { - // silence errors and usages since we'll be printing them manually. - // This is because if we execute a plugin, the initial - // errors and usage are always going to get printed that we don't want. - command.SilenceErrors = true - command.SilenceUsage = true - } - - err := command.Execute() - // if the err is non-nil, try to look for various scenarios - // such as if the error is from the execution of a normal argocd command, - // unknown command error or any other. - if err != nil { - pluginHandler := cli.NewDefaultPluginHandler([]string{"argocd"}) - pluginErr := pluginHandler.HandleCommandExecutionError(err, isArgocdCLI, os.Args) - if pluginErr != nil { - var exitErr *exec.ExitError - if errors.As(pluginErr, &exitErr) { - // Return the actual plugin exit code - os.Exit(exitErr.ExitCode()) - } - // Fallback to exit code 1 if the error isn't an exec.ExitError - os.Exit(1) - } + if err := command.Execute(); err != nil { + os.Exit(1) } } diff --git a/cmd/util/app.go b/cmd/util/app.go index 7f3ba56615..e66c03f4e9 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -2,7 +2,6 @@ package util import ( "bufio" - stderrors "errors" "fmt" "io" "net/url" @@ -19,15 +18,15 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/pflag" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/config" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/text/label" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + argoappv1 "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/config" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/text/label" ) type AppOptions struct { @@ -55,7 +54,7 @@ type AppOptions struct { helmSkipTests bool helmNamespace string helmKubeVersion string - helmApiVersions []string //nolint:revive //FIXME(var-naming) + helmApiVersions []string project string syncPolicy string syncOptions []string @@ -77,13 +76,11 @@ type AppOptions struct { kustomizeCommonLabels []string kustomizeCommonAnnotations []string kustomizeLabelWithoutSelector bool - kustomizeLabelIncludeTemplates bool kustomizeForceCommonLabels bool kustomizeForceCommonAnnotations bool kustomizeNamespace string kustomizeKubeVersion string - kustomizeApiVersions []string //nolint:revive //FIXME(var-naming) - ignoreMissingComponents bool + kustomizeApiVersions []string pluginEnvs []string Validate bool directoryExclude string @@ -165,13 +162,11 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) { command.Flags().StringArrayVar(&opts.jsonnetLibs, "jsonnet-libs", []string{}, "Additional jsonnet libs (prefixed by repoRoot)") command.Flags().StringArrayVar(&opts.kustomizeImages, "kustomize-image", []string{}, "Kustomize images (e.g. --kustomize-image node:8.15.0 --kustomize-image mysql=mariadb,alpine@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d)") command.Flags().StringArrayVar(&opts.kustomizeReplicas, "kustomize-replica", []string{}, "Kustomize replicas (e.g. --kustomize-replica my-development=2 --kustomize-replica my-statefulset=4)") - command.Flags().BoolVar(&opts.ignoreMissingComponents, "ignore-missing-components", false, "Ignore locally missing component directories when setting Kustomize components") command.Flags().StringArrayVar(&opts.pluginEnvs, "plugin-env", []string{}, "Additional plugin envs") command.Flags().BoolVar(&opts.Validate, "validate", true, "Validation of repo and cluster") command.Flags().StringArrayVar(&opts.kustomizeCommonLabels, "kustomize-common-label", []string{}, "Set common labels in Kustomize") command.Flags().StringArrayVar(&opts.kustomizeCommonAnnotations, "kustomize-common-annotation", []string{}, "Set common labels in Kustomize") - command.Flags().BoolVar(&opts.kustomizeLabelWithoutSelector, "kustomize-label-without-selector", false, "Do not apply common label to selectors. Also do not apply label to templates unless --kustomize-label-include-templates is set") - command.Flags().BoolVar(&opts.kustomizeLabelIncludeTemplates, "kustomize-label-include-templates", false, "Apply common label to resource templates") + command.Flags().BoolVar(&opts.kustomizeLabelWithoutSelector, "kustomize-label-without-selector", false, "Do not apply common label to selectors or templates") command.Flags().BoolVar(&opts.kustomizeForceCommonLabels, "kustomize-force-common-label", false, "Force common labels in Kustomize") command.Flags().BoolVar(&opts.kustomizeForceCommonAnnotations, "kustomize-force-common-annotation", false, "Force common annotations in Kustomize") command.Flags().StringVar(&opts.kustomizeNamespace, "kustomize-namespace", "", "Kustomize namespace") @@ -203,12 +198,11 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap } source, visited = ConstructSource(source, *appOpts, flags) if spec.HasMultipleSources() { - switch { - case sourcePosition == 0: + if sourcePosition == 0 { spec.Sources[sourcePosition] = *source - case sourcePosition > 0: + } else if sourcePosition > 0 { spec.Sources[sourcePosition-1] = *source - default: + } else { spec.Sources = append(spec.Sources, *source) } } else { @@ -264,8 +258,7 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap spec.SyncPolicy = nil } case "sync-retry-limit": - switch { - case appOpts.retryLimit > 0: + if appOpts.retryLimit > 0 { if spec.SyncPolicy == nil { spec.SyncPolicy = &argoappv1.SyncPolicy{} } @@ -277,31 +270,31 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap Factor: ptr.To(appOpts.retryBackoffFactor), }, } - case appOpts.retryLimit == 0: + } else if appOpts.retryLimit == 0 { if spec.SyncPolicy.IsZero() { spec.SyncPolicy = nil } else { spec.SyncPolicy.Retry = nil } - default: + } else { log.Fatalf("Invalid sync-retry-limit [%d]", appOpts.retryLimit) } } }) if flags.Changed("auto-prune") { - if spec.SyncPolicy == nil || !spec.SyncPolicy.IsAutomatedSyncEnabled() { + if spec.SyncPolicy == nil || spec.SyncPolicy.Automated == nil { log.Fatal("Cannot set --auto-prune: application not configured with automatic sync") } spec.SyncPolicy.Automated.Prune = appOpts.autoPrune } if flags.Changed("self-heal") { - if spec.SyncPolicy == nil || !spec.SyncPolicy.IsAutomatedSyncEnabled() { + if spec.SyncPolicy == nil || spec.SyncPolicy.Automated == nil { log.Fatal("Cannot set --self-heal: application not configured with automatic sync") } spec.SyncPolicy.Automated.SelfHeal = appOpts.selfHeal } if flags.Changed("allow-empty") { - if spec.SyncPolicy == nil || !spec.SyncPolicy.IsAutomatedSyncEnabled() { + if spec.SyncPolicy == nil || spec.SyncPolicy.Automated == nil { log.Fatal("Cannot set --allow-empty: application not configured with automatic sync") } spec.SyncPolicy.Automated.AllowEmpty = appOpts.allowEmpty @@ -311,21 +304,19 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap } type kustomizeOpts struct { - namePrefix string - nameSuffix string - images []string - replicas []string - version string - commonLabels map[string]string - commonAnnotations map[string]string - labelWithoutSelector bool - labelIncludeTemplates bool - forceCommonLabels bool - forceCommonAnnotations bool - namespace string - kubeVersion string - apiVersions []string - ignoreMissingComponents bool + namePrefix string + nameSuffix string + images []string + replicas []string + version string + commonLabels map[string]string + commonAnnotations map[string]string + labelWithoutSelector bool + forceCommonLabels bool + forceCommonAnnotations bool + namespace string + kubeVersion string + apiVersions []string } func setKustomizeOpt(src *argoappv1.ApplicationSource, opts kustomizeOpts) { @@ -359,18 +350,12 @@ func setKustomizeOpt(src *argoappv1.ApplicationSource, opts kustomizeOpts) { if opts.labelWithoutSelector { src.Kustomize.LabelWithoutSelector = opts.labelWithoutSelector } - if opts.labelIncludeTemplates { - src.Kustomize.LabelIncludeTemplates = opts.labelIncludeTemplates - } if opts.forceCommonLabels { src.Kustomize.ForceCommonLabels = opts.forceCommonLabels } if opts.forceCommonAnnotations { src.Kustomize.ForceCommonAnnotations = opts.forceCommonAnnotations } - if opts.ignoreMissingComponents { - src.Kustomize.IgnoreMissingComponents = opts.ignoreMissingComponents - } for _, image := range opts.images { src.Kustomize.MergeImage(argoappv1.KustomizeImage(image)) } @@ -581,7 +566,7 @@ func readAppsFromStdin(apps *[]*argoappv1.Application) error { func readAppsFromURI(fileURL string, apps *[]*argoappv1.Application) error { readFilePayload := func() ([]byte, error) { parsedURL, err := url.ParseRequestURI(fileURL) - if err != nil || (parsedURL.Scheme != "http" && parsedURL.Scheme != "https") { + if err != nil || !(parsedURL.Scheme == "http" || parsedURL.Scheme == "https") { return os.ReadFile(fileURL) } return config.ReadRemoteFile(fileURL) @@ -617,11 +602,11 @@ func constructAppsBaseOnName(appName string, labels, annotations, args []string, } appName, appNs := argo.ParseFromQualifiedName(appName, "") app = &argoappv1.Application{ - TypeMeta: metav1.TypeMeta{ + TypeMeta: v1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: application.Group + "/v1alpha1", }, - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: appName, Namespace: appNs, }, @@ -636,7 +621,7 @@ func constructAppsBaseOnName(appName string, labels, annotations, args []string, }, nil } -func constructAppsFromFileURL(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet) ([]*argoappv1.Application, error) { +func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet) ([]*argoappv1.Application, error) { apps := make([]*argoappv1.Application, 0) // read uri err := readAppsFromURI(fileURL, &apps) @@ -651,7 +636,7 @@ func constructAppsFromFileURL(fileURL, appName string, labels, annotations, args app.Name = appName } if app.Name == "" { - return nil, stderrors.New("app.Name is empty. --name argument can be used to provide app.Name") + return nil, fmt.Errorf("app.Name is empty. --name argument can be used to provide app.Name") } mergeLabels(app, labels) @@ -670,7 +655,7 @@ func ConstructApps(fileURL, appName string, labels, annotations, args []string, if fileURL == "-" { return constructAppsFromStdin() } else if fileURL != "" { - return constructAppsFromFileURL(fileURL, appName, labels, annotations, args, appOpts, flags) + return constructAppsFromFileUrl(fileURL, appName, labels, annotations, args, appOpts, flags) } return constructAppsBaseOnName(appName, labels, annotations, args, appOpts, flags) @@ -697,7 +682,7 @@ func ConstructSource(source *argoappv1.ApplicationSource, appOpts AppOptions, fl var data []byte // read uri parsedURL, err := url.ParseRequestURI(appOpts.values) - if err != nil || (parsedURL.Scheme != "http" && parsedURL.Scheme != "https") { + if err != nil || !(parsedURL.Scheme == "http" || parsedURL.Scheme == "https") { data, err = os.ReadFile(appOpts.values) } else { data, err = config.ReadRemoteFile(appOpts.values) @@ -774,14 +759,10 @@ func ConstructSource(source *argoappv1.ApplicationSource, appOpts AppOptions, fl setKustomizeOpt(source, kustomizeOpts{commonAnnotations: parsedAnnotations}) case "kustomize-label-without-selector": setKustomizeOpt(source, kustomizeOpts{labelWithoutSelector: appOpts.kustomizeLabelWithoutSelector}) - case "kustomize-label-include-templates": - setKustomizeOpt(source, kustomizeOpts{labelIncludeTemplates: appOpts.kustomizeLabelIncludeTemplates}) case "kustomize-force-common-label": setKustomizeOpt(source, kustomizeOpts{forceCommonLabels: appOpts.kustomizeForceCommonLabels}) case "kustomize-force-common-annotation": setKustomizeOpt(source, kustomizeOpts{forceCommonAnnotations: appOpts.kustomizeForceCommonAnnotations}) - case "ignore-missing-components": - setKustomizeOpt(source, kustomizeOpts{ignoreMissingComponents: appOpts.ignoreMissingComponents}) case "jsonnet-tla-str": setJsonnetOpt(source, appOpts.jsonnetTlaStr, false) case "jsonnet-tla-code": @@ -914,10 +895,10 @@ func FilterResources(groupChanged bool, resources []*argoappv1.ResourceDiff, gro filteredObjects = append(filteredObjects, deepCopy) } if len(filteredObjects) == 0 { - return nil, stderrors.New("no matching resource found") + return nil, fmt.Errorf("No matching resource found") } if len(filteredObjects) > 1 && !all { - return nil, stderrors.New("multiple resources match inputs, use the --all flag to patch multiple resources") + return nil, fmt.Errorf("Multiple resources match inputs. Use the --all flag to patch multiple resources") } return filteredObjects, nil } diff --git a/cmd/util/app_test.go b/cmd/util/app_test.go index 0f767fbb70..46b4115033 100644 --- a/cmd/util/app_test.go +++ b/cmd/util/app_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -165,17 +165,6 @@ func Test_setKustomizeOpt(t *testing.T) { setKustomizeOpt(&src, kustomizeOpts{commonLabels: map[string]string{"foo1": "bar1", "foo2": "bar2"}, labelWithoutSelector: true}) assert.Equal(t, &v1alpha1.ApplicationSourceKustomize{CommonLabels: map[string]string{"foo1": "bar1", "foo2": "bar2"}, LabelWithoutSelector: true}, src.Kustomize) }) - t.Run("Label include templates", func(t *testing.T) { - src := v1alpha1.ApplicationSource{} - setKustomizeOpt(&src, kustomizeOpts{commonLabels: map[string]string{"foo1": "bar1", "foo2": "bar2"}, labelIncludeTemplates: true}) - assert.Equal(t, &v1alpha1.ApplicationSourceKustomize{CommonLabels: map[string]string{"foo1": "bar1", "foo2": "bar2"}, LabelIncludeTemplates: true}, src.Kustomize) - }) - t.Run("IgnoreMissingComponents", func(t *testing.T) { - src := v1alpha1.ApplicationSource{} - setKustomizeOpt(&src, kustomizeOpts{ignoreMissingComponents: true}) - t.Logf("HERE IS THE SOURCE\n %+v\n", src) - assert.True(t, src.Kustomize.IgnoreMissingComponents) - }) } func Test_setJsonnetOpt(t *testing.T) { @@ -554,7 +543,7 @@ func TestFilterResources(t *testing.T) { } filteredResources, err := FilterResources(false, resources, "g", "Service", "argocd-unknown", "test-helm", true) - require.ErrorContains(t, err, "no matching resource found") + require.ErrorContains(t, err, "No matching resource found") assert.Nil(t, filteredResources) }) @@ -569,7 +558,7 @@ func TestFilterResources(t *testing.T) { } filteredResources, err := FilterResources(false, resources, "g", "Service", "argocd", "test-helm", false) - require.ErrorContains(t, err, "use the --all flag") + require.ErrorContains(t, err, "Use the --all flag") assert.Nil(t, filteredResources) }) } diff --git a/cmd/util/applicationset.go b/cmd/util/applicationset.go index edf7718485..6f6fd1e3de 100644 --- a/cmd/util/applicationset.go +++ b/cmd/util/applicationset.go @@ -7,18 +7,18 @@ import ( "github.com/argoproj/gitops-engine/pkg/utils/kube" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/config" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/config" ) func ConstructApplicationSet(fileURL string) ([]*argoprojiov1alpha1.ApplicationSet, error) { if fileURL != "" { - return constructAppsetFromFileURL(fileURL) + return constructAppsetFromFileUrl(fileURL) } return nil, nil } -func constructAppsetFromFileURL(fileURL string) ([]*argoprojiov1alpha1.ApplicationSet, error) { +func constructAppsetFromFileUrl(fileURL string) ([]*argoprojiov1alpha1.ApplicationSet, error) { appset := make([]*argoprojiov1alpha1.ApplicationSet, 0) // read uri err := readAppsetFromURI(fileURL, &appset) @@ -32,7 +32,7 @@ func constructAppsetFromFileURL(fileURL string) ([]*argoprojiov1alpha1.Applicati func readAppsetFromURI(fileURL string, appset *[]*argoprojiov1alpha1.ApplicationSet) error { readFilePayload := func() ([]byte, error) { parsedURL, err := url.ParseRequestURI(fileURL) - if err != nil || (parsedURL.Scheme != "http" && parsedURL.Scheme != "https") { + if err != nil || !(parsedURL.Scheme == "http" || parsedURL.Scheme == "https") { return os.ReadFile(fileURL) } return config.ReadRemoteFile(fileURL) diff --git a/cmd/util/applicationset_test.go b/cmd/util/applicationset_test.go index 45255fd6d3..0fdc0a9f89 100644 --- a/cmd/util/applicationset_test.go +++ b/cmd/util/applicationset_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) var appSet = `apiVersion: argoproj.io/v1alpha1 diff --git a/cmd/util/cluster.go b/cmd/util/cluster.go index d674525c97..ab4e4816cf 100644 --- a/cmd/util/cluster.go +++ b/cmd/util/cluster.go @@ -2,7 +2,6 @@ package util import ( "context" - stderrors "errors" "fmt" "os" "sort" @@ -17,8 +16,8 @@ import ( clientcmdapiv1 "k8s.io/client-go/tools/clientcmd/api/v1" "sigs.k8s.io/yaml" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/errors" + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/errors" ) type ClusterEndpoint string @@ -70,24 +69,24 @@ func PrintKubeContexts(ca clientcmd.ConfigAccess) { func NewCluster(name string, namespaces []string, clusterResources bool, conf *rest.Config, managerBearerToken string, awsAuthConf *argoappv1.AWSAuthConfig, execProviderConf *argoappv1.ExecProviderConfig, labels, annotations map[string]string) *argoappv1.Cluster { tlsClientConfig := argoappv1.TLSClientConfig{ - Insecure: conf.Insecure, - ServerName: conf.ServerName, - CAData: conf.CAData, - CertData: conf.CertData, - KeyData: conf.KeyData, + Insecure: conf.TLSClientConfig.Insecure, + ServerName: conf.TLSClientConfig.ServerName, + CAData: conf.TLSClientConfig.CAData, + CertData: conf.TLSClientConfig.CertData, + KeyData: conf.TLSClientConfig.KeyData, } - if len(conf.CAData) == 0 && conf.CAFile != "" { - data, err := os.ReadFile(conf.CAFile) + if len(conf.TLSClientConfig.CAData) == 0 && conf.TLSClientConfig.CAFile != "" { + data, err := os.ReadFile(conf.TLSClientConfig.CAFile) errors.CheckError(err) tlsClientConfig.CAData = data } - if len(conf.CertData) == 0 && conf.CertFile != "" { - data, err := os.ReadFile(conf.CertFile) + if len(conf.TLSClientConfig.CertData) == 0 && conf.TLSClientConfig.CertFile != "" { + data, err := os.ReadFile(conf.TLSClientConfig.CertFile) errors.CheckError(err) tlsClientConfig.CertData = data } - if len(conf.KeyData) == 0 && conf.KeyFile != "" { - data, err := os.ReadFile(conf.KeyFile) + if len(conf.TLSClientConfig.KeyData) == 0 && conf.TLSClientConfig.KeyFile != "" { + data, err := os.ReadFile(conf.TLSClientConfig.KeyFile) errors.CheckError(err) tlsClientConfig.KeyData = data } @@ -123,30 +122,28 @@ func NewCluster(name string, namespaces []string, clusterResources bool, conf *r return &clst } -// GetKubePublicEndpoint returns the kubernetes apiserver endpoint and certificate authority data as published +// GetKubePublicEndpoint returns the kubernetes apiserver endpoint as published // in the kube-public. -func GetKubePublicEndpoint(client kubernetes.Interface) (string, []byte, error) { +func GetKubePublicEndpoint(client kubernetes.Interface) (string, error) { clusterInfo, err := client.CoreV1().ConfigMaps("kube-public").Get(context.TODO(), "cluster-info", metav1.GetOptions{}) if err != nil { - return "", nil, err + return "", err } kubeconfig, ok := clusterInfo.Data["kubeconfig"] if !ok { - return "", nil, stderrors.New("cluster-info does not contain a public kubeconfig") + return "", fmt.Errorf("cluster-info does not contain a public kubeconfig") } // Parse Kubeconfig and get server address config := &clientcmdapiv1.Config{} err = yaml.Unmarshal([]byte(kubeconfig), config) if err != nil { - return "", nil, fmt.Errorf("failed to parse cluster-info kubeconfig: %w", err) + return "", fmt.Errorf("failed to parse cluster-info kubeconfig: %w", err) } if len(config.Clusters) == 0 { - return "", nil, stderrors.New("cluster-info kubeconfig does not have any clusters") + return "", fmt.Errorf("cluster-info kubeconfig does not have any clusters") } - endpoint := config.Clusters[0].Cluster.Server - certificateAuthorityData := config.Clusters[0].Cluster.CertificateAuthorityData - return endpoint, certificateAuthorityData, nil + return config.Clusters[0].Cluster.Server, nil } type ClusterOptions struct { @@ -169,7 +166,7 @@ type ClusterOptions struct { ExecProviderInstallHint string ClusterEndpoint string DisableCompression bool - ProxyUrl string //nolint:revive //FIXME(var-naming) + ProxyUrl string } // InClusterEndpoint returns true if ArgoCD should reference the in-cluster diff --git a/cmd/util/cluster_test.go b/cmd/util/cluster_test.go index 3706b2d7df..12ed3fe5cc 100644 --- a/cmd/util/cluster_test.go +++ b/cmd/util/cluster_test.go @@ -13,7 +13,7 @@ import ( clientcmdapiv1 "k8s.io/client-go/tools/clientcmd/api/v1" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func Test_newCluster(t *testing.T) { @@ -35,7 +35,7 @@ func Test_newCluster(t *testing.T) { assert.Equal(t, "test-cert-data", string(clusterWithData.Config.CertData)) assert.Equal(t, "test-key-data", string(clusterWithData.Config.KeyData)) - assert.Empty(t, clusterWithData.Config.BearerToken) + assert.Equal(t, "", clusterWithData.Config.BearerToken) assert.Equal(t, labels, clusterWithData.Labels) assert.Equal(t, annotations, clusterWithData.Annotations) assert.False(t, clusterWithData.Config.DisableCompression) @@ -56,7 +56,7 @@ func Test_newCluster(t *testing.T) { assert.Contains(t, string(clusterWithFiles.Config.CertData), "test-cert-data") assert.Contains(t, string(clusterWithFiles.Config.KeyData), "test-key-data") - assert.Empty(t, clusterWithFiles.Config.BearerToken) + assert.Equal(t, "", clusterWithFiles.Config.BearerToken) assert.Equal(t, labels, clusterWithFiles.Labels) assert.Nil(t, clusterWithFiles.Annotations) @@ -96,23 +96,8 @@ func TestGetKubePublicEndpoint(t *testing.T) { name string clusterInfo *corev1.ConfigMap expectedEndpoint string - expectedCAData []byte expectError bool }{ - { - name: "has public endpoint and certificate authority data", - clusterInfo: &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "kube-public", - Name: "cluster-info", - }, - Data: map[string]string{ - "kubeconfig": kubeconfigFixture("https://test-cluster:6443", []byte("test-ca-data")), - }, - }, - expectedEndpoint: "https://test-cluster:6443", - expectedCAData: []byte("test-ca-data"), - }, { name: "has public endpoint", clusterInfo: &corev1.ConfigMap{ @@ -121,11 +106,10 @@ func TestGetKubePublicEndpoint(t *testing.T) { Name: "cluster-info", }, Data: map[string]string{ - "kubeconfig": kubeconfigFixture("https://test-cluster:6443", nil), + "kubeconfig": kubeconfigFixture("https://test-cluster:6443"), }, }, expectedEndpoint: "https://test-cluster:6443", - expectedCAData: nil, }, { name: "no cluster-info", @@ -152,7 +136,7 @@ func TestGetKubePublicEndpoint(t *testing.T) { Name: "cluster-info", }, Data: map[string]string{ - "kubeconfig": kubeconfigFixture("", nil), + "kubeconfig": kubeconfigFixture(""), }, }, expectError: true, @@ -179,27 +163,25 @@ func TestGetKubePublicEndpoint(t *testing.T) { objects = append(objects, tc.clusterInfo) } clientset := fake.NewClientset(objects...) - endpoint, caData, err := GetKubePublicEndpoint(clientset) + endpoint, err := GetKubePublicEndpoint(clientset) if tc.expectError { require.Error(t, err) } else { require.NoError(t, err) } require.Equalf(t, tc.expectedEndpoint, endpoint, "expected endpoint %s, got %s", tc.expectedEndpoint, endpoint) - require.Equalf(t, tc.expectedCAData, caData, "expected caData %s, got %s", tc.expectedCAData, caData) }) } } -func kubeconfigFixture(endpoint string, certificateAuthorityData []byte) string { +func kubeconfigFixture(endpoint string) string { kubeconfig := &clientcmdapiv1.Config{} if len(endpoint) > 0 { kubeconfig.Clusters = []clientcmdapiv1.NamedCluster{ { Name: "test-kube", Cluster: clientcmdapiv1.Cluster{ - Server: endpoint, - CertificateAuthorityData: certificateAuthorityData, + Server: endpoint, }, }, } diff --git a/cmd/util/common.go b/cmd/util/common.go index b4312e5836..7c7b629ab4 100644 --- a/cmd/util/common.go +++ b/cmd/util/common.go @@ -1,39 +1,6 @@ package util -import ( - stderrors "errors" -) - var ( LogFormat string LogLevel string ) - -func ValidateBearerTokenForHTTPSRepoOnly(bearerToken string, isHTTPS bool) error { - // Bearer token is only valid for HTTPS repositories - if bearerToken != "" { - if !isHTTPS { - err := stderrors.New("--bearer-token is only supported for HTTPS repositories") - return err - } - } - return nil -} - -func ValidateBearerTokenForGitOnly(bearerToken string, repoType string) error { - // Bearer token is only valid for Git repositories - if bearerToken != "" && repoType != "git" { - err := stderrors.New("--bearer-token is only supported for Git repositories") - return err - } - return nil -} - -func ValidateBearerTokenAndPasswordCombo(bearerToken string, password string) error { - // Either the password or the bearer token must be set, but not both - if bearerToken != "" && password != "" { - err := stderrors.New("only --bearer-token or --password is allowed, not both") - return err - } - return nil -} diff --git a/cmd/util/common_test.go b/cmd/util/common_test.go deleted file mode 100644 index c6950ab84f..0000000000 --- a/cmd/util/common_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package util - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestValidateBearerTokenAndPasswordCombo(t *testing.T) { - tests := []struct { - name string - bearerToken string - password string - expectError bool - errorMsg string - }{ - { - name: "Both token and password set", - bearerToken: "some-token", - password: "some-password", - expectError: true, - errorMsg: "only --bearer-token or --password is allowed, not both", - }, - { - name: "Only token set", - bearerToken: "some-token", - password: "", - expectError: false, - }, - { - name: "Only password set", - bearerToken: "", - password: "some-password", - expectError: false, - }, - { - name: "Neither token nor password set", - bearerToken: "", - password: "", - expectError: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := ValidateBearerTokenAndPasswordCombo(tt.bearerToken, tt.password) - if tt.expectError { - require.ErrorContains(t, err, tt.errorMsg) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestValidateBearerTokenForGitOnly(t *testing.T) { - tests := []struct { - name string - bearerToken string - repoType string - expectError bool - errorMsg string - }{ - { - name: "Bearer token with helm repo", - bearerToken: "some-token", - repoType: "helm", - expectError: true, - errorMsg: "--bearer-token is only supported for Git repositories", - }, - { - name: "Bearer token with git repo", - bearerToken: "some-token", - repoType: "git", - expectError: false, - }, - { - name: "No bearer token with helm repo", - bearerToken: "", - repoType: "helm", - expectError: false, - }, - { - name: "No bearer token with git repo", - bearerToken: "", - repoType: "git", - expectError: false, - }, - { - name: "Bearer token with empty repo", - bearerToken: "some-token", - repoType: "", - expectError: true, - errorMsg: "--bearer-token is only supported for Git repositories", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := ValidateBearerTokenForGitOnly(tt.bearerToken, tt.repoType) - if tt.expectError { - require.ErrorContains(t, err, tt.errorMsg) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestValidateBearerTokenForHTTPSRepoOnly(t *testing.T) { - tests := []struct { - name string - bearerToken string - isHTTPS bool - expectError bool - errorMsg string - }{ - { - name: "Bearer token with HTTPS repo", - bearerToken: "some-token", - isHTTPS: true, - expectError: false, - }, - { - name: "Bearer token with non-HTTPS repo", - bearerToken: "some-token", - isHTTPS: false, - expectError: true, - errorMsg: "--bearer-token is only supported for HTTPS repositories", - }, - { - name: "No bearer token with HTTPS repo", - bearerToken: "", - isHTTPS: true, - expectError: false, - }, - { - name: "No bearer token with non-HTTPS repo", - bearerToken: "", - isHTTPS: false, - expectError: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := ValidateBearerTokenForHTTPSRepoOnly(tt.bearerToken, tt.isHTTPS) - if tt.expectError { - require.ErrorContains(t, err, tt.errorMsg) - } else { - require.NoError(t, err) - } - }) - } -} diff --git a/cmd/util/project.go b/cmd/util/project.go index c86bbdc018..63dff2018c 100644 --- a/cmd/util/project.go +++ b/cmd/util/project.go @@ -10,13 +10,13 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/config" - "github.com/argoproj/argo-cd/v3/util/gpg" + "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/config" + "github.com/argoproj/argo-cd/v2/util/gpg" ) type ProjectOpts struct { @@ -52,31 +52,31 @@ func AddProjFlags(command *cobra.Command, opts *ProjectOpts) { "Destination server, namespace and target service account (e.g. https://192.168.99.100:8443,default,default-sa)") } -func getGroupKindList(values []string) []metav1.GroupKind { - var res []metav1.GroupKind +func getGroupKindList(values []string) []v1.GroupKind { + var res []v1.GroupKind for _, val := range values { if parts := strings.Split(val, "/"); len(parts) == 2 { - res = append(res, metav1.GroupKind{Group: parts[0], Kind: parts[1]}) + res = append(res, v1.GroupKind{Group: parts[0], Kind: parts[1]}) } else if len(parts) == 1 { - res = append(res, metav1.GroupKind{Kind: parts[0]}) + res = append(res, v1.GroupKind{Kind: parts[0]}) } } return res } -func (opts *ProjectOpts) GetAllowedClusterResources() []metav1.GroupKind { +func (opts *ProjectOpts) GetAllowedClusterResources() []v1.GroupKind { return getGroupKindList(opts.allowedClusterResources) } -func (opts *ProjectOpts) GetDeniedClusterResources() []metav1.GroupKind { +func (opts *ProjectOpts) GetDeniedClusterResources() []v1.GroupKind { return getGroupKindList(opts.deniedClusterResources) } -func (opts *ProjectOpts) GetAllowedNamespacedResources() []metav1.GroupKind { +func (opts *ProjectOpts) GetAllowedNamespacedResources() []v1.GroupKind { return getGroupKindList(opts.allowedNamespacedResources) } -func (opts *ProjectOpts) GetDeniedNamespacedResources() []metav1.GroupKind { +func (opts *ProjectOpts) GetDeniedNamespacedResources() []v1.GroupKind { return getGroupKindList(opts.deniedNamespacedResources) } @@ -86,11 +86,12 @@ func (opts *ProjectOpts) GetDestinations() []v1alpha1.ApplicationDestination { parts := strings.Split(destStr, ",") if len(parts) != 2 { log.Fatalf("Expected destination of the form: server,namespace. Received: %s", destStr) + } else { + destinations = append(destinations, v1alpha1.ApplicationDestination{ + Server: parts[0], + Namespace: parts[1], + }) } - destinations = append(destinations, v1alpha1.ApplicationDestination{ - Server: parts[0], - Namespace: parts[1], - }) } return destinations } @@ -101,12 +102,13 @@ func (opts *ProjectOpts) GetDestinationServiceAccounts() []v1alpha1.ApplicationD parts := strings.Split(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], + Namespace: parts[1], + DefaultServiceAccount: parts[2], + }) } - destinationServiceAccounts = append(destinationServiceAccounts, v1alpha1.ApplicationDestinationServiceAccount{ - Server: parts[0], - Namespace: parts[1], - DefaultServiceAccount: parts[2], - }) } return destinationServiceAccounts } @@ -150,7 +152,7 @@ func readProjFromStdin(proj *v1alpha1.AppProject) error { func readProjFromURI(fileURL string, proj *v1alpha1.AppProject) error { parsedURL, err := url.ParseRequestURI(fileURL) - if err != nil || (parsedURL.Scheme != "http" && parsedURL.Scheme != "https") { + if err != nil || !(parsedURL.Scheme == "http" || parsedURL.Scheme == "https") { err = config.UnmarshalLocalFile(fileURL, &proj) } else { err = config.UnmarshalRemoteFile(fileURL, &proj) @@ -197,19 +199,18 @@ func SetProjSpecOptions(flags *pflag.FlagSet, spec *v1alpha1.AppProjectSpec, pro func ConstructAppProj(fileURL string, args []string, opts ProjectOpts, c *cobra.Command) (*v1alpha1.AppProject, error) { proj := v1alpha1.AppProject{ - TypeMeta: metav1.TypeMeta{ + TypeMeta: v1.TypeMeta{ Kind: application.AppProjectKind, APIVersion: application.Group + "/v1alpha1", }, } - switch { - case fileURL == "-": + if fileURL == "-" { // read stdin err := readProjFromStdin(&proj) if err != nil { return nil, err } - case fileURL != "": + } else if fileURL != "" { // read uri err := readProjFromURI(fileURL, &proj) if err != nil { @@ -219,7 +220,7 @@ func ConstructAppProj(fileURL string, args []string, opts ProjectOpts, c *cobra. if len(args) == 1 && args[0] != proj.Name { return nil, fmt.Errorf("project name '%s' does not match project spec metadata.name '%s'", args[0], proj.Name) } - default: + } else { // read arguments if len(args) == 0 { c.HelpFunc()(c, args) diff --git a/cmd/util/project_test.go b/cmd/util/project_test.go index dea5cabb2c..83f5974b6c 100644 --- a/cmd/util/project_test.go +++ b/cmd/util/project_test.go @@ -4,9 +4,9 @@ import ( "testing" "github.com/stretchr/testify/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestProjectOpts_ResourceLists(t *testing.T) { @@ -17,10 +17,14 @@ func TestProjectOpts_ResourceLists(t *testing.T) { deniedClusterResources: []string{"rbac.authorization.k8s.io/ClusterRole"}, } - assert.ElementsMatch(t, []metav1.GroupKind{{Kind: "ConfigMap"}}, opts.GetAllowedNamespacedResources()) - assert.ElementsMatch(t, []metav1.GroupKind{{Group: "apps", Kind: "DaemonSet"}}, opts.GetDeniedNamespacedResources()) - assert.ElementsMatch(t, []metav1.GroupKind{{Group: "apiextensions.k8s.io", Kind: "CustomResourceDefinition"}}, opts.GetAllowedClusterResources()) - assert.ElementsMatch(t, []metav1.GroupKind{{Group: "rbac.authorization.k8s.io", Kind: "ClusterRole"}}, opts.GetDeniedClusterResources()) + assert.ElementsMatch(t, + []v1.GroupKind{{Kind: "ConfigMap"}}, opts.GetAllowedNamespacedResources()) + assert.ElementsMatch(t, + []v1.GroupKind{{Group: "apps", Kind: "DaemonSet"}}, opts.GetDeniedNamespacedResources()) + assert.ElementsMatch(t, + []v1.GroupKind{{Group: "apiextensions.k8s.io", Kind: "CustomResourceDefinition"}}, opts.GetAllowedClusterResources()) + assert.ElementsMatch(t, + []v1.GroupKind{{Group: "rbac.authorization.k8s.io", Kind: "ClusterRole"}}, opts.GetDeniedClusterResources()) } func TestProjectOpts_GetDestinationServiceAccounts(t *testing.T) { diff --git a/cmd/util/repo.go b/cmd/util/repo.go index a46951071d..d87d428367 100644 --- a/cmd/util/repo.go +++ b/cmd/util/repo.go @@ -3,18 +3,18 @@ package util import ( "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/common" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/common" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) type RepoOptions struct { Repo appsv1.Repository Upsert bool - SshPrivateKeyPath string //nolint:revive //FIXME(var-naming) + SshPrivateKeyPath string InsecureIgnoreHostKey bool InsecureSkipServerVerification bool - TlsClientCertPath string //nolint:revive //FIXME(var-naming) - TlsClientCertKeyPath string //nolint:revive //FIXME(var-naming) + TlsClientCertPath string + TlsClientCertKeyPath string EnableLfs bool EnableOci bool GithubAppId int64 @@ -24,8 +24,7 @@ type RepoOptions struct { Proxy string NoProxy string GCPServiceAccountKeyPath string - ForceHttpBasicAuth bool //nolint:revive //FIXME(var-naming) - UseAzureWorkloadIdentity bool + ForceHttpBasicAuth bool } func AddRepoFlags(command *cobra.Command, opts *RepoOptions) { @@ -34,7 +33,6 @@ func AddRepoFlags(command *cobra.Command, opts *RepoOptions) { command.Flags().StringVar(&opts.Repo.Project, "project", "", "project of the repository") command.Flags().StringVar(&opts.Repo.Username, "username", "", "username to the repository") command.Flags().StringVar(&opts.Repo.Password, "password", "", "password to the repository") - command.Flags().StringVar(&opts.Repo.BearerToken, "bearer-token", "", "bearer token to the Git BitBucket Data Center repository") command.Flags().StringVar(&opts.SshPrivateKeyPath, "ssh-private-key-path", "", "path to the private ssh key (e.g. ~/.ssh/id_rsa)") command.Flags().StringVar(&opts.TlsClientCertPath, "tls-client-cert-path", "", "path to the TLS client cert (must be PEM format)") command.Flags().StringVar(&opts.TlsClientCertKeyPath, "tls-client-cert-key-path", "", "path to the TLS client cert's key path (must be PEM format)") @@ -50,5 +48,4 @@ func AddRepoFlags(command *cobra.Command, opts *RepoOptions) { command.Flags().StringVar(&opts.NoProxy, "no-proxy", "", "don't access these targets via proxy") command.Flags().StringVar(&opts.GCPServiceAccountKeyPath, "gcp-service-account-key-path", "", "service account key for the Google Cloud Platform") command.Flags().BoolVar(&opts.ForceHttpBasicAuth, "force-http-basic-auth", false, "whether to force use of basic auth when connecting repository via HTTP") - command.Flags().BoolVar(&opts.UseAzureWorkloadIdentity, "use-azure-workload-identity", false, "whether to use azure workload identity for authentication") } diff --git a/cmpserver/apiclient/clientset.go b/cmpserver/apiclient/clientset.go index fb751850e6..8e3ff9b856 100644 --- a/cmpserver/apiclient/clientset.go +++ b/cmpserver/apiclient/clientset.go @@ -5,16 +5,17 @@ import ( "math" "time" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/env" - grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/retry" + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry" log "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - grpc_util "github.com/argoproj/argo-cd/v3/util/grpc" - utilio "github.com/argoproj/argo-cd/v3/util/io" + grpc_util "github.com/argoproj/argo-cd/v2/util/grpc" + "github.com/argoproj/argo-cd/v2/util/io" ) // MaxGRPCMessageSize contains max grpc message size @@ -22,14 +23,14 @@ var MaxGRPCMessageSize = env.ParseNumFromEnv(common.EnvGRPCMaxSizeMB, 100, 0, ma // Clientset represents config management plugin server api clients type Clientset interface { - NewConfigManagementPluginClient() (utilio.Closer, ConfigManagementPluginServiceClient, error) + NewConfigManagementPluginClient() (io.Closer, ConfigManagementPluginServiceClient, error) } type clientSet struct { address string } -func (c *clientSet) NewConfigManagementPluginClient() (utilio.Closer, ConfigManagementPluginServiceClient, error) { +func (c *clientSet) NewConfigManagementPluginClient() (io.Closer, ConfigManagementPluginServiceClient, error) { conn, err := NewConnection(c.address) if err != nil { return nil, nil, err @@ -45,7 +46,7 @@ func NewConnection(address string) (*grpc.ClientConn, error) { unaryInterceptors := []grpc.UnaryClientInterceptor{grpc_retry.UnaryClientInterceptor(retryOpts...)} dialOpts := []grpc.DialOption{ grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(retryOpts...)), - grpc.WithChainUnaryInterceptor(unaryInterceptors...), + grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(unaryInterceptors...)), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(MaxGRPCMessageSize), grpc.MaxCallSendMsgSize(MaxGRPCMessageSize)), grpc.WithUnaryInterceptor(grpc_util.OTELUnaryClientInterceptor()), grpc.WithStreamInterceptor(grpc_util.OTELStreamClientInterceptor()), diff --git a/cmpserver/apiclient/plugin.pb.go b/cmpserver/apiclient/plugin.pb.go index ed46f6f864..5e60bcfabe 100644 --- a/cmpserver/apiclient/plugin.pb.go +++ b/cmpserver/apiclient/plugin.pb.go @@ -6,7 +6,7 @@ package apiclient import ( context "context" fmt "fmt" - apiclient "github.com/argoproj/argo-cd/v3/reposerver/apiclient" + apiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" proto "github.com/gogo/protobuf/proto" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -538,49 +538,49 @@ func init() { func init() { proto.RegisterFile("cmpserver/plugin/plugin.proto", fileDescriptor_b21875a7079a06ed) } var fileDescriptor_b21875a7079a06ed = []byte{ - // 668 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x54, 0xcd, 0x6e, 0xd3, 0x40, - 0x10, 0x8e, 0x9b, 0xb4, 0x4d, 0x26, 0x95, 0x1a, 0xad, 0xa0, 0x98, 0xd0, 0x86, 0xe0, 0x03, 0xca, - 0x05, 0x47, 0x4a, 0x7b, 0x45, 0xa2, 0x2d, 0xa1, 0x15, 0x28, 0x28, 0x72, 0xb9, 0xc0, 0x01, 0x69, - 0xe3, 0x4c, 0x92, 0xa5, 0xf6, 0xee, 0xb2, 0x5e, 0x5b, 0x0a, 0x5c, 0x10, 0x2f, 0xc3, 0xab, 0x70, - 0xe4, 0x11, 0x50, 0x5f, 0x83, 0x0b, 0xf2, 0xda, 0x4e, 0xa2, 0x36, 0x6d, 0x4f, 0x9e, 0xbf, 0xfd, - 0xfc, 0xcd, 0xec, 0x37, 0x0b, 0x07, 0x7e, 0x28, 0x23, 0x54, 0x09, 0xaa, 0xae, 0x0c, 0xe2, 0x29, - 0xe3, 0xf9, 0xc7, 0x95, 0x4a, 0x68, 0x41, 0xb6, 0x32, 0xaf, 0xd9, 0x9f, 0x32, 0x3d, 0x8b, 0x47, - 0xae, 0x2f, 0xc2, 0x2e, 0x55, 0x53, 0x21, 0x95, 0xf8, 0x62, 0x8c, 0x17, 0xfe, 0xb8, 0x9b, 0x1c, - 0x76, 0x15, 0x4a, 0x91, 0xc3, 0x18, 0x93, 0x69, 0xa1, 0xe6, 0x2b, 0x66, 0x06, 0xd7, 0x7c, 0x32, - 0x15, 0x62, 0x1a, 0x60, 0xd7, 0x78, 0xa3, 0x78, 0xd2, 0xc5, 0x50, 0xea, 0x3c, 0xe9, 0xfc, 0xb0, - 0xa0, 0x71, 0x2c, 0xe5, 0x85, 0x56, 0x48, 0x43, 0x0f, 0xbf, 0xc6, 0x18, 0x69, 0xf2, 0x12, 0xaa, - 0x21, 0x6a, 0x3a, 0xa6, 0x9a, 0xda, 0x56, 0xdb, 0xea, 0xd4, 0x7b, 0x4f, 0xdd, 0x9c, 0xe1, 0x80, - 0x72, 0x36, 0xc1, 0x48, 0xe7, 0xa5, 0x83, 0xbc, 0xec, 0xbc, 0xe4, 0x2d, 0x8e, 0x10, 0x07, 0x2a, - 0x13, 0x16, 0xa0, 0xbd, 0x61, 0x8e, 0xee, 0x14, 0x47, 0xdf, 0xb0, 0x00, 0xcf, 0x4b, 0x9e, 0xc9, - 0x9d, 0xd4, 0x60, 0x5b, 0x65, 0x10, 0xce, 0x2f, 0x0b, 0x1e, 0xdd, 0x02, 0x4b, 0x6c, 0xd8, 0xa6, - 0x52, 0xbe, 0xa7, 0x21, 0x1a, 0x22, 0x35, 0xaf, 0x70, 0x49, 0x0b, 0x80, 0x4a, 0xe9, 0x61, 0x30, - 0xa4, 0x7a, 0x66, 0x7e, 0x55, 0xf3, 0x56, 0x22, 0xa4, 0x09, 0x55, 0x7f, 0x86, 0xfe, 0x65, 0x14, - 0x87, 0x76, 0xd9, 0x64, 0x17, 0x3e, 0x21, 0x50, 0x89, 0xd8, 0x37, 0xb4, 0x2b, 0x6d, 0xab, 0x53, - 0xf6, 0x8c, 0x4d, 0x1c, 0x28, 0x23, 0x4f, 0xec, 0xcd, 0x76, 0xb9, 0x53, 0xef, 0x35, 0x0a, 0xce, - 0x7d, 0x9e, 0xf4, 0xb9, 0x56, 0x73, 0x2f, 0x4d, 0x3a, 0x47, 0x50, 0x2d, 0x02, 0x29, 0x06, 0x5f, - 0xd2, 0x32, 0x36, 0x79, 0x00, 0x9b, 0x09, 0x0d, 0x62, 0xcc, 0xe9, 0x64, 0x8e, 0x33, 0x84, 0xc6, - 0xb2, 0xbd, 0x48, 0x0a, 0x1e, 0x21, 0xd9, 0x87, 0x5a, 0x98, 0xc7, 0x22, 0xdb, 0x6a, 0x97, 0x3b, - 0x35, 0x6f, 0x19, 0x48, 0x7b, 0x8b, 0x44, 0xac, 0x7c, 0xfc, 0x30, 0x97, 0x05, 0xd8, 0x4a, 0xc4, - 0x99, 0x00, 0xf1, 0x16, 0xb7, 0xbc, 0xc0, 0x6c, 0x43, 0x9d, 0x45, 0x17, 0xb1, 0x94, 0x42, 0x69, - 0x1c, 0x1b, 0x62, 0x55, 0x6f, 0x35, 0x44, 0x5c, 0x20, 0x2c, 0x7a, 0xcd, 0x22, 0x5f, 0x24, 0xa8, - 0xe6, 0x7d, 0x4e, 0x47, 0x01, 0x8e, 0x0d, 0x7e, 0xd5, 0x5b, 0x93, 0x71, 0xbe, 0x43, 0x6b, 0x48, - 0x15, 0x0d, 0x51, 0xa3, 0x8a, 0x8e, 0x39, 0x17, 0x31, 0xf7, 0x31, 0x44, 0xbe, 0xec, 0xe3, 0x23, - 0xec, 0xc9, 0xa2, 0x62, 0xb5, 0x20, 0x6b, 0xaa, 0xde, 0x7b, 0xe6, 0xae, 0xc8, 0x71, 0xb8, 0xae, - 0xd2, 0xbb, 0x05, 0xc0, 0xd9, 0x87, 0x4a, 0xaa, 0x98, 0x74, 0xa8, 0xfe, 0x2c, 0xe6, 0x97, 0xa6, - 0xa1, 0x1d, 0x2f, 0x73, 0x9c, 0x9f, 0x16, 0xb4, 0x4f, 0xd3, 0xfb, 0x1c, 0x9a, 0x8b, 0x3a, 0x15, - 0x7c, 0xc2, 0xa6, 0xb1, 0xa2, 0x9a, 0x09, 0xbe, 0x60, 0x77, 0x04, 0x0f, 0x57, 0xba, 0x2a, 0x6a, - 0x16, 0xb3, 0x59, 0x9f, 0x24, 0x1d, 0xd8, 0x95, 0x4a, 0x24, 0x6c, 0x8c, 0x67, 0x4c, 0x9f, 0x2a, - 0x1c, 0x47, 0xf9, 0x88, 0xae, 0x87, 0x7b, 0xff, 0x36, 0xe0, 0x20, 0x3b, 0x38, 0xa0, 0x9c, 0x4e, - 0x0d, 0xf1, 0x8c, 0xcf, 0x05, 0xaa, 0x84, 0xf9, 0x48, 0xde, 0x42, 0xe3, 0x0c, 0x39, 0x2a, 0xaa, - 0xb1, 0xd0, 0x00, 0xb1, 0x0b, 0x71, 0x5d, 0xdf, 0xbb, 0xa6, 0x7d, 0x73, 0xcb, 0xb2, 0x4e, 0x9c, - 0x52, 0xc7, 0x22, 0x9f, 0xc1, 0xbe, 0xad, 0x63, 0xb2, 0xe7, 0x66, 0x4b, 0xee, 0x16, 0x4b, 0xee, - 0xf6, 0xd3, 0x25, 0x6f, 0x76, 0x0a, 0xc4, 0xfb, 0x66, 0xe5, 0x94, 0xc8, 0x3b, 0xd8, 0x1d, 0x50, - 0xed, 0xcf, 0x96, 0xd2, 0xba, 0x83, 0x6a, 0xb3, 0xc8, 0xdc, 0x14, 0xa2, 0x21, 0x4b, 0xe1, 0xf1, - 0x19, 0xea, 0xf5, 0xea, 0xb9, 0x03, 0xf6, 0x79, 0x91, 0xb9, 0x5b, 0x77, 0xe9, 0x2f, 0x4e, 0x5e, - 0xfd, 0xbe, 0x6a, 0x59, 0x7f, 0xae, 0x5a, 0xd6, 0xdf, 0xab, 0x96, 0xf5, 0xa9, 0x77, 0xcf, 0x63, - 0xb9, 0x7c, 0x72, 0xa9, 0x64, 0x7e, 0xc0, 0x90, 0xeb, 0xd1, 0x96, 0x99, 0xd6, 0xe1, 0xff, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xb0, 0x8d, 0xb8, 0x47, 0x90, 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. diff --git a/cmpserver/plugin/config.go b/cmpserver/plugin/config.go index ed1ee8b5ea..949e212d9c 100644 --- a/cmpserver/plugin/config.go +++ b/cmpserver/plugin/config.go @@ -1,15 +1,14 @@ package plugin import ( - "errors" "fmt" "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - configUtil "github.com/argoproj/argo-cd/v3/util/config" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + configUtil "github.com/argoproj/argo-cd/v2/util/config" ) const ( @@ -83,13 +82,13 @@ func ReadPluginConfig(filePath string) (*PluginConfig, error) { func ValidatePluginConfig(config PluginConfig) error { if config.Metadata.Name == "" { - return errors.New("invalid plugin configuration file. metadata.name should be non-empty") + return fmt.Errorf("invalid plugin configuration file. metadata.name should be non-empty.") } - if config.Kind != ConfigManagementPluginKind { - return fmt.Errorf("invalid plugin configuration file. kind should be %s, found %s", ConfigManagementPluginKind, config.Kind) + if config.TypeMeta.Kind != ConfigManagementPluginKind { + return fmt.Errorf("invalid plugin configuration file. kind should be %s, found %s", ConfigManagementPluginKind, config.TypeMeta.Kind) } if len(config.Spec.Generate.Command) == 0 { - return errors.New("invalid plugin configuration file. spec.generate command should be non-empty") + return fmt.Errorf("invalid plugin configuration file. spec.generate command should be non-empty") } // discovery field is optional as apps can now specify plugin names directly return nil diff --git a/cmpserver/plugin/config_test.go b/cmpserver/plugin/config_test.go index 982e365c01..db08e92a2f 100644 --- a/cmpserver/plugin/config_test.go +++ b/cmpserver/plugin/config_test.go @@ -8,9 +8,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) func Test_IsDefined(t *testing.T) { @@ -88,7 +88,7 @@ func Test_ReadPluginConfig(t *testing.T) { metadata: `, expected: nil, - expectedErr: "invalid plugin configuration file. metadata.name should be non-empty", + expectedErr: "invalid plugin configuration file. metadata.name should be non-empty.", }, { name: "empty metadata name", @@ -97,7 +97,7 @@ metadata: name: "" `, expected: nil, - expectedErr: "invalid plugin configuration file. metadata.name should be non-empty", + expectedErr: "invalid plugin configuration file. metadata.name should be non-empty.", }, { name: "invalid kind", @@ -130,10 +130,10 @@ spec: command: [command] `, expected: &PluginConfig{ - TypeMeta: metav1.TypeMeta{ + TypeMeta: v1.TypeMeta{ Kind: ConfigManagementPluginKind, }, - Metadata: metav1.ObjectMeta{ + Metadata: v1.ObjectMeta{ Name: "name", }, Spec: PluginConfigSpec{ @@ -177,10 +177,10 @@ func Test_PluginConfig_Address(t *testing.T) { { name: "no version specified", config: &PluginConfig{ - TypeMeta: metav1.TypeMeta{ + TypeMeta: v1.TypeMeta{ Kind: ConfigManagementPluginKind, }, - Metadata: metav1.ObjectMeta{ + Metadata: v1.ObjectMeta{ Name: "name", }, }, @@ -189,10 +189,10 @@ func Test_PluginConfig_Address(t *testing.T) { { name: "version specified", config: &PluginConfig{ - TypeMeta: metav1.TypeMeta{ + TypeMeta: v1.TypeMeta{ Kind: ConfigManagementPluginKind, }, - Metadata: metav1.ObjectMeta{ + Metadata: v1.ObjectMeta{ Name: "name", }, Spec: PluginConfigSpec{ diff --git a/cmpserver/plugin/plugin.go b/cmpserver/plugin/plugin.go index d52a9ca3a7..c708edf9a0 100644 --- a/cmpserver/plugin/plugin.go +++ b/cmpserver/plugin/plugin.go @@ -3,8 +3,6 @@ package plugin import ( "bytes" "context" - "crypto/rand" - "encoding/hex" "encoding/json" "errors" "fmt" @@ -14,15 +12,16 @@ import ( "strings" "time" + "github.com/argoproj/pkg/rand" "github.com/golang/protobuf/ptypes/empty" - "github.com/argoproj/argo-cd/v3/cmpserver/apiclient" - "github.com/argoproj/argo-cd/v3/common" - repoclient "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/buffered_context" - "github.com/argoproj/argo-cd/v3/util/cmp" - argoexec "github.com/argoproj/argo-cd/v3/util/exec" - "github.com/argoproj/argo-cd/v3/util/io/files" + "github.com/argoproj/argo-cd/v2/cmpserver/apiclient" + "github.com/argoproj/argo-cd/v2/common" + repoclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/buffered_context" + "github.com/argoproj/argo-cd/v2/util/cmp" + argoexec "github.com/argoproj/argo-cd/v2/util/exec" + "github.com/argoproj/argo-cd/v2/util/io/files" "github.com/argoproj/gitops-engine/pkg/utils/kube" securejoin "github.com/cyphar/filepath-securejoin" @@ -62,26 +61,16 @@ func (s *Service) Init(workDir string) error { return nil } -const execIDLen = 5 - -func randExecID() (string, error) { - execIDBytes := make([]byte, execIDLen/2+1) // we need one extra letter to discard - if _, err := rand.Read(execIDBytes); err != nil { - return "", err - } - return hex.EncodeToString(execIDBytes)[0:execIDLen], nil -} - func runCommand(ctx context.Context, command Command, path string, env []string) (string, error) { if len(command.Command) == 0 { - return "", errors.New("Command is empty") + return "", fmt.Errorf("Command is empty") } cmd := exec.CommandContext(ctx, command.Command[0], append(command.Command[1:], command.Args...)...) cmd.Env = env cmd.Dir = path - execId, err := randExecID() + execId, err := rand.RandString(5) if err != nil { return "", err } @@ -168,7 +157,7 @@ func newCmdError(args string, cause error, stderr string) *CmdError { func environ(envVars []*apiclient.EnvEntry) []string { var environ []string for _, item := range envVars { - if item != nil && item.Name != "" { + if item != nil && item.Name != "" && item.Value != "" { environ = append(environ, fmt.Sprintf("%s=%s", item.Name, item.Value)) } } @@ -183,7 +172,7 @@ func getTempDirMustCleanup(baseDir string) (workDir string, cleanup func(), err } cleanup = func() { if err := os.RemoveAll(workDir); err != nil { - log.WithFields(map[string]any{ + log.WithFields(map[string]interface{}{ common.SecurityField: common.SecurityHigh, common.SecurityCWEField: common.SecurityCWEIncompleteCleanup, }).Errorf("Failed to clean up temp directory: %s", err) @@ -223,7 +212,7 @@ func (s *Service) generateManifestGeneric(stream GenerateManifestStream) error { appPath := filepath.Clean(filepath.Join(workDir, metadata.AppRelPath)) if !strings.HasPrefix(appPath, workDir) { - return errors.New("illegal appPath: out of workDir bound") + return fmt.Errorf("illegal appPath: out of workDir bound") } response, err := s.generateManifest(ctx, appPath, metadata.GetEnv()) if err != nil { @@ -326,7 +315,7 @@ func (s *Service) matchRepository(ctx context.Context, workdir string, envEntrie appPath, err := securejoin.SecureJoin(workdir, appRelPath) if err != nil { - log.WithFields(map[string]any{ + log.WithFields(map[string]interface{}{ common.SecurityField: common.SecurityHigh, common.SecurityCWEField: common.SecurityCWEIncompleteCleanup, }).Errorf("error joining workdir %q and appRelPath %q: %v", workdir, appRelPath, err) @@ -395,7 +384,7 @@ func (s *Service) GetParametersAnnouncement(stream apiclient.ConfigManagementPlu } appPath := filepath.Clean(filepath.Join(workDir, metadata.AppRelPath)) if !strings.HasPrefix(appPath, workDir) { - return errors.New("illegal appPath: out of workDir bound") + return fmt.Errorf("illegal appPath: out of workDir bound") } repoResponse, err := getParametersAnnouncement(bufferedCtx, appPath, s.initConstants.PluginConfig.Spec.Parameters.Static, s.initConstants.PluginConfig.Spec.Parameters.Dynamic, metadata.GetEnv()) @@ -436,7 +425,7 @@ func getParametersAnnouncement(ctx context.Context, appDir string, announcements return repoResponse, nil } -func (s *Service) CheckPluginConfiguration(_ context.Context, _ *empty.Empty) (*apiclient.CheckPluginConfigurationResponse, error) { +func (s *Service) CheckPluginConfiguration(ctx context.Context, _ *empty.Empty) (*apiclient.CheckPluginConfigurationResponse, error) { isDiscoveryConfigured := s.isDiscoveryConfigured() response := &apiclient.CheckPluginConfigurationResponse{IsDiscoveryConfigured: isDiscoveryConfigured, ProvideGitCreds: s.initConstants.PluginConfig.Spec.ProvideGitCreds} diff --git a/cmpserver/plugin/plugin.proto b/cmpserver/plugin/plugin.proto index 2b50785857..89fdd7418c 100644 --- a/cmpserver/plugin/plugin.proto +++ b/cmpserver/plugin/plugin.proto @@ -1,9 +1,9 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/cmpserver/apiclient"; +option go_package = "github.com/argoproj/argo-cd/v2/cmpserver/apiclient"; package plugin; -import "github.com/argoproj/argo-cd/v3/reposerver/repository/repository.proto"; +import "github.com/argoproj/argo-cd/v2/reposerver/repository/repository.proto"; import "google/protobuf/empty.proto"; // AppStreamRequest is the request object used to send the application's diff --git a/cmpserver/plugin/plugin_test.go b/cmpserver/plugin/plugin_test.go index 3c6e436324..30bd0a97be 100644 --- a/cmpserver/plugin/plugin_test.go +++ b/cmpserver/plugin/plugin_test.go @@ -18,11 +18,11 @@ import ( "gopkg.in/yaml.v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/cmpserver/apiclient" - repoclient "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/cmp" - "github.com/argoproj/argo-cd/v3/util/tgzstream" + "github.com/argoproj/argo-cd/v2/cmpserver/apiclient" + repoclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/cmp" + "github.com/argoproj/argo-cd/v2/util/tgzstream" ) func newService(configFilePath string) (*Service, error) { @@ -100,7 +100,7 @@ func TestMatchRepository(t *testing.T) { f := setup(t, withDiscover(d)) // when - match, discovery, err := f.service.matchRepository(t.Context(), f.path, f.env, ".") + match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then require.NoError(t, err) @@ -115,7 +115,7 @@ func TestMatchRepository(t *testing.T) { f := setup(t, withDiscover(d)) // when - match, discovery, err := f.service.matchRepository(t.Context(), f.path, f.env, ".") + match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then require.NoError(t, err) @@ -130,7 +130,7 @@ func TestMatchRepository(t *testing.T) { f := setup(t, withDiscover(d)) // when - _, _, err := f.service.matchRepository(t.Context(), f.path, f.env, ".") + _, _, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then require.ErrorContains(t, err, "syntax error") @@ -145,7 +145,7 @@ func TestMatchRepository(t *testing.T) { f := setup(t, withDiscover(d)) // when - match, discovery, err := f.service.matchRepository(t.Context(), f.path, f.env, ".") + match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then require.NoError(t, err) @@ -162,7 +162,7 @@ func TestMatchRepository(t *testing.T) { f := setup(t, withDiscover(d)) // when - match, discovery, err := f.service.matchRepository(t.Context(), f.path, f.env, ".") + match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then require.NoError(t, err) @@ -179,7 +179,7 @@ func TestMatchRepository(t *testing.T) { f := setup(t, withDiscover(d)) // when - _, _, err := f.service.matchRepository(t.Context(), f.path, f.env, ".") + _, _, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then require.ErrorContains(t, err, "error finding glob match for pattern") @@ -196,7 +196,7 @@ func TestMatchRepository(t *testing.T) { f := setup(t, withDiscover(d)) // when - match, discovery, err := f.service.matchRepository(t.Context(), f.path, f.env, ".") + match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then require.NoError(t, err) @@ -215,7 +215,7 @@ func TestMatchRepository(t *testing.T) { f := setup(t, withDiscover(d)) // when - match, discovery, err := f.service.matchRepository(t.Context(), f.path, f.env, ".") + match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then require.NoError(t, err) assert.False(t, match) @@ -233,7 +233,7 @@ func TestMatchRepository(t *testing.T) { f := setup(t, withDiscover(d)) // when - match, discovery, err := f.service.matchRepository(t.Context(), f.path, f.env, ".") + match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then require.NoError(t, err) @@ -253,7 +253,7 @@ func TestMatchRepository(t *testing.T) { f := setup(t, withDiscover(d)) // when - match, discovery, err := f.service.matchRepository(t.Context(), f.path, f.env, ".") + match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then require.NoError(t, err) @@ -272,7 +272,7 @@ func TestMatchRepository(t *testing.T) { f := setup(t, withDiscover(d)) // when - match, discovery, err := f.service.matchRepository(t.Context(), f.path, f.env, ".") + match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then require.Error(t, err) @@ -285,7 +285,7 @@ func TestMatchRepository(t *testing.T) { f := setup(t, withDiscover(d)) // when - match, discovery, err := f.service.matchRepository(t.Context(), f.path, f.env, ".") + match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then require.NoError(t, err) @@ -308,7 +308,7 @@ func TestGenerateManifest(t *testing.T) { service, err := newService(configFilePath) require.NoError(t, err) - res1, err := service.generateManifest(t.Context(), "testdata/kustomize", nil) + res1, err := service.generateManifest(context.Background(), "testdata/kustomize", nil) require.NoError(t, err) require.NotNil(t, res1) @@ -322,7 +322,7 @@ func TestGenerateManifest(t *testing.T) { require.NoError(t, err) service.WithGenerateCommand(Command{Command: []string{"bad-command"}}) - res, err := service.generateManifest(t.Context(), "testdata/kustomize", nil) + res, err := service.generateManifest(context.Background(), "testdata/kustomize", nil) require.ErrorContains(t, err, "executable file not found") assert.Nil(t, res.Manifests) }) @@ -331,7 +331,7 @@ func TestGenerateManifest(t *testing.T) { require.NoError(t, err) service.WithGenerateCommand(Command{Command: []string{"echo", "invalid yaml: }"}}) - res, err := service.generateManifest(t.Context(), "testdata/kustomize", nil) + res, err := service.generateManifest(context.Background(), "testdata/kustomize", nil) require.ErrorContains(t, err, "failed to unmarshal manifest") assert.Nil(t, res.Manifests) }) @@ -342,7 +342,7 @@ func TestGenerateManifest_deadline_exceeded(t *testing.T) { service, err := newService(configFilePath) require.NoError(t, err) - expiredCtx, cancel := context.WithTimeout(t.Context(), time.Second*0) + expiredCtx, cancel := context.WithTimeout(context.Background(), time.Second*0) defer cancel() _, err = service.generateManifest(expiredCtx, "", nil) require.ErrorContains(t, err, "context deadline exceeded") @@ -350,7 +350,7 @@ func TestGenerateManifest_deadline_exceeded(t *testing.T) { // TestRunCommandContextTimeout makes sure the command dies at timeout rather than sleeping past the timeout. func TestRunCommandContextTimeout(t *testing.T) { - ctx, cancel := context.WithTimeout(t.Context(), 990*time.Millisecond) + ctx, cancel := context.WithTimeout(context.Background(), 990*time.Millisecond) defer cancel() // Use a subshell so there's a child command. command := Command{ @@ -365,13 +365,13 @@ func TestRunCommandContextTimeout(t *testing.T) { } func TestRunCommandEmptyCommand(t *testing.T) { - _, err := runCommand(t.Context(), Command{}, "", nil) + _, err := runCommand(context.Background(), Command{}, "", nil) require.ErrorContains(t, err, "Command is empty") } // TestRunCommandContextTimeoutWithCleanup makes sure that the process is given enough time to cleanup before sending SIGKILL. func TestRunCommandContextTimeoutWithCleanup(t *testing.T) { - ctx, cancel := context.WithTimeout(t.Context(), 900*time.Millisecond) + ctx, cancel := context.WithTimeout(context.Background(), 900*time.Millisecond) defer cancel() // Use a subshell so there's a child command. @@ -403,7 +403,7 @@ func Test_getParametersAnnouncement_empty_command(t *testing.T) { Command: []string{"echo"}, Args: []string{`[]`}, } - res, err := getParametersAnnouncement(t.Context(), "", *static, command, []*apiclient.EnvEntry{}) + res, err := getParametersAnnouncement(context.Background(), "", *static, command, []*apiclient.EnvEntry{}) require.NoError(t, err) assert.Equal(t, []*repoclient.ParameterAnnouncement{{Name: "static-a"}, {Name: "static-b"}}, res.ParameterAnnouncements) } @@ -417,7 +417,7 @@ func Test_getParametersAnnouncement_no_command(t *testing.T) { err := yaml.Unmarshal([]byte(staticYAML), static) require.NoError(t, err) command := Command{} - res, err := getParametersAnnouncement(t.Context(), "", *static, command, []*apiclient.EnvEntry{}) + res, err := getParametersAnnouncement(context.Background(), "", *static, command, []*apiclient.EnvEntry{}) require.NoError(t, err) assert.Equal(t, []*repoclient.ParameterAnnouncement{{Name: "static-a"}, {Name: "static-b"}}, res.ParameterAnnouncements) } @@ -434,7 +434,7 @@ func Test_getParametersAnnouncement_static_and_dynamic(t *testing.T) { Command: []string{"echo"}, Args: []string{`[{"name": "dynamic-a"}, {"name": "dynamic-b"}]`}, } - res, err := getParametersAnnouncement(t.Context(), "", *static, command, []*apiclient.EnvEntry{}) + res, err := getParametersAnnouncement(context.Background(), "", *static, command, []*apiclient.EnvEntry{}) require.NoError(t, err) expected := []*repoclient.ParameterAnnouncement{ {Name: "dynamic-a"}, @@ -450,7 +450,7 @@ func Test_getParametersAnnouncement_invalid_json(t *testing.T) { Command: []string{"echo"}, Args: []string{`[`}, } - _, err := getParametersAnnouncement(t.Context(), "", []*repoclient.ParameterAnnouncement{}, command, []*apiclient.EnvEntry{}) + _, err := getParametersAnnouncement(context.Background(), "", []*repoclient.ParameterAnnouncement{}, command, []*apiclient.EnvEntry{}) assert.ErrorContains(t, err, "unexpected end of JSON input") } @@ -459,7 +459,7 @@ func Test_getParametersAnnouncement_bad_command(t *testing.T) { Command: []string{"exit"}, Args: []string{"1"}, } - _, err := getParametersAnnouncement(t.Context(), "", []*repoclient.ParameterAnnouncement{}, command, []*apiclient.EnvEntry{}) + _, err := getParametersAnnouncement(context.Background(), "", []*repoclient.ParameterAnnouncement{}, command, []*apiclient.EnvEntry{}) assert.ErrorContains(t, err, "error executing dynamic parameter output command") } @@ -514,20 +514,19 @@ func TestEnviron(t *testing.T) { env := environ([]*apiclient.EnvEntry{}) assert.Nil(t, env) }) - t.Run("env vars with empty names", func(t *testing.T) { + t.Run("env vars with empty names or values", func(t *testing.T) { env := environ([]*apiclient.EnvEntry{ {Value: "test"}, {Name: "test"}, }) - assert.Equal(t, []string{"test="}, env) + assert.Nil(t, env) }) t.Run("proper env vars", func(t *testing.T) { env := environ([]*apiclient.EnvEntry{ {Name: "name1", Value: "value1"}, {Name: "name2", Value: "value2"}, - {Name: "name3", Value: ""}, }) - assert.Equal(t, []string{"name1=value1", "name2=value2", "name3="}, env) + assert.Equal(t, []string{"name1=value1", "name2=value2"}, env) }) } @@ -807,11 +806,11 @@ func (m *MockParametersAnnouncementStream) Context() context.Context { return context.Background() } -func (m *MockParametersAnnouncementStream) SendMsg(any) error { +func (m *MockParametersAnnouncementStream) SendMsg(interface{}) error { return nil } -func (m *MockParametersAnnouncementStream) RecvMsg(any) error { +func (m *MockParametersAnnouncementStream) RecvMsg(interface{}) error { return nil } @@ -868,7 +867,7 @@ func TestService_CheckPluginConfiguration(t *testing.T) { f := setup(t, withDiscover(d)) // when - resp, err := f.service.CheckPluginConfiguration(t.Context(), &empty.Empty{}) + resp, err := f.service.CheckPluginConfiguration(context.Background(), &empty.Empty{}) // then require.NoError(t, err) @@ -881,7 +880,7 @@ func TestService_CheckPluginConfiguration(t *testing.T) { f := setup(t, withDiscover(d)) // when - resp, err := f.service.CheckPluginConfiguration(t.Context(), &empty.Empty{}) + resp, err := f.service.CheckPluginConfiguration(context.Background(), &empty.Empty{}) // then require.NoError(t, err) diff --git a/cmpserver/server.go b/cmpserver/server.go index fbf6d93c1f..5d7eacd2fd 100644 --- a/cmpserver/server.go +++ b/cmpserver/server.go @@ -7,25 +7,26 @@ import ( "os/signal" "syscall" - grpc_prometheus "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery" - "github.com/prometheus/client_golang/prometheus" - log "github.com/sirupsen/logrus" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" + + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + log "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/health" "google.golang.org/grpc/health/grpc_health_v1" - "google.golang.org/grpc/keepalive" "google.golang.org/grpc/reflection" - "github.com/argoproj/argo-cd/v3/cmpserver/apiclient" - "github.com/argoproj/argo-cd/v3/cmpserver/plugin" - "github.com/argoproj/argo-cd/v3/common" - versionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/version" - "github.com/argoproj/argo-cd/v3/server/version" - "github.com/argoproj/argo-cd/v3/util/errors" - grpc_util "github.com/argoproj/argo-cd/v3/util/grpc" + "google.golang.org/grpc/keepalive" + + "github.com/argoproj/argo-cd/v2/cmpserver/apiclient" + "github.com/argoproj/argo-cd/v2/cmpserver/plugin" + "github.com/argoproj/argo-cd/v2/common" + versionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/version" + "github.com/argoproj/argo-cd/v2/server/version" + "github.com/argoproj/argo-cd/v2/util/errors" + grpc_util "github.com/argoproj/argo-cd/v2/util/grpc" ) // ArgoCDCMPServer is the config management plugin server implementation @@ -34,37 +35,33 @@ type ArgoCDCMPServer struct { opts []grpc.ServerOption initConstants plugin.CMPServerInitConstants stopCh chan os.Signal - doneCh chan any + doneCh chan interface{} sig os.Signal } // NewServer returns a new instance of the Argo CD config management plugin server func NewServer(initConstants plugin.CMPServerInitConstants) (*ArgoCDCMPServer, error) { - var serverMetricsOptions []grpc_prometheus.ServerMetricsOption if os.Getenv(common.EnvEnableGRPCTimeHistogramEnv) == "true" { - serverMetricsOptions = append(serverMetricsOptions, grpc_prometheus.WithServerHandlingTimeHistogram()) + grpc_prometheus.EnableHandlingTimeHistogram() } - serverMetrics := grpc_prometheus.NewServerMetrics(serverMetricsOptions...) - reg := prometheus.NewRegistry() - reg.MustRegister(serverMetrics) serverLog := log.NewEntry(log.StandardLogger()) streamInterceptors := []grpc.StreamServerInterceptor{ otelgrpc.StreamServerInterceptor(), //nolint:staticcheck // TODO: ignore SA1019 for depreciation: see https://github.com/argoproj/argo-cd/issues/18258 - logging.StreamServerInterceptor(grpc_util.InterceptorLogger(serverLog)), - serverMetrics.StreamServerInterceptor(), - recovery.StreamServerInterceptor(recovery.WithRecoveryHandler(grpc_util.LoggerRecoveryHandler(serverLog))), + grpc_logrus.StreamServerInterceptor(serverLog), + grpc_prometheus.StreamServerInterceptor, + grpc_util.PanicLoggerStreamServerInterceptor(serverLog), } unaryInterceptors := []grpc.UnaryServerInterceptor{ otelgrpc.UnaryServerInterceptor(), //nolint:staticcheck // TODO: ignore SA1019 for depreciation: see https://github.com/argoproj/argo-cd/issues/18258 - logging.UnaryServerInterceptor(grpc_util.InterceptorLogger(serverLog)), - serverMetrics.UnaryServerInterceptor(), - recovery.UnaryServerInterceptor(recovery.WithRecoveryHandler(grpc_util.LoggerRecoveryHandler(serverLog))), + grpc_logrus.UnaryServerInterceptor(serverLog), + grpc_prometheus.UnaryServerInterceptor, + grpc_util.PanicLoggerUnaryServerInterceptor(serverLog), } serverOpts := []grpc.ServerOption{ - grpc.ChainUnaryInterceptor(unaryInterceptors...), - grpc.ChainStreamInterceptor(streamInterceptors...), + grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(unaryInterceptors...)), + grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(streamInterceptors...)), grpc.MaxRecvMsgSize(apiclient.MaxGRPCMessageSize), grpc.MaxSendMsgSize(apiclient.MaxGRPCMessageSize), grpc.KeepaliveEnforcementPolicy( @@ -78,7 +75,7 @@ func NewServer(initConstants plugin.CMPServerInitConstants) (*ArgoCDCMPServer, e log: serverLog, opts: serverOpts, stopCh: make(chan os.Signal), - doneCh: make(chan any), + doneCh: make(chan interface{}), initConstants: initConstants, }, nil } diff --git a/commitserver/apiclient/clientset.go b/commitserver/apiclient/clientset.go index 0726c86434..795766e54e 100644 --- a/commitserver/apiclient/clientset.go +++ b/commitserver/apiclient/clientset.go @@ -7,12 +7,12 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "github.com/argoproj/argo-cd/v2/util/io" ) // Clientset represents commit server api clients type Clientset interface { - NewCommitServerClient() (utilio.Closer, CommitServiceClient, error) + NewCommitServerClient() (io.Closer, CommitServiceClient, error) } type clientSet struct { @@ -20,7 +20,7 @@ type clientSet struct { } // NewCommitServerClient creates new instance of commit server client -func (c *clientSet) NewCommitServerClient() (utilio.Closer, CommitServiceClient, error) { +func (c *clientSet) NewCommitServerClient() (io.Closer, CommitServiceClient, error) { conn, err := NewConnection(c.address) if err != nil { return nil, nil, fmt.Errorf("failed to open a new connection to commit server: %w", err) @@ -34,7 +34,7 @@ func NewConnection(address string) (*grpc.ClientConn, error) { opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) // TODO: switch to grpc.NewClient. - //nolint:staticcheck + // nolint:staticcheck conn, err := grpc.Dial(address, opts...) if err != nil { log.Errorf("Unable to connect to commit service with address %s", address) diff --git a/commitserver/apiclient/commit.pb.go b/commitserver/apiclient/commit.pb.go index 8a6cd85e71..3e37157582 100644 --- a/commitserver/apiclient/commit.pb.go +++ b/commitserver/apiclient/commit.pb.go @@ -6,7 +6,7 @@ package apiclient import ( context "context" fmt "fmt" - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" proto "github.com/gogo/protobuf/proto" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -301,32 +301,32 @@ var fileDescriptor_cf3a3abbc35e3069 = []byte{ // 446 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x93, 0xc1, 0x6e, 0xd3, 0x40, 0x10, 0x86, 0xe5, 0x24, 0x8d, 0xc8, 0xa4, 0xbd, 0xec, 0x81, 0x5a, 0x39, 0xb8, 0x96, 0xc5, 0x21, - 0x17, 0xd6, 0x6a, 0x22, 0xb8, 0x71, 0x69, 0x38, 0x54, 0x88, 0x02, 0x72, 0x6e, 0xa8, 0x12, 0xda, - 0xae, 0x07, 0x7b, 0x69, 0xec, 0x5d, 0x76, 0x37, 0x96, 0xf2, 0x3e, 0x3c, 0x0c, 0x47, 0x1e, 0x01, - 0xe5, 0x49, 0x90, 0xd7, 0x36, 0x8d, 0x91, 0x42, 0x4e, 0x9e, 0xf9, 0x67, 0xf4, 0xcd, 0xe8, 0xf7, - 0x2c, 0x84, 0x5c, 0x16, 0x85, 0xb0, 0x06, 0x75, 0x85, 0x3a, 0x6e, 0x92, 0xf6, 0x43, 0x95, 0x96, - 0x56, 0xce, 0xde, 0x67, 0xc2, 0xe6, 0xdb, 0x07, 0xca, 0x65, 0x11, 0x33, 0x9d, 0x49, 0xa5, 0xe5, - 0x37, 0x17, 0xbc, 0xe4, 0x69, 0x5c, 0x2d, 0x63, 0xf5, 0x98, 0xc5, 0x4c, 0x09, 0x13, 0x33, 0xa5, - 0x36, 0x82, 0x33, 0x2b, 0x64, 0x19, 0x57, 0xd7, 0x6c, 0xa3, 0x72, 0x76, 0x1d, 0x67, 0x58, 0xa2, - 0x66, 0x16, 0xd3, 0x86, 0x16, 0xfd, 0x18, 0x40, 0xb0, 0x72, 0xf8, 0xdb, 0x5d, 0xea, 0x0a, 0x77, - 0xac, 0x14, 0x5f, 0xd1, 0x58, 0x93, 0xe0, 0xf7, 0x2d, 0x1a, 0x4b, 0xee, 0x61, 0xa4, 0x51, 0x49, - 0xdf, 0x0b, 0xbd, 0xf9, 0x74, 0x71, 0x4b, 0x9f, 0xe6, 0xd3, 0x6e, 0xbe, 0x0b, 0xbe, 0xf0, 0x94, - 0x56, 0x4b, 0xaa, 0x1e, 0x33, 0x5a, 0xcf, 0xa7, 0x07, 0xf3, 0x69, 0x37, 0x9f, 0x26, 0xa8, 0xa4, - 0x11, 0x56, 0xea, 0x5d, 0xe2, 0xa8, 0x24, 0x00, 0x30, 0xbb, 0x92, 0xdf, 0x68, 0x56, 0xf2, 0xdc, - 0x1f, 0x84, 0xde, 0x7c, 0x92, 0x1c, 0x28, 0x24, 0x82, 0x73, 0xcb, 0x74, 0x86, 0xb6, 0xed, 0x18, - 0xba, 0x8e, 0x9e, 0x46, 0x9e, 0xc3, 0x38, 0xd5, 0xbb, 0x75, 0xce, 0xfc, 0x91, 0xab, 0xb6, 0x19, - 0x79, 0x01, 0x17, 0x8d, 0x75, 0x77, 0x68, 0x0c, 0xcb, 0xd0, 0x3f, 0x73, 0xe5, 0xbe, 0x48, 0x22, - 0x38, 0x53, 0xcc, 0xe6, 0xc6, 0x1f, 0x87, 0xc3, 0xf9, 0x74, 0x71, 0x4e, 0x3f, 0x31, 0x9b, 0xbf, - 0x45, 0xcb, 0xc4, 0xc6, 0x24, 0x4d, 0x29, 0xda, 0xc2, 0xf4, 0x40, 0x25, 0x04, 0x46, 0xb5, 0xee, - 0x2c, 0x99, 0x24, 0x2e, 0x26, 0xaf, 0x61, 0x52, 0x74, 0xd6, 0xf9, 0x03, 0x87, 0xf2, 0xe9, 0xbf, - 0xa6, 0x76, 0xd8, 0xa7, 0x56, 0x32, 0x83, 0x67, 0xf5, 0x3e, 0xac, 0x4c, 0x8d, 0x3f, 0x0c, 0x87, - 0xf3, 0x49, 0xf2, 0x37, 0x8f, 0xde, 0xc0, 0xe5, 0x11, 0x42, 0xed, 0x4b, 0xc7, 0x78, 0xb7, 0xfe, - 0xf8, 0xa1, 0x5d, 0xa5, 0xa7, 0x45, 0x2b, 0xb8, 0x3a, 0xfa, 0x6f, 0x8d, 0x92, 0xa5, 0x41, 0x12, - 0xc2, 0x34, 0x6f, 0x8b, 0xb5, 0x7f, 0x0d, 0xe5, 0x50, 0x5a, 0x14, 0x70, 0xd1, 0x40, 0xd6, 0xa8, - 0x2b, 0xc1, 0x91, 0xdc, 0xc3, 0xe5, 0x11, 0x2a, 0xb9, 0xa2, 0xff, 0xbf, 0xa5, 0x59, 0x48, 0x4f, - 0x2c, 0x74, 0xb3, 0xfa, 0xb9, 0x0f, 0xbc, 0x5f, 0xfb, 0xc0, 0xfb, 0xbd, 0x0f, 0xbc, 0xcf, 0xaf, - 0x4e, 0x1c, 0x7b, 0xef, 0xb5, 0x30, 0x25, 0xf8, 0x46, 0x60, 0x69, 0x1f, 0xc6, 0xee, 0xb8, 0x97, - 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xf1, 0x83, 0xe8, 0xd7, 0x4e, 0x03, 0x00, 0x00, + 0x17, 0xd6, 0xaa, 0x11, 0xdc, 0xb8, 0x34, 0x1c, 0x2a, 0x44, 0x01, 0x39, 0x37, 0x54, 0x09, 0x6d, + 0xd7, 0x83, 0xbd, 0x34, 0xf6, 0x2e, 0xbb, 0x1b, 0x4b, 0x79, 0x1f, 0x1e, 0x86, 0x23, 0x8f, 0x80, + 0xf2, 0x24, 0xc8, 0x6b, 0x9b, 0xc6, 0x48, 0x69, 0x4f, 0x9e, 0xf9, 0x67, 0xf4, 0xcd, 0xe8, 0xf7, + 0x2c, 0x84, 0x5c, 0x96, 0xa5, 0xb0, 0x06, 0x75, 0x8d, 0x3a, 0x6e, 0x93, 0xee, 0x43, 0x95, 0x96, + 0x56, 0x2e, 0x3e, 0xe4, 0xc2, 0x16, 0xdb, 0x3b, 0xca, 0x65, 0x19, 0x33, 0x9d, 0x4b, 0xa5, 0xe5, + 0x77, 0x17, 0xbc, 0xe4, 0x59, 0x5c, 0x27, 0xb1, 0xba, 0xcf, 0x63, 0xa6, 0x84, 0x89, 0x99, 0x52, + 0x1b, 0xc1, 0x99, 0x15, 0xb2, 0x8a, 0xeb, 0x4b, 0xb6, 0x51, 0x05, 0xbb, 0x8c, 0x73, 0xac, 0x50, + 0x33, 0x8b, 0x59, 0x4b, 0x8b, 0x7e, 0x8e, 0x20, 0x58, 0x39, 0xfc, 0xf5, 0x2e, 0x73, 0x85, 0x1b, + 0x56, 0x89, 0x6f, 0x68, 0xac, 0x49, 0xf1, 0xc7, 0x16, 0x8d, 0x25, 0xb7, 0x30, 0xd1, 0xa8, 0xa4, + 0xef, 0x85, 0xde, 0x72, 0x9e, 0x5c, 0xd3, 0x87, 0xf9, 0xb4, 0x9f, 0xef, 0x82, 0xaf, 0x3c, 0xa3, + 0x75, 0x42, 0xd5, 0x7d, 0x4e, 0x9b, 0xf9, 0xf4, 0x60, 0x3e, 0xed, 0xe7, 0xd3, 0x14, 0x95, 0x34, + 0xc2, 0x4a, 0xbd, 0x4b, 0x1d, 0x95, 0x04, 0x00, 0x66, 0x57, 0xf1, 0x2b, 0xcd, 0x2a, 0x5e, 0xf8, + 0xa3, 0xd0, 0x5b, 0xce, 0xd2, 0x03, 0x85, 0x44, 0x70, 0x6a, 0x99, 0xce, 0xd1, 0x76, 0x1d, 0x63, + 0xd7, 0x31, 0xd0, 0xc8, 0x73, 0x98, 0x66, 0x7a, 0xb7, 0x2e, 0x98, 0x3f, 0x71, 0xd5, 0x2e, 0x23, + 0x2f, 0xe0, 0xac, 0xb5, 0xee, 0x06, 0x8d, 0x61, 0x39, 0xfa, 0x27, 0xae, 0x3c, 0x14, 0x49, 0x04, + 0x27, 0x8a, 0xd9, 0xc2, 0xf8, 0xd3, 0x70, 0xbc, 0x9c, 0x27, 0xa7, 0xf4, 0x33, 0xb3, 0xc5, 0x3b, + 0xb4, 0x4c, 0x6c, 0x4c, 0xda, 0x96, 0xa2, 0x2d, 0xcc, 0x0f, 0x54, 0x42, 0x60, 0xd2, 0xe8, 0xce, + 0x92, 0x59, 0xea, 0x62, 0xf2, 0x06, 0x66, 0x65, 0x6f, 0x9d, 0x3f, 0x72, 0x28, 0x9f, 0xfe, 0x6f, + 0x6a, 0x8f, 0x7d, 0x68, 0x25, 0x0b, 0x78, 0xd6, 0xec, 0xc3, 0xaa, 0xcc, 0xf8, 0xe3, 0x70, 0xbc, + 0x9c, 0xa5, 0xff, 0xf2, 0xe8, 0x2d, 0x9c, 0x1f, 0x21, 0x34, 0xbe, 0xf4, 0x8c, 0xf7, 0xeb, 0x4f, + 0x1f, 0xbb, 0x55, 0x06, 0x5a, 0xb4, 0x82, 0x8b, 0xa3, 0xff, 0xd6, 0x28, 0x59, 0x19, 0x24, 0x21, + 0xcc, 0x8b, 0xae, 0xd8, 0xf8, 0xd7, 0x52, 0x0e, 0xa5, 0xa4, 0x84, 0xb3, 0x16, 0xb2, 0x46, 0x5d, + 0x0b, 0x8e, 0xe4, 0x16, 0xce, 0x8f, 0x50, 0xc9, 0x05, 0x7d, 0xfc, 0x96, 0x16, 0x21, 0x7d, 0x62, + 0xa1, 0xab, 0xd5, 0xaf, 0x7d, 0xe0, 0xfd, 0xde, 0x07, 0xde, 0x9f, 0x7d, 0xe0, 0x7d, 0x79, 0xfd, + 0xc4, 0xb1, 0x0f, 0x5e, 0x0b, 0x53, 0x82, 0x6f, 0x04, 0x56, 0xf6, 0x6e, 0xea, 0x8e, 0xfb, 0xd5, + 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x89, 0xb8, 0xdf, 0x48, 0x4e, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/commitserver/apiclient/mocks/Clientset.go b/commitserver/apiclient/mocks/Clientset.go index 4e156f6e7e..7ec0166f66 100644 --- a/commitserver/apiclient/mocks/Clientset.go +++ b/commitserver/apiclient/mocks/Clientset.go @@ -1,15 +1,58 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "github.com/argoproj/argo-cd/v3/commitserver/apiclient" - "github.com/argoproj/argo-cd/v3/util/io" + apiclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + io "github.com/argoproj/argo-cd/v2/util/io" + mock "github.com/stretchr/testify/mock" ) +// Clientset is an autogenerated mock type for the Clientset type +type Clientset struct { + mock.Mock +} + +// NewCommitServerClient provides a mock function with no fields +func (_m *Clientset) NewCommitServerClient() (io.Closer, apiclient.CommitServiceClient, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for NewCommitServerClient") + } + + var r0 io.Closer + var r1 apiclient.CommitServiceClient + var r2 error + if rf, ok := ret.Get(0).(func() (io.Closer, apiclient.CommitServiceClient, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() io.Closer); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.Closer) + } + } + + if rf, ok := ret.Get(1).(func() apiclient.CommitServiceClient); ok { + r1 = rf() + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(apiclient.CommitServiceClient) + } + } + + if rf, ok := ret.Get(2).(func() error); ok { + r2 = rf() + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + // NewClientset creates a new instance of Clientset. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewClientset(t interface { @@ -23,79 +66,3 @@ func NewClientset(t interface { return mock } - -// Clientset is an autogenerated mock type for the Clientset type -type Clientset struct { - mock.Mock -} - -type Clientset_Expecter struct { - mock *mock.Mock -} - -func (_m *Clientset) EXPECT() *Clientset_Expecter { - return &Clientset_Expecter{mock: &_m.Mock} -} - -// NewCommitServerClient provides a mock function for the type Clientset -func (_mock *Clientset) NewCommitServerClient() (io.Closer, apiclient.CommitServiceClient, error) { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for NewCommitServerClient") - } - - var r0 io.Closer - var r1 apiclient.CommitServiceClient - var r2 error - if returnFunc, ok := ret.Get(0).(func() (io.Closer, apiclient.CommitServiceClient, error)); ok { - return returnFunc() - } - if returnFunc, ok := ret.Get(0).(func() io.Closer); ok { - r0 = returnFunc() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(io.Closer) - } - } - if returnFunc, ok := ret.Get(1).(func() apiclient.CommitServiceClient); ok { - r1 = returnFunc() - } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).(apiclient.CommitServiceClient) - } - } - if returnFunc, ok := ret.Get(2).(func() error); ok { - r2 = returnFunc() - } else { - r2 = ret.Error(2) - } - return r0, r1, r2 -} - -// Clientset_NewCommitServerClient_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewCommitServerClient' -type Clientset_NewCommitServerClient_Call struct { - *mock.Call -} - -// NewCommitServerClient is a helper method to define mock.On call -func (_e *Clientset_Expecter) NewCommitServerClient() *Clientset_NewCommitServerClient_Call { - return &Clientset_NewCommitServerClient_Call{Call: _e.mock.On("NewCommitServerClient")} -} - -func (_c *Clientset_NewCommitServerClient_Call) Run(run func()) *Clientset_NewCommitServerClient_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *Clientset_NewCommitServerClient_Call) Return(closer io.Closer, commitServiceClient apiclient.CommitServiceClient, err error) *Clientset_NewCommitServerClient_Call { - _c.Call.Return(closer, commitServiceClient, err) - return _c -} - -func (_c *Clientset_NewCommitServerClient_Call) RunAndReturn(run func() (io.Closer, apiclient.CommitServiceClient, error)) *Clientset_NewCommitServerClient_Call { - _c.Call.Return(run) - return _c -} diff --git a/commitserver/apiclient/mocks/CommitServiceClient.go b/commitserver/apiclient/mocks/CommitServiceClient.go index 03588692ea..3119edf3cd 100644 --- a/commitserver/apiclient/mocks/CommitServiceClient.go +++ b/commitserver/apiclient/mocks/CommitServiceClient.go @@ -1,17 +1,59 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" + context "context" + + apiclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + + grpc "google.golang.org/grpc" - "github.com/argoproj/argo-cd/v3/commitserver/apiclient" mock "github.com/stretchr/testify/mock" - "google.golang.org/grpc" ) +// CommitServiceClient is an autogenerated mock type for the CommitServiceClient type +type CommitServiceClient struct { + mock.Mock +} + +// CommitHydratedManifests provides a mock function with given fields: ctx, in, opts +func (_m *CommitServiceClient) CommitHydratedManifests(ctx context.Context, in *apiclient.CommitHydratedManifestsRequest, opts ...grpc.CallOption) (*apiclient.CommitHydratedManifestsResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for CommitHydratedManifests") + } + + var r0 *apiclient.CommitHydratedManifestsResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.CommitHydratedManifestsRequest, ...grpc.CallOption) (*apiclient.CommitHydratedManifestsResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.CommitHydratedManifestsRequest, ...grpc.CallOption) *apiclient.CommitHydratedManifestsResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.CommitHydratedManifestsResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.CommitHydratedManifestsRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewCommitServiceClient creates a new instance of CommitServiceClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewCommitServiceClient(t interface { @@ -25,89 +67,3 @@ func NewCommitServiceClient(t interface { return mock } - -// CommitServiceClient is an autogenerated mock type for the CommitServiceClient type -type CommitServiceClient struct { - mock.Mock -} - -type CommitServiceClient_Expecter struct { - mock *mock.Mock -} - -func (_m *CommitServiceClient) EXPECT() *CommitServiceClient_Expecter { - return &CommitServiceClient_Expecter{mock: &_m.Mock} -} - -// CommitHydratedManifests provides a mock function for the type CommitServiceClient -func (_mock *CommitServiceClient) CommitHydratedManifests(ctx context.Context, in *apiclient.CommitHydratedManifestsRequest, opts ...grpc.CallOption) (*apiclient.CommitHydratedManifestsResponse, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for CommitHydratedManifests") - } - - var r0 *apiclient.CommitHydratedManifestsResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.CommitHydratedManifestsRequest, ...grpc.CallOption) (*apiclient.CommitHydratedManifestsResponse, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.CommitHydratedManifestsRequest, ...grpc.CallOption) *apiclient.CommitHydratedManifestsResponse); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.CommitHydratedManifestsResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.CommitHydratedManifestsRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// CommitServiceClient_CommitHydratedManifests_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CommitHydratedManifests' -type CommitServiceClient_CommitHydratedManifests_Call struct { - *mock.Call -} - -// CommitHydratedManifests is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *CommitServiceClient_Expecter) CommitHydratedManifests(ctx interface{}, in interface{}, opts ...interface{}) *CommitServiceClient_CommitHydratedManifests_Call { - return &CommitServiceClient_CommitHydratedManifests_Call{Call: _e.mock.On("CommitHydratedManifests", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *CommitServiceClient_CommitHydratedManifests_Call) Run(run func(ctx context.Context, in *apiclient.CommitHydratedManifestsRequest, opts ...grpc.CallOption)) *CommitServiceClient_CommitHydratedManifests_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.CommitHydratedManifestsRequest), variadicArgs...) - }) - return _c -} - -func (_c *CommitServiceClient_CommitHydratedManifests_Call) Return(commitHydratedManifestsResponse *apiclient.CommitHydratedManifestsResponse, err error) *CommitServiceClient_CommitHydratedManifests_Call { - _c.Call.Return(commitHydratedManifestsResponse, err) - return _c -} - -func (_c *CommitServiceClient_CommitHydratedManifests_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.CommitHydratedManifestsRequest, opts ...grpc.CallOption) (*apiclient.CommitHydratedManifestsResponse, error)) *CommitServiceClient_CommitHydratedManifests_Call { - _c.Call.Return(run) - return _c -} diff --git a/commitserver/commit/commit.go b/commitserver/commit/commit.go index b752ad509b..0a40b3a7d6 100644 --- a/commitserver/commit/commit.go +++ b/commitserver/commit/commit.go @@ -2,17 +2,16 @@ package commit import ( "context" - "errors" "fmt" "os" "time" log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/commitserver/apiclient" - "github.com/argoproj/argo-cd/v3/commitserver/metrics" - "github.com/argoproj/argo-cd/v3/util/git" - "github.com/argoproj/argo-cd/v3/util/io/files" + "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/commitserver/metrics" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/io/files" ) // Service is the service that handles commit requests. @@ -34,7 +33,7 @@ func NewService(gitCredsStore git.CredsStore, metricsServer *metrics.Server) *Se // CommitHydratedManifests handles a commit request. It clones the repository, checks out the sync branch, checks out // the target branch, clears the repository contents, writes the manifests to the repository, commits the changes, and // pushes the changes. It returns the hydrated revision SHA and an error if one occurred. -func (s *Service) CommitHydratedManifests(_ context.Context, r *apiclient.CommitHydratedManifestsRequest) (*apiclient.CommitHydratedManifestsResponse, error) { +func (s *Service) CommitHydratedManifests(ctx context.Context, r *apiclient.CommitHydratedManifestsRequest) (*apiclient.CommitHydratedManifestsResponse, error) { // This method is intentionally short. It's a wrapper around handleCommitRequest that adds metrics and logging. // Keep logic here minimal and put most of the logic in handleCommitRequest. startTime := time.Now() @@ -79,16 +78,16 @@ func (s *Service) CommitHydratedManifests(_ context.Context, r *apiclient.Commit // the changes. It returns the output of the git commands and an error if one occurred. func (s *Service) handleCommitRequest(logCtx *log.Entry, r *apiclient.CommitHydratedManifestsRequest) (string, string, error) { if r.Repo == nil { - return "", "", errors.New("repo is required") + return "", "", fmt.Errorf("repo is required") } if r.Repo.Repo == "" { - return "", "", errors.New("repo URL is required") + return "", "", fmt.Errorf("repo URL is required") } if r.TargetBranch == "" { - return "", "", errors.New("target branch is required") + return "", "", fmt.Errorf("target branch is required") } if r.SyncBranch == "" { - return "", "", errors.New("sync branch is required") + return "", "", fmt.Errorf("sync branch is required") } logCtx = logCtx.WithField("repo", r.Repo.Repo) @@ -176,15 +175,15 @@ func (s *Service) initGitClient(logCtx *log.Entry, r *apiclient.CommitHydratedMa } // FIXME: make it work for GHE - // logCtx.Debugf("Getting user info for repo credentials") - // gitCreds := r.Repo.GetGitCreds(s.gitCredsStore) - // startTime := time.Now() - // authorName, authorEmail, err := gitCreds.GetUserInfo(ctx) - // s.metricsServer.ObserveUserInfoRequestDuration(r.Repo.Repo, getCredentialType(r.Repo), time.Since(startTime)) - // if err != nil { - // cleanupOrLog() - // return nil, "", nil, fmt.Errorf("failed to get github app info: %w", err) - // } + //logCtx.Debugf("Getting user info for repo credentials") + //gitCreds := r.Repo.GetGitCreds(s.gitCredsStore) + //startTime := time.Now() + //authorName, authorEmail, err := gitCreds.GetUserInfo(ctx) + //s.metricsServer.ObserveUserInfoRequestDuration(r.Repo.Repo, getCredentialType(r.Repo), time.Since(startTime)) + //if err != nil { + // cleanupOrLog() + // return nil, "", nil, fmt.Errorf("failed to get github app info: %w", err) + //} var authorName, authorEmail string if authorName == "" { diff --git a/commitserver/commit/commit.proto b/commitserver/commit/commit.proto index a6eda97ed6..fdf8b23c0d 100644 --- a/commitserver/commit/commit.proto +++ b/commitserver/commit/commit.proto @@ -1,13 +1,13 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/commitserver/apiclient"; +option go_package = "github.com/argoproj/argo-cd/v2/commitserver/apiclient"; -import "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto"; +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; // CommitHydratedManifestsRequest is the request to commit hydrated manifests to a repository. message CommitHydratedManifestsRequest { // Repo contains repository information including, at minimum, the URL of the repository. Generally it will contain // repo credentials. - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; // SyncBranch is the branch Argo CD syncs from, i.e. the hydrated branch. string syncBranch = 2; // TargetBranch is the branch Argo CD is committing to, i.e. the branch that will be updated. diff --git a/commitserver/commit/commit_test.go b/commitserver/commit/commit_test.go index 547561a906..77bb9b5348 100644 --- a/commitserver/commit/commit_test.go +++ b/commitserver/commit/commit_test.go @@ -1,18 +1,19 @@ package commit import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/commitserver/apiclient" - "github.com/argoproj/argo-cd/v3/commitserver/commit/mocks" - "github.com/argoproj/argo-cd/v3/commitserver/metrics" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/git" - gitmocks "github.com/argoproj/argo-cd/v3/util/git/mocks" + "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/commitserver/commit/mocks" + "github.com/argoproj/argo-cd/v2/commitserver/metrics" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/git" + gitmocks "github.com/argoproj/argo-cd/v2/util/git/mocks" ) func Test_CommitHydratedManifests(t *testing.T) { @@ -32,7 +33,7 @@ func Test_CommitHydratedManifests(t *testing.T) { service, _ := newServiceWithMocks(t) request := &apiclient.CommitHydratedManifestsRequest{} - _, err := service.CommitHydratedManifests(t.Context(), request) + _, err := service.CommitHydratedManifests(context.Background(), request) require.Error(t, err) assert.ErrorContains(t, err, "repo is required") }) @@ -44,7 +45,7 @@ func Test_CommitHydratedManifests(t *testing.T) { request := &apiclient.CommitHydratedManifestsRequest{ Repo: &v1alpha1.Repository{}, } - _, err := service.CommitHydratedManifests(t.Context(), request) + _, err := service.CommitHydratedManifests(context.Background(), request) require.Error(t, err) assert.ErrorContains(t, err, "repo URL is required") }) @@ -58,7 +59,7 @@ func Test_CommitHydratedManifests(t *testing.T) { Repo: "https://github.com/argoproj/argocd-example-apps.git", }, } - _, err := service.CommitHydratedManifests(t.Context(), request) + _, err := service.CommitHydratedManifests(context.Background(), request) require.Error(t, err) assert.ErrorContains(t, err, "target branch is required") }) @@ -73,7 +74,7 @@ func Test_CommitHydratedManifests(t *testing.T) { }, TargetBranch: "main", } - _, err := service.CommitHydratedManifests(t.Context(), request) + _, err := service.CommitHydratedManifests(context.Background(), request) require.Error(t, err) assert.ErrorContains(t, err, "sync branch is required") }) @@ -84,7 +85,7 @@ func Test_CommitHydratedManifests(t *testing.T) { service, mockRepoClientFactory := newServiceWithMocks(t) mockRepoClientFactory.On("NewClient", mock.Anything, mock.Anything).Return(nil, assert.AnError).Once() - _, err := service.CommitHydratedManifests(t.Context(), validRequest) + _, err := service.CommitHydratedManifests(context.Background(), validRequest) require.Error(t, err) assert.ErrorIs(t, err, assert.AnError) }) @@ -104,7 +105,7 @@ func Test_CommitHydratedManifests(t *testing.T) { mockGitClient.On("CommitSHA").Return("it-worked!", nil).Once() mockRepoClientFactory.On("NewClient", mock.Anything, mock.Anything).Return(mockGitClient, nil).Once() - resp, err := service.CommitHydratedManifests(t.Context(), validRequest) + resp, err := service.CommitHydratedManifests(context.Background(), validRequest) require.NoError(t, err) require.NotNil(t, resp) assert.Equal(t, "it-worked!", resp.HydratedSha) diff --git a/commitserver/commit/credentialtypehelper.go b/commitserver/commit/credentialtypehelper.go index 2eea0a885b..eda3b8040d 100644 --- a/commitserver/commit/credentialtypehelper.go +++ b/commitserver/commit/credentialtypehelper.go @@ -1,6 +1,6 @@ package commit -import "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" // getCredentialType returns the type of credential used by the repository. func getCredentialType(repo *v1alpha1.Repository) string { diff --git a/commitserver/commit/credentialtypehelper_test.go b/commitserver/commit/credentialtypehelper_test.go index 2bdf97472a..45a013410c 100644 --- a/commitserver/commit/credentialtypehelper_test.go +++ b/commitserver/commit/credentialtypehelper_test.go @@ -3,9 +3,7 @@ package commit import ( "testing" - "github.com/stretchr/testify/assert" - - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestRepository_GetCredentialType(t *testing.T) { @@ -56,7 +54,9 @@ func TestRepository_GetCredentialType(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, getCredentialType(tt.repo), "Repository.GetCredentialType()") + if got := getCredentialType(tt.repo); got != tt.want { + t.Errorf("Repository.GetCredentialType() = %v, want %v", got, tt.want) + } }) } } diff --git a/commitserver/commit/hydratorhelper.go b/commitserver/commit/hydratorhelper.go index 18fd0c8073..a4fbeb591b 100644 --- a/commitserver/commit/hydratorhelper.go +++ b/commitserver/commit/hydratorhelper.go @@ -11,13 +11,13 @@ import ( "gopkg.in/yaml.v3" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/v3/commitserver/apiclient" - "github.com/argoproj/argo-cd/v3/util/io/files" + "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/util/io/files" ) // WriteForPaths writes the manifests, hydrator.metadata, and README.md files for each path in the provided paths. It // also writes a root-level hydrator.metadata file containing the repo URL and dry SHA. -func WriteForPaths(rootPath string, repoUrl string, drySha string, paths []*apiclient.PathDetails) error { //nolint:revive //FIXME(var-naming) +func WriteForPaths(rootPath string, repoUrl string, drySha string, paths []*apiclient.PathDetails) error { // Write the top-level readme. err := writeMetadata(rootPath, hydratorMetadataFile{DrySHA: drySha, RepoURL: repoUrl}) if err != nil { @@ -64,13 +64,13 @@ func WriteForPaths(rootPath string, repoUrl string, drySha string, paths []*apic // writeMetadata writes the metadata to the hydrator.metadata file. func writeMetadata(dirPath string, metadata hydratorMetadataFile) error { - hydratorMetadataJSON, err := json.MarshalIndent(metadata, "", " ") + hydratorMetadataJson, err := json.MarshalIndent(metadata, "", " ") if err != nil { return fmt.Errorf("failed to marshal hydrator metadata: %w", err) } // No need to use SecureJoin here, as the path is already sanitized. hydratorMetadataPath := path.Join(dirPath, "hydrator.metadata") - err = os.WriteFile(hydratorMetadataPath, hydratorMetadataJSON, os.ModePerm) + err = os.WriteFile(hydratorMetadataPath, hydratorMetadataJson, os.ModePerm) if err != nil { return fmt.Errorf("failed to write hydrator metadata: %w", err) } diff --git a/commitserver/commit/hydratorhelper_test.go b/commitserver/commit/hydratorhelper_test.go index e2e5e06f2e..51e8adf0c6 100644 --- a/commitserver/commit/hydratorhelper_test.go +++ b/commitserver/commit/hydratorhelper_test.go @@ -10,13 +10,13 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/commitserver/apiclient" ) func TestWriteForPaths(t *testing.T) { dir := t.TempDir() - repoURL := "https://github.com/example/repo" + repoUrl := "https://github.com/example/repo" drySha := "abc123" paths := []*apiclient.PathDetails{ { @@ -35,7 +35,7 @@ func TestWriteForPaths(t *testing.T) { }, } - err := WriteForPaths(dir, repoURL, drySha, paths) + err := WriteForPaths(dir, repoUrl, drySha, paths) require.NoError(t, err) // Check if the top-level hydrator.metadata exists and contains the repo URL and dry SHA @@ -46,7 +46,7 @@ func TestWriteForPaths(t *testing.T) { var topMetadata hydratorMetadataFile err = json.Unmarshal(topMetadataBytes, &topMetadata) require.NoError(t, err) - assert.Equal(t, repoURL, topMetadata.RepoURL) + assert.Equal(t, repoUrl, topMetadata.RepoURL) assert.Equal(t, drySha, topMetadata.DrySHA) for _, p := range paths { @@ -64,13 +64,13 @@ func TestWriteForPaths(t *testing.T) { var readMetadata hydratorMetadataFile err = json.Unmarshal(metadataBytes, &readMetadata) require.NoError(t, err) - assert.Equal(t, repoURL, readMetadata.RepoURL) + assert.Equal(t, repoUrl, readMetadata.RepoURL) // Check if each path contains a README.md file and contains the repo URL readmePath := path.Join(fullHydratePath, "README.md") readmeBytes, err := os.ReadFile(readmePath) require.NoError(t, err) - assert.Contains(t, string(readmeBytes), repoURL) + assert.Contains(t, string(readmeBytes), repoUrl) // Check if each path contains a manifest.yaml file and contains the word Pod manifestPath := path.Join(fullHydratePath, "manifest.yaml") diff --git a/commitserver/commit/mocks/RepoClientFactory.go b/commitserver/commit/mocks/RepoClientFactory.go index eb571c9018..7c2a2afa49 100644 --- a/commitserver/commit/mocks/RepoClientFactory.go +++ b/commitserver/commit/mocks/RepoClientFactory.go @@ -1,15 +1,49 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/git" + git "github.com/argoproj/argo-cd/v2/util/git" mock "github.com/stretchr/testify/mock" + + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) +// RepoClientFactory is an autogenerated mock type for the RepoClientFactory type +type RepoClientFactory struct { + mock.Mock +} + +// NewClient provides a mock function with given fields: repo, rootPath +func (_m *RepoClientFactory) NewClient(repo *v1alpha1.Repository, rootPath string) (git.Client, error) { + ret := _m.Called(repo, rootPath) + + if len(ret) == 0 { + panic("no return value specified for NewClient") + } + + var r0 git.Client + var r1 error + if rf, ok := ret.Get(0).(func(*v1alpha1.Repository, string) (git.Client, error)); ok { + return rf(repo, rootPath) + } + if rf, ok := ret.Get(0).(func(*v1alpha1.Repository, string) git.Client); ok { + r0 = rf(repo, rootPath) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(git.Client) + } + } + + if rf, ok := ret.Get(1).(func(*v1alpha1.Repository, string) error); ok { + r1 = rf(repo, rootPath) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewRepoClientFactory creates a new instance of RepoClientFactory. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewRepoClientFactory(t interface { @@ -23,73 +57,3 @@ func NewRepoClientFactory(t interface { return mock } - -// RepoClientFactory is an autogenerated mock type for the RepoClientFactory type -type RepoClientFactory struct { - mock.Mock -} - -type RepoClientFactory_Expecter struct { - mock *mock.Mock -} - -func (_m *RepoClientFactory) EXPECT() *RepoClientFactory_Expecter { - return &RepoClientFactory_Expecter{mock: &_m.Mock} -} - -// NewClient provides a mock function for the type RepoClientFactory -func (_mock *RepoClientFactory) NewClient(repo *v1alpha1.Repository, rootPath string) (git.Client, error) { - ret := _mock.Called(repo, rootPath) - - if len(ret) == 0 { - panic("no return value specified for NewClient") - } - - var r0 git.Client - var r1 error - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Repository, string) (git.Client, error)); ok { - return returnFunc(repo, rootPath) - } - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Repository, string) git.Client); ok { - r0 = returnFunc(repo, rootPath) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(git.Client) - } - } - if returnFunc, ok := ret.Get(1).(func(*v1alpha1.Repository, string) error); ok { - r1 = returnFunc(repo, rootPath) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoClientFactory_NewClient_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewClient' -type RepoClientFactory_NewClient_Call struct { - *mock.Call -} - -// NewClient is a helper method to define mock.On call -// - repo -// - rootPath -func (_e *RepoClientFactory_Expecter) NewClient(repo interface{}, rootPath interface{}) *RepoClientFactory_NewClient_Call { - return &RepoClientFactory_NewClient_Call{Call: _e.mock.On("NewClient", repo, rootPath)} -} - -func (_c *RepoClientFactory_NewClient_Call) Run(run func(repo *v1alpha1.Repository, rootPath string)) *RepoClientFactory_NewClient_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.Repository), args[1].(string)) - }) - return _c -} - -func (_c *RepoClientFactory_NewClient_Call) Return(client git.Client, err error) *RepoClientFactory_NewClient_Call { - _c.Call.Return(client, err) - return _c -} - -func (_c *RepoClientFactory_NewClient_Call) RunAndReturn(run func(repo *v1alpha1.Repository, rootPath string) (git.Client, error)) *RepoClientFactory_NewClient_Call { - _c.Call.Return(run) - return _c -} diff --git a/commitserver/commit/repo_client_factory.go b/commitserver/commit/repo_client_factory.go index 2ebf7c8969..f0f3b5c75d 100644 --- a/commitserver/commit/repo_client_factory.go +++ b/commitserver/commit/repo_client_factory.go @@ -1,9 +1,9 @@ package commit import ( - "github.com/argoproj/argo-cd/v3/commitserver/metrics" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/git" + "github.com/argoproj/argo-cd/v2/commitserver/metrics" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/git" ) // RepoClientFactory is a factory for creating git clients for a repository. diff --git a/commitserver/metrics/githandlers.go b/commitserver/metrics/githandlers.go index 0005b3a8c9..4a960ebd54 100644 --- a/commitserver/metrics/githandlers.go +++ b/commitserver/metrics/githandlers.go @@ -3,7 +3,7 @@ package metrics import ( "time" - "github.com/argoproj/argo-cd/v3/util/git" + "github.com/argoproj/argo-cd/v2/util/git" ) // NewGitClientEventHandlers creates event handlers that update Git related metrics diff --git a/commitserver/server.go b/commitserver/server.go index 3404267cae..5e5b63324c 100644 --- a/commitserver/server.go +++ b/commitserver/server.go @@ -5,12 +5,12 @@ import ( "google.golang.org/grpc/health" "google.golang.org/grpc/health/grpc_health_v1" - "github.com/argoproj/argo-cd/v3/commitserver/apiclient" - "github.com/argoproj/argo-cd/v3/commitserver/commit" - "github.com/argoproj/argo-cd/v3/commitserver/metrics" - versionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/version" - "github.com/argoproj/argo-cd/v3/server/version" - "github.com/argoproj/argo-cd/v3/util/git" + "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/commitserver/commit" + "github.com/argoproj/argo-cd/v2/commitserver/metrics" + versionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/version" + "github.com/argoproj/argo-cd/v2/server/version" + "github.com/argoproj/argo-cd/v2/util/git" ) // ArgoCDCommitServer is the server that handles commit requests. diff --git a/common/common.go b/common/common.go index f43394a22e..82e0d91f72 100644 --- a/common/common.go +++ b/common/common.go @@ -2,25 +2,24 @@ package common import ( "context" - "errors" "fmt" "os" "path/filepath" "strconv" "time" + "github.com/pkg/errors" "github.com/redis/go-redis/v9" "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ) // Component names const ( - ApplicationController = "argocd-application-controller" - ApplicationSetController = "argocd-applicationset-controller" + ApplicationController = "argocd-application-controller" ) // Default service addresses and URLS of Argo CD internal services @@ -159,8 +158,6 @@ const ( ArgoCDCLIClientAppName = "Argo CD CLI" // ArgoCDCLIClientAppID is the Oauth client ID we will use when registering our CLI to dex ArgoCDCLIClientAppID = "argo-cd-cli" - // DexFederatedScope allows to receive the federated_claims from Dex. https://dexidp.io/docs/configuration/custom-scopes-claims-clients/ - DexFederatedScope = "federated:id" ) // Resource metadata labels and annotations (keys and values) used by Argo CD components @@ -280,8 +277,6 @@ const ( EnvLogLevel = "ARGOCD_LOG_LEVEL" // EnvLogFormatEnableFullTimestamp enables the FullTimestamp option in logs EnvLogFormatEnableFullTimestamp = "ARGOCD_LOG_FORMAT_ENABLE_FULL_TIMESTAMP" - // EnvLogFormatTimestamp is the timestamp format used in logs - EnvLogFormatTimestamp = "ARGOCD_LOG_FORMAT_TIMESTAMP" // EnvMaxCookieNumber max number of chunks a cookie can be broken into EnvMaxCookieNumber = "ARGOCD_MAX_COOKIE_NUMBER" // EnvPluginSockFilePath allows to override the pluginSockFilePath for repo server and cmp server @@ -292,8 +287,6 @@ const ( EnvCMPWorkDir = "ARGOCD_CMP_WORKDIR" // EnvGPGDataPath overrides the location where GPG keyring for signature verification is stored EnvGPGDataPath = "ARGOCD_GPG_DATA_PATH" - // EnvServer is the server address of the Argo CD API server. - EnvServer = "ARGOCD_SERVER" // EnvServerName is the name of the Argo CD server component, as specified by the value under the LabelKeyAppName label key. EnvServerName = "ARGOCD_SERVER_NAME" // EnvRepoServerName is the name of the Argo CD repo server component, as specified by the value under the LabelKeyAppName label key. @@ -361,20 +354,20 @@ const ( // GetGnuPGHomePath retrieves the path to use for GnuPG home directory, which is either taken from GNUPGHOME environment or a default value func GetGnuPGHomePath() string { - gnuPgHome := os.Getenv(EnvGnuPGHome) - if gnuPgHome == "" { + if gnuPgHome := os.Getenv(EnvGnuPGHome); gnuPgHome == "" { return DefaultGnuPgHomePath + } else { + return gnuPgHome } - return gnuPgHome } // GetPluginSockFilePath retrieves the path of plugin sock file, which is either taken from PluginSockFilePath environment or a default value func GetPluginSockFilePath() string { - pluginSockFilePath := os.Getenv(EnvPluginSockFilePath) - if pluginSockFilePath == "" { + if pluginSockFilePath := os.Getenv(EnvPluginSockFilePath); pluginSockFilePath == "" { return DefaultPluginSockFilePath + } else { + return pluginSockFilePath } - return pluginSockFilePath } // GetCMPChunkSize will return the env var EnvCMPChunkSize value if defined or DefaultCMPChunkSize otherwise. @@ -444,7 +437,7 @@ const ( // TokenVerificationError is a generic error message for a failure to verify a JWT const TokenVerificationError = "failed to verify the token" -var ErrTokenVerification = errors.New(TokenVerificationError) +var TokenVerificationErr = errors.New(TokenVerificationError) var PermissionDeniedAPIError = status.Error(codes.PermissionDenied, "permission denied") @@ -462,7 +455,7 @@ 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, RedisInitialCredentials, metav1.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, RedisInitialCredentials, err) } diff --git a/common/common_test.go b/common/common_test.go index 87e0f3474e..5fc8faf2a2 100644 --- a/common/common_test.go +++ b/common/common_test.go @@ -1,7 +1,9 @@ package common import ( + "context" "fmt" + "os" "strconv" "testing" "time" @@ -27,7 +29,7 @@ func Test_GRPCKeepAliveMinNotSet(t *testing.T) { // Test valid env var set for EnvGRPCKeepAliveMin func Test_GRPCKeepAliveMinIsSet(t *testing.T) { numSeconds := 15 - t.Setenv(EnvGRPCKeepAliveMin, fmt.Sprintf("%ds", numSeconds)) + os.Setenv(EnvGRPCKeepAliveMin, fmt.Sprintf("%ds", numSeconds)) grpcKeepAliveMin := GetGRPCKeepAliveEnforcementMinimum() grpcKeepAliveExpectedMin := time.Duration(numSeconds) * time.Second @@ -40,7 +42,7 @@ func Test_GRPCKeepAliveMinIsSet(t *testing.T) { // Test invalid env var set for EnvGRPCKeepAliveMin func Test_GRPCKeepAliveMinIncorrectlySet(t *testing.T) { numSeconds := 15 - t.Setenv(EnvGRPCKeepAliveMin, strconv.Itoa(numSeconds)) + os.Setenv(EnvGRPCKeepAliveMin, strconv.Itoa(numSeconds)) grpcKeepAliveMin := GetGRPCKeepAliveEnforcementMinimum() grpcKeepAliveExpectedMin := defaultGRPCKeepAliveEnforcementMinimum @@ -70,7 +72,7 @@ func TestSetOptionalRedisPasswordFromKubeConfig(t *testing.T) { name: "Secret does not exist", namespace: "default", expectedPassword: "", - expectedErr: "failed to get secret default/" + RedisInitialCredentials, + expectedErr: fmt.Sprintf("failed to get secret default/%s", RedisInitialCredentials), secret: nil, }, { @@ -89,13 +91,14 @@ func TestSetOptionalRedisPasswordFromKubeConfig(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() var ( - ctx = t.Context() + ctx = context.TODO() kubeClient = kubefake.NewClientset() redisOptions = &redis.Options{} ) if tc.secret != nil { - _, err := kubeClient.CoreV1().Secrets(tc.namespace).Create(ctx, tc.secret, metav1.CreateOptions{}) - require.NoErrorf(t, err, "Failed to create secret") + if _, err := kubeClient.CoreV1().Secrets(tc.namespace).Create(ctx, tc.secret, metav1.CreateOptions{}); err != nil { + t.Fatalf("Failed to create secret: %v", err) + } } err := SetOptionalRedisPasswordFromKubeConfig(ctx, kubeClient, tc.namespace, redisOptions) if tc.expectedErr != "" { diff --git a/controller/appcontroller.go b/controller/appcontroller.go index a82ecac76c..5471f58c35 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -3,7 +3,7 @@ package controller import ( "context" "encoding/json" - stderrors "errors" + goerrors "errors" "fmt" "math" "math/rand" @@ -25,8 +25,8 @@ import ( jsonpatch "github.com/evanphx/json-patch" log "github.com/sirupsen/logrus" "golang.org/x/sync/semaphore" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/api/core/v1" + apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" @@ -43,33 +43,34 @@ import ( "k8s.io/client-go/util/workqueue" "k8s.io/utils/ptr" - commitclient "github.com/argoproj/argo-cd/v3/commitserver/apiclient" - "github.com/argoproj/argo-cd/v3/common" - statecache "github.com/argoproj/argo-cd/v3/controller/cache" - "github.com/argoproj/argo-cd/v3/controller/hydrator" - "github.com/argoproj/argo-cd/v3/controller/metrics" - "github.com/argoproj/argo-cd/v3/controller/sharding" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions/application/v1alpha1" - applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - applog "github.com/argoproj/argo-cd/v3/util/app/log" - "github.com/argoproj/argo-cd/v3/util/argo" - argodiff "github.com/argoproj/argo-cd/v3/util/argo/diff" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/stats" + commitclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/common" + statecache "github.com/argoproj/argo-cd/v2/controller/cache" + "github.com/argoproj/argo-cd/v2/controller/hydrator" + "github.com/argoproj/argo-cd/v2/controller/metrics" + "github.com/argoproj/argo-cd/v2/controller/sharding" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + appv1 "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/pkg/client/informers/externalversions/application/v1alpha1" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/argo" + argodiff "github.com/argoproj/argo-cd/v2/util/argo/diff" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/stats" - "github.com/argoproj/argo-cd/v3/pkg/ratelimiter" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/glob" - "github.com/argoproj/argo-cd/v3/util/helm" - logutils "github.com/argoproj/argo-cd/v3/util/log" - settings_util "github.com/argoproj/argo-cd/v3/util/settings" + kubeerrors "k8s.io/apimachinery/pkg/api/errors" + + "github.com/argoproj/argo-cd/v2/pkg/ratelimiter" + appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/glob" + "github.com/argoproj/argo-cd/v2/util/helm" + logutils "github.com/argoproj/argo-cd/v2/util/log" + settings_util "github.com/argoproj/argo-cd/v2/util/settings" ) const ( @@ -100,6 +101,15 @@ func (a CompareWith) Pointer() *CompareWith { return &a } +func getAppLog(app *appv1.Application) *log.Entry { + return log.WithFields(log.Fields{ + "application": app.Name, + "app-namespace": app.Namespace, + "app-qualified-name": app.QualifiedName(), + "project": app.Spec.Project, + }) +} + // ApplicationController is the controller for application resources. type ApplicationController struct { cache *appstatecache.Cache @@ -133,7 +143,6 @@ type ApplicationController struct { refreshRequestedApps map[string]CompareWith refreshRequestedAppsMutex *sync.Mutex metricsServer *metrics.MetricsServer - metricsClusterLabels []string kubectlSemaphore *semaphore.Weighted clusterSharding sharding.ClusterShardingCache projByNameCache sync.Map @@ -169,7 +178,6 @@ func NewApplicationController( metricsCacheExpiration time.Duration, metricsApplicationLabels []string, metricsApplicationConditions []string, - metricsClusterLabels []string, kubectlParallelismLimit int64, persistResourceHealth bool, clusterSharding sharding.ClusterShardingCache, @@ -216,7 +224,6 @@ func NewApplicationController( applicationNamespaces: applicationNamespaces, dynamicClusterDistributionEnabled: dynamicClusterDistributionEnabled, ignoreNormalizerOpts: ignoreNormalizerOpts, - metricsClusterLabels: metricsClusterLabels, } if hydratorEnabled { ctrl.hydrator = hydrator.NewHydrator(&ctrl, appResyncPeriod, commitClientset) @@ -230,7 +237,7 @@ func NewApplicationController( projInformer := v1alpha1.NewAppProjectInformer(applicationClientset, namespace, appResyncPeriod, indexers) var err error _, err = projInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj any) { + AddFunc: func(obj interface{}) { if key, err := cache.MetaNamespaceKeyFunc(obj); err == nil { ctrl.projectRefreshQueue.AddRateLimited(key) if projMeta, ok := obj.(metav1.Object); ok { @@ -238,7 +245,7 @@ func NewApplicationController( } } }, - UpdateFunc: func(_, new any) { + UpdateFunc: func(old, new interface{}) { if key, err := cache.MetaNamespaceKeyFunc(new); err == nil { ctrl.projectRefreshQueue.AddRateLimited(key) if projMeta, ok := new.(metav1.Object); ok { @@ -246,7 +253,7 @@ func NewApplicationController( } } }, - DeleteFunc: func(obj any) { + DeleteFunc: func(obj interface{}) { if key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj); err == nil { // immediately push to queue for deletes ctrl.projectRefreshQueue.Add(key) @@ -269,47 +276,25 @@ func NewApplicationController( deploymentInformer = factory.Apps().V1().Deployments() } - readinessHealthCheck := func(_ *http.Request) error { + readinessHealthCheck := func(r *http.Request) error { if dynamicClusterDistributionEnabled { applicationControllerName := env.StringFromEnv(common.EnvAppControllerName, common.DefaultApplicationControllerName) appControllerDeployment, err := deploymentInformer.Lister().Deployments(settingsMgr.GetNamespace()).Get(applicationControllerName) if err != nil { - if !apierrors.IsNotFound(err) { + if kubeerrors.IsNotFound(err) { + appControllerDeployment = nil + } else { return fmt.Errorf("error retrieving Application Controller Deployment: %w", err) } - appControllerDeployment = nil } if appControllerDeployment != nil { if appControllerDeployment.Spec.Replicas != nil && int(*appControllerDeployment.Spec.Replicas) <= 0 { return fmt.Errorf("application controller deployment replicas is not set or is less than 0, replicas: %d", appControllerDeployment.Spec.Replicas) } shard := env.ParseNumFromEnv(common.EnvControllerShard, -1, -math.MaxInt32, math.MaxInt32) - shard, err := sharding.GetOrUpdateShardFromConfigMap(kubeClientset.(*kubernetes.Clientset), settingsMgr, int(*appControllerDeployment.Spec.Replicas), shard) - if err != nil { + if _, err := sharding.GetOrUpdateShardFromConfigMap(kubeClientset.(*kubernetes.Clientset), settingsMgr, int(*appControllerDeployment.Spec.Replicas), shard); err != nil { return fmt.Errorf("error while updating the heartbeat for to the Shard Mapping ConfigMap: %w", err) } - - // update the shard number in the clusterSharding, and resync all applications if the shard number is updated - if ctrl.clusterSharding.UpdateShard(shard) { - // update shard number in stateCache - ctrl.stateCache.UpdateShard(shard) - - // resync all applications - apps, err := ctrl.appLister.List(labels.Everything()) - if err != nil { - return err - } - for _, app := range apps { - if !ctrl.canProcessApp(app) { - continue - } - key, err := cache.MetaNamespaceKeyFunc(app) - if err == nil { - ctrl.appRefreshQueue.AddRateLimited(key) - ctrl.clusterSharding.AddApp(app) - } - } - } } } return nil @@ -345,7 +330,7 @@ func (ctrl *ApplicationController) InvalidateProjectsCache(names ...string) { ctrl.projByNameCache.Delete(name) } } else if ctrl != nil { - ctrl.projByNameCache.Range(func(key, _ any) bool { + ctrl.projByNameCache.Range(func(key, _ interface{}) bool { ctrl.projByNameCache.Delete(key) return true }) @@ -372,7 +357,7 @@ func (ctrl *ApplicationController) onKubectlRun(command string) (kube.CleanupFun }, nil } -func isSelfReferencedApp(app *appv1.Application, ref corev1.ObjectReference) bool { +func isSelfReferencedApp(app *appv1.Application, ref v1.ObjectReference) bool { gvk := ref.GroupVersionKind() return ref.UID == app.UID && ref.Name == app.Name && @@ -402,7 +387,7 @@ func (projCache *appProjCache) GetAppProject(ctx context.Context) (*appv1.AppPro if projCache.appProj != nil { return projCache.appProj, nil } - proj, err := argo.GetAppProjectByName(ctx, projCache.name, applisters.NewAppProjectLister(projCache.ctrl.projInformer.GetIndexer()), projCache.ctrl.namespace, projCache.ctrl.settingsMgr, projCache.ctrl.db) + proj, err := argo.GetAppProjectByName(projCache.name, applisters.NewAppProjectLister(projCache.ctrl.projInformer.GetIndexer()), projCache.ctrl.namespace, projCache.ctrl.settingsMgr, projCache.ctrl.db, ctx) if err != nil { return nil, err } @@ -419,10 +404,11 @@ func (ctrl *ApplicationController) getAppProj(app *appv1.Application) (*appv1.Ap } proj, err := projCache.(*appProjCache).GetAppProject(context.TODO()) if err != nil { - if apierrors.IsNotFound(err) { + if apierr.IsNotFound(err) { return nil, err + } else { + return nil, fmt.Errorf("could not retrieve AppProject '%s' from cache: %w", app.Spec.Project, err) } - return nil, fmt.Errorf("could not retrieve AppProject '%s' from cache: %w", app.Spec.Project, err) } if !proj.IsAppNamespacePermitted(app, ctrl.namespace) { return nil, argo.ErrProjectNotPermitted(app.GetName(), app.GetNamespace(), proj.GetName()) @@ -430,7 +416,7 @@ func (ctrl *ApplicationController) getAppProj(app *appv1.Application) (*appv1.Ap return proj, nil } -func (ctrl *ApplicationController) handleObjectUpdated(managedByApp map[string]bool, ref corev1.ObjectReference) { +func (ctrl *ApplicationController) handleObjectUpdated(managedByApp map[string]bool, ref v1.ObjectReference) { // if namespaced resource is not managed by any app it might be orphaned resource of some other apps if len(managedByApp) == 0 && ref.Namespace != "" { // retrieve applications which monitor orphaned resources in the same namespace and refresh them unless resource is denied in app project @@ -461,7 +447,7 @@ func (ctrl *ApplicationController) handleObjectUpdated(managedByApp map[string]b continue } - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := getAppLog(app) // Enforce application's permission for the source namespace _, err = ctrl.getAppProj(app) if err != nil { @@ -494,22 +480,22 @@ func (ctrl *ApplicationController) handleObjectUpdated(managedByApp map[string]b // setAppManagedResources will build a list of ResourceDiff based on the provided comparisonResult // and persist app resources related data in the cache. Will return the persisted ApplicationTree. -func (ctrl *ApplicationController) setAppManagedResources(destCluster *appv1.Cluster, a *appv1.Application, comparisonResult *comparisonResult) (*appv1.ApplicationTree, error) { +func (ctrl *ApplicationController) setAppManagedResources(a *appv1.Application, comparisonResult *comparisonResult) (*appv1.ApplicationTree, error) { ts := stats.NewTimingStats() defer func() { - logCtx := log.WithFields(applog.GetAppLogFields(a)) + logCtx := getAppLog(a) for k, v := range ts.Timings() { logCtx = logCtx.WithField(k, v.Milliseconds()) } logCtx = logCtx.WithField("time_ms", time.Since(ts.StartTime).Milliseconds()) logCtx.Debug("Finished setting app managed resources") }() - managedResources, err := ctrl.hideSecretData(destCluster, a, comparisonResult) + managedResources, err := ctrl.hideSecretData(a, comparisonResult) ts.AddCheckpoint("hide_secret_data_ms") if err != nil { return nil, fmt.Errorf("error getting managed resources: %w", err) } - tree, err := ctrl.getResourceTree(destCluster, a, managedResources) + tree, err := ctrl.getResourceTree(a, managedResources) ts.AddCheckpoint("get_resource_tree_ms") if err != nil { return nil, fmt.Errorf("error getting resource tree: %w", err) @@ -551,10 +537,10 @@ func isKnownOrphanedResourceExclusion(key kube.ResourceKey, proj *appv1.AppProje return false } -func (ctrl *ApplicationController) getResourceTree(destCluster *appv1.Cluster, a *appv1.Application, managedResources []*appv1.ResourceDiff) (*appv1.ApplicationTree, error) { +func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managedResources []*appv1.ResourceDiff) (*appv1.ApplicationTree, error) { ts := stats.NewTimingStats() defer func() { - logCtx := log.WithFields(applog.GetAppLogFields(a)) + logCtx := getAppLog(a) for k, v := range ts.Timings() { logCtx = logCtx.WithField(k, v.Milliseconds()) } @@ -571,7 +557,7 @@ func (ctrl *ApplicationController) getResourceTree(destCluster *appv1.Cluster, a orphanedNodesMap := make(map[kube.ResourceKey]appv1.ResourceNode) warnOrphaned := true if proj.Spec.OrphanedResources != nil { - orphanedNodesMap, err = ctrl.stateCache.GetNamespaceTopLevelResources(destCluster, a.Spec.Destination.Namespace) + orphanedNodesMap, err = ctrl.stateCache.GetNamespaceTopLevelResources(a.Spec.Destination.Server, a.Spec.Destination.Namespace) if err != nil { return nil, fmt.Errorf("failed to get namespace top-level resources: %w", err) } @@ -607,8 +593,8 @@ func (ctrl *ApplicationController) getResourceTree(destCluster *appv1.Cluster, a managedResourcesKeys = append(managedResourcesKeys, kube.GetResourceKey(live)) } } - err = ctrl.stateCache.IterateHierarchyV2(destCluster, managedResourcesKeys, func(child appv1.ResourceNode, _ string) bool { - permitted, _ := proj.IsResourcePermitted(schema.GroupKind{Group: child.Group, Kind: child.Kind}, child.Namespace, destCluster, func(project string) ([]*appv1.Cluster, error) { + err = ctrl.stateCache.IterateHierarchyV2(a.Spec.Destination.Server, managedResourcesKeys, func(child appv1.ResourceNode, appName string) bool { + permitted, _ := proj.IsResourcePermitted(schema.GroupKind{Group: child.ResourceRef.Group, Kind: child.ResourceRef.Kind}, child.Namespace, a.Spec.Destination, func(project string) ([]*appv1.Cluster, error) { clusters, err := ctrl.db.GetProjectClusters(context.TODO(), project) if err != nil { return nil, fmt.Errorf("failed to get project clusters: %w", err) @@ -632,7 +618,7 @@ func (ctrl *ApplicationController) getResourceTree(destCluster *appv1.Cluster, a orphanedNodesKeys = append(orphanedNodesKeys, k) } } - err = ctrl.stateCache.IterateHierarchyV2(destCluster, orphanedNodesKeys, func(child appv1.ResourceNode, appName string) bool { + err = ctrl.stateCache.IterateHierarchyV2(a.Spec.Destination.Server, orphanedNodesKeys, func(child appv1.ResourceNode, appName string) bool { belongToAnotherApp := false if appName != "" { appKey := ctrl.toAppKey(appName) @@ -645,7 +631,7 @@ func (ctrl *ApplicationController) getResourceTree(destCluster *appv1.Cluster, a return false } - permitted, _ := proj.IsResourcePermitted(schema.GroupKind{Group: child.Group, Kind: child.Kind}, child.Namespace, destCluster, func(project string) ([]*appv1.Cluster, error) { + permitted, _ := proj.IsResourcePermitted(schema.GroupKind{Group: child.ResourceRef.Group, Kind: child.ResourceRef.Kind}, child.Namespace, a.Spec.Destination, func(project string) ([]*appv1.Cluster, error) { return ctrl.db.GetProjectClusters(context.TODO(), project) }) @@ -673,7 +659,7 @@ func (ctrl *ApplicationController) getResourceTree(destCluster *appv1.Cluster, a }) ts.AddCheckpoint("process_orphaned_resources_ms") - hosts, err := ctrl.getAppHosts(destCluster, a, nodes) + hosts, err := ctrl.getAppHosts(a, nodes) if err != nil { return nil, fmt.Errorf("failed to get app hosts: %w", err) } @@ -681,20 +667,20 @@ func (ctrl *ApplicationController) getResourceTree(destCluster *appv1.Cluster, a return &appv1.ApplicationTree{Nodes: nodes, OrphanedNodes: orphanedNodes, Hosts: hosts}, nil } -func (ctrl *ApplicationController) getAppHosts(destCluster *appv1.Cluster, a *appv1.Application, appNodes []appv1.ResourceNode) ([]appv1.HostInfo, error) { +func (ctrl *ApplicationController) getAppHosts(a *appv1.Application, appNodes []appv1.ResourceNode) ([]appv1.HostInfo, error) { ts := stats.NewTimingStats() defer func() { - logCtx := log.WithFields(applog.GetAppLogFields(a)) + logCtx := getAppLog(a) for k, v := range ts.Timings() { logCtx = logCtx.WithField(k, v.Milliseconds()) } logCtx = logCtx.WithField("time_ms", time.Since(ts.StartTime).Milliseconds()) logCtx.Debug("Finished getting app hosts") }() - supportedResourceNames := map[corev1.ResourceName]bool{ - corev1.ResourceCPU: true, - corev1.ResourceStorage: true, - corev1.ResourceMemory: true, + supportedResourceNames := map[v1.ResourceName]bool{ + v1.ResourceCPU: true, + v1.ResourceStorage: true, + v1.ResourceMemory: true, } appPods := map[kube.ResourceKey]bool{} for _, node := range appNodes { @@ -706,7 +692,7 @@ func (ctrl *ApplicationController) getAppHosts(destCluster *appv1.Cluster, a *ap allNodesInfo := map[string]statecache.NodeInfo{} allPodsByNode := map[string][]statecache.PodInfo{} appPodsByNode := map[string][]statecache.PodInfo{} - err := ctrl.stateCache.IterateResources(destCluster, func(res *clustercache.Resource, info *statecache.ResourceInfo) { + err := ctrl.stateCache.IterateResources(a.Spec.Destination.Server, func(res *clustercache.Resource, info *statecache.ResourceInfo) { key := res.ResourceKey() switch { @@ -734,7 +720,7 @@ func (ctrl *ApplicationController) getAppHosts(destCluster *appv1.Cluster, a *ap neighbors := allPodsByNode[nodeName] - resources := map[corev1.ResourceName]appv1.HostResourceInfo{} + resources := map[v1.ResourceName]appv1.HostResourceInfo{} for name, resource := range node.Capacity { info := resources[name] info.ResourceName = name @@ -756,7 +742,7 @@ func (ctrl *ApplicationController) getAppHosts(destCluster *appv1.Cluster, a *ap for _, pod := range neighbors { for name, resource := range pod.ResourceRequests { - if !supportedResourceNames[name] || pod.Phase == corev1.PodSucceeded || pod.Phase == corev1.PodFailed { + if !supportedResourceNames[name] || pod.Phase == v1.PodSucceeded || pod.Phase == v1.PodFailed { continue } info := resources[name] @@ -780,7 +766,7 @@ func (ctrl *ApplicationController) getAppHosts(destCluster *appv1.Cluster, a *ap return hosts, nil } -func (ctrl *ApplicationController) hideSecretData(destCluster *appv1.Cluster, app *appv1.Application, comparisonResult *comparisonResult) ([]*appv1.ResourceDiff, error) { +func (ctrl *ApplicationController) hideSecretData(app *appv1.Application, comparisonResult *comparisonResult) ([]*appv1.ResourceDiff, error) { items := make([]*appv1.ResourceDiff, len(comparisonResult.managedResources)) for i := range comparisonResult.managedResources { res := comparisonResult.managedResources[i] @@ -819,7 +805,7 @@ func (ctrl *ApplicationController) hideSecretData(destCluster *appv1.Cluster, ap return nil, fmt.Errorf("error getting tracking method: %w", err) } - clusterCache, err := ctrl.stateCache.GetClusterCache(destCluster) + clusterCache, err := ctrl.stateCache.GetClusterCache(app.Spec.Destination.Server) if err != nil { return nil, fmt.Errorf("error getting cluster cache: %w", err) } @@ -879,8 +865,11 @@ func (ctrl *ApplicationController) Run(ctx context.Context, statusProcessors int defer ctrl.appHydrateQueue.ShutDown() defer ctrl.hydrationQueue.ShutDown() + ctrl.metricsServer.RegisterClustersInfoSource(ctx, ctrl.stateCache) ctrl.RegisterClusterSecretUpdater(ctx) - ctrl.metricsServer.RegisterClustersInfoSource(ctx, ctrl.stateCache, ctrl.db, ctrl.metricsClusterLabels) + + go ctrl.appInformer.Run(ctx.Done()) + go ctrl.projInformer.Run(ctx.Done()) if ctrl.dynamicClusterDistributionEnabled { // only start deployment informer if dynamic distribution is enabled @@ -900,9 +889,6 @@ func (ctrl *ApplicationController) Run(ctx context.Context, statusProcessors int } } - go ctrl.appInformer.Run(ctx.Done()) - go ctrl.projInformer.Run(ctx.Done()) - errors.CheckError(ctrl.stateCache.Init()) if !cache.WaitForCacheSync(ctx.Done(), ctrl.appInformer.HasSynced, ctrl.projInformer.HasSynced) { @@ -1012,7 +998,7 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b return } app := origApp.DeepCopy() - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := getAppLog(app) ts := stats.NewTimingStats() defer func() { for k, v := range ts.Timings() { @@ -1026,7 +1012,7 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b // If we get here, we are about to process an operation, but we cannot rely on informer since it might have stale data. // So always retrieve the latest version to ensure it is not stale to avoid unnecessary syncing. // We cannot rely on informer since applications might be updated by both application controller and api server. - freshApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.ObjectMeta.Namespace).Get(context.Background(), app.Name, metav1.GetOptions{}) + freshApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.ObjectMeta.Namespace).Get(context.Background(), app.ObjectMeta.Name, metav1.GetOptions{}) if err != nil { logCtx.Errorf("Failed to retrieve latest application state: %v", err) return @@ -1047,7 +1033,7 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b Message: err.Error(), }) message := fmt.Sprintf("Unable to delete application resources: %v", err.Error()) - ctrl.logAppEvent(context.TODO(), app, argo.EventInfo{Reason: argo.EventReasonStatusRefreshed, Type: corev1.EventTypeWarning}, message) + ctrl.logAppEvent(app, argo.EventInfo{Reason: argo.EventReasonStatusRefreshed, Type: v1.EventTypeWarning}, message, context.TODO()) } ts.AddCheckpoint("finalize_application_deletion_ms") } @@ -1072,12 +1058,12 @@ func (ctrl *ApplicationController) processAppComparisonTypeQueueItem() (processN if parts := strings.Split(key, "/"); len(parts) != 3 { log.Warnf("Unexpected key format in appComparisonTypeRefreshTypeQueue. Key should consists of namespace/name/comparisonType but got: %s", key) } else { - compareWith, err := strconv.Atoi(parts[2]) - if err != nil { + if compareWith, err := strconv.Atoi(parts[2]); err != nil { log.Warnf("Unable to parse comparison type: %v", err) return + } else { + ctrl.requestAppRefresh(ctrl.toAppQualifiedName(parts[1], parts[0]), CompareWith(compareWith).Pointer(), nil) } - ctrl.requestAppRefresh(ctrl.toAppQualifiedName(parts[1], parts[0]), CompareWith(compareWith).Pointer(), nil) } return } @@ -1132,16 +1118,17 @@ func (ctrl *ApplicationController) finalizeProjectDeletion(proj *appv1.AppProjec } if appsCount == 0 { return ctrl.removeProjectFinalizer(proj) + } else { + log.Infof("Cannot remove project '%s' finalizer as is referenced by %d applications", proj.Name, appsCount) } - log.Infof("Cannot remove project '%s' finalizer as is referenced by %d applications", proj.Name, appsCount) return nil } func (ctrl *ApplicationController) removeProjectFinalizer(proj *appv1.AppProject) error { proj.RemoveFinalizer() var patch []byte - patch, _ = json.Marshal(map[string]any{ - "metadata": map[string]any{ + patch, _ = json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ "finalizers": proj.Finalizers, }, }) @@ -1156,14 +1143,14 @@ func (ctrl *ApplicationController) shouldBeDeleted(app *appv1.Application, obj * !resourceutil.HasAnnotationOption(obj, helm.ResourcePolicyAnnotation, helm.ResourcePolicyKeep) } -func (ctrl *ApplicationController) getPermittedAppLiveObjects(destCluster *appv1.Cluster, app *appv1.Application, proj *appv1.AppProject, projectClusters func(project string) ([]*appv1.Cluster, error)) (map[kube.ResourceKey]*unstructured.Unstructured, error) { - objsMap, err := ctrl.stateCache.GetManagedLiveObjs(destCluster, app, []*unstructured.Unstructured{}) +func (ctrl *ApplicationController) getPermittedAppLiveObjects(app *appv1.Application, proj *appv1.AppProject, projectClusters func(project string) ([]*appv1.Cluster, error)) (map[kube.ResourceKey]*unstructured.Unstructured, error) { + objsMap, err := ctrl.stateCache.GetManagedLiveObjs(app, []*unstructured.Unstructured{}) if err != nil { return nil, err } // Don't delete live resources which are not permitted in the app project for k, v := range objsMap { - permitted, err := proj.IsLiveResourcePermitted(v, destCluster, projectClusters) + permitted, err := proj.IsLiveResourcePermitted(v, app.Spec.Destination.Server, app.Spec.Destination.Name, projectClusters) if err != nil { return nil, err } @@ -1175,12 +1162,29 @@ func (ctrl *ApplicationController) getPermittedAppLiveObjects(destCluster *appv1 return objsMap, nil } +func (ctrl *ApplicationController) isValidDestination(app *appv1.Application) (bool, *appv1.Cluster) { + logCtx := getAppLog(app) + // Validate the cluster using the Application destination's `name` field, if applicable, + // and set the Server field, if needed. + if err := argo.ValidateDestination(context.Background(), &app.Spec.Destination, ctrl.db); err != nil { + logCtx.Warnf("Unable to validate destination of the Application being deleted: %v", err) + return false, nil + } + + cluster, err := ctrl.db.GetCluster(context.Background(), app.Spec.Destination.Server) + if err != nil { + logCtx.Warnf("Unable to locate cluster URL for Application being deleted: %v", err) + return false, nil + } + return true, cluster +} + func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Application, projectClusters func(project string) ([]*appv1.Cluster, error)) error { - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := getAppLog(app) // Get refreshed application info, since informer app copy might be stale app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(context.Background(), app.Name, metav1.GetOptions{}) if err != nil { - if !apierrors.IsNotFound(err) { + if !apierr.IsNotFound(err) { logCtx.Errorf("Unable to get refreshed application info prior deleting resources: %v", err) } return nil @@ -1189,9 +1193,9 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic if err != nil { return err } - destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, ctrl.db) - if err != nil { - logCtx.Warnf("Unable to get destination cluster: %v", err) + + isValid, cluster := ctrl.isValidDestination(app) + if !isValid { app.UnSetCascadedDeletion() app.UnSetPostDeleteFinalizer() if err := ctrl.updateFinalizers(app); err != nil { @@ -1200,7 +1204,7 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic logCtx.Infof("Resource entries removed from undefined cluster") return nil } - clusterRESTConfig, err := destCluster.RESTConfig() + clusterRESTConfig, err := cluster.RESTConfig() if err != nil { return err } @@ -1212,7 +1216,7 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic logCtx.Infof("Deleting resources") // ApplicationDestination points to a valid cluster, so we may clean up the live objects objs := make([]*unstructured.Unstructured, 0) - objsMap, err := ctrl.getPermittedAppLiveObjects(destCluster, app, proj, projectClusters) + objsMap, err := ctrl.getPermittedAppLiveObjects(app, proj, projectClusters) if err != nil { return err } @@ -1249,7 +1253,7 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic return err } - objsMap, err = ctrl.getPermittedAppLiveObjects(destCluster, app, proj, projectClusters) + objsMap, err = ctrl.getPermittedAppLiveObjects(app, proj, projectClusters) if err != nil { return err } @@ -1269,7 +1273,7 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic } if app.HasPostDeleteFinalizer() { - objsMap, err := ctrl.getPermittedAppLiveObjects(destCluster, app, proj, projectClusters) + objsMap, err := ctrl.getPermittedAppLiveObjects(app, proj, projectClusters) if err != nil { return err } @@ -1286,7 +1290,7 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic } if app.HasPostDeleteFinalizer("cleanup") { - objsMap, err := ctrl.getPermittedAppLiveObjects(destCluster, app, proj, projectClusters) + objsMap, err := ctrl.getPermittedAppLiveObjects(app, proj, projectClusters) if err != nil { return err } @@ -1323,8 +1327,8 @@ func (ctrl *ApplicationController) updateFinalizers(app *appv1.Application) erro } var patch []byte - patch, _ = json.Marshal(map[string]any{ - "metadata": map[string]any{ + patch, _ = json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ "finalizers": app.Finalizers, }, }) @@ -1334,7 +1338,7 @@ func (ctrl *ApplicationController) updateFinalizers(app *appv1.Application) erro } func (ctrl *ApplicationController) setAppCondition(app *appv1.Application, condition appv1.ApplicationCondition) { - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := getAppLog(app) // do nothing if app already has same condition for _, c := range app.Status.Conditions { if c.Message == condition.Message && c.Type == condition.Type { @@ -1345,8 +1349,8 @@ func (ctrl *ApplicationController) setAppCondition(app *appv1.Application, condi app.Status.SetConditions([]appv1.ApplicationCondition{condition}, map[appv1.ApplicationConditionType]bool{condition.Type: true}) var patch []byte - patch, err := json.Marshal(map[string]any{ - "status": map[string]any{ + patch, err := json.Marshal(map[string]interface{}{ + "status": map[string]interface{}{ "conditions": app.Status.Conditions, }, }) @@ -1359,7 +1363,7 @@ func (ctrl *ApplicationController) setAppCondition(app *appv1.Application, condi } func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Application) { - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := getAppLog(app) var state *appv1.OperationState // Recover from any unexpected panics and automatically set the status to be failed defer func() { @@ -1387,8 +1391,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli state = app.Status.OperationState.DeepCopy() terminating = state.Phase == synccommon.OperationTerminating // Failed operation with retry strategy might have be in-progress and has completion time - switch { - case state.FinishedAt != nil && !terminating: + if state.FinishedAt != nil && !terminating { retryAt, err := app.Status.OperationState.Operation.Retry.NextRetryAt(state.FinishedAt.Time, state.RetryCount) if err != nil { state.Phase = synccommon.OperationFailed @@ -1401,19 +1404,20 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli logCtx.Infof("Skipping retrying in-progress operation. Attempting again at: %s", retryAt.Format(time.RFC3339)) ctrl.requestAppRefresh(app.QualifiedName(), CompareWithLatest.Pointer(), &retryAfter) return + } else { + // retrying operation. remove previous failure time in app since it is used as a trigger + // that previous failed and operation should be retried + state.FinishedAt = nil + ctrl.setOperationState(app, state) + // Get rid of sync results and null out previous operation completion time + state.SyncResult = nil } - // retrying operation. remove previous failure time in app since it is used as a trigger - // that previous failed and operation should be retried - state.FinishedAt = nil - ctrl.setOperationState(app, state) - // Get rid of sync results and null out previous operation completion time - state.SyncResult = nil - case ctrl.syncTimeout != time.Duration(0) && time.Now().After(state.StartedAt.Add(ctrl.syncTimeout)) && !terminating: + } else if ctrl.syncTimeout != time.Duration(0) && time.Now().After(state.StartedAt.Add(ctrl.syncTimeout)) && !terminating { state.Phase = synccommon.OperationTerminating state.Message = "operation is terminating due to timeout" ctrl.setOperationState(app, state) logCtx.Infof("Terminating in-progress operation due to timeout. Started at: %v, timeout: %v", state.StartedAt, ctrl.syncTimeout) - default: + } else { logCtx.Infof("Resuming in-progress operation. phase: %s, message: %s", state.Phase, state.Message) } } else { @@ -1427,8 +1431,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli } ts.AddCheckpoint("initial_operation_stage_ms") - // Call GetDestinationCluster to validate the destination cluster. - if _, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, ctrl.db); err != nil { + if err := argo.ValidateDestination(context.Background(), &app.Spec.Destination, ctrl.db); err != nil { state.Phase = synccommon.OperationFailed state.Message = err.Error() } else { @@ -1444,11 +1447,10 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli state.Message = err.Error() } - switch state.Phase { - case synccommon.OperationRunning: + if state.Phase == synccommon.OperationRunning { // It's possible for an app to be terminated while we were operating on it. We do not want // to clobber the Terminated state with Running. Get the latest app state to check for this. - freshApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(context.Background(), app.Name, metav1.GetOptions{}) + freshApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(context.Background(), app.ObjectMeta.Name, metav1.GetOptions{}) if err == nil { // App may have lost permissions to use the project meanwhile. _, err = ctrl.getAppProj(freshApp) @@ -1464,7 +1466,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli // cleanup (e.g. delete jobs, workflows, etc...) } } - case synccommon.OperationFailed, synccommon.OperationError: + } else if state.Phase == synccommon.OperationFailed || state.Phase == synccommon.OperationError { if !terminating && (state.RetryCount < state.Operation.Retry.Limit || state.Operation.Retry.Limit < 0) { now := metav1.Now() state.FinishedAt = &now @@ -1474,7 +1476,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli } else { state.Phase = synccommon.OperationRunning state.RetryCount++ - state.Message = fmt.Sprintf("%s. Retrying attempt #%d at %s.", state.Message, state.RetryCount, retryAt.Format(time.Kitchen)) + state.Message = fmt.Sprintf("%s due to application controller sync timeout. Retrying attempt #%d at %s.", state.Message, state.RetryCount, retryAt.Format(time.Kitchen)) } } else if state.RetryCount > 0 { state.Message = fmt.Sprintf("%s (retried %d times).", state.Message, state.RetryCount) @@ -1497,7 +1499,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli } func (ctrl *ApplicationController) setOperationState(app *appv1.Application, state *appv1.OperationState) { - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := getAppLog(app) if state.Phase == "" { // expose any bugs where we neglect to set phase panic("no phase was set") @@ -1506,8 +1508,8 @@ func (ctrl *ApplicationController) setOperationState(app *appv1.Application, sta now := metav1.Now() state.FinishedAt = &now } - patch := map[string]any{ - "status": map[string]any{ + patch := map[string]interface{}{ + "status": map[string]interface{}{ "operationState": state, }, } @@ -1537,7 +1539,7 @@ func (ctrl *ApplicationController) setOperationState(app *appv1.Application, sta _, err := ctrl.PatchAppWithWriteBack(context.Background(), app.Name, app.Namespace, types.MergePatchType, patchJSON, metav1.PatchOptions{}) if err != nil { // Stop retrying updating deleted application - if apierrors.IsNotFound(err) { + if apierr.IsNotFound(err) { return nil } // kube.RetryUntilSucceed logs failed attempts at "debug" level, but we want to know if this fails. Log a @@ -1561,13 +1563,13 @@ func (ctrl *ApplicationController) setOperationState(app *appv1.Application, sta messages = append(messages, "to", state.SyncResult.Revision) } if state.Phase.Successful() { - eventInfo.Type = corev1.EventTypeNormal + eventInfo.Type = v1.EventTypeNormal messages = append(messages, "succeeded") } else { - eventInfo.Type = corev1.EventTypeWarning + eventInfo.Type = v1.EventTypeWarning messages = append(messages, "failed:", state.Message) } - ctrl.logAppEvent(context.TODO(), app, eventInfo, strings.Join(messages, " ")) + ctrl.logAppEvent(app, eventInfo, strings.Join(messages, " "), context.TODO()) ctrl.metricsServer.IncSync(app, state) } } @@ -1575,7 +1577,7 @@ func (ctrl *ApplicationController) setOperationState(app *appv1.Application, sta // writeBackToInformer writes a just recently updated App back into the informer cache. // This prevents the situation where the controller operates on a stale app and repeats work func (ctrl *ApplicationController) writeBackToInformer(app *appv1.Application) { - logCtx := log.WithFields(applog.GetAppLogFields(app)).WithField("informer-writeBack", true) + logCtx := getAppLog(app).WithField("informer-writeBack", true) err := ctrl.appInformer.GetStore().Update(app) if err != nil { logCtx.Errorf("failed to update informer store: %v", err) @@ -1594,8 +1596,8 @@ func (ctrl *ApplicationController) PatchAppWithWriteBack(ctx context.Context, na } func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext bool) { - patchDuration := time.Duration(0) // time spent in doing patch/update calls - setOpDuration := time.Duration(0) // time spent in doing Operation patch calls in autosync + patchMs := time.Duration(0) // time spent in doing patch/update calls + setOpMs := time.Duration(0) // time spent in doing Operation patch calls in autosync appKey, shutdown := ctrl.appRefreshQueue.Get() if shutdown { processNext = false @@ -1632,7 +1634,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo return } app := origApp.DeepCopy() - logCtx := log.WithFields(applog.GetAppLogFields(app)).WithFields(log.Fields{ + logCtx := getAppLog(app).WithFields(log.Fields{ "comparison-level": comparisonLevel, "dest-server": origApp.Spec.Destination.Server, "dest-name": origApp.Spec.Destination.Name, @@ -1649,40 +1651,37 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo } logCtx.WithFields(log.Fields{ "time_ms": reconcileDuration.Milliseconds(), - "patch_ms": patchDuration.Milliseconds(), - "setop_ms": setOpDuration.Milliseconds(), + "patch_ms": patchMs.Milliseconds(), + "setop_ms": setOpMs.Milliseconds(), }).Info("Reconciliation completed") }() if comparisonLevel == ComparisonWithNothing { - // If the destination cluster is invalid, fallback to the normal reconciliation flow - if destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, ctrl.db); err == nil { - managedResources := make([]*appv1.ResourceDiff, 0) - if err := ctrl.cache.GetAppManagedResources(app.InstanceName(ctrl.namespace), &managedResources); err == nil { - var tree *appv1.ApplicationTree - if tree, err = ctrl.getResourceTree(destCluster, app, managedResources); err == nil { - app.Status.Summary = tree.GetSummary(app) - if err := ctrl.cache.SetAppResourcesTree(app.InstanceName(ctrl.namespace), tree); err != nil { - logCtx.Errorf("Failed to cache resources tree: %v", err) - return - } - } - - patchDuration = ctrl.persistAppStatus(origApp, &app.Status) - return - } + managedResources := make([]*appv1.ResourceDiff, 0) + if err := ctrl.cache.GetAppManagedResources(app.InstanceName(ctrl.namespace), &managedResources); err != nil { logCtx.Warnf("Failed to get cached managed resources for tree reconciliation, fall back to full reconciliation") + } else { + var tree *appv1.ApplicationTree + if tree, err = ctrl.getResourceTree(app, managedResources); err == nil { + app.Status.Summary = tree.GetSummary(app) + if err := ctrl.cache.SetAppResourcesTree(app.InstanceName(ctrl.namespace), tree); err != nil { + logCtx.Errorf("Failed to cache resources tree: %v", err) + return + } + } + + patchMs = ctrl.persistAppStatus(origApp, &app.Status) + return } } ts.AddCheckpoint("comparison_with_nothing_ms") project, hasErrors := ctrl.refreshAppConditions(app) ts.AddCheckpoint("refresh_app_conditions_ms") - now := metav1.Now() if hasErrors { app.Status.Sync.Status = appv1.SyncStatusCodeUnknown app.Status.Health.Status = health.HealthStatusUnknown - patchDuration = ctrl.persistAppStatus(origApp, &app.Status) + patchMs = ctrl.persistAppStatus(origApp, &app.Status) if err := ctrl.cache.SetAppResourcesTree(app.InstanceName(ctrl.namespace), &appv1.ApplicationTree{}); err != nil { logCtx.Warnf("failed to set app resource tree: %v", err) @@ -1694,13 +1693,6 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo return } - destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, ctrl.db) - if err != nil { - logCtx.Errorf("Failed to get destination cluster: %v", err) - // exit the reconciliation. ctrl.refreshAppConditions should have caught the error - return - } - var localManifests []string if opState := app.Status.OperationState; opState != nil && opState.Operation.Sync != nil { localManifests = opState.Operation.Sync.Manifests @@ -1733,11 +1725,12 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo sources = append(sources, app.Spec.GetSource()) } - compareResult, err := ctrl.appStateManager.CompareAppState(app, project, revisions, sources, refreshType == appv1.RefreshTypeHard, comparisonLevel == CompareWithLatestForceResolve, localManifests, hasMultipleSources, false) - + compareResult, err := ctrl.appStateManager.CompareAppState(app, project, revisions, sources, + refreshType == appv1.RefreshTypeHard, + comparisonLevel == CompareWithLatestForceResolve, localManifests, hasMultipleSources, false) ts.AddCheckpoint("compare_app_state_ms") - if stderrors.Is(err, ErrCompareStateRepo) { + if goerrors.Is(err, CompareStateRepoError) { logCtx.Warnf("Ignoring temporary failed attempt to compare app state against repo: %v", err) return // short circuit if git error is encountered } @@ -1749,7 +1742,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo ctrl.normalizeApplication(origApp, app) ts.AddCheckpoint("normalize_application_ms") - tree, err := ctrl.setAppManagedResources(destCluster, app, compareResult) + tree, err := ctrl.setAppManagedResources(app, compareResult) ts.AddCheckpoint("set_app_managed_resources_ms") if err != nil { logCtx.Errorf("Failed to cache app resources: %v", err) @@ -1759,8 +1752,8 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo canSync, _ := project.Spec.SyncWindows.Matches(app).CanSync(false) if canSync { - syncErrCond, opDuration := ctrl.autoSync(app, compareResult.syncStatus, compareResult.resources, compareResult.revisionUpdated) - setOpDuration = opDuration + syncErrCond, opMS := ctrl.autoSync(app, compareResult.syncStatus, compareResult.resources, compareResult.revisionUpdated) + setOpMs = opMS if syncErrCond != nil { app.Status.SetConditions( []appv1.ApplicationCondition{*syncErrCond}, @@ -1778,10 +1771,11 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo ts.AddCheckpoint("auto_sync_ms") if app.Status.ReconciledAt == nil || comparisonLevel >= CompareWithLatest { + now := metav1.Now() app.Status.ReconciledAt = &now } app.Status.Sync = *compareResult.syncStatus - app.Status.Health.Status = compareResult.healthStatus + app.Status.Health = *compareResult.healthStatus app.Status.Resources = compareResult.resources sort.Slice(app.Status.Resources, func(i, j int) bool { return resourceStatusKey(app.Status.Resources[i]) < resourceStatusKey(app.Status.Resources[j]) @@ -1790,7 +1784,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo app.Status.SourceTypes = compareResult.appSourceTypes app.Status.ControllerNamespace = ctrl.namespace ts.AddCheckpoint("app_status_update_ms") - patchDuration = ctrl.persistAppStatus(origApp, &app.Status) + patchMs = ctrl.persistAppStatus(origApp, &app.Status) // This is a partly a duplicate of patch_ms, but more descriptive and allows to have measurement for the next step. ts.AddCheckpoint("persist_app_status_ms") if (compareResult.hasPostDeleteHooks != app.HasPostDeleteFinalizer() || compareResult.hasPostDeleteHooks != app.HasPostDeleteFinalizer("cleanup")) && @@ -1841,7 +1835,7 @@ func (ctrl *ApplicationController) processAppHydrateQueueItem() (processNext boo ctrl.hydrator.ProcessAppHydrateQueueItem(origApp) - log.WithFields(applog.GetAppLogFields(origApp)).Debug("Successfully processed app hydrate queue item") + getAppLog(origApp).Debug("Successfully processed app hydrate queue item") return } @@ -1890,7 +1884,7 @@ func currentSourceEqualsSyncedSource(app *appv1.Application) bool { // Additionally, it returns whether full refresh was requested or not. // If full refresh is requested then target and live state should be reconciled, else only live state tree should be updated. func (ctrl *ApplicationController) needRefreshAppStatus(app *appv1.Application, statusRefreshTimeout, statusHardRefreshTimeout time.Duration) (bool, appv1.RefreshType, CompareWith) { - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := getAppLog(app) var reason string compareWith := CompareWithLatest refreshType := appv1.RefreshTypeNormal @@ -1923,7 +1917,7 @@ func (ctrl *ApplicationController) needRefreshAppStatus(app *appv1.Application, reason = fmt.Sprintf("comparison expired, requesting hard refresh. reconciledAt: %v, expiry: %v", reconciledAtStr, statusHardRefreshTimeout) refreshType = appv1.RefreshTypeHard } - } else if !reflect.DeepEqual(app.Spec.Destination, app.Status.Sync.ComparedTo.Destination) { + } else if !app.Spec.Destination.Equals(app.Status.Sync.ComparedTo.Destination) { reason = "spec.destination differs" } else if app.HasChangedManagedNamespaceMetadata() { reason = "spec.syncPolicy.managedNamespaceMetadata differs" @@ -1968,7 +1962,7 @@ func (ctrl *ApplicationController) refreshAppConditions(app *appv1.Application) // normalizeApplication normalizes an application.spec and additionally persists updates if it changed func (ctrl *ApplicationController) normalizeApplication(orig, app *appv1.Application) { app.Spec = *argo.NormalizeApplicationSpec(&app.Spec) - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := getAppLog(app) patch, modified, err := diff.CreateTwoWayMergePatch(orig, app, appv1.Application{}) @@ -1984,7 +1978,7 @@ func (ctrl *ApplicationController) normalizeApplication(orig, app *appv1.Applica } } -func createMergePatch(orig, new any) ([]byte, bool, error) { +func createMergePatch(orig, new interface{}) ([]byte, bool, error) { origBytes, err := json.Marshal(orig) if err != nil { return nil, false, err @@ -2001,24 +1995,22 @@ func createMergePatch(orig, new any) ([]byte, bool, error) { } // persistAppStatus persists updates to application status. If no changes were made, it is a no-op -func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, newStatus *appv1.ApplicationStatus) (patchDuration time.Duration) { - logCtx := log.WithFields(applog.GetAppLogFields(orig)) +func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, newStatus *appv1.ApplicationStatus) (patchMs time.Duration) { + logCtx := getAppLog(orig) if orig.Status.Sync.Status != newStatus.Sync.Status { message := fmt.Sprintf("Updated sync status: %s -> %s", orig.Status.Sync.Status, newStatus.Sync.Status) - ctrl.logAppEvent(context.TODO(), orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: corev1.EventTypeNormal}, message) + ctrl.logAppEvent(orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: v1.EventTypeNormal}, message, context.TODO()) } if orig.Status.Health.Status != newStatus.Health.Status { - // Update the last transition time to now. This should be the ONLY place in code where this is set, because it's - // the only place that is reliably aware of the previous and updated health statuses. now := metav1.Now() newStatus.Health.LastTransitionTime = &now - message := fmt.Sprintf("Updated health status: %s -> %s", orig.Status.Health.Status, newStatus.Health.Status) - ctrl.logAppEvent(context.TODO(), orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: corev1.EventTypeNormal}, message) + ctrl.logAppEvent(orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: v1.EventTypeNormal}, message, context.TODO()) } else { // make sure the last transition time is the same and populated if the health is the same newStatus.Health.LastTransitionTime = orig.Status.Health.LastTransitionTime } + var newAnnotations map[string]string if orig.GetAnnotations() != nil { newAnnotations = make(map[string]string) @@ -2042,7 +2034,7 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new // calculate time for path call start := time.Now() defer func() { - patchDuration = time.Since(start) + patchMs = time.Since(start) }() _, err = ctrl.PatchAppWithWriteBack(context.Background(), orig.Name, orig.Namespace, types.MergePatchType, patch, metav1.PatchOptions{}) if err != nil { @@ -2050,12 +2042,12 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new } else { logCtx.Infof("Update successful") } - return patchDuration + return patchMs } // autoSync will initiate a sync operation for an application configured with automated sync func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus *appv1.SyncStatus, resources []appv1.ResourceStatus, revisionUpdated bool) (*appv1.ApplicationCondition, time.Duration) { - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := getAppLog(app) ts := stats.NewTimingStats() defer func() { for k, v := range ts.Timings() { @@ -2064,7 +2056,7 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * logCtx = logCtx.WithField("time_ms", time.Since(ts.StartTime).Milliseconds()) logCtx.Debug("Finished auto sync") }() - if app.Spec.SyncPolicy == nil || !app.Spec.SyncPolicy.IsAutomatedSyncEnabled() { + if app.Spec.SyncPolicy == nil || app.Spec.SyncPolicy.Automated == nil { return nil, 0 } @@ -2183,7 +2175,7 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * ts.AddCheckpoint("set_app_operation_ms") setOpTime := time.Since(start) if err != nil { - if stderrors.Is(err, argo.ErrAnotherOperationInProgress) { + if goerrors.Is(err, argo.ErrAnotherOperationInProgress) { // skipping auto-sync because another operation is in progress and was not noticed due to stale data in informer // it is safe to skip auto-sync because it is already running logCtx.Warnf("Failed to initiate auto-sync to %s: %v", desiredCommitSHA, err) @@ -2192,8 +2184,9 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * logCtx.Errorf("Failed to initiate auto-sync to %s: %v", desiredCommitSHA, err) return &appv1.ApplicationCondition{Type: appv1.ApplicationConditionSyncError, Message: err.Error()}, setOpTime + } else { + ctrl.writeBackToInformer(updatedApp) } - ctrl.writeBackToInformer(updatedApp) ts.AddCheckpoint("write_back_to_informer_ms") var target string @@ -2203,7 +2196,7 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * target = desiredCommitSHA } message := fmt.Sprintf("Initiated automated sync to '%s'", target) - ctrl.logAppEvent(context.TODO(), app, argo.EventInfo{Reason: argo.EventReasonOperationStarted, Type: corev1.EventTypeNormal}, message) + ctrl.logAppEvent(app, argo.EventInfo{Reason: argo.EventReasonOperationStarted, Type: v1.EventTypeNormal}, message, context.TODO()) logCtx.Info(message) return nil, setOpTime } @@ -2220,23 +2213,24 @@ func alreadyAttemptedSync(app *appv1.Application, commitSHA string, commitSHAsMS return false, "" } } else { - log.WithFields(applog.GetAppLogFields(app)).Debugf("Skipping auto-sync: commitSHA %s has no changes", commitSHA) + log.WithField("application", app.Name).Debugf("Skipping auto-sync: commitSHA %s has no changes", commitSHA) } } else { if revisionUpdated { - log.WithFields(applog.GetAppLogFields(app)).Infof("Executing compare of syncResult.Revision and commitSha because manifest changed: %v", commitSHA) + log.WithField("application", app.Name).Infof("Executing compare of syncResult.Revision and commitSha because manifest changed: %v", commitSHA) if app.Status.OperationState.SyncResult.Revision != commitSHA { return false, "" } } else { - log.WithFields(applog.GetAppLogFields(app)).Debugf("Skipping auto-sync: commitSHA %s has no changes", commitSHA) + log.WithField("application", app.Name).Debugf("Skipping auto-sync: commitSHA %s has no changes", commitSHA) } } if hasMultipleSources { return reflect.DeepEqual(app.Spec.Sources, app.Status.OperationState.SyncResult.Sources), app.Status.OperationState.Phase + } else { + return reflect.DeepEqual(app.Spec.GetSource(), app.Status.OperationState.SyncResult.Source), app.Status.OperationState.Phase } - return reflect.DeepEqual(app.Spec.GetSource(), app.Status.OperationState.SyncResult.Source), app.Status.OperationState.Phase } func (ctrl *ApplicationController) shouldSelfHeal(app *appv1.Application, alreadyAttempted bool) (bool, time.Duration) { @@ -2285,7 +2279,7 @@ func (ctrl *ApplicationController) isAppNamespaceAllowed(app *appv1.Application) return app.Namespace == ctrl.namespace || glob.MatchStringInList(ctrl.applicationNamespaces, app.Namespace, glob.REGEXP) } -func (ctrl *ApplicationController) canProcessApp(obj any) bool { +func (ctrl *ApplicationController) canProcessApp(obj interface{}) bool { app, ok := obj.(*appv1.Application) if !ok { return false @@ -2299,7 +2293,7 @@ func (ctrl *ApplicationController) canProcessApp(obj any) bool { if annotations := app.GetAnnotations(); annotations != nil { if skipVal, ok := annotations[common.AnnotationKeyAppSkipReconcile]; ok { - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := getAppLog(app) if skipReconcile, err := strconv.ParseBool(skipVal); err == nil { if skipReconcile { logCtx.Debugf("Skipping Application reconcile based on annotation %s", common.AnnotationKeyAppSkipReconcile) @@ -2311,11 +2305,11 @@ func (ctrl *ApplicationController) canProcessApp(obj any) bool { } } - destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, ctrl.db) + cluster, err := ctrl.db.GetCluster(context.Background(), app.Spec.Destination.Server) if err != nil { return ctrl.clusterSharding.IsManagedCluster(nil) } - return ctrl.clusterSharding.IsManagedCluster(destCluster) + return ctrl.clusterSharding.IsManagedCluster(cluster) } func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.SharedIndexInformer, applisters.ApplicationLister) { @@ -2354,7 +2348,7 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar &appv1.Application{}, refreshTimeout, cache.Indexers{ - cache.NamespaceIndex: func(obj any) ([]string, error) { + cache.NamespaceIndex: func(obj interface{}) ([]string, error) { app, ok := obj.(*appv1.Application) if ok { // We only generally work with applications that are in one @@ -2364,15 +2358,23 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar // log an error. if _, err := ctrl.getAppProj(app); err != nil { ctrl.setAppCondition(app, ctrl.projectErrorToCondition(err, app)) - } else if _, err = argo.GetDestinationCluster(context.Background(), app.Spec.Destination, ctrl.db); err != nil { - ctrl.setAppCondition(app, appv1.ApplicationCondition{Type: appv1.ApplicationConditionInvalidSpecError, Message: err.Error()}) + } else { + // This call to 'ValidateDestination' ensures that the .spec.destination field of all Applications + // returned by the informer/lister will have server field set (if not already set) based on the name. + // (or, if not found, an error app condition) + + // If the server field is not set, set it based on the cluster name; if the cluster name can't be found, + // log an error as an App Condition. + if err := argo.ValidateDestination(context.Background(), &app.Spec.Destination, ctrl.db); err != nil { + ctrl.setAppCondition(app, appv1.ApplicationCondition{Type: appv1.ApplicationConditionInvalidSpecError, Message: err.Error()}) + } } } } return cache.MetaNamespaceIndexFunc(obj) }, - orphanedIndex: func(obj any) (i []string, e error) { + orphanedIndex: func(obj interface{}) (i []string, e error) { app, ok := obj.(*appv1.Application) if !ok { return nil, nil @@ -2396,7 +2398,7 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar lister := applisters.NewApplicationLister(informer.GetIndexer()) _, err := informer.AddEventHandler( cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj any) { + AddFunc: func(obj interface{}) { if !ctrl.canProcessApp(obj) { return } @@ -2409,7 +2411,7 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar ctrl.clusterSharding.AddApp(newApp) } }, - UpdateFunc: func(old, new any) { + UpdateFunc: func(old, new interface{}) { if !ctrl.canProcessApp(new) { return } @@ -2426,7 +2428,7 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar newApp, newOK := new.(*appv1.Application) if oldOK && newOK { if automatedSyncEnabled(oldApp, newApp) { - log.WithFields(applog.GetAppLogFields(newApp)).Info("Enabled automated sync") + getAppLog(newApp).Info("Enabled automated sync") compareWith = CompareWithLatest.Pointer() } if ctrl.statusRefreshJitter != 0 && oldApp.ResourceVersion == newApp.ResourceVersion { @@ -2445,7 +2447,7 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar } ctrl.clusterSharding.UpdateApp(newApp) }, - DeleteFunc: func(obj any) { + DeleteFunc: func(obj interface{}) { if !ctrl.canProcessApp(obj) { return } @@ -2471,7 +2473,7 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar func (ctrl *ApplicationController) projectErrorToCondition(err error, app *appv1.Application) appv1.ApplicationCondition { var condition appv1.ApplicationCondition - if apierrors.IsNotFound(err) { + if apierr.IsNotFound(err) { condition = appv1.ApplicationCondition{ Type: appv1.ApplicationConditionInvalidSpecError, Message: fmt.Sprintf("Application referencing project %s which does not exist", app.Spec.Project), @@ -2496,14 +2498,14 @@ func isOperationInProgress(app *appv1.Application) bool { func automatedSyncEnabled(oldApp *appv1.Application, newApp *appv1.Application) bool { oldEnabled := false oldSelfHealEnabled := false - if oldApp.Spec.SyncPolicy != nil && oldApp.Spec.SyncPolicy.IsAutomatedSyncEnabled() { + if oldApp.Spec.SyncPolicy != nil && oldApp.Spec.SyncPolicy.Automated != nil { oldEnabled = true oldSelfHealEnabled = oldApp.Spec.SyncPolicy.Automated.SelfHeal } newEnabled := false newSelfHealEnabled := false - if newApp.Spec.SyncPolicy != nil && newApp.Spec.SyncPolicy.IsAutomatedSyncEnabled() { + if newApp.Spec.SyncPolicy != nil && newApp.Spec.SyncPolicy.Automated != nil { newEnabled = true newSelfHealEnabled = newApp.Spec.SyncPolicy.Automated.SelfHeal } @@ -2526,8 +2528,9 @@ func (ctrl *ApplicationController) toAppKey(appName string) string { return ctrl.namespace + "/" + appName } else if strings.Contains(appName, "/") { return appName + } else { + return strings.ReplaceAll(appName, "_", "/") } - return strings.ReplaceAll(appName, "_", "/") } func (ctrl *ApplicationController) toAppQualifiedName(appName, appNamespace string) string { @@ -2556,8 +2559,8 @@ func (ctrl *ApplicationController) getAppList(options metav1.ListOptions) (*appv return appList, nil } -func (ctrl *ApplicationController) logAppEvent(ctx context.Context, a *appv1.Application, eventInfo argo.EventInfo, message string) { - eventLabels := argo.GetAppEventLabels(ctx, a, applisters.NewAppProjectLister(ctrl.projInformer.GetIndexer()), ctrl.namespace, ctrl.settingsMgr, ctrl.db) +func (ctrl *ApplicationController) logAppEvent(a *appv1.Application, eventInfo argo.EventInfo, message string, ctx context.Context) { + eventLabels := argo.GetAppEventLabels(a, applisters.NewAppProjectLister(ctrl.projInformer.GetIndexer()), ctrl.namespace, ctrl.settingsMgr, ctrl.db, ctx) ctrl.auditLogger.LogAppEvent(a, eventInfo, message, "", eventLabels) } diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index 8185b54628..9efe356245 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -19,18 +19,18 @@ import ( "k8s.io/client-go/rest" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/common" - statecache "github.com/argoproj/argo-cd/v3/controller/cache" - "github.com/argoproj/argo-cd/v3/controller/sharding" + "github.com/argoproj/argo-cd/v2/common" + statecache "github.com/argoproj/argo-cd/v2/controller/cache" + "github.com/argoproj/argo-cd/v2/controller/sharding" "github.com/argoproj/gitops-engine/pkg/cache/mocks" synccommon "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -40,21 +40,20 @@ import ( "k8s.io/client-go/tools/cache" "sigs.k8s.io/yaml" - dbmocks "github.com/argoproj/argo-cd/v3/util/db/mocks" + dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" - mockcommitclient "github.com/argoproj/argo-cd/v3/commitserver/apiclient/mocks" - mockstatecache "github.com/argoproj/argo-cd/v3/controller/cache/mocks" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - mockrepoclient "github.com/argoproj/argo-cd/v3/reposerver/apiclient/mocks" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/settings" - utilTest "github.com/argoproj/argo-cd/v3/util/test" + mockcommitclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient/mocks" + mockstatecache "github.com/argoproj/argo-cd/v2/controller/cache/mocks" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + "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() @@ -179,7 +178,6 @@ func newFakeControllerWithResync(data *fakeData, appResyncPeriod time.Duration, data.metricsCacheExpiration, []string{}, []string{}, - []string{}, 0, true, nil, @@ -211,7 +209,7 @@ func newFakeControllerWithResync(data *fakeData, appResyncPeriod time.Duration, ctrl.appStateManager.(*appStateManager).liveStateCache = &mockStateCache ctrl.stateCache = &mockStateCache mockStateCache.On("IsNamespaced", mock.Anything, mock.Anything).Return(true, nil) - mockStateCache.On("GetManagedLiveObjs", mock.Anything, mock.Anything, mock.Anything).Return(data.managedLiveObjs, nil) + mockStateCache.On("GetManagedLiveObjs", mock.Anything, mock.Anything).Return(data.managedLiveObjs, nil) mockStateCache.On("GetVersionsInfo", mock.Anything).Return("v1.2.3", nil, nil) response := make(map[kube.ResourceKey]v1alpha1.ResourceNode) for k, v := range data.namespacedResources { @@ -518,7 +516,7 @@ func newFakeMultiSourceApp() *v1alpha1.Application { func createFakeAppWithHealthAndTime(testApp string, status health.HealthStatusCode, timestamp metav1.Time) *v1alpha1.Application { app := createFakeApp(testApp) - app.Status.Health = v1alpha1.AppHealthStatus{ + app.Status.Health = v1alpha1.HealthStatus{ Status: status, LastTransitionTime: ×tamp, } @@ -542,8 +540,8 @@ func createFakeApp(testApp string) *v1alpha1.Application { return &app } -func newFakeCM() map[string]any { - var cm map[string]any +func newFakeCM() map[string]interface{} { + var cm map[string]interface{} err := yaml.Unmarshal([]byte(fakeStrayResource), &cm) if err != nil { panic(err) @@ -551,8 +549,8 @@ func newFakeCM() map[string]any { return cm } -func newFakePostDeleteHook() map[string]any { - var hook map[string]any +func newFakePostDeleteHook() map[string]interface{} { + var hook map[string]interface{} err := yaml.Unmarshal([]byte(fakePostDeleteHook), &hook) if err != nil { panic(err) @@ -560,8 +558,8 @@ func newFakePostDeleteHook() map[string]any { return hook } -func newFakeRoleBinding() map[string]any { - var roleBinding map[string]any +func newFakeRoleBinding() map[string]interface{} { + var roleBinding map[string]interface{} err := yaml.Unmarshal([]byte(fakeRoleBinding), &roleBinding) if err != nil { panic(err) @@ -569,8 +567,8 @@ func newFakeRoleBinding() map[string]any { return roleBinding } -func newFakeRole() map[string]any { - var role map[string]any +func newFakeRole() map[string]interface{} { + var role map[string]interface{} err := yaml.Unmarshal([]byte(fakeRole), &role) if err != nil { panic(err) @@ -578,8 +576,8 @@ func newFakeRole() map[string]any { return role } -func newFakeServiceAccount() map[string]any { - var serviceAccount map[string]any +func newFakeServiceAccount() map[string]interface{} { + var serviceAccount map[string]interface{} err := yaml.Unmarshal([]byte(fakeServiceAccount), &serviceAccount) if err != nil { panic(err) @@ -596,25 +594,7 @@ func TestAutoSync(t *testing.T) { } cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}}, true) assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) - require.NoError(t, err) - assert.NotNil(t, app.Operation) - assert.NotNil(t, app.Operation.Sync) - assert.False(t, app.Operation.Sync.Prune) -} - -func TestAutoSyncEnabledSetToTrue(t *testing.T) { - app := newFakeApp() - enable := true - app.Spec.SyncPolicy.Automated = &v1alpha1.SyncPolicyAutomated{Enabled: &enable} - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) - syncStatus := v1alpha1.SyncStatus{ - Status: v1alpha1.SyncStatusCodeOutOfSync, - Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - } - cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}}, true) - assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, app.Operation) assert.NotNil(t, app.Operation.Sync) @@ -635,7 +615,7 @@ func TestMultiSourceSelfHeal(t *testing.T) { } cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook-1", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}}, true) assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) require.NoError(t, err) assert.Nil(t, app.Operation) }) @@ -651,7 +631,7 @@ func TestMultiSourceSelfHeal(t *testing.T) { } cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook-1", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}}, true) assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, app.Operation) }) @@ -694,7 +674,7 @@ func TestSkipAutoSync(t *testing.T) { } cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}, true) assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) require.NoError(t, err) assert.Nil(t, app.Operation) }) @@ -709,7 +689,7 @@ func TestSkipAutoSync(t *testing.T) { } cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}, true) assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) require.NoError(t, err) assert.Nil(t, app.Operation) }) @@ -725,24 +705,7 @@ func TestSkipAutoSync(t *testing.T) { } cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}, true) assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) - require.NoError(t, err) - assert.Nil(t, app.Operation) - }) - - // Verify we skip when auto-sync is disabled - t.Run("AutoSyncEnableFieldIsSetFalse", func(t *testing.T) { - app := newFakeApp() - enable := false - app.Spec.SyncPolicy.Automated = &v1alpha1.SyncPolicyAutomated{Enabled: &enable} - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) - syncStatus := v1alpha1.SyncStatus{ - Status: v1alpha1.SyncStatusCodeOutOfSync, - Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - } - cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}, true) - assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) require.NoError(t, err) assert.Nil(t, app.Operation) }) @@ -759,7 +722,7 @@ func TestSkipAutoSync(t *testing.T) { } cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}, true) assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) require.NoError(t, err) assert.Nil(t, app.Operation) }) @@ -785,7 +748,7 @@ func TestSkipAutoSync(t *testing.T) { } cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}}, true) assert.NotNil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) require.NoError(t, err) assert.Nil(t, app.Operation) }) @@ -801,7 +764,7 @@ func TestSkipAutoSync(t *testing.T) { {Name: "guestbook", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync, RequiresPruning: true}, }, true) assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) require.NoError(t, err) assert.Nil(t, app.Operation) }) @@ -837,7 +800,7 @@ func TestAutoSyncIndicateError(t *testing.T) { } cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}}, true) assert.NotNil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) require.NoError(t, err) assert.Nil(t, app.Operation) } @@ -880,7 +843,7 @@ func TestAutoSyncParameterOverrides(t *testing.T) { } cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}}, true) assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(t.Context(), "my-app", metav1.GetOptions{}) + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, app.Operation) } @@ -918,11 +881,11 @@ func TestFinalizeAppDeletion(t *testing.T) { fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { return defaultReactor.React(action) }) - fakeAppCs.AddReactor("patch", "*", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true return true, &v1alpha1.Application{}, nil }) - err := ctrl.finalizeApplicationDeletion(app, func(_ string) ([]*v1alpha1.Cluster, error) { + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) require.NoError(t, err) @@ -970,16 +933,16 @@ func TestFinalizeAppDeletion(t *testing.T) { fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { return defaultReactor.React(action) }) - fakeAppCs.AddReactor("patch", "*", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true return true, &v1alpha1.Application{}, nil }) - err := ctrl.finalizeApplicationDeletion(app, func(_ string) ([]*v1alpha1.Cluster, error) { + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) require.NoError(t, err) assert.True(t, patched) - objsMap, err := ctrl.stateCache.GetManagedLiveObjs(&v1alpha1.Cluster{Server: "test", Name: "test"}, app, []*unstructured.Unstructured{}) + objsMap, err := ctrl.stateCache.GetManagedLiveObjs(app, []*unstructured.Unstructured{}) if err != nil { require.NoError(t, err) } @@ -1004,11 +967,11 @@ func TestFinalizeAppDeletion(t *testing.T) { fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { return defaultReactor.React(action) }) - fakeAppCs.AddReactor("patch", "*", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true return true, &v1alpha1.Application{}, nil }) - err := ctrl.finalizeApplicationDeletion(app, func(_ string) ([]*v1alpha1.Cluster, error) { + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) require.NoError(t, err) @@ -1032,7 +995,7 @@ func TestFinalizeAppDeletion(t *testing.T) { fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { return defaultReactor.React(action) }) - err := ctrl.finalizeApplicationDeletion(app, func(_ string) ([]*v1alpha1.Cluster, error) { + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) require.NoError(t, err) @@ -1071,11 +1034,11 @@ func TestFinalizeAppDeletion(t *testing.T) { fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { return defaultReactor.React(action) }) - fakeAppCs.AddReactor("patch", "*", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true return true, &v1alpha1.Application{}, nil }) - err := ctrl.finalizeApplicationDeletion(app, func(_ string) ([]*v1alpha1.Cluster, error) { + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) require.NoError(t, err) @@ -1091,8 +1054,8 @@ func TestFinalizeAppDeletion(t *testing.T) { app.SetPostDeleteFinalizer() app.Spec.Destination.Namespace = test.FakeArgoCDNamespace liveHook := &unstructured.Unstructured{Object: newFakePostDeleteHook()} - conditions := []any{ - map[string]any{ + conditions := []interface{}{ + map[string]interface{}{ "type": "Complete", "status": "True", }, @@ -1115,11 +1078,11 @@ func TestFinalizeAppDeletion(t *testing.T) { fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { return defaultReactor.React(action) }) - fakeAppCs.AddReactor("patch", "*", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true return true, &v1alpha1.Application{}, nil }) - err := ctrl.finalizeApplicationDeletion(app, func(_ string) ([]*v1alpha1.Cluster, error) { + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) require.NoError(t, err) @@ -1135,8 +1098,8 @@ func TestFinalizeAppDeletion(t *testing.T) { liveRole := &unstructured.Unstructured{Object: newFakeRole()} liveServiceAccount := &unstructured.Unstructured{Object: newFakeServiceAccount()} liveHook := &unstructured.Unstructured{Object: newFakePostDeleteHook()} - conditions := []any{ - map[string]any{ + conditions := []interface{}{ + map[string]interface{}{ "type": "Complete", "status": "True", }, @@ -1162,11 +1125,11 @@ func TestFinalizeAppDeletion(t *testing.T) { fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { return defaultReactor.React(action) }) - fakeAppCs.AddReactor("patch", "*", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true return true, &v1alpha1.Application{}, nil }) - err := ctrl.finalizeApplicationDeletion(app, func(_ string) ([]*v1alpha1.Cluster, error) { + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) require.NoError(t, err) @@ -1326,7 +1289,7 @@ func TestGetResourceTree_HasOrphanedResources(t *testing.T) { kube.NewResourceKey("apps", "Deployment", "default", "deploy2"): {ResourceNode: orphanedDeploy2}, }, }, nil) - tree, err := ctrl.getResourceTree(&v1alpha1.Cluster{Server: "https://localhost:6443", Name: "fake-cluster"}, app, []*v1alpha1.ResourceDiff{{ + tree, err := ctrl.getResourceTree(app, []*v1alpha1.ResourceDiff{{ Namespace: "default", Name: "nginx-deployment", Kind: "Deployment", @@ -1345,16 +1308,29 @@ func TestSetOperationStateOnDeletedApp(t *testing.T) { fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) fakeAppCs.ReactionChain = nil patched := false - fakeAppCs.AddReactor("patch", "*", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true - return true, &v1alpha1.Application{}, apierrors.NewNotFound(schema.GroupResource{}, "my-app") + return true, &v1alpha1.Application{}, apierr.NewNotFound(schema.GroupResource{}, "my-app") }) ctrl.setOperationState(newFakeApp(), &v1alpha1.OperationState{Phase: synccommon.OperationSucceeded}) assert.True(t, patched) } +type logHook struct { + entries []logrus.Entry +} + +func (h *logHook) Levels() []logrus.Level { + return []logrus.Level{logrus.WarnLevel} +} + +func (h *logHook) Fire(entry *logrus.Entry) error { + h.entries = append(h.entries, *entry) + return nil +} + func TestSetOperationStateLogRetries(t *testing.T) { - hook := utilTest.LogHook{} + hook := logHook{} logrus.AddHook(&hook) t.Cleanup(func() { logrus.StandardLogger().ReplaceHooks(logrus.LevelHooks{}) @@ -1363,7 +1339,7 @@ func TestSetOperationStateLogRetries(t *testing.T) { fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) fakeAppCs.ReactionChain = nil patched := false - fakeAppCs.AddReactor("patch", "*", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { if !patched { patched = true return true, &v1alpha1.Application{}, errors.New("fake error") @@ -1372,7 +1348,7 @@ func TestSetOperationStateLogRetries(t *testing.T) { }) ctrl.setOperationState(newFakeApp(), &v1alpha1.OperationState{Phase: synccommon.OperationSucceeded}) assert.True(t, patched) - assert.Contains(t, hook.Entries[0].Message, "fake error") + assert.Contains(t, hook.entries[0].Message, "fake error") } func TestNeedRefreshAppStatus(t *testing.T) { @@ -1698,7 +1674,7 @@ func TestUpdateReconciledAt(t *testing.T) { key, _ := cache.MetaNamespaceKeyFunc(app) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) fakeAppCs.ReactionChain = nil - receivedPatch := map[string]any{} + receivedPatch := map[string]interface{}{} fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { if patchAction, ok := action.(kubetesting.PatchAction); ok { require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) @@ -1707,7 +1683,7 @@ func TestUpdateReconciledAt(t *testing.T) { }) t.Run("UpdatedOnFullReconciliation", func(t *testing.T) { - receivedPatch = map[string]any{} + receivedPatch = map[string]interface{}{} ctrl.requestAppRefresh(app.Name, CompareWithLatest.Pointer(), nil) ctrl.appRefreshQueue.AddRateLimited(key) @@ -1723,7 +1699,7 @@ func TestUpdateReconciledAt(t *testing.T) { }) t.Run("NotUpdatedOnPartialReconciliation", func(t *testing.T) { - receivedPatch = map[string]any{} + receivedPatch = map[string]interface{}{} ctrl.appRefreshQueue.AddRateLimited(key) ctrl.requestAppRefresh(app.Name, CompareWithRecent.Pointer(), nil) @@ -1740,7 +1716,7 @@ func TestUpdateReconciledAt(t *testing.T) { } func TestUpdateHealthStatusTransitionTime(t *testing.T) { - deployment := kube.MustToUnstructured(&appsv1.Deployment{ + deployment := kube.MustToUnstructured(&v1.Deployment{ TypeMeta: metav1.TypeMeta{ APIVersion: "apps/v1", Kind: "Deployment", @@ -1842,7 +1818,7 @@ apps/Deployment: func TestUpdateHealthStatusProgression(t *testing.T) { app := newFakeAppWithHealthAndTime(health.HealthStatusDegraded, testTimestamp) - deployment := kube.MustToUnstructured(&appsv1.Deployment{ + deployment := kube.MustToUnstructured(&v1.Deployment{ TypeMeta: metav1.TypeMeta{ APIVersion: "apps/v1", Kind: "Deployment", @@ -1851,7 +1827,7 @@ func TestUpdateHealthStatusProgression(t *testing.T) { Name: "demo", Namespace: "default", }, - Status: appsv1.DeploymentStatus{ + Status: v1.DeploymentStatus{ ObservedGeneration: 0, }, }) @@ -1862,7 +1838,7 @@ apps/Deployment: hs = {} hs.status = "" hs.message = "" - + if obj.metadata ~= nil then if obj.metadata.labels ~= nil then current_status = obj.metadata.labels["status"] @@ -1979,7 +1955,7 @@ func TestFinalizeProjectDeletion_HasApplications(t *testing.T) { fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) patched := false - fakeAppCs.PrependReactor("patch", "*", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true return true, &v1alpha1.Application{}, nil }) @@ -1994,7 +1970,7 @@ func TestFinalizeProjectDeletion_DoesNotHaveApplications(t *testing.T) { ctrl := newFakeController(&fakeData{apps: []runtime.Object{&defaultProj}}, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) - receivedPatch := map[string]any{} + receivedPatch := map[string]interface{}{} fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { if patchAction, ok := action.(kubetesting.PatchAction); ok { require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) @@ -2004,8 +1980,8 @@ func TestFinalizeProjectDeletion_DoesNotHaveApplications(t *testing.T) { err := ctrl.finalizeProjectDeletion(proj) require.NoError(t, err) - assert.Equal(t, map[string]any{ - "metadata": map[string]any{ + assert.Equal(t, map[string]interface{}{ + "metadata": map[string]interface{}{ "finalizers": nil, }, }, receivedPatch) @@ -2019,7 +1995,7 @@ func TestProcessRequestedAppOperation_FailedNoRetries(t *testing.T) { } ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) - receivedPatch := map[string]any{} + receivedPatch := map[string]interface{}{} fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { if patchAction, ok := action.(kubetesting.PatchAction); ok { require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) @@ -2044,7 +2020,7 @@ func TestProcessRequestedAppOperation_InvalidDestination(t *testing.T) { proj.Spec.SourceNamespaces = []string{test.FakeArgoCDNamespace} ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &proj}}, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) - receivedPatch := map[string]any{} + receivedPatch := map[string]interface{}{} func() { fakeAppCs.Lock() defer fakeAppCs.Unlock() @@ -2073,7 +2049,7 @@ func TestProcessRequestedAppOperation_FailedHasRetries(t *testing.T) { } ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) - receivedPatch := map[string]any{} + receivedPatch := map[string]interface{}{} fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { if patchAction, ok := action.(kubetesting.PatchAction); ok { require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) @@ -2086,7 +2062,7 @@ func TestProcessRequestedAppOperation_FailedHasRetries(t *testing.T) { phase, _, _ := unstructured.NestedString(receivedPatch, "status", "operationState", "phase") assert.Equal(t, string(synccommon.OperationRunning), phase) message, _, _ := unstructured.NestedString(receivedPatch, "status", "operationState", "message") - assert.Contains(t, message, "Retrying attempt #1") + assert.Contains(t, message, "due to application controller sync timeout. Retrying attempt #1") retryCount, _, _ := unstructured.NestedFloat64(receivedPatch, "status", "operationState", "retryCount") assert.InEpsilon(t, float64(1), retryCount, 0.0001) } @@ -2116,7 +2092,7 @@ func TestProcessRequestedAppOperation_RunningPreviouslyFailed(t *testing.T) { } ctrl := newFakeController(data, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) - receivedPatch := map[string]any{} + receivedPatch := map[string]interface{}{} fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { if patchAction, ok := action.(kubetesting.PatchAction); ok { require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) @@ -2149,7 +2125,7 @@ func TestProcessRequestedAppOperation_HasRetriesTerminated(t *testing.T) { } ctrl := newFakeController(data, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) - receivedPatch := map[string]any{} + receivedPatch := map[string]interface{}{} fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { if patchAction, ok := action.(kubetesting.PatchAction); ok { require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) @@ -2176,7 +2152,7 @@ func TestProcessRequestedAppOperation_Successful(t *testing.T) { }}, }, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) - receivedPatch := map[string]any{} + receivedPatch := map[string]interface{}{} fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { if patchAction, ok := action.(kubetesting.PatchAction); ok { require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) @@ -2234,7 +2210,7 @@ func TestGetAppHosts(t *testing.T) { })).Return(nil) ctrl.stateCache = mockStateCache - hosts, err := ctrl.getAppHosts(&v1alpha1.Cluster{Server: "test", Name: "test"}, app, []v1alpha1.ResourceNode{{ + hosts, err := ctrl.getAppHosts(app, []v1alpha1.ResourceNode{{ ResourceRef: v1alpha1.ResourceRef{Name: "pod1", Namespace: "default", Kind: kube.PodKind}, Info: []v1alpha1.InfoItem{{ Name: "Host", @@ -2319,7 +2295,7 @@ func Test_canProcessAppSkipReconcileAnnotation(t *testing.T) { ctrl := newFakeController(&fakeData{}, nil) tests := []struct { name string - input any + input interface{} expected bool }{ {"No skip reconcile annotation", newFakeApp(), true}, @@ -2368,7 +2344,7 @@ func TestAddControllerNamespace(t *testing.T) { ctrl.processAppRefreshQueueItem() - updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(ctrl.namespace).Get(t.Context(), app.Name, metav1.GetOptions{}) + updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(ctrl.namespace).Get(context.Background(), app.Name, metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, test.FakeArgoCDNamespace, updatedApp.Status.ControllerNamespace) }) @@ -2376,7 +2352,7 @@ func TestAddControllerNamespace(t *testing.T) { appNamespace := "app-namespace" app := newFakeApp() - app.Namespace = appNamespace + app.ObjectMeta.Namespace = appNamespace proj := defaultProj proj.Spec.SourceNamespaces = []string{appNamespace} ctrl := newFakeController(&fakeData{ @@ -2387,7 +2363,7 @@ func TestAddControllerNamespace(t *testing.T) { ctrl.processAppRefreshQueueItem() - updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(appNamespace).Get(t.Context(), app.Name, metav1.GetOptions{}) + updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(appNamespace).Get(context.Background(), app.Name, metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, test.FakeArgoCDNamespace, updatedApp.Status.ControllerNamespace) }) @@ -2399,7 +2375,7 @@ func TestHelmValuesObjectHasReplaceStrategy(t *testing.T) { Source: v1alpha1.ApplicationSource{ Helm: &v1alpha1.ApplicationSourceHelm{ ValuesObject: &runtime.RawExtension{ - Object: &unstructured.Unstructured{Object: map[string]any{"key": []string{"value"}}}, + Object: &unstructured.Unstructured{Object: map[string]interface{}{"key": []string{"value"}}}, }, }, }, @@ -2411,7 +2387,7 @@ func TestHelmValuesObjectHasReplaceStrategy(t *testing.T) { Source: v1alpha1.ApplicationSource{ Helm: &v1alpha1.ApplicationSourceHelm{ ValuesObject: &runtime.RawExtension{ - Object: &unstructured.Unstructured{Object: map[string]any{"key": []string{"value-modified1"}}}, + Object: &unstructured.Unstructured{Object: map[string]interface{}{"key": []string{"value-modified1"}}}, }, }, }, @@ -2446,7 +2422,7 @@ func TestAppStatusIsReplaced(t *testing.T) { require.NoError(t, err) require.True(t, ok) - patchObj := map[string]any{} + patchObj := map[string]interface{}{} require.NoError(t, json.Unmarshal(patchData, &patchObj)) val, has, err := unstructured.NestedFieldNoCopy(patchObj, "sync", "comparedTo", "destination", "server") @@ -2718,7 +2694,7 @@ func TestSyncTimeout(t *testing.T) { } ctrl.processRequestedAppOperation(app) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.ObjectMeta.Namespace).Get(t.Context(), app.Name, metav1.GetOptions{}) + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.ObjectMeta.Namespace).Get(context.Background(), app.ObjectMeta.Name, metav1.GetOptions{}) require.NoError(t, err) require.Equal(t, tc.expectedPhase, app.Status.OperationState.Phase) require.Equal(t, tc.expectedMessage, app.Status.OperationState.Message) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 99f85d50bb..73a8d0bc60 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -20,8 +20,8 @@ import ( "github.com/argoproj/gitops-engine/pkg/utils/kube" log "github.com/sirupsen/logrus" "golang.org/x/sync/semaphore" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/api/core/v1" + kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" @@ -29,17 +29,17 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" - "github.com/argoproj/argo-cd/v3/controller/metrics" - "github.com/argoproj/argo-cd/v3/controller/sharding" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/env" - logutils "github.com/argoproj/argo-cd/v3/util/log" - "github.com/argoproj/argo-cd/v3/util/lua" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/controller/metrics" + "github.com/argoproj/argo-cd/v2/controller/sharding" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/env" + logutils "github.com/argoproj/argo-cd/v2/util/log" + "github.com/argoproj/argo-cd/v2/util/lua" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( @@ -108,10 +108,10 @@ var ( clusterCacheAttemptLimit int32 = 1 // clusterCacheRetryUseBackoff specifies whether to use a backoff strategy on cluster cache sync, if retry is enabled - clusterCacheRetryUseBackoff = false + clusterCacheRetryUseBackoff bool = false // clusterCacheBatchEventsProcessing specifies whether to enable batch events processing - clusterCacheBatchEventsProcessing = false + clusterCacheBatchEventsProcessing bool = false // clusterCacheEventsProcessingInterval specifies the interval between processing events when BatchEventsProcessing is enabled clusterCacheEventsProcessingInterval = 100 * time.Millisecond @@ -126,49 +126,47 @@ func init() { clusterCacheListSemaphoreSize = env.ParseInt64FromEnv(EnvClusterCacheListSemaphore, clusterCacheListSemaphoreSize, 0, math.MaxInt64) clusterCacheAttemptLimit = int32(env.ParseNumFromEnv(EnvClusterCacheAttemptLimit, int(clusterCacheAttemptLimit), 1, math.MaxInt32)) clusterCacheRetryUseBackoff = env.ParseBoolFromEnv(EnvClusterCacheRetryUseBackoff, false) - clusterCacheBatchEventsProcessing = env.ParseBoolFromEnv(EnvClusterCacheBatchEventsProcessing, true) + clusterCacheBatchEventsProcessing = env.ParseBoolFromEnv(EnvClusterCacheBatchEventsProcessing, false) clusterCacheEventsProcessingInterval = env.ParseDurationFromEnv(EnvClusterCacheEventsProcessingInterval, clusterCacheEventsProcessingInterval, 0, math.MaxInt64) } type LiveStateCache interface { // Returns k8s server version - GetVersionsInfo(server *appv1.Cluster) (string, []kube.APIResourceInfo, error) + GetVersionsInfo(serverURL string) (string, []kube.APIResourceInfo, error) // Returns true of given group kind is a namespaced resource - IsNamespaced(server *appv1.Cluster, gk schema.GroupKind) (bool, error) + IsNamespaced(server string, gk schema.GroupKind) (bool, error) // Returns synced cluster cache - GetClusterCache(server *appv1.Cluster) (clustercache.ClusterCache, error) + GetClusterCache(server string) (clustercache.ClusterCache, error) // Executes give callback against resource specified by the key and all its children - IterateHierarchy(server *appv1.Cluster, key kube.ResourceKey, action func(child appv1.ResourceNode, appName string) bool) error + IterateHierarchy(server string, key kube.ResourceKey, action func(child appv1.ResourceNode, appName string) bool) error // Executes give callback against resources specified by the keys and all its children - IterateHierarchyV2(server *appv1.Cluster, keys []kube.ResourceKey, action func(child appv1.ResourceNode, appName string) bool) error + IterateHierarchyV2(server string, keys []kube.ResourceKey, action func(child appv1.ResourceNode, appName string) bool) error // Returns state of live nodes which correspond for target nodes of specified application. - GetManagedLiveObjs(destCluster *appv1.Cluster, a *appv1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error) + GetManagedLiveObjs(a *appv1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error) // IterateResources iterates all resource stored in cache - IterateResources(server *appv1.Cluster, callback func(res *clustercache.Resource, info *ResourceInfo)) error + IterateResources(server string, callback func(res *clustercache.Resource, info *ResourceInfo)) error // Returns all top level resources (resources without owner references) of a specified namespace - GetNamespaceTopLevelResources(server *appv1.Cluster, namespace string) (map[kube.ResourceKey]appv1.ResourceNode, error) + GetNamespaceTopLevelResources(server string, namespace string) (map[kube.ResourceKey]appv1.ResourceNode, error) // Starts watching resources of each controlled cluster. Run(ctx context.Context) error // Returns information about monitored clusters GetClustersInfo() []clustercache.ClusterInfo // Init must be executed before cache can be used Init() error - // UpdateShard will update the shard of ClusterSharding when the shard has changed. - UpdateShard(shard int) bool } -type ObjectUpdatedHandler = func(managedByApp map[string]bool, ref corev1.ObjectReference) +type ObjectUpdatedHandler = func(managedByApp map[string]bool, ref v1.ObjectReference) type PodInfo struct { NodeName string - ResourceRequests corev1.ResourceList - Phase corev1.PodPhase + ResourceRequests v1.ResourceList + Phase v1.PodPhase } type NodeInfo struct { Name string - Capacity corev1.ResourceList - SystemInfo corev1.NodeSystemInfo + Capacity v1.ResourceList + SystemInfo v1.NodeSystemInfo } type ResourceInfo struct { @@ -242,10 +240,6 @@ func (c *liveStateCache) loadCacheSettings() (*cacheSettings, error) { if err != nil { return nil, err } - trackingMethod, err := c.settingsMgr.GetTrackingMethod() - if err != nil { - return nil, err - } installationID, err := c.settingsMgr.GetInstallationID() if err != nil { return nil, err @@ -271,7 +265,7 @@ func (c *liveStateCache) loadCacheSettings() (*cacheSettings, error) { ResourcesFilter: resourcesFilter, } - return &cacheSettings{clusterSettings, appInstanceLabelKey, appv1.TrackingMethod(trackingMethod), installationID, resourceUpdatesOverrides, ignoreResourceUpdatesEnabled}, nil + return &cacheSettings{clusterSettings, appInstanceLabelKey, argo.GetTrackingMethod(c.settingsMgr), installationID, resourceUpdatesOverrides, ignoreResourceUpdatesEnabled}, nil } func asResourceNode(r *clustercache.Resource) appv1.ResourceNode { @@ -282,14 +276,8 @@ func asResourceNode(r *clustercache.Resource) appv1.ResourceNode { parentRefs := make([]appv1.ResourceRef, len(r.OwnerRefs)) for i, ownerRef := range r.OwnerRefs { ownerGvk := schema.FromAPIVersionAndKind(ownerRef.APIVersion, ownerRef.Kind) - parentRefs[i] = appv1.ResourceRef{ - Group: ownerGvk.Group, - Kind: ownerGvk.Kind, - Version: ownerGvk.Version, - Namespace: r.Ref.Namespace, - Name: ownerRef.Name, - UID: string(ownerRef.UID), - } + ownerKey := kube.NewResourceKey(ownerGvk.Group, ownerRef.Kind, r.Ref.Namespace, ownerRef.Name) + parentRefs[i] = appv1.ResourceRef{Name: ownerRef.Name, Kind: ownerKey.Kind, Namespace: r.Ref.Namespace, Group: ownerKey.Group, UID: string(ownerRef.UID)} } var resHealth *appv1.HealthStatus resourceInfo := resInfo(r) @@ -341,11 +329,12 @@ func ownerRefGV(ownerRef metav1.OwnerReference) schema.GroupVersion { } func getAppRecursive(r *clustercache.Resource, ns map[kube.ResourceKey]*clustercache.Resource, visited map[kube.ResourceKey]bool) (string, bool) { - if visited[r.ResourceKey()] { + if !visited[r.ResourceKey()] { + visited[r.ResourceKey()] = true + } else { log.Warnf("Circular dependency detected: %v.", visited) return resInfo(r).AppName, false } - visited[r.ResourceKey()] = true if resInfo(r).AppName != "" { return resInfo(r).AppName, true @@ -353,11 +342,11 @@ func getAppRecursive(r *clustercache.Resource, ns map[kube.ResourceKey]*clusterc for _, ownerRef := range r.OwnerRefs { gv := ownerRefGV(ownerRef) if parent, ok := ns[kube.NewResourceKey(gv.Group, ownerRef.Kind, r.Ref.Namespace, ownerRef.Name)]; ok { - visitedBranch := make(map[kube.ResourceKey]bool, len(visited)) + visited_branch := make(map[kube.ResourceKey]bool, len(visited)) for k, v := range visited { - visitedBranch[k] = v + visited_branch[k] = v } - app, ok := getAppRecursive(parent, ns, visitedBranch) + app, ok := getAppRecursive(parent, ns, visited_branch) if app != "" || !ok { return app, ok } @@ -420,14 +409,14 @@ func isRetryableError(err error) bool { if err == nil { return false } - return apierrors.IsInternalError(err) || - apierrors.IsInvalid(err) || - apierrors.IsTooManyRequests(err) || - apierrors.IsServerTimeout(err) || - apierrors.IsServiceUnavailable(err) || - apierrors.IsTimeout(err) || - apierrors.IsUnexpectedObjectError(err) || - apierrors.IsUnexpectedServerError(err) || + return kerrors.IsInternalError(err) || + kerrors.IsInvalid(err) || + kerrors.IsTooManyRequests(err) || + kerrors.IsServerTimeout(err) || + kerrors.IsServiceUnavailable(err) || + kerrors.IsTimeout(err) || + kerrors.IsUnexpectedObjectError(err) || + kerrors.IsUnexpectedServerError(err) || isResourceQuotaConflictErr(err) || isTransientNetworkErr(err) || isExceededQuotaErr(err) || @@ -440,16 +429,17 @@ func isHTTP2GoawayErr(err error) bool { } func isExceededQuotaErr(err error) bool { - return apierrors.IsForbidden(err) && strings.Contains(err.Error(), "exceeded quota") + return kerrors.IsForbidden(err) && strings.Contains(err.Error(), "exceeded quota") } func isResourceQuotaConflictErr(err error) bool { - return apierrors.IsConflict(err) && strings.Contains(err.Error(), "Operation cannot be fulfilled on resourcequota") + return kerrors.IsConflict(err) && strings.Contains(err.Error(), "Operation cannot be fulfilled on resourcequota") } func isTransientNetworkErr(err error) bool { var netErr net.Error - if errors.As(err, &netErr) { + switch { + case errors.As(err, &netErr): var dnsErr *net.DNSError var opErr *net.OpError var unknownNetworkErr net.UnknownNetworkError @@ -478,9 +468,9 @@ func isTransientNetworkErr(err error) bool { return false } -func (c *liveStateCache) getCluster(cluster *appv1.Cluster) (clustercache.ClusterCache, error) { +func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, error) { c.lock.RLock() - clusterCache, ok := c.clusters[cluster.Server] + clusterCache, ok := c.clusters[server] cacheSettings := c.cacheSettings c.lock.RUnlock() @@ -491,11 +481,16 @@ func (c *liveStateCache) getCluster(cluster *appv1.Cluster) (clustercache.Cluste c.lock.Lock() defer c.lock.Unlock() - clusterCache, ok = c.clusters[cluster.Server] + clusterCache, ok = c.clusters[server] if ok { return clusterCache, nil } + cluster, err := c.db.GetCluster(context.Background(), server) + if err != nil { + return nil, fmt.Errorf("error getting cluster: %w", err) + } + if c.clusterSharding == nil { return nil, fmt.Errorf("unable to handle cluster %s: cluster sharding is not configured", cluster.Server) } @@ -541,7 +536,7 @@ func (c *liveStateCache) getCluster(cluster *appv1.Cluster) (clustercache.Cluste clustercache.SetSettings(cacheSettings.clusterSettings), clustercache.SetNamespaces(cluster.Namespaces), clustercache.SetClusterResources(cluster.ClusterResources), - clustercache.SetPopulateResourceInfoHandler(func(un *unstructured.Unstructured, isRoot bool) (any, bool) { + clustercache.SetPopulateResourceInfoHandler(func(un *unstructured.Unstructured, isRoot bool) (interface{}, bool) { res := &ResourceInfo{} populateNodeInfo(un, res, resourceCustomLabels) c.lock.RLock() @@ -581,7 +576,7 @@ func (c *liveStateCache) getCluster(cluster *appv1.Cluster) (clustercache.Cluste _ = clusterCache.OnResourceUpdated(func(newRes *clustercache.Resource, oldRes *clustercache.Resource, namespaceResources map[kube.ResourceKey]*clustercache.Resource) { toNotify := make(map[string]bool) - var ref corev1.ObjectReference + var ref v1.ObjectReference if newRes != nil { ref = newRes.Ref } else { @@ -624,7 +619,7 @@ func (c *liveStateCache) getCluster(cluster *appv1.Cluster) (clustercache.Cluste c.onObjectUpdated(toNotify, ref) }) - _ = clusterCache.OnEvent(func(_ watch.EventType, un *unstructured.Unstructured) { + _ = clusterCache.OnEvent(func(event watch.EventType, un *unstructured.Unstructured) { gvk := un.GroupVersionKind() c.metricsServer.IncClusterEventsCount(cluster.Server, gvk.Group, gvk.Kind) }) @@ -633,12 +628,12 @@ func (c *liveStateCache) getCluster(cluster *appv1.Cluster) (clustercache.Cluste c.metricsServer.ObserveResourceEventsProcessingDuration(cluster.Server, duration, processedEventsNumber) }) - c.clusters[cluster.Server] = clusterCache + c.clusters[server] = clusterCache return clusterCache, nil } -func (c *liveStateCache) getSyncedCluster(server *appv1.Cluster) (clustercache.ClusterCache, error) { +func (c *liveStateCache) getSyncedCluster(server string) (clustercache.ClusterCache, error) { clusterCache, err := c.getCluster(server) if err != nil { return nil, fmt.Errorf("error getting cluster: %w", err) @@ -663,7 +658,7 @@ func (c *liveStateCache) invalidate(cacheSettings cacheSettings) { log.Info("live state cache invalidated") } -func (c *liveStateCache) IsNamespaced(server *appv1.Cluster, gk schema.GroupKind) (bool, error) { +func (c *liveStateCache) IsNamespaced(server string, gk schema.GroupKind) (bool, error) { clusterInfo, err := c.getSyncedCluster(server) if err != nil { return false, err @@ -671,7 +666,7 @@ func (c *liveStateCache) IsNamespaced(server *appv1.Cluster, gk schema.GroupKind return clusterInfo.IsNamespaced(gk) } -func (c *liveStateCache) IterateHierarchy(server *appv1.Cluster, key kube.ResourceKey, action func(child appv1.ResourceNode, appName string) bool) error { +func (c *liveStateCache) IterateHierarchy(server string, key kube.ResourceKey, action func(child appv1.ResourceNode, appName string) bool) error { clusterInfo, err := c.getSyncedCluster(server) if err != nil { return err @@ -682,7 +677,7 @@ func (c *liveStateCache) IterateHierarchy(server *appv1.Cluster, key kube.Resour return nil } -func (c *liveStateCache) IterateHierarchyV2(server *appv1.Cluster, keys []kube.ResourceKey, action func(child appv1.ResourceNode, appName string) bool) error { +func (c *liveStateCache) IterateHierarchyV2(server string, keys []kube.ResourceKey, action func(child appv1.ResourceNode, appName string) bool) error { clusterInfo, err := c.getSyncedCluster(server) if err != nil { return err @@ -693,7 +688,7 @@ func (c *liveStateCache) IterateHierarchyV2(server *appv1.Cluster, keys []kube.R return nil } -func (c *liveStateCache) IterateResources(server *appv1.Cluster, callback func(res *clustercache.Resource, info *ResourceInfo)) error { +func (c *liveStateCache) IterateResources(server string, callback func(res *clustercache.Resource, info *ResourceInfo)) error { clusterInfo, err := c.getSyncedCluster(server) if err != nil { return err @@ -707,7 +702,7 @@ func (c *liveStateCache) IterateResources(server *appv1.Cluster, callback func(r return nil } -func (c *liveStateCache) GetNamespaceTopLevelResources(server *appv1.Cluster, namespace string) (map[kube.ResourceKey]appv1.ResourceNode, error) { +func (c *liveStateCache) GetNamespaceTopLevelResources(server string, namespace string) (map[kube.ResourceKey]appv1.ResourceNode, error) { clusterInfo, err := c.getSyncedCluster(server) if err != nil { return nil, err @@ -720,36 +715,35 @@ func (c *liveStateCache) GetNamespaceTopLevelResources(server *appv1.Cluster, na return res, nil } -func (c *liveStateCache) GetManagedLiveObjs(destCluster *appv1.Cluster, a *appv1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error) { - clusterInfo, err := c.getSyncedCluster(destCluster) +func (c *liveStateCache) GetManagedLiveObjs(a *appv1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error) { + clusterInfo, err := c.getSyncedCluster(a.Spec.Destination.Server) if err != nil { - return nil, fmt.Errorf("failed to get cluster info for %q: %w", destCluster.Server, err) + return nil, fmt.Errorf("failed to get cluster info for %q: %w", a.Spec.Destination.Server, err) } return clusterInfo.GetManagedLiveObjs(targetObjs, func(r *clustercache.Resource) bool { return resInfo(r).AppName == a.InstanceName(c.settingsMgr.GetNamespace()) }) } -func (c *liveStateCache) GetVersionsInfo(server *appv1.Cluster) (string, []kube.APIResourceInfo, error) { - clusterInfo, err := c.getSyncedCluster(server) +func (c *liveStateCache) GetVersionsInfo(serverURL string) (string, []kube.APIResourceInfo, error) { + clusterInfo, err := c.getSyncedCluster(serverURL) if err != nil { - return "", nil, fmt.Errorf("failed to get cluster info for %q: %w", server.Server, err) + return "", nil, fmt.Errorf("failed to get cluster info for %q: %w", serverURL, err) } return clusterInfo.GetServerVersion(), clusterInfo.GetAPIResources(), nil } -func (c *liveStateCache) isClusterHasApps(apps []any, cluster *appv1.Cluster) bool { +func (c *liveStateCache) isClusterHasApps(apps []interface{}, cluster *appv1.Cluster) bool { for _, obj := range apps { app, ok := obj.(*appv1.Application) if !ok { continue } - destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, c.db) + err := argo.ValidateDestination(context.Background(), &app.Spec.Destination, c.db) if err != nil { - log.Warnf("Failed to get destination cluster: %v", err) continue } - if destCluster.Server == cluster.Server { + if app.Spec.Destination.Server == cluster.Server { return true } } @@ -833,7 +827,7 @@ func (c *liveStateCache) handleAddEvent(cluster *appv1.Cluster) { if c.isClusterHasApps(c.appInformer.GetStore().List(), cluster) { go func() { // warm up cache for cluster with apps - _, _ = c.getSyncedCluster(cluster) + _, _ = c.getSyncedCluster(cluster.Server) }() } } @@ -915,11 +909,6 @@ func (c *liveStateCache) GetClustersInfo() []clustercache.ClusterInfo { return res } -func (c *liveStateCache) GetClusterCache(server *appv1.Cluster) (clustercache.ClusterCache, error) { +func (c *liveStateCache) GetClusterCache(server string) (clustercache.ClusterCache, error) { return c.getSyncedCluster(server) } - -// UpdateShard will update the shard of ClusterSharding when the shard has changed. -func (c *liveStateCache) UpdateShard(shard int) bool { - return c.clusterSharding.UpdateShard(shard) -} diff --git a/controller/cache/cache_test.go b/controller/cache/cache_test.go index 006f5108da..652b4b5549 100644 --- a/controller/cache/cache_test.go +++ b/controller/cache/cache_test.go @@ -1,6 +1,7 @@ package cache import ( + "context" "errors" "net" "net/url" @@ -8,12 +9,11 @@ import ( "testing" "time" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/api/core/v1" + apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -24,13 +24,13 @@ import ( "github.com/stretchr/testify/mock" "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/controller/metrics" - "github.com/argoproj/argo-cd/v3/controller/sharding" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - dbmocks "github.com/argoproj/argo-cd/v3/util/db/mocks" - argosettings "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/controller/metrics" + "github.com/argoproj/argo-cd/v2/controller/sharding" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" + argosettings "github.com/argoproj/argo-cd/v2/util/settings" ) type netError string @@ -39,7 +39,7 @@ func (n netError) Error() string { return string(n) } func (n netError) Timeout() bool { return false } func (n netError) Temporary() bool { return false } -func TestHandleModEvent_HasChanges(_ *testing.T) { +func TestHandleModEvent_HasChanges(t *testing.T) { clusterCache := &mocks.ClusterCache{} clusterCache.On("Invalidate", mock.Anything, mock.Anything).Return(nil).Once() clusterCache.On("EnsureSynced").Return(nil).Once() @@ -71,7 +71,7 @@ func TestHandleModEvent_ClusterExcluded(t *testing.T) { clustersCache := liveStateCache{ db: nil, appInformer: nil, - onObjectUpdated: func(_ map[string]bool, _ corev1.ObjectReference) { + onObjectUpdated: func(managedByApp map[string]bool, ref v1.ObjectReference) { }, kubectl: nil, settingsMgr: &argosettings.SettingsManager{}, @@ -96,7 +96,7 @@ func TestHandleModEvent_ClusterExcluded(t *testing.T) { assert.Len(t, clustersCache.clusters, 1) } -func TestHandleModEvent_NoChanges(_ *testing.T) { +func TestHandleModEvent_NoChanges(t *testing.T) { clusterCache := &mocks.ClusterCache{} clusterCache.On("Invalidate", mock.Anything).Panic("should not invalidate") clusterCache.On("EnsureSynced").Return(nil).Panic("should not re-sync") @@ -141,7 +141,7 @@ func TestHandleDeleteEvent_CacheDeadlock(t *testing.T) { db := &dbmocks.ArgoDB{} db.On("GetApplicationControllerReplicas").Return(1) fakeClient := fake.NewClientset() - settingsMgr := argosettings.NewSettingsManager(t.Context(), fakeClient, "argocd") + settingsMgr := argosettings.NewSettingsManager(context.TODO(), fakeClient, "argocd") liveStateCacheLock := sync.RWMutex{} gitopsEngineClusterCache := &mocks.ClusterCache{} clustersCache := liveStateCache{ @@ -151,7 +151,7 @@ func TestHandleDeleteEvent_CacheDeadlock(t *testing.T) { clusterSharding: sharding.NewClusterSharding(db, 0, 1, common.DefaultShardingAlgorithm), settingsMgr: settingsMgr, // Set the lock here so we can reference it later - //nolint:govet // We need to overwrite here to have access to the lock + // nolint We need to overwrite here to have access to the lock lock: liveStateCacheLock, } channel := make(chan string) @@ -173,7 +173,7 @@ func TestHandleDeleteEvent_CacheDeadlock(t *testing.T) { handleDeleteWasCalled.Lock() engineHoldsEngineLock.Lock() - gitopsEngineClusterCache.On("EnsureSynced").Run(func(_ mock.Arguments) { + gitopsEngineClusterCache.On("EnsureSynced").Run(func(args mock.Arguments) { gitopsEngineClusterCacheLock.Lock() t.Log("EnsureSynced: Engine has engine lock") engineHoldsEngineLock.Unlock() @@ -187,7 +187,7 @@ func TestHandleDeleteEvent_CacheDeadlock(t *testing.T) { ensureSyncedCompleted.Unlock() }).Return(nil).Once() - gitopsEngineClusterCache.On("Invalidate").Run(func(_ mock.Arguments) { + gitopsEngineClusterCache.On("Invalidate").Run(func(args mock.Arguments) { // Allow EnsureSynced to continue now that we're in the deadlock condition handleDeleteWasCalled.Unlock() // Wait until gitops engine holds the gitops lock @@ -238,15 +238,15 @@ func TestIsRetryableError(t *testing.T) { assert.False(t, isRetryableError(nil)) }) t.Run("ResourceQuotaConflictErr", func(t *testing.T) { - assert.False(t, isRetryableError(apierrors.NewConflict(schema.GroupResource{}, "", nil))) - assert.True(t, isRetryableError(apierrors.NewConflict(schema.GroupResource{Group: "v1", Resource: "resourcequotas"}, "", nil))) + assert.False(t, isRetryableError(apierr.NewConflict(schema.GroupResource{}, "", nil))) + assert.True(t, isRetryableError(apierr.NewConflict(schema.GroupResource{Group: "v1", Resource: "resourcequotas"}, "", nil))) }) t.Run("ExceededQuotaErr", func(t *testing.T) { - assert.False(t, isRetryableError(apierrors.NewForbidden(schema.GroupResource{}, "", nil))) - assert.True(t, isRetryableError(apierrors.NewForbidden(schema.GroupResource{Group: "v1", Resource: "pods"}, "", errors.New("exceeded quota")))) + assert.False(t, isRetryableError(apierr.NewForbidden(schema.GroupResource{}, "", nil))) + assert.True(t, isRetryableError(apierr.NewForbidden(schema.GroupResource{Group: "v1", Resource: "pods"}, "", errors.New("exceeded quota")))) }) t.Run("TooManyRequestsDNS", func(t *testing.T) { - assert.True(t, isRetryableError(apierrors.NewTooManyRequests("", 0))) + assert.True(t, isRetryableError(apierr.NewTooManyRequests("", 0))) }) t.Run("DNSError", func(t *testing.T) { assert.True(t, isRetryableError(&net.DNSError{})) @@ -278,7 +278,7 @@ func TestIsRetryableError(t *testing.T) { func Test_asResourceNode_owner_refs(t *testing.T) { resNode := asResourceNode(&cache.Resource{ ResourceVersion: "", - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ APIVersion: "v1", }, OwnerRefs: []metav1.OwnerReference{ @@ -303,16 +303,14 @@ func Test_asResourceNode_owner_refs(t *testing.T) { }, ParentRefs: []appv1.ResourceRef{ { - Group: "", - Kind: "ConfigMap", - Version: "v1", - Name: "cm-1", + Group: "", + Kind: "ConfigMap", + Name: "cm-1", }, { - Group: "", - Kind: "ConfigMap", - Version: "v1", - Name: "cm-2", + Group: "", + Kind: "ConfigMap", + Name: "cm-2", }, }, Info: nil, @@ -336,7 +334,7 @@ func Test_getAppRecursive(t *testing.T) { { name: "ok: cm1->app1", r: &cache.Resource{ - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm1", }, OwnerRefs: []metav1.OwnerReference{ @@ -356,7 +354,7 @@ func Test_getAppRecursive(t *testing.T) { { name: "ok: cm1->cm2->app1", r: &cache.Resource{ - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm1", }, OwnerRefs: []metav1.OwnerReference{ @@ -365,7 +363,7 @@ func Test_getAppRecursive(t *testing.T) { }, ns: map[kube.ResourceKey]*cache.Resource{ kube.NewResourceKey("", "", "", "cm2"): { - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm2", }, OwnerRefs: []metav1.OwnerReference{ @@ -384,7 +382,7 @@ func Test_getAppRecursive(t *testing.T) { { name: "cm1->cm2->app1 & cm1->cm3->app1", r: &cache.Resource{ - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm1", }, OwnerRefs: []metav1.OwnerReference{ @@ -394,7 +392,7 @@ func Test_getAppRecursive(t *testing.T) { }, ns: map[kube.ResourceKey]*cache.Resource{ kube.NewResourceKey("", "", "", "cm2"): { - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm2", }, OwnerRefs: []metav1.OwnerReference{ @@ -402,7 +400,7 @@ func Test_getAppRecursive(t *testing.T) { }, }, kube.NewResourceKey("", "", "", "cm3"): { - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm3", }, OwnerRefs: []metav1.OwnerReference{ @@ -423,7 +421,7 @@ func Test_getAppRecursive(t *testing.T) { // Issue #11699, fixed #12667. name: "ok: cm1->cm2 & cm1->cm3->cm2 & cm1->cm3->app1", r: &cache.Resource{ - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm1", }, OwnerRefs: []metav1.OwnerReference{ @@ -433,12 +431,12 @@ func Test_getAppRecursive(t *testing.T) { }, ns: map[kube.ResourceKey]*cache.Resource{ kube.NewResourceKey("", "", "", "cm2"): { - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm2", }, }, kube.NewResourceKey("", "", "", "cm3"): { - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm3", }, OwnerRefs: []metav1.OwnerReference{ @@ -458,7 +456,7 @@ func Test_getAppRecursive(t *testing.T) { { name: "cycle: cm1<->cm2", r: &cache.Resource{ - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm1", }, OwnerRefs: []metav1.OwnerReference{ @@ -467,7 +465,7 @@ func Test_getAppRecursive(t *testing.T) { }, ns: map[kube.ResourceKey]*cache.Resource{ kube.NewResourceKey("", "", "", "cm1"): { - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm1", }, OwnerRefs: []metav1.OwnerReference{ @@ -475,7 +473,7 @@ func Test_getAppRecursive(t *testing.T) { }, }, kube.NewResourceKey("", "", "", "cm2"): { - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm2", }, OwnerRefs: []metav1.OwnerReference{ @@ -489,7 +487,7 @@ func Test_getAppRecursive(t *testing.T) { { name: "cycle: cm1->cm2->cm3->cm1", r: &cache.Resource{ - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm1", }, OwnerRefs: []metav1.OwnerReference{ @@ -498,7 +496,7 @@ func Test_getAppRecursive(t *testing.T) { }, ns: map[kube.ResourceKey]*cache.Resource{ kube.NewResourceKey("", "", "", "cm1"): { - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm1", }, OwnerRefs: []metav1.OwnerReference{ @@ -506,7 +504,7 @@ func Test_getAppRecursive(t *testing.T) { }, }, kube.NewResourceKey("", "", "", "cm2"): { - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm2", }, OwnerRefs: []metav1.OwnerReference{ @@ -514,7 +512,7 @@ func Test_getAppRecursive(t *testing.T) { }, }, kube.NewResourceKey("", "", "", "cm3"): { - Ref: corev1.ObjectReference{ + Ref: v1.ObjectReference{ Name: "cm3", }, OwnerRefs: []metav1.OwnerReference{ @@ -537,12 +535,12 @@ func Test_getAppRecursive(t *testing.T) { func TestSkipResourceUpdate(t *testing.T) { var ( - hash1X = "x" - hash2Y = "y" - hash3X = "x" + hash1_x string = "x" + hash2_y string = "y" + hash3_x string = "x" ) info := &ResourceInfo{ - manifestHash: hash1X, + manifestHash: hash1_x, Health: &health.HealthStatus{ Status: health.HealthStatusHealthy, Message: "default", @@ -562,51 +560,51 @@ func TestSkipResourceUpdate(t *testing.T) { }) t.Run("Same hash", func(t *testing.T) { assert.True(t, skipResourceUpdate(&ResourceInfo{ - manifestHash: hash1X, + manifestHash: hash1_x, }, &ResourceInfo{ - manifestHash: hash1X, + manifestHash: hash1_x, })) }) t.Run("Same hash value", func(t *testing.T) { assert.True(t, skipResourceUpdate(&ResourceInfo{ - manifestHash: hash1X, + manifestHash: hash1_x, }, &ResourceInfo{ - manifestHash: hash3X, + manifestHash: hash3_x, })) }) t.Run("Different hash value", func(t *testing.T) { assert.False(t, skipResourceUpdate(&ResourceInfo{ - manifestHash: hash1X, + manifestHash: hash1_x, }, &ResourceInfo{ - manifestHash: hash2Y, + manifestHash: hash2_y, })) }) t.Run("Same hash, empty health", func(t *testing.T) { assert.True(t, skipResourceUpdate(&ResourceInfo{ - manifestHash: hash1X, + manifestHash: hash1_x, Health: &health.HealthStatus{}, }, &ResourceInfo{ - manifestHash: hash3X, + manifestHash: hash3_x, Health: &health.HealthStatus{}, })) }) t.Run("Same hash, old health", func(t *testing.T) { assert.False(t, skipResourceUpdate(&ResourceInfo{ - manifestHash: hash1X, + manifestHash: hash1_x, Health: &health.HealthStatus{ Status: health.HealthStatusHealthy, }, }, &ResourceInfo{ - manifestHash: hash3X, + manifestHash: hash3_x, Health: nil, })) }) t.Run("Same hash, new health", func(t *testing.T) { assert.False(t, skipResourceUpdate(&ResourceInfo{ - manifestHash: hash1X, + manifestHash: hash1_x, Health: &health.HealthStatus{}, }, &ResourceInfo{ - manifestHash: hash3X, + manifestHash: hash3_x, Health: &health.HealthStatus{ Status: health.HealthStatusHealthy, }, @@ -614,13 +612,13 @@ func TestSkipResourceUpdate(t *testing.T) { }) t.Run("Same hash, same health", func(t *testing.T) { assert.True(t, skipResourceUpdate(&ResourceInfo{ - manifestHash: hash1X, + manifestHash: hash1_x, Health: &health.HealthStatus{ Status: health.HealthStatusHealthy, Message: "same", }, }, &ResourceInfo{ - manifestHash: hash3X, + manifestHash: hash3_x, Health: &health.HealthStatus{ Status: health.HealthStatusHealthy, Message: "same", @@ -629,13 +627,13 @@ func TestSkipResourceUpdate(t *testing.T) { }) t.Run("Same hash, different health status", func(t *testing.T) { assert.False(t, skipResourceUpdate(&ResourceInfo{ - manifestHash: hash1X, + manifestHash: hash1_x, Health: &health.HealthStatus{ Status: health.HealthStatusHealthy, Message: "same", }, }, &ResourceInfo{ - manifestHash: hash3X, + manifestHash: hash3_x, Health: &health.HealthStatus{ Status: health.HealthStatusDegraded, Message: "same", @@ -644,13 +642,13 @@ func TestSkipResourceUpdate(t *testing.T) { }) t.Run("Same hash, different health message", func(t *testing.T) { assert.True(t, skipResourceUpdate(&ResourceInfo{ - manifestHash: hash1X, + manifestHash: hash1_x, Health: &health.HealthStatus{ Status: health.HealthStatusHealthy, Message: "same", }, }, &ResourceInfo{ - manifestHash: hash3X, + manifestHash: hash3_x, Health: &health.HealthStatus{ Status: health.HealthStatusHealthy, Message: "different", @@ -728,21 +726,9 @@ func TestShouldHashManifest(t *testing.T) { test.un.SetAnnotations(test.annotations) } got := shouldHashManifest(test.appName, test.gvk, test.un) - require.Equalf(t, test.want, got, "test=%v", test.name) + if test.want != got { + t.Fatalf("test=%v want %v got %v", test.name, test.want, got) + } }) } } - -func Test_GetVersionsInfo_error_redacted(t *testing.T) { - c := liveStateCache{} - cluster := &appv1.Cluster{ - Server: "https://localhost:1234", - Config: appv1.ClusterConfig{ - Username: "admin", - Password: "password", - }, - } - _, _, err := c.GetVersionsInfo(cluster) - require.Error(t, err) - assert.NotContains(t, err.Error(), "password") -} diff --git a/controller/cache/info.go b/controller/cache/info.go index 78de447bbe..635000e688 100644 --- a/controller/cache/info.go +++ b/controller/cache/info.go @@ -6,20 +6,20 @@ import ( "strconv" "strings" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime/schema" "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/argoproj/gitops-engine/pkg/utils/text" "github.com/cespare/xxhash/v2" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" resourcehelper "k8s.io/kubectl/pkg/util/resource" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - "github.com/argoproj/argo-cd/v3/util/resource" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" + "github.com/argoproj/argo-cd/v2/util/resource" ) func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLabels []string) { @@ -58,7 +58,8 @@ func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLa populateHostNodeInfo(un, res) } case "extensions", "networking.k8s.io": - if gvk.Kind == kube.IngressKind { + switch gvk.Kind { + case kube.IngressKind: populateIngressInfo(un, res) } case "networking.istio.io": @@ -71,18 +72,18 @@ func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLa } } -func getIngress(un *unstructured.Unstructured) []corev1.LoadBalancerIngress { +func getIngress(un *unstructured.Unstructured) []v1.LoadBalancerIngress { ingress, ok, err := unstructured.NestedSlice(un.Object, "status", "loadBalancer", "ingress") if !ok || err != nil { return nil } - res := make([]corev1.LoadBalancerIngress, 0) + res := make([]v1.LoadBalancerIngress, 0) for _, item := range ingress { - if lbIngress, ok := item.(map[string]any); ok { + if lbIngress, ok := item.(map[string]interface{}); ok { if hostname := lbIngress["hostname"]; hostname != nil { - res = append(res, corev1.LoadBalancerIngress{Hostname: fmt.Sprintf("%s", hostname)}) + res = append(res, v1.LoadBalancerIngress{Hostname: fmt.Sprintf("%s", hostname)}) } else if ip := lbIngress["ip"]; ip != nil { - res = append(res, corev1.LoadBalancerIngress{IP: fmt.Sprintf("%s", ip)}) + res = append(res, v1.LoadBalancerIngress{IP: fmt.Sprintf("%s", ip)}) } } } @@ -91,8 +92,8 @@ func getIngress(un *unstructured.Unstructured) []corev1.LoadBalancerIngress { func populateServiceInfo(un *unstructured.Unstructured, res *ResourceInfo) { targetLabels, _, _ := unstructured.NestedStringMap(un.Object, "spec", "selector") - ingress := make([]corev1.LoadBalancerIngress, 0) - if serviceType, ok, err := unstructured.NestedString(un.Object, "spec", "type"); ok && err == nil && serviceType == string(corev1.ServiceTypeLoadBalancer) { + ingress := make([]v1.LoadBalancerIngress, 0) + if serviceType, ok, err := unstructured.NestedString(un.Object, "spec", "type"); ok && err == nil && serviceType == string(v1.ServiceTypeLoadBalancer) { ingress = getIngress(un) } @@ -104,7 +105,7 @@ func populateServiceInfo(un *unstructured.Unstructured, res *ResourceInfo) { res.NetworkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetLabels: targetLabels, Ingress: ingress, ExternalURLs: urls} } -func getServiceName(backend map[string]any, gvk schema.GroupVersionKind) (string, error) { +func getServiceName(backend map[string]interface{}, gvk schema.GroupVersionKind) (string, error) { switch gvk.Group { case "extensions": return fmt.Sprintf("%s", backend["serviceName"]), nil @@ -138,7 +139,7 @@ func populateIngressInfo(un *unstructured.Unstructured, res *ResourceInfo) { urlsSet := make(map[string]bool) if rules, ok, err := unstructured.NestedSlice(un.Object, "spec", "rules"); ok && err == nil { for i := range rules { - rule, ok := rules[i].(map[string]any) + rule, ok := rules[i].(map[string]interface{}) if !ok { continue } @@ -156,7 +157,7 @@ func populateIngressInfo(un *unstructured.Unstructured, res *ResourceInfo) { continue } for i := range paths { - path, ok := paths[i].(map[string]any) + path, ok := paths[i].(map[string]interface{}) if !ok { continue } @@ -178,7 +179,7 @@ func populateIngressInfo(un *unstructured.Unstructured, res *ResourceInfo) { stringPort := "http" if tls, ok, err := unstructured.NestedSlice(un.Object, "spec", "tls"); ok && err == nil { for i := range tls { - tlsline, ok := tls[i].(map[string]any) + tlsline, ok := tls[i].(map[string]interface{}) secretName := tlsline["secretName"] if ok && secretName != nil { stringPort = "https" @@ -189,7 +190,7 @@ func populateIngressInfo(un *unstructured.Unstructured, res *ResourceInfo) { continue } if hosts := tlsline["hosts"]; hosts != nil { - tlshosts, ok := tlsline["hosts"].(map[string]any) + tlshosts, ok := tlsline["hosts"].(map[string]interface{}) if ok { for j := range tlshosts { if tlshosts[j] == host { @@ -232,7 +233,7 @@ func populateIstioVirtualServiceInfo(un *unstructured.Unstructured, res *Resourc if rules, ok, err := unstructured.NestedSlice(un.Object, "spec", "http"); ok && err == nil { for i := range rules { - rule, ok := rules[i].(map[string]any) + rule, ok := rules[i].(map[string]interface{}) if !ok { continue } @@ -241,7 +242,7 @@ func populateIstioVirtualServiceInfo(un *unstructured.Unstructured, res *Resourc continue } for i := range routes { - route, ok := routes[i].(map[string]any) + route, ok := routes[i].(map[string]interface{}) if !ok { continue } @@ -295,18 +296,18 @@ func populateIstioServiceEntryInfo(un *unstructured.Unstructured, res *ResourceI } } -func isPodInitializedConditionTrue(status *corev1.PodStatus) bool { +func isPodInitializedConditionTrue(status *v1.PodStatus) bool { for _, condition := range status.Conditions { - if condition.Type != corev1.PodInitialized { + if condition.Type != v1.PodInitialized { continue } - return condition.Status == corev1.ConditionTrue + return condition.Status == v1.ConditionTrue } return false } -func isRestartableInitContainer(initContainer *corev1.Container) bool { +func isRestartableInitContainer(initContainer *v1.Container) bool { if initContainer == nil { return false } @@ -314,15 +315,15 @@ func isRestartableInitContainer(initContainer *corev1.Container) bool { return false } - return *initContainer.RestartPolicy == corev1.ContainerRestartPolicyAlways + return *initContainer.RestartPolicy == v1.ContainerRestartPolicyAlways } -func isPodPhaseTerminal(phase corev1.PodPhase) bool { - return phase == corev1.PodFailed || phase == corev1.PodSucceeded +func isPodPhaseTerminal(phase v1.PodPhase) bool { + return phase == v1.PodFailed || phase == v1.PodSucceeded } func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { - pod := corev1.Pod{} + pod := v1.Pod{} err := runtime.DefaultUnstructuredConverter.FromUnstructured(un.Object, &pod) if err != nil { return @@ -352,12 +353,12 @@ func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { // If the Pod carries {type:PodScheduled, reason:SchedulingGated}, set reason to 'SchedulingGated'. for _, condition := range pod.Status.Conditions { - if condition.Type == corev1.PodScheduled && condition.Reason == corev1.PodReasonSchedulingGated { - reason = corev1.PodReasonSchedulingGated + if condition.Type == v1.PodScheduled && condition.Reason == v1.PodReasonSchedulingGated { + reason = v1.PodReasonSchedulingGated } } - initContainers := make(map[string]*corev1.Container) + 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]) { @@ -405,18 +406,17 @@ func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { container := pod.Status.ContainerStatuses[i] restarts += int(container.RestartCount) - switch { - case container.State.Waiting != nil && container.State.Waiting.Reason != "": + if container.State.Waiting != nil && container.State.Waiting.Reason != "" { reason = container.State.Waiting.Reason - case container.State.Terminated != nil && container.State.Terminated.Reason != "": + } else if container.State.Terminated != nil && container.State.Terminated.Reason != "" { reason = container.State.Terminated.Reason - case container.State.Terminated != nil && container.State.Terminated.Reason == "": + } else if container.State.Terminated != nil && container.State.Terminated.Reason == "" { if container.State.Terminated.Signal != 0 { reason = fmt.Sprintf("Signal:%d", container.State.Terminated.Signal) } else { reason = fmt.Sprintf("ExitCode:%d", container.State.Terminated.ExitCode) } - case container.Ready && container.State.Running != nil: + } else if container.Ready && container.State.Running != nil { hasRunning = true readyContainers++ } @@ -463,7 +463,7 @@ func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { } func populateHostNodeInfo(un *unstructured.Unstructured, res *ResourceInfo) { - node := corev1.Node{} + node := v1.Node{} err := runtime.DefaultUnstructuredConverter.FromUnstructured(un.Object, &node) if err != nil { return diff --git a/controller/cache/info_test.go b/controller/cache/info_test.go index 91f816fd15..db58d209f1 100644 --- a/controller/cache/info_test.go +++ b/controller/cache/info_test.go @@ -5,21 +5,22 @@ import ( "strings" "testing" + "k8s.io/apimachinery/pkg/api/resource" + "github.com/argoproj/gitops-engine/pkg/utils/kube" + "github.com/argoproj/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" ) func strToUnstructured(jsonStr string) *unstructured.Unstructured { - obj := make(map[string]any) + obj := make(map[string]interface{}) err := yaml.Unmarshal([]byte(jsonStr), &obj) errors.CheckError(err) return &unstructured.Unstructured{Object: obj} @@ -157,7 +158,7 @@ var ( ingress: - ip: 107.178.210.11`) - testIngressWithoutTLS = strToUnstructured(` + testIngressWithoutTls = strToUnstructured(` apiVersion: extensions/v1beta1 kind: Ingress metadata: @@ -309,7 +310,7 @@ func TestGetPodInfo(t *testing.T) { assert.Equal(t, []string{"bar"}, info.Images) assert.Equal(t, &PodInfo{ NodeName: "minikube", - ResourceRequests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("128Mi")}, + ResourceRequests: v1.ResourceList{v1.ResourceMemory: resource.MustParse("128Mi")}, }, info.PodInfo) assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{Labels: map[string]string{"app": "guestbook"}}, info.NetworkingInfo) }) @@ -906,8 +907,8 @@ status: populateNodeInfo(node, info, []string{}) assert.Equal(t, &NodeInfo{ Name: "minikube", - Capacity: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("6091320Ki"), corev1.ResourceCPU: resource.MustParse("6")}, - SystemInfo: corev1.NodeSystemInfo{Architecture: "amd64", OperatingSystem: "linux", OSImage: "Ubuntu 20.04 LTS"}, + Capacity: v1.ResourceList{v1.ResourceMemory: resource.MustParse("6091320Ki"), v1.ResourceCPU: resource.MustParse("6")}, + SystemInfo: v1.NodeSystemInfo{Architecture: "amd64", OperatingSystem: "linux", OSImage: "Ubuntu 20.04 LTS"}, }, info.NodeInfo) } @@ -917,7 +918,7 @@ func TestGetServiceInfo(t *testing.T) { assert.Empty(t, info.Info) assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{ TargetLabels: map[string]string{"app": "guestbook"}, - Ingress: []corev1.LoadBalancerIngress{{Hostname: "localhost"}}, + Ingress: []v1.LoadBalancerIngress{{Hostname: "localhost"}}, }, info.NetworkingInfo) } @@ -927,7 +928,7 @@ func TestGetLinkAnnotatedServiceInfo(t *testing.T) { assert.Empty(t, info.Info) assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{ TargetLabels: map[string]string{"app": "guestbook"}, - Ingress: []corev1.LoadBalancerIngress{{Hostname: "localhost"}}, + Ingress: []v1.LoadBalancerIngress{{Hostname: "localhost"}}, ExternalURLs: []string{"http://my-grafana.example.com/pre-generated-link"}, }, info.NetworkingInfo) } @@ -985,7 +986,7 @@ func TestGetIngressInfo(t *testing.T) { return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0 }) assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{ - Ingress: []corev1.LoadBalancerIngress{{IP: "107.178.210.11"}}, + Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}}, TargetRefs: []v1alpha1.ResourceRef{{ Namespace: "default", Group: "", @@ -1010,7 +1011,7 @@ func TestGetLinkAnnotatedIngressInfo(t *testing.T) { return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0 }) assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{ - Ingress: []corev1.LoadBalancerIngress{{IP: "107.178.210.11"}}, + Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}}, TargetRefs: []v1alpha1.ResourceRef{{ Namespace: "default", Group: "", @@ -1034,7 +1035,7 @@ func TestGetIngressInfoWildCardPath(t *testing.T) { return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0 }) assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{ - Ingress: []corev1.LoadBalancerIngress{{IP: "107.178.210.11"}}, + Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}}, TargetRefs: []v1alpha1.ResourceRef{{ Namespace: "default", Group: "", @@ -1052,13 +1053,13 @@ func TestGetIngressInfoWildCardPath(t *testing.T) { func TestGetIngressInfoWithoutTls(t *testing.T) { info := &ResourceInfo{} - populateNodeInfo(testIngressWithoutTLS, info, []string{}) + populateNodeInfo(testIngressWithoutTls, info, []string{}) assert.Empty(t, info.Info) sort.Slice(info.NetworkingInfo.TargetRefs, func(i, j int) bool { return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0 }) assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{ - Ingress: []corev1.LoadBalancerIngress{{IP: "107.178.210.11"}}, + Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}}, TargetRefs: []v1alpha1.ResourceRef{{ Namespace: "default", Group: "", @@ -1100,7 +1101,7 @@ func TestGetIngressInfoWithHost(t *testing.T) { populateNodeInfo(ingress, info, []string{}) assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{ - Ingress: []corev1.LoadBalancerIngress{{IP: "107.178.210.11"}}, + Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}}, TargetRefs: []v1alpha1.ResourceRef{{ Namespace: "default", Group: "", diff --git a/controller/cache/mocks/LiveStateCache.go b/controller/cache/mocks/LiveStateCache.go index 378338c170..f25e8166a5 100644 --- a/controller/cache/mocks/LiveStateCache.go +++ b/controller/cache/mocks/LiveStateCache.go @@ -1,21 +1,295 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" + context "context" + + cache "github.com/argoproj/gitops-engine/pkg/cache" + + controllercache "github.com/argoproj/argo-cd/v2/controller/cache" + + kube "github.com/argoproj/gitops-engine/pkg/utils/kube" - cache0 "github.com/argoproj/argo-cd/v3/controller/cache" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/gitops-engine/pkg/cache" - "github.com/argoproj/gitops-engine/pkg/utils/kube" mock "github.com/stretchr/testify/mock" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" + + schema "k8s.io/apimachinery/pkg/runtime/schema" + + unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) +// LiveStateCache is an autogenerated mock type for the LiveStateCache type +type LiveStateCache struct { + mock.Mock +} + +// GetClusterCache provides a mock function with given fields: server +func (_m *LiveStateCache) GetClusterCache(server string) (cache.ClusterCache, error) { + ret := _m.Called(server) + + if len(ret) == 0 { + panic("no return value specified for GetClusterCache") + } + + var r0 cache.ClusterCache + var r1 error + if rf, ok := ret.Get(0).(func(string) (cache.ClusterCache, error)); ok { + return rf(server) + } + if rf, ok := ret.Get(0).(func(string) cache.ClusterCache); ok { + r0 = rf(server) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(cache.ClusterCache) + } + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(server) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetClustersInfo provides a mock function with no fields +func (_m *LiveStateCache) GetClustersInfo() []cache.ClusterInfo { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetClustersInfo") + } + + var r0 []cache.ClusterInfo + if rf, ok := ret.Get(0).(func() []cache.ClusterInfo); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]cache.ClusterInfo) + } + } + + return r0 +} + +// GetManagedLiveObjs provides a mock function with given fields: a, targetObjs +func (_m *LiveStateCache) GetManagedLiveObjs(a *v1alpha1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error) { + ret := _m.Called(a, targetObjs) + + if len(ret) == 0 { + panic("no return value specified for GetManagedLiveObjs") + } + + var r0 map[kube.ResourceKey]*unstructured.Unstructured + var r1 error + if rf, ok := ret.Get(0).(func(*v1alpha1.Application, []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error)); ok { + return rf(a, targetObjs) + } + if rf, ok := ret.Get(0).(func(*v1alpha1.Application, []*unstructured.Unstructured) map[kube.ResourceKey]*unstructured.Unstructured); ok { + r0 = rf(a, targetObjs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[kube.ResourceKey]*unstructured.Unstructured) + } + } + + if rf, ok := ret.Get(1).(func(*v1alpha1.Application, []*unstructured.Unstructured) error); ok { + r1 = rf(a, targetObjs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetNamespaceTopLevelResources provides a mock function with given fields: server, namespace +func (_m *LiveStateCache) GetNamespaceTopLevelResources(server string, namespace string) (map[kube.ResourceKey]v1alpha1.ResourceNode, error) { + ret := _m.Called(server, namespace) + + if len(ret) == 0 { + panic("no return value specified for GetNamespaceTopLevelResources") + } + + var r0 map[kube.ResourceKey]v1alpha1.ResourceNode + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (map[kube.ResourceKey]v1alpha1.ResourceNode, error)); ok { + return rf(server, namespace) + } + if rf, ok := ret.Get(0).(func(string, string) map[kube.ResourceKey]v1alpha1.ResourceNode); ok { + r0 = rf(server, namespace) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[kube.ResourceKey]v1alpha1.ResourceNode) + } + } + + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(server, namespace) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetVersionsInfo provides a mock function with given fields: serverURL +func (_m *LiveStateCache) GetVersionsInfo(serverURL string) (string, []kube.APIResourceInfo, error) { + ret := _m.Called(serverURL) + + if len(ret) == 0 { + panic("no return value specified for GetVersionsInfo") + } + + var r0 string + var r1 []kube.APIResourceInfo + var r2 error + if rf, ok := ret.Get(0).(func(string) (string, []kube.APIResourceInfo, error)); ok { + return rf(serverURL) + } + if rf, ok := ret.Get(0).(func(string) string); ok { + r0 = rf(serverURL) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string) []kube.APIResourceInfo); ok { + r1 = rf(serverURL) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).([]kube.APIResourceInfo) + } + } + + if rf, ok := ret.Get(2).(func(string) error); ok { + r2 = rf(serverURL) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// Init provides a mock function with no fields +func (_m *LiveStateCache) Init() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Init") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// IsNamespaced provides a mock function with given fields: server, gk +func (_m *LiveStateCache) IsNamespaced(server string, gk schema.GroupKind) (bool, error) { + ret := _m.Called(server, gk) + + if len(ret) == 0 { + panic("no return value specified for IsNamespaced") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(string, schema.GroupKind) (bool, error)); ok { + return rf(server, gk) + } + if rf, ok := ret.Get(0).(func(string, schema.GroupKind) bool); ok { + r0 = rf(server, gk) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(string, schema.GroupKind) error); ok { + r1 = rf(server, gk) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// IterateHierarchy provides a mock function with given fields: server, key, action +func (_m *LiveStateCache) IterateHierarchy(server string, key kube.ResourceKey, action func(v1alpha1.ResourceNode, string) bool) error { + ret := _m.Called(server, key, action) + + if len(ret) == 0 { + panic("no return value specified for IterateHierarchy") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string, kube.ResourceKey, func(v1alpha1.ResourceNode, string) bool) error); ok { + r0 = rf(server, key, action) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// IterateHierarchyV2 provides a mock function with given fields: server, keys, action +func (_m *LiveStateCache) IterateHierarchyV2(server string, keys []kube.ResourceKey, action func(v1alpha1.ResourceNode, string) bool) error { + ret := _m.Called(server, keys, action) + + if len(ret) == 0 { + panic("no return value specified for IterateHierarchyV2") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string, []kube.ResourceKey, func(v1alpha1.ResourceNode, string) bool) error); ok { + r0 = rf(server, keys, action) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// IterateResources provides a mock function with given fields: server, callback +func (_m *LiveStateCache) IterateResources(server string, callback func(*cache.Resource, *controllercache.ResourceInfo)) error { + ret := _m.Called(server, callback) + + if len(ret) == 0 { + panic("no return value specified for IterateResources") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string, func(*cache.Resource, *controllercache.ResourceInfo)) error); ok { + r0 = rf(server, callback) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Run provides a mock function with given fields: ctx +func (_m *LiveStateCache) Run(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Run") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // NewLiveStateCache creates a new instance of LiveStateCache. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewLiveStateCache(t interface { @@ -29,624 +303,3 @@ func NewLiveStateCache(t interface { return mock } - -// LiveStateCache is an autogenerated mock type for the LiveStateCache type -type LiveStateCache struct { - mock.Mock -} - -type LiveStateCache_Expecter struct { - mock *mock.Mock -} - -func (_m *LiveStateCache) EXPECT() *LiveStateCache_Expecter { - return &LiveStateCache_Expecter{mock: &_m.Mock} -} - -// GetClusterCache provides a mock function for the type LiveStateCache -func (_mock *LiveStateCache) GetClusterCache(server *v1alpha1.Cluster) (cache.ClusterCache, error) { - ret := _mock.Called(server) - - if len(ret) == 0 { - panic("no return value specified for GetClusterCache") - } - - var r0 cache.ClusterCache - var r1 error - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster) (cache.ClusterCache, error)); ok { - return returnFunc(server) - } - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster) cache.ClusterCache); ok { - r0 = returnFunc(server) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(cache.ClusterCache) - } - } - if returnFunc, ok := ret.Get(1).(func(*v1alpha1.Cluster) error); ok { - r1 = returnFunc(server) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// LiveStateCache_GetClusterCache_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetClusterCache' -type LiveStateCache_GetClusterCache_Call struct { - *mock.Call -} - -// GetClusterCache is a helper method to define mock.On call -// - server -func (_e *LiveStateCache_Expecter) GetClusterCache(server interface{}) *LiveStateCache_GetClusterCache_Call { - return &LiveStateCache_GetClusterCache_Call{Call: _e.mock.On("GetClusterCache", server)} -} - -func (_c *LiveStateCache_GetClusterCache_Call) Run(run func(server *v1alpha1.Cluster)) *LiveStateCache_GetClusterCache_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.Cluster)) - }) - return _c -} - -func (_c *LiveStateCache_GetClusterCache_Call) Return(clusterCache cache.ClusterCache, err error) *LiveStateCache_GetClusterCache_Call { - _c.Call.Return(clusterCache, err) - return _c -} - -func (_c *LiveStateCache_GetClusterCache_Call) RunAndReturn(run func(server *v1alpha1.Cluster) (cache.ClusterCache, error)) *LiveStateCache_GetClusterCache_Call { - _c.Call.Return(run) - return _c -} - -// GetClustersInfo provides a mock function for the type LiveStateCache -func (_mock *LiveStateCache) GetClustersInfo() []cache.ClusterInfo { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for GetClustersInfo") - } - - var r0 []cache.ClusterInfo - if returnFunc, ok := ret.Get(0).(func() []cache.ClusterInfo); ok { - r0 = returnFunc() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]cache.ClusterInfo) - } - } - return r0 -} - -// LiveStateCache_GetClustersInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetClustersInfo' -type LiveStateCache_GetClustersInfo_Call struct { - *mock.Call -} - -// GetClustersInfo is a helper method to define mock.On call -func (_e *LiveStateCache_Expecter) GetClustersInfo() *LiveStateCache_GetClustersInfo_Call { - return &LiveStateCache_GetClustersInfo_Call{Call: _e.mock.On("GetClustersInfo")} -} - -func (_c *LiveStateCache_GetClustersInfo_Call) Run(run func()) *LiveStateCache_GetClustersInfo_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *LiveStateCache_GetClustersInfo_Call) Return(clusterInfos []cache.ClusterInfo) *LiveStateCache_GetClustersInfo_Call { - _c.Call.Return(clusterInfos) - return _c -} - -func (_c *LiveStateCache_GetClustersInfo_Call) RunAndReturn(run func() []cache.ClusterInfo) *LiveStateCache_GetClustersInfo_Call { - _c.Call.Return(run) - return _c -} - -// GetManagedLiveObjs provides a mock function for the type LiveStateCache -func (_mock *LiveStateCache) GetManagedLiveObjs(destCluster *v1alpha1.Cluster, a *v1alpha1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error) { - ret := _mock.Called(destCluster, a, targetObjs) - - if len(ret) == 0 { - panic("no return value specified for GetManagedLiveObjs") - } - - var r0 map[kube.ResourceKey]*unstructured.Unstructured - var r1 error - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster, *v1alpha1.Application, []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error)); ok { - return returnFunc(destCluster, a, targetObjs) - } - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster, *v1alpha1.Application, []*unstructured.Unstructured) map[kube.ResourceKey]*unstructured.Unstructured); ok { - r0 = returnFunc(destCluster, a, targetObjs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[kube.ResourceKey]*unstructured.Unstructured) - } - } - if returnFunc, ok := ret.Get(1).(func(*v1alpha1.Cluster, *v1alpha1.Application, []*unstructured.Unstructured) error); ok { - r1 = returnFunc(destCluster, a, targetObjs) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// LiveStateCache_GetManagedLiveObjs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetManagedLiveObjs' -type LiveStateCache_GetManagedLiveObjs_Call struct { - *mock.Call -} - -// GetManagedLiveObjs is a helper method to define mock.On call -// - destCluster -// - a -// - targetObjs -func (_e *LiveStateCache_Expecter) GetManagedLiveObjs(destCluster interface{}, a interface{}, targetObjs interface{}) *LiveStateCache_GetManagedLiveObjs_Call { - return &LiveStateCache_GetManagedLiveObjs_Call{Call: _e.mock.On("GetManagedLiveObjs", destCluster, a, targetObjs)} -} - -func (_c *LiveStateCache_GetManagedLiveObjs_Call) Run(run func(destCluster *v1alpha1.Cluster, a *v1alpha1.Application, targetObjs []*unstructured.Unstructured)) *LiveStateCache_GetManagedLiveObjs_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.Cluster), args[1].(*v1alpha1.Application), args[2].([]*unstructured.Unstructured)) - }) - return _c -} - -func (_c *LiveStateCache_GetManagedLiveObjs_Call) Return(resourceKeyToUnstructured map[kube.ResourceKey]*unstructured.Unstructured, err error) *LiveStateCache_GetManagedLiveObjs_Call { - _c.Call.Return(resourceKeyToUnstructured, err) - return _c -} - -func (_c *LiveStateCache_GetManagedLiveObjs_Call) RunAndReturn(run func(destCluster *v1alpha1.Cluster, a *v1alpha1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error)) *LiveStateCache_GetManagedLiveObjs_Call { - _c.Call.Return(run) - return _c -} - -// GetNamespaceTopLevelResources provides a mock function for the type LiveStateCache -func (_mock *LiveStateCache) GetNamespaceTopLevelResources(server *v1alpha1.Cluster, namespace string) (map[kube.ResourceKey]v1alpha1.ResourceNode, error) { - ret := _mock.Called(server, namespace) - - if len(ret) == 0 { - panic("no return value specified for GetNamespaceTopLevelResources") - } - - var r0 map[kube.ResourceKey]v1alpha1.ResourceNode - var r1 error - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster, string) (map[kube.ResourceKey]v1alpha1.ResourceNode, error)); ok { - return returnFunc(server, namespace) - } - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster, string) map[kube.ResourceKey]v1alpha1.ResourceNode); ok { - r0 = returnFunc(server, namespace) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[kube.ResourceKey]v1alpha1.ResourceNode) - } - } - if returnFunc, ok := ret.Get(1).(func(*v1alpha1.Cluster, string) error); ok { - r1 = returnFunc(server, namespace) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// LiveStateCache_GetNamespaceTopLevelResources_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetNamespaceTopLevelResources' -type LiveStateCache_GetNamespaceTopLevelResources_Call struct { - *mock.Call -} - -// GetNamespaceTopLevelResources is a helper method to define mock.On call -// - server -// - namespace -func (_e *LiveStateCache_Expecter) GetNamespaceTopLevelResources(server interface{}, namespace interface{}) *LiveStateCache_GetNamespaceTopLevelResources_Call { - return &LiveStateCache_GetNamespaceTopLevelResources_Call{Call: _e.mock.On("GetNamespaceTopLevelResources", server, namespace)} -} - -func (_c *LiveStateCache_GetNamespaceTopLevelResources_Call) Run(run func(server *v1alpha1.Cluster, namespace string)) *LiveStateCache_GetNamespaceTopLevelResources_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.Cluster), args[1].(string)) - }) - return _c -} - -func (_c *LiveStateCache_GetNamespaceTopLevelResources_Call) Return(resourceKeyToResourceNode map[kube.ResourceKey]v1alpha1.ResourceNode, err error) *LiveStateCache_GetNamespaceTopLevelResources_Call { - _c.Call.Return(resourceKeyToResourceNode, err) - return _c -} - -func (_c *LiveStateCache_GetNamespaceTopLevelResources_Call) RunAndReturn(run func(server *v1alpha1.Cluster, namespace string) (map[kube.ResourceKey]v1alpha1.ResourceNode, error)) *LiveStateCache_GetNamespaceTopLevelResources_Call { - _c.Call.Return(run) - return _c -} - -// GetVersionsInfo provides a mock function for the type LiveStateCache -func (_mock *LiveStateCache) GetVersionsInfo(server *v1alpha1.Cluster) (string, []kube.APIResourceInfo, error) { - ret := _mock.Called(server) - - if len(ret) == 0 { - panic("no return value specified for GetVersionsInfo") - } - - var r0 string - var r1 []kube.APIResourceInfo - var r2 error - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster) (string, []kube.APIResourceInfo, error)); ok { - return returnFunc(server) - } - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster) string); ok { - r0 = returnFunc(server) - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func(*v1alpha1.Cluster) []kube.APIResourceInfo); ok { - r1 = returnFunc(server) - } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).([]kube.APIResourceInfo) - } - } - if returnFunc, ok := ret.Get(2).(func(*v1alpha1.Cluster) error); ok { - r2 = returnFunc(server) - } else { - r2 = ret.Error(2) - } - return r0, r1, r2 -} - -// LiveStateCache_GetVersionsInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetVersionsInfo' -type LiveStateCache_GetVersionsInfo_Call struct { - *mock.Call -} - -// GetVersionsInfo is a helper method to define mock.On call -// - server -func (_e *LiveStateCache_Expecter) GetVersionsInfo(server interface{}) *LiveStateCache_GetVersionsInfo_Call { - return &LiveStateCache_GetVersionsInfo_Call{Call: _e.mock.On("GetVersionsInfo", server)} -} - -func (_c *LiveStateCache_GetVersionsInfo_Call) Run(run func(server *v1alpha1.Cluster)) *LiveStateCache_GetVersionsInfo_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.Cluster)) - }) - return _c -} - -func (_c *LiveStateCache_GetVersionsInfo_Call) Return(s string, aPIResourceInfos []kube.APIResourceInfo, err error) *LiveStateCache_GetVersionsInfo_Call { - _c.Call.Return(s, aPIResourceInfos, err) - return _c -} - -func (_c *LiveStateCache_GetVersionsInfo_Call) RunAndReturn(run func(server *v1alpha1.Cluster) (string, []kube.APIResourceInfo, error)) *LiveStateCache_GetVersionsInfo_Call { - _c.Call.Return(run) - return _c -} - -// Init provides a mock function for the type LiveStateCache -func (_mock *LiveStateCache) Init() error { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for Init") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func() error); ok { - r0 = returnFunc() - } else { - r0 = ret.Error(0) - } - return r0 -} - -// LiveStateCache_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' -type LiveStateCache_Init_Call struct { - *mock.Call -} - -// Init is a helper method to define mock.On call -func (_e *LiveStateCache_Expecter) Init() *LiveStateCache_Init_Call { - return &LiveStateCache_Init_Call{Call: _e.mock.On("Init")} -} - -func (_c *LiveStateCache_Init_Call) Run(run func()) *LiveStateCache_Init_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *LiveStateCache_Init_Call) Return(err error) *LiveStateCache_Init_Call { - _c.Call.Return(err) - return _c -} - -func (_c *LiveStateCache_Init_Call) RunAndReturn(run func() error) *LiveStateCache_Init_Call { - _c.Call.Return(run) - return _c -} - -// IsNamespaced provides a mock function for the type LiveStateCache -func (_mock *LiveStateCache) IsNamespaced(server *v1alpha1.Cluster, gk schema.GroupKind) (bool, error) { - ret := _mock.Called(server, gk) - - if len(ret) == 0 { - panic("no return value specified for IsNamespaced") - } - - var r0 bool - var r1 error - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster, schema.GroupKind) (bool, error)); ok { - return returnFunc(server, gk) - } - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster, schema.GroupKind) bool); ok { - r0 = returnFunc(server, gk) - } else { - r0 = ret.Get(0).(bool) - } - if returnFunc, ok := ret.Get(1).(func(*v1alpha1.Cluster, schema.GroupKind) error); ok { - r1 = returnFunc(server, gk) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// LiveStateCache_IsNamespaced_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsNamespaced' -type LiveStateCache_IsNamespaced_Call struct { - *mock.Call -} - -// IsNamespaced is a helper method to define mock.On call -// - server -// - gk -func (_e *LiveStateCache_Expecter) IsNamespaced(server interface{}, gk interface{}) *LiveStateCache_IsNamespaced_Call { - return &LiveStateCache_IsNamespaced_Call{Call: _e.mock.On("IsNamespaced", server, gk)} -} - -func (_c *LiveStateCache_IsNamespaced_Call) Run(run func(server *v1alpha1.Cluster, gk schema.GroupKind)) *LiveStateCache_IsNamespaced_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.Cluster), args[1].(schema.GroupKind)) - }) - return _c -} - -func (_c *LiveStateCache_IsNamespaced_Call) Return(b bool, err error) *LiveStateCache_IsNamespaced_Call { - _c.Call.Return(b, err) - return _c -} - -func (_c *LiveStateCache_IsNamespaced_Call) RunAndReturn(run func(server *v1alpha1.Cluster, gk schema.GroupKind) (bool, error)) *LiveStateCache_IsNamespaced_Call { - _c.Call.Return(run) - return _c -} - -// IterateHierarchy provides a mock function for the type LiveStateCache -func (_mock *LiveStateCache) IterateHierarchy(server *v1alpha1.Cluster, key kube.ResourceKey, action func(child v1alpha1.ResourceNode, appName string) bool) error { - ret := _mock.Called(server, key, action) - - if len(ret) == 0 { - panic("no return value specified for IterateHierarchy") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster, kube.ResourceKey, func(child v1alpha1.ResourceNode, appName string) bool) error); ok { - r0 = returnFunc(server, key, action) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// LiveStateCache_IterateHierarchy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IterateHierarchy' -type LiveStateCache_IterateHierarchy_Call struct { - *mock.Call -} - -// IterateHierarchy is a helper method to define mock.On call -// - server -// - key -// - action -func (_e *LiveStateCache_Expecter) IterateHierarchy(server interface{}, key interface{}, action interface{}) *LiveStateCache_IterateHierarchy_Call { - return &LiveStateCache_IterateHierarchy_Call{Call: _e.mock.On("IterateHierarchy", server, key, action)} -} - -func (_c *LiveStateCache_IterateHierarchy_Call) Run(run func(server *v1alpha1.Cluster, key kube.ResourceKey, action func(child v1alpha1.ResourceNode, appName string) bool)) *LiveStateCache_IterateHierarchy_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.Cluster), args[1].(kube.ResourceKey), args[2].(func(child v1alpha1.ResourceNode, appName string) bool)) - }) - return _c -} - -func (_c *LiveStateCache_IterateHierarchy_Call) Return(err error) *LiveStateCache_IterateHierarchy_Call { - _c.Call.Return(err) - return _c -} - -func (_c *LiveStateCache_IterateHierarchy_Call) RunAndReturn(run func(server *v1alpha1.Cluster, key kube.ResourceKey, action func(child v1alpha1.ResourceNode, appName string) bool) error) *LiveStateCache_IterateHierarchy_Call { - _c.Call.Return(run) - return _c -} - -// IterateHierarchyV2 provides a mock function for the type LiveStateCache -func (_mock *LiveStateCache) IterateHierarchyV2(server *v1alpha1.Cluster, keys []kube.ResourceKey, action func(child v1alpha1.ResourceNode, appName string) bool) error { - ret := _mock.Called(server, keys, action) - - if len(ret) == 0 { - panic("no return value specified for IterateHierarchyV2") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster, []kube.ResourceKey, func(child v1alpha1.ResourceNode, appName string) bool) error); ok { - r0 = returnFunc(server, keys, action) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// LiveStateCache_IterateHierarchyV2_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IterateHierarchyV2' -type LiveStateCache_IterateHierarchyV2_Call struct { - *mock.Call -} - -// IterateHierarchyV2 is a helper method to define mock.On call -// - server -// - keys -// - action -func (_e *LiveStateCache_Expecter) IterateHierarchyV2(server interface{}, keys interface{}, action interface{}) *LiveStateCache_IterateHierarchyV2_Call { - return &LiveStateCache_IterateHierarchyV2_Call{Call: _e.mock.On("IterateHierarchyV2", server, keys, action)} -} - -func (_c *LiveStateCache_IterateHierarchyV2_Call) Run(run func(server *v1alpha1.Cluster, keys []kube.ResourceKey, action func(child v1alpha1.ResourceNode, appName string) bool)) *LiveStateCache_IterateHierarchyV2_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.Cluster), args[1].([]kube.ResourceKey), args[2].(func(child v1alpha1.ResourceNode, appName string) bool)) - }) - return _c -} - -func (_c *LiveStateCache_IterateHierarchyV2_Call) Return(err error) *LiveStateCache_IterateHierarchyV2_Call { - _c.Call.Return(err) - return _c -} - -func (_c *LiveStateCache_IterateHierarchyV2_Call) RunAndReturn(run func(server *v1alpha1.Cluster, keys []kube.ResourceKey, action func(child v1alpha1.ResourceNode, appName string) bool) error) *LiveStateCache_IterateHierarchyV2_Call { - _c.Call.Return(run) - return _c -} - -// IterateResources provides a mock function for the type LiveStateCache -func (_mock *LiveStateCache) IterateResources(server *v1alpha1.Cluster, callback func(res *cache.Resource, info *cache0.ResourceInfo)) error { - ret := _mock.Called(server, callback) - - if len(ret) == 0 { - panic("no return value specified for IterateResources") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(*v1alpha1.Cluster, func(res *cache.Resource, info *cache0.ResourceInfo)) error); ok { - r0 = returnFunc(server, callback) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// LiveStateCache_IterateResources_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IterateResources' -type LiveStateCache_IterateResources_Call struct { - *mock.Call -} - -// IterateResources is a helper method to define mock.On call -// - server -// - callback -func (_e *LiveStateCache_Expecter) IterateResources(server interface{}, callback interface{}) *LiveStateCache_IterateResources_Call { - return &LiveStateCache_IterateResources_Call{Call: _e.mock.On("IterateResources", server, callback)} -} - -func (_c *LiveStateCache_IterateResources_Call) Run(run func(server *v1alpha1.Cluster, callback func(res *cache.Resource, info *cache0.ResourceInfo))) *LiveStateCache_IterateResources_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*v1alpha1.Cluster), args[1].(func(res *cache.Resource, info *cache0.ResourceInfo))) - }) - return _c -} - -func (_c *LiveStateCache_IterateResources_Call) Return(err error) *LiveStateCache_IterateResources_Call { - _c.Call.Return(err) - return _c -} - -func (_c *LiveStateCache_IterateResources_Call) RunAndReturn(run func(server *v1alpha1.Cluster, callback func(res *cache.Resource, info *cache0.ResourceInfo)) error) *LiveStateCache_IterateResources_Call { - _c.Call.Return(run) - return _c -} - -// Run provides a mock function for the type LiveStateCache -func (_mock *LiveStateCache) Run(ctx context.Context) error { - ret := _mock.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for Run") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = returnFunc(ctx) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// LiveStateCache_Run_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Run' -type LiveStateCache_Run_Call struct { - *mock.Call -} - -// Run is a helper method to define mock.On call -// - ctx -func (_e *LiveStateCache_Expecter) Run(ctx interface{}) *LiveStateCache_Run_Call { - return &LiveStateCache_Run_Call{Call: _e.mock.On("Run", ctx)} -} - -func (_c *LiveStateCache_Run_Call) Run(run func(ctx context.Context)) *LiveStateCache_Run_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *LiveStateCache_Run_Call) Return(err error) *LiveStateCache_Run_Call { - _c.Call.Return(err) - return _c -} - -func (_c *LiveStateCache_Run_Call) RunAndReturn(run func(ctx context.Context) error) *LiveStateCache_Run_Call { - _c.Call.Return(run) - return _c -} - -// UpdateShard provides a mock function for the type LiveStateCache -func (_mock *LiveStateCache) UpdateShard(shard int) bool { - ret := _mock.Called(shard) - - if len(ret) == 0 { - panic("no return value specified for UpdateShard") - } - - var r0 bool - if returnFunc, ok := ret.Get(0).(func(int) bool); ok { - r0 = returnFunc(shard) - } else { - r0 = ret.Get(0).(bool) - } - return r0 -} - -// LiveStateCache_UpdateShard_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateShard' -type LiveStateCache_UpdateShard_Call struct { - *mock.Call -} - -// UpdateShard is a helper method to define mock.On call -// - shard -func (_e *LiveStateCache_Expecter) UpdateShard(shard interface{}) *LiveStateCache_UpdateShard_Call { - return &LiveStateCache_UpdateShard_Call{Call: _e.mock.On("UpdateShard", shard)} -} - -func (_c *LiveStateCache_UpdateShard_Call) Run(run func(shard int)) *LiveStateCache_UpdateShard_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int)) - }) - return _c -} - -func (_c *LiveStateCache_UpdateShard_Call) Return(b bool) *LiveStateCache_UpdateShard_Call { - _c.Call.Return(b) - return _c -} - -func (_c *LiveStateCache_UpdateShard_Call) RunAndReturn(run func(shard int) bool) *LiveStateCache_UpdateShard_Call { - _c.Call.Return(run) - return _c -} diff --git a/controller/clusterinfoupdater.go b/controller/clusterinfoupdater.go index 65f4aed596..655ff6a59b 100644 --- a/controller/clusterinfoupdater.go +++ b/controller/clusterinfoupdater.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/gitops-engine/pkg/cache" "github.com/argoproj/gitops-engine/pkg/utils/kube" @@ -13,14 +13,14 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/util/env" - "github.com/argoproj/argo-cd/v3/controller/metrics" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/db" + "github.com/argoproj/argo-cd/v2/controller/metrics" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo" + appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" + "github.com/argoproj/argo-cd/v2/util/db" ) const ( @@ -132,12 +132,11 @@ func (c *clusterInfoUpdater) getUpdatedClusterInfo(ctx context.Context, apps []* continue } } - destCluster, err := argo.GetDestinationCluster(ctx, a.Spec.Destination, c.db) - if err != nil { + if err := argo.ValidateDestination(ctx, &a.Spec.Destination, c.db); err != nil { continue } - if destCluster.Server == cluster.Server { - appCount++ + if a.Spec.Destination.Server == cluster.Server { + appCount += 1 } } clusterInfo := appv1.ClusterInfo{ @@ -147,16 +146,15 @@ func (c *clusterInfoUpdater) getUpdatedClusterInfo(ctx context.Context, apps []* if info != nil { clusterInfo.ServerVersion = info.K8SVersion clusterInfo.APIVersions = argo.APIResourcesToStrings(info.APIResources, true) - switch { - case info.LastCacheSyncTime == nil: + if info.LastCacheSyncTime == nil { clusterInfo.ConnectionState.Status = appv1.ConnectionStatusUnknown - case info.SyncError == nil: + } else if info.SyncError == nil { clusterInfo.ConnectionState.Status = appv1.ConnectionStatusSuccessful syncTime := metav1.NewTime(*info.LastCacheSyncTime) clusterInfo.CacheInfo.LastCacheSyncTime = &syncTime clusterInfo.CacheInfo.APIsCount = int64(info.APIsCount) clusterInfo.CacheInfo.ResourcesCount = int64(info.ResourcesCount) - default: + } else { clusterInfo.ConnectionState.Status = appv1.ConnectionStatusFailed clusterInfo.ConnectionState.Message = info.SyncError.Error() } diff --git a/controller/clusterinfoupdater_test.go b/controller/clusterinfoupdater_test.go index 8c66e1ce13..6dc10d9db3 100644 --- a/controller/clusterinfoupdater_test.go +++ b/controller/clusterinfoupdater_test.go @@ -7,19 +7,19 @@ import ( "testing" "time" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appsfake "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - appinformers "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions/application/v1alpha1" - applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appsfake "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + appinformers "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions/application/v1alpha1" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/argoproj/argo-cd/v2/util/cache/appstate" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/settings" clustercache "github.com/argoproj/gitops-engine/pkg/cache" "github.com/stretchr/testify/assert" @@ -41,10 +41,10 @@ func TestClusterSecretUpdater(t *testing.T) { }{ {nil, nil, v1alpha1.ConnectionStatusUnknown}, {&now, nil, v1alpha1.ConnectionStatusSuccessful}, - {&now, errors.New("sync failed"), v1alpha1.ConnectionStatusFailed}, + {&now, fmt.Errorf("sync failed"), v1alpha1.ConnectionStatusFailed}, } - emptyArgoCDConfigMap := &corev1.ConfigMap{ + emptyArgoCDConfigMap := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: fakeNamespace, @@ -54,7 +54,7 @@ func TestClusterSecretUpdater(t *testing.T) { }, Data: map[string]string{}, } - argoCDSecret := &corev1.Secret{ + argoCDSecret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: fakeNamespace, @@ -70,9 +70,9 @@ func TestClusterSecretUpdater(t *testing.T) { kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret) appclientset := appsfake.NewSimpleClientset() appInformer := appinformers.NewApplicationInformer(appclientset, "", time.Minute, cache.Indexers{}) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) + settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) argoDB := db.NewDB(fakeNamespace, settingsManager, kubeclientset) - ctx, cancel := context.WithCancel(t.Context()) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() appCache := appstate.NewCache(cacheutil.NewCache(cacheutil.NewInMemoryCache(time.Minute)), time.Minute) @@ -90,7 +90,7 @@ func TestClusterSecretUpdater(t *testing.T) { lister := applisters.NewApplicationLister(appInformer.GetIndexer()).Applications(fakeNamespace) updater := NewClusterInfoUpdater(nil, argoDB, lister, appCache, nil, nil, fakeNamespace) - err = updater.updateClusterInfo(t.Context(), *cluster, info) + err = updater.updateClusterInfo(context.Background(), *cluster, info) require.NoError(t, err, "Invoking updateClusterInfo failed.") var clusterInfo v1alpha1.ClusterInfo @@ -102,7 +102,7 @@ func TestClusterSecretUpdater(t *testing.T) { } func TestUpdateClusterLabels(t *testing.T) { - shouldNotBeInvoked := func(_ context.Context, _ *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { + shouldNotBeInvoked := func(ctx context.Context, cluster *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { shouldNotHappen := errors.New("if an error happens here, something's wrong") require.NoError(t, shouldNotHappen) return nil, shouldNotHappen @@ -160,7 +160,7 @@ func TestUpdateClusterLabels(t *testing.T) { Server: "kubernetes.svc.local", Labels: map[string]string{"argocd.argoproj.io/kubernetes-version": "1.27", "argocd.argoproj.io/auto-label-cluster-info": "true"}, }, - func(_ context.Context, cluster *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { + func(ctx context.Context, cluster *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { assert.Equal(t, "1.28", cluster.Labels["argocd.argoproj.io/kubernetes-version"]) return nil, nil }, @@ -176,7 +176,7 @@ func TestUpdateClusterLabels(t *testing.T) { Server: "kubernetes.svc.local", Labels: map[string]string{"argocd.argoproj.io/kubernetes-version": "1.27", "argocd.argoproj.io/auto-label-cluster-info": "true"}, }, - func(_ context.Context, cluster *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { + func(ctx context.Context, cluster *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { assert.Equal(t, "1.28", cluster.Labels["argocd.argoproj.io/kubernetes-version"]) return nil, errors.New("some error happened while saving") }, @@ -185,7 +185,7 @@ func TestUpdateClusterLabels(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tt.wantErr(t, updateClusterLabels(t.Context(), tt.clusterInfo, tt.cluster, tt.updateCluster), fmt.Sprintf("updateClusterLabels(%v, %v, %v)", t.Context(), tt.clusterInfo, tt.cluster)) + tt.wantErr(t, updateClusterLabels(context.Background(), tt.clusterInfo, tt.cluster, tt.updateCluster), fmt.Sprintf("updateClusterLabels(%v, %v, %v)", context.Background(), tt.clusterInfo, tt.cluster)) }) } } diff --git a/controller/health.go b/controller/health.go index ba2270629d..81bdcb06f1 100644 --- a/controller/health.go +++ b/controller/health.go @@ -10,19 +10,20 @@ import ( log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/runtime/schema" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - applog "github.com/argoproj/argo-cd/v3/util/app/log" - "github.com/argoproj/argo-cd/v3/util/lua" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/lua" ) // setApplicationHealth updates the health statuses of all resources performed in the comparison -func setApplicationHealth(resources []managedResource, statuses []appv1.ResourceStatus, resourceOverrides map[string]appv1.ResourceOverride, app *appv1.Application, persistResourceHealth bool) (health.HealthStatusCode, error) { +func setApplicationHealth(resources []managedResource, statuses []appv1.ResourceStatus, resourceOverrides map[string]appv1.ResourceOverride, app *appv1.Application, persistResourceHealth bool) (*appv1.HealthStatus, error) { var savedErr error var errCount uint - appHealthStatus := health.HealthStatusHealthy + appHealth := app.Status.Health.DeepCopy() + appHealth.Status = health.HealthStatusHealthy + for i, res := range resources { if res.Target != nil && hookutil.Skip(res.Target) { continue @@ -51,7 +52,7 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource errCount++ savedErr = fmt.Errorf("failed to get resource health for %q with name %q in namespace %q: %w", res.Live.GetKind(), res.Live.GetName(), res.Live.GetNamespace(), err) // also log so we don't lose the message - log.WithFields(applog.GetAppLogFields(app)).Warn(savedErr) + log.WithField("application", app.QualifiedName()).Warn(savedErr) } } @@ -76,8 +77,8 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource continue } - if health.IsWorse(appHealthStatus, healthStatus.Status) { - appHealthStatus = healthStatus.Status + if health.IsWorse(appHealth.Status, healthStatus.Status) { + appHealth.Status = healthStatus.Status } } if persistResourceHealth { @@ -88,5 +89,5 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource if savedErr != nil && errCount > 1 { savedErr = fmt.Errorf("see application-controller logs for %d other errors; most recent error was: %w", errCount-1, savedErr) } - return appHealthStatus, savedErr + return appHealth, savedErr } diff --git a/controller/health_test.go b/controller/health_test.go index fff2adce73..03594df26b 100644 --- a/controller/health_test.go +++ b/controller/health_test.go @@ -16,15 +16,15 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/lua" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/lua" ) var ( app = &appv1.Application{ Status: appv1.ApplicationStatus{ - Health: appv1.AppHealthStatus{ + Health: appv1.HealthStatus{ LastTransitionTime: &metav1.Time{Time: time.Date(2020, time.January, 1, 12, 0, 0, 0, time.UTC)}, }, }, @@ -66,17 +66,23 @@ func TestSetApplicationHealth(t *testing.T) { healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true) require.NoError(t, err) - assert.Equal(t, health.HealthStatusDegraded, healthStatus) + assert.Equal(t, health.HealthStatusDegraded, healthStatus.Status) assert.Equal(t, health.HealthStatusHealthy, resourceStatuses[0].Health.Status) assert.Equal(t, health.HealthStatusDegraded, resourceStatuses[1].Health.Status) - app.Status.Health.Status = healthStatus + // Health.LastTransitionTime is set only for app health and not at individual resource level + assert.NotNil(t, healthStatus.LastTransitionTime) + assert.Nil(t, resourceStatuses[0].Health.LastTransitionTime) + assert.Nil(t, resourceStatuses[1].Health.LastTransitionTime) + app.Status.Health = *healthStatus // now mark the job as a hook and retry. it should ignore the hook and consider the app healthy failedJob.SetAnnotations(map[string]string{synccommon.AnnotationKeyHook: "PreSync"}) healthStatus, err = setApplicationHealth(resources, resourceStatuses, nil, app, true) require.NoError(t, err) - assert.Equal(t, health.HealthStatusHealthy, healthStatus) - app.Status.Health.Status = healthStatus + assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status) + // timestamp should be the same in case health did not change + assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime) + app.Status.Health = *healthStatus // now we set the `argocd.argoproj.io/ignore-healthcheck: "true"` annotation on the job's target. // The app is considered healthy @@ -85,7 +91,8 @@ func TestSetApplicationHealth(t *testing.T) { resources[1].Target = &failedJobIgnoreHealthcheck healthStatus, err = setApplicationHealth(resources, resourceStatuses, nil, app, true) require.NoError(t, err) - assert.Equal(t, health.HealthStatusHealthy, healthStatus) + assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status) + assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime) } func TestSetApplicationHealth_ResourceHealthNotPersisted(t *testing.T) { @@ -98,7 +105,7 @@ func TestSetApplicationHealth_ResourceHealthNotPersisted(t *testing.T) { healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, false) require.NoError(t, err) - assert.Equal(t, health.HealthStatusDegraded, healthStatus) + assert.Equal(t, health.HealthStatusDegraded, healthStatus.Status) assert.Nil(t, resourceStatuses[0].Health) } @@ -113,7 +120,8 @@ func TestSetApplicationHealth_MissingResource(t *testing.T) { healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true) require.NoError(t, err) - assert.Equal(t, health.HealthStatusMissing, healthStatus) + assert.Equal(t, health.HealthStatusMissing, healthStatus.Status) + assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime) } func TestSetApplicationHealth_HealthImproves(t *testing.T) { @@ -144,7 +152,8 @@ func TestSetApplicationHealth_HealthImproves(t *testing.T) { t.Run(string(fmt.Sprintf("%s to %s", tc.oldStatus, tc.newStatus)), func(t *testing.T) { healthStatus, err := setApplicationHealth(resources, resourceStatuses, overrides, app, true) require.NoError(t, err) - assert.Equal(t, tc.newStatus, healthStatus) + assert.Equal(t, tc.newStatus, healthStatus.Status) + assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime) }) } } @@ -160,7 +169,8 @@ func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) { t.Run("NoOverride", func(t *testing.T) { healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true) require.NoError(t, err) - assert.Equal(t, health.HealthStatusHealthy, healthStatus) + assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status) + assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime) assert.Equal(t, health.HealthStatusMissing, resourceStatuses[0].Health.Status) }) @@ -171,7 +181,8 @@ func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) { }, }, app, true) require.NoError(t, err) - assert.Equal(t, health.HealthStatusMissing, healthStatus) + assert.Equal(t, health.HealthStatusMissing, healthStatus.Status) + assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime) }) } @@ -185,7 +196,7 @@ func newAppLiveObj(status health.HealthStatusCode) *unstructured.Unstructured { Kind: application.ApplicationKind, }, Status: appv1.ApplicationStatus{ - Health: appv1.AppHealthStatus{ + Health: appv1.HealthStatus{ Status: status, }, }, @@ -222,7 +233,7 @@ return hs`, healthStatus, err := setApplicationHealth(resources, resourceStatuses, overrides, app, true) require.NoError(t, err) - assert.Equal(t, health.HealthStatusDegraded, healthStatus) + assert.Equal(t, health.HealthStatusDegraded, healthStatus.Status) }) t.Run("ChildAppMissing", func(t *testing.T) { @@ -234,6 +245,6 @@ return hs`, healthStatus, err := setApplicationHealth(resources, resourceStatuses, overrides, app, true) require.NoError(t, err) - assert.Equal(t, health.HealthStatusHealthy, healthStatus) + assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status) }) } diff --git a/controller/hook.go b/controller/hook.go index 2bf30d1b7f..b0fd8ebb03 100644 --- a/controller/hook.go +++ b/controller/hook.go @@ -8,13 +8,13 @@ import ( "github.com/argoproj/gitops-engine/pkg/sync/hook" "github.com/argoproj/gitops-engine/pkg/utils/kube" log "github.com/sirupsen/logrus" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/client-go/rest" - "github.com/argoproj/argo-cd/v3/util/lua" + "github.com/argoproj/argo-cd/v2/util/lua" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) var ( @@ -76,7 +76,7 @@ func (ctrl *ApplicationController) executePostDeleteHooks(app *v1alpha1.Applicat } createdCnt := 0 for _, obj := range expectedHook { - _, err = ctrl.kubectl.CreateResource(context.Background(), config, obj.GroupVersionKind(), obj.GetName(), obj.GetNamespace(), obj, metav1.CreateOptions{}) + _, err = ctrl.kubectl.CreateResource(context.Background(), config, obj.GroupVersionKind(), obj.GetName(), obj.GetNamespace(), obj, v1.CreateOptions{}) if err != nil { return false, err } @@ -159,7 +159,7 @@ func (ctrl *ApplicationController) cleanupPostDeleteHooks(liveObjs map[kube.Reso continue } logCtx.Infof("Deleting post-delete hook %s/%s", obj.GetNamespace(), obj.GetName()) - err = ctrl.kubectl.DeleteResource(context.Background(), config, obj.GroupVersionKind(), obj.GetName(), obj.GetNamespace(), metav1.DeleteOptions{}) + err = ctrl.kubectl.DeleteResource(context.Background(), config, obj.GroupVersionKind(), obj.GetName(), obj.GetNamespace(), v1.DeleteOptions{}) if err != nil { return false, err } diff --git a/controller/hydrator/hydrator.go b/controller/hydrator/hydrator.go index 023fb360f4..6c16d97dbe 100644 --- a/controller/hydrator/hydrator.go +++ b/controller/hydrator/hydrator.go @@ -10,11 +10,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - commitclient "github.com/argoproj/argo-cd/v3/commitserver/apiclient" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - applog "github.com/argoproj/argo-cd/v3/util/app/log" - utilio "github.com/argoproj/argo-cd/v3/util/io" + commitclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/controller/utils" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + argoio "github.com/argoproj/argo-cd/v2/util/io" ) // Dependencies is the interface for the dependencies of the Hydrator. It serves two purposes: 1) it prevents the @@ -55,7 +55,7 @@ func (h *Hydrator) ProcessAppHydrateQueueItem(origApp *appv1.Application) { return } - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := utils.GetAppLog(app) logCtx.Debug("Processing app hydrate queue item") @@ -130,7 +130,7 @@ func (h *Hydrator) ProcessHydrationQueueItem(hydrationKey HydrationQueueKey) (pr // in case we did. app.Status.SourceHydrator.CurrentOperation.DrySHA = drySHA h.dependencies.PersistAppHydratorStatus(origApp, &app.Status.SourceHydrator) - logCtx = logCtx.WithFields(applog.GetAppLogFields(app)) + logCtx = logCtx.WithField("app", app.QualifiedName()) logCtx.Errorf("Failed to hydrate app: %v", err) } return @@ -262,7 +262,7 @@ func (h *Hydrator) hydrate(logCtx *log.Entry, apps []*appv1.Application) (string // TODO: enable signature verification objs, resp, err := h.dependencies.GetRepoObjs(app, drySource, targetRevision, project) if err != nil { - return "", "", fmt.Errorf("failed to get repo objects for app %q: %w", app.QualifiedName(), err) + return "", "", fmt.Errorf("failed to get repo objects: %w", err) } // This should be the DRY SHA. We set it here so that after processing the first app, all apps are hydrated @@ -272,11 +272,11 @@ func (h *Hydrator) hydrate(logCtx *log.Entry, apps []*appv1.Application) (string // Set up a ManifestsRequest manifestDetails := make([]*commitclient.HydratedManifestDetails, len(objs)) for i, obj := range objs { - objJSON, err := json.Marshal(obj) + objJson, err := json.Marshal(obj) if err != nil { return "", "", fmt.Errorf("failed to marshal object: %w", err) } - manifestDetails[i] = &commitclient.HydratedManifestDetails{ManifestJSON: string(objJSON)} + manifestDetails[i] = &commitclient.HydratedManifestDetails{ManifestJSON: string(objJson)} } paths = append(paths, &commitclient.PathDetails{ @@ -312,7 +312,7 @@ func (h *Hydrator) hydrate(logCtx *log.Entry, apps []*appv1.Application) (string SyncBranch: syncBranch, TargetBranch: targetBranch, DrySha: targetRevision, - CommitMessage: "[Argo CD Bot] hydrate " + targetRevision, + CommitMessage: fmt.Sprintf("[Argo CD Bot] hydrate %s", targetRevision), Paths: paths, } @@ -320,7 +320,7 @@ func (h *Hydrator) hydrate(logCtx *log.Entry, apps []*appv1.Application) (string if err != nil { return targetRevision, "", fmt.Errorf("failed to create commit service: %w", err) } - defer utilio.Close(closer) + defer argoio.Close(closer) resp, err := commitService.CommitHydratedManifests(context.Background(), &manifestsRequest) if err != nil { return targetRevision, "", fmt.Errorf("failed to commit hydrated manifests: %w", err) @@ -339,16 +339,15 @@ func appNeedsHydration(app *appv1.Application, statusHydrateTimeout time.Duratio hydratedAt = &app.Status.SourceHydrator.CurrentOperation.StartedAt } - switch { - case app.IsHydrateRequested(): + if app.IsHydrateRequested() { return true, "hydrate requested" - case app.Status.SourceHydrator.CurrentOperation == nil: + } else if app.Status.SourceHydrator.CurrentOperation == nil { return true, "no previous hydrate operation" - case !app.Spec.SourceHydrator.DeepEquals(app.Status.SourceHydrator.CurrentOperation.SourceHydrator): + } else if !app.Spec.SourceHydrator.DeepEquals(app.Status.SourceHydrator.CurrentOperation.SourceHydrator) { return true, "spec.sourceHydrator differs" - case app.Status.SourceHydrator.CurrentOperation.Phase == appv1.HydrateOperationPhaseFailed && metav1.Now().Sub(app.Status.SourceHydrator.CurrentOperation.FinishedAt.Time) > 2*time.Minute: + } else if app.Status.SourceHydrator.CurrentOperation.Phase == appv1.HydrateOperationPhaseFailed && metav1.Now().Sub(app.Status.SourceHydrator.CurrentOperation.FinishedAt.Time) > 2*time.Minute { return true, "previous hydrate operation failed more than 2 minutes ago" - case hydratedAt == nil || hydratedAt.Add(statusHydrateTimeout).Before(time.Now().UTC()): + } else if hydratedAt == nil || hydratedAt.Add(statusHydrateTimeout).Before(time.Now().UTC()) { return true, "hydration expired" } diff --git a/controller/hydrator/hydrator_test.go b/controller/hydrator/hydrator_test.go index e0b7cfee79..c4e62931a5 100644 --- a/controller/hydrator/hydrator_test.go +++ b/controller/hydrator/hydrator_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func Test_appNeedsHydration(t *testing.T) { diff --git a/controller/hydrator_dependencies.go b/controller/hydrator_dependencies.go index e846499248..a65fb7d2c3 100644 --- a/controller/hydrator_dependencies.go +++ b/controller/hydrator_dependencies.go @@ -4,10 +4,10 @@ import ( "context" "fmt" - "github.com/argoproj/argo-cd/v3/controller/hydrator" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - argoutil "github.com/argoproj/argo-cd/v3/util/argo" + "github.com/argoproj/argo-cd/v2/controller/hydrator" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + argoutil "github.com/argoproj/argo-cd/v2/util/argo" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/controller/metrics/clustercollector.go b/controller/metrics/clustercollector.go index 1881ae6efe..edbe8c2581 100644 --- a/controller/metrics/clustercollector.go +++ b/controller/metrics/clustercollector.go @@ -6,27 +6,21 @@ import ( "time" "github.com/argoproj/gitops-engine/pkg/cache" - "github.com/prometheus/client_golang/prometheus" - log "github.com/sirupsen/logrus" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - metricsutil "github.com/argoproj/argo-cd/v3/util/metrics" + "github.com/prometheus/client_golang/prometheus" ) const ( metricsCollectionInterval = 30 * time.Second - metricsCollectionTimeout = 10 * time.Second ) var ( descClusterDefaultLabels = []string{"server"} - descClusterLabels *prometheus.Desc - descClusterInfo = prometheus.NewDesc( "argocd_cluster_info", "Information about cluster.", - append(descClusterDefaultLabels, "k8s_version", "name"), + append(descClusterDefaultLabels, "k8s_version"), nil, ) descClusterCacheResources = prometheus.NewDesc( @@ -59,101 +53,30 @@ type HasClustersInfo interface { GetClustersInfo() []cache.ClusterInfo } -type ClusterLister func(ctx context.Context) (*argoappv1.ClusterList, error) - type clusterCollector struct { - infoSource HasClustersInfo - lock sync.RWMutex - clusterLabels []string - clusterLister ClusterLister - - latestInfo []*clusterData + infoSource HasClustersInfo + info []cache.ClusterInfo + lock sync.Mutex } -type clusterData struct { - info *cache.ClusterInfo - cluster *argoappv1.Cluster -} - -func NewClusterCollector(ctx context.Context, source HasClustersInfo, clusterLister ClusterLister, clusterLabels []string) prometheus.Collector { - if len(clusterLabels) > 0 { - normalizedClusterLabels := metricsutil.NormalizeLabels("label", clusterLabels) - descClusterLabels = prometheus.NewDesc( - "argocd_cluster_labels", - "Argo Cluster labels converted to Prometheus labels", - append(append(descClusterDefaultLabels, "name"), normalizedClusterLabels...), - nil, - ) - } - - collector := &clusterCollector{ - infoSource: source, - clusterLabels: clusterLabels, - clusterLister: clusterLister, - lock: sync.RWMutex{}, - } - - collector.setClusterData() - go collector.run(ctx) - - return collector -} - -func (c *clusterCollector) run(ctx context.Context) { - //nolint:staticcheck // FIXME: complains about SA1015 +func (c *clusterCollector) Run(ctx context.Context) { + // FIXME: complains about SA1015 + // nolint:staticcheck tick := time.Tick(metricsCollectionInterval) for { select { case <-ctx.Done(): + break case <-tick: - c.setClusterData() + info := c.infoSource.GetClustersInfo() + + c.lock.Lock() + c.info = info + c.lock.Unlock() } } } -func (c *clusterCollector) setClusterData() { - if clusterData, err := c.getClusterData(); err == nil { - c.lock.Lock() - c.latestInfo = clusterData - c.lock.Unlock() - } else { - log.Warnf("error collecting cluster metrics: %v", err) - } -} - -func (c *clusterCollector) getClusterData() ([]*clusterData, error) { - clusterDatas := []*clusterData{} - clusterInfos := c.infoSource.GetClustersInfo() - - ctx, cancel := context.WithTimeout(context.Background(), metricsCollectionTimeout) - defer cancel() - clusters, err := c.clusterLister(ctx) - if err != nil { - return nil, err - } - - clusterMap := map[string]*argoappv1.Cluster{} - for i, cluster := range clusters.Items { - clusterMap[cluster.Server] = &clusters.Items[i] - } - - // Base the cluster data on the ClusterInfo because it only contains the - // clusters managed by this controller instance - for i, info := range clusterInfos { - cluster, ok := clusterMap[info.Server] - if !ok { - // This should not happen, but we cannot emit incomplete metrics, so we skip this cluster - log.WithField("server", info.Server).Warnf("could find cluster for metrics collection") - continue - } - clusterDatas = append(clusterDatas, &clusterData{ - info: &clusterInfos[i], - cluster: cluster, - }) - } - return clusterDatas, nil -} - // Describe implements the prometheus.Collector interface func (c *clusterCollector) Describe(ch chan<- *prometheus.Desc) { ch <- descClusterInfo @@ -161,41 +84,20 @@ func (c *clusterCollector) Describe(ch chan<- *prometheus.Desc) { ch <- descClusterAPIs ch <- descClusterCacheAgeSeconds ch <- descClusterConnectionStatus - if len(c.clusterLabels) > 0 { - ch <- descClusterLabels - } } func (c *clusterCollector) Collect(ch chan<- prometheus.Metric) { - c.lock.RLock() - latestInfo := c.latestInfo - c.lock.RUnlock() - now := time.Now() - for _, clusterData := range latestInfo { - info := clusterData.info - name := clusterData.cluster.Name - labels := clusterData.cluster.Labels - - defaultValues := []string{info.Server} - ch <- prometheus.MustNewConstMetric(descClusterInfo, prometheus.GaugeValue, 1, append(defaultValues, info.K8SVersion, name)...) - ch <- prometheus.MustNewConstMetric(descClusterCacheResources, prometheus.GaugeValue, float64(info.ResourcesCount), defaultValues...) - ch <- prometheus.MustNewConstMetric(descClusterAPIs, prometheus.GaugeValue, float64(info.APIsCount), defaultValues...) + for _, c := range c.info { + defaultValues := []string{c.Server} + ch <- prometheus.MustNewConstMetric(descClusterInfo, prometheus.GaugeValue, 1, append(defaultValues, c.K8SVersion)...) + ch <- prometheus.MustNewConstMetric(descClusterCacheResources, prometheus.GaugeValue, float64(c.ResourcesCount), defaultValues...) + ch <- prometheus.MustNewConstMetric(descClusterAPIs, prometheus.GaugeValue, float64(c.APIsCount), defaultValues...) cacheAgeSeconds := -1 - if info.LastCacheSyncTime != nil { - cacheAgeSeconds = int(now.Sub(*info.LastCacheSyncTime).Seconds()) + if c.LastCacheSyncTime != nil { + cacheAgeSeconds = int(now.Sub(*c.LastCacheSyncTime).Seconds()) } ch <- prometheus.MustNewConstMetric(descClusterCacheAgeSeconds, prometheus.GaugeValue, float64(cacheAgeSeconds), defaultValues...) - ch <- prometheus.MustNewConstMetric(descClusterConnectionStatus, prometheus.GaugeValue, boolFloat64(info.SyncError == nil), append(defaultValues, info.K8SVersion)...) - - if len(c.clusterLabels) > 0 && labels != nil { - labelValues := []string{} - labelValues = append(labelValues, info.Server, name) - for _, desiredLabel := range c.clusterLabels { - value := labels[desiredLabel] - labelValues = append(labelValues, value) - } - ch <- prometheus.MustNewConstMetric(descClusterLabels, prometheus.GaugeValue, 1, labelValues...) - } + ch <- prometheus.MustNewConstMetric(descClusterConnectionStatus, prometheus.GaugeValue, boolFloat64(c.SyncError == nil), append(defaultValues, c.K8SVersion)...) } } diff --git a/controller/metrics/clustercollector_test.go b/controller/metrics/clustercollector_test.go index 3f1881447b..cbe124ca29 100644 --- a/controller/metrics/clustercollector_test.go +++ b/controller/metrics/clustercollector_test.go @@ -5,36 +5,21 @@ import ( "testing" gitopsCache "github.com/argoproj/gitops-engine/pkg/cache" - "github.com/stretchr/testify/mock" - - dbmocks "github.com/argoproj/argo-cd/v3/util/db/mocks" - - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" ) func TestMetricClusterConnectivity(t *testing.T) { - db := dbmocks.ArgoDB{} - cluster1 := v1alpha1.Cluster{Name: "cluster1", Server: "server1", Labels: map[string]string{"env": "dev", "team": "team1"}} - cluster2 := v1alpha1.Cluster{Name: "cluster2", Server: "server2", Labels: map[string]string{"env": "staging", "team": "team2"}} - cluster3 := v1alpha1.Cluster{Name: "cluster3", Server: "server3", Labels: map[string]string{"env": "production", "team": "team3"}} - clusterList := &v1alpha1.ClusterList{Items: []v1alpha1.Cluster{cluster1, cluster2, cluster3}} - db.On("ListClusters", mock.Anything).Return(clusterList, nil) - type testCases struct { testCombination - skip bool - description string - metricLabels []string - clusterLabels []string - clustersInfo []gitopsCache.ClusterInfo + skip bool + description string + metricLabels []string + clustersInfo []gitopsCache.ClusterInfo } - cases := []testCases{ { - description: "metric will have value 1 if connected with the cluster", - skip: false, - metricLabels: []string{"non-existing"}, - clusterLabels: []string{"env"}, + description: "metric will have value 1 if connected with the cluster", + skip: false, + metricLabels: []string{"non-existing"}, testCombination: testCombination{ applications: []string{fakeApp}, responseContains: ` @@ -51,10 +36,9 @@ argocd_cluster_connection_status{k8s_version="1.21",server="server1"} 1 }, }, { - description: "metric will have value 0 if not connected with the cluster", - skip: false, - metricLabels: []string{"non-existing"}, - clusterLabels: []string{"env"}, + description: "metric will have value 0 if not connected with the cluster", + skip: false, + metricLabels: []string{"non-existing"}, testCombination: testCombination{ applications: []string{fakeApp}, responseContains: ` @@ -71,10 +55,9 @@ argocd_cluster_connection_status{k8s_version="1.21",server="server1"} 0 }, }, { - description: "will have one metric per cluster", - skip: false, - metricLabels: []string{"non-existing"}, - clusterLabels: []string{"env", "team"}, + description: "will have one metric per cluster", + skip: false, + metricLabels: []string{"non-existing"}, testCombination: testCombination{ applications: []string{fakeApp}, responseContains: ` @@ -82,16 +65,6 @@ argocd_cluster_connection_status{k8s_version="1.21",server="server1"} 0 argocd_cluster_connection_status{k8s_version="1.21",server="server1"} 1 argocd_cluster_connection_status{k8s_version="1.21",server="server2"} 1 argocd_cluster_connection_status{k8s_version="1.21",server="server3"} 1 - -# TYPE argocd_cluster_info gauge -argocd_cluster_info{k8s_version="1.21",name="cluster1",server="server1"} 1 -argocd_cluster_info{k8s_version="1.21",name="cluster2",server="server2"} 1 -argocd_cluster_info{k8s_version="1.21",name="cluster3",server="server3"} 1 - -# TYPE argocd_cluster_labels gauge -argocd_cluster_labels{label_env="dev",label_team="team1",name="cluster1",server="server1"} 1 -argocd_cluster_labels{label_env="staging",label_team="team2",name="cluster2",server="server2"} 1 -argocd_cluster_labels{label_env="production",label_team="team3",name="cluster3",server="server3"} 1 `, }, clustersInfo: []gitopsCache.ClusterInfo{ @@ -122,9 +95,7 @@ argocd_cluster_labels{label_env="production",label_team="team3",name="cluster3", FakeAppYAMLs: c.applications, ExpectedResponse: c.responseContains, AppLabels: c.metricLabels, - ClusterLabels: c.clusterLabels, ClustersInfo: c.clustersInfo, - ClusterLister: db.ListClusters, } runTest(t, cfg) } diff --git a/controller/metrics/metrics.go b/controller/metrics/metrics.go index 47a6396182..70339499e0 100644 --- a/controller/metrics/metrics.go +++ b/controller/metrics/metrics.go @@ -16,17 +16,16 @@ import ( "github.com/robfig/cron/v3" log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/labels" - ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics" - "github.com/argoproj/argo-cd/v3/common" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - applister "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/git" - "github.com/argoproj/argo-cd/v3/util/healthz" - metricsutil "github.com/argoproj/argo-cd/v3/util/metrics" - "github.com/argoproj/argo-cd/v3/util/metrics/kubectl" - "github.com/argoproj/argo-cd/v3/util/profile" + "github.com/argoproj/argo-cd/v2/common" + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + applister "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/healthz" + metricsutil "github.com/argoproj/argo-cd/v2/util/metrics" + "github.com/argoproj/argo-cd/v2/util/profile" + + ctrl_metrics "sigs.k8s.io/controller-runtime/pkg/metrics" ) type MetricsServer struct { @@ -50,6 +49,8 @@ type MetricsServer struct { const ( // MetricsPath is the endpoint to collect application metrics MetricsPath = "/metrics" + // EnvVarLegacyControllerMetrics is a env var to re-enable deprecated prometheus metrics + EnvVarLegacyControllerMetrics = "ARGOCD_LEGACY_CONTROLLER_METRICS" ) // Follow Prometheus naming practices @@ -67,12 +68,34 @@ var ( nil, ) + // Deprecated + descAppCreated = prometheus.NewDesc( + "argocd_app_created_time", + "Creation time in unix timestamp for an application.", + descAppDefaultLabels, + nil, + ) + // Deprecated: superseded by sync_status label in argocd_app_info + descAppSyncStatusCode = prometheus.NewDesc( + "argocd_app_sync_status", + "The application current sync status.", + append(descAppDefaultLabels, "sync_status"), + nil, + ) + // Deprecated: superseded by health_status label in argocd_app_info + descAppHealthStatus = prometheus.NewDesc( + "argocd_app_health_status", + "The application current health status.", + append(descAppDefaultLabels, "health_status"), + nil, + ) + syncCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "argocd_app_sync_total", Help: "Number of application syncs.", }, - append(descAppDefaultLabels, "dest_server", "phase", "dry_run"), + append(descAppDefaultLabels, "dest_server", "phase"), ) k8sRequestCounter = prometheus.NewCounterVec( @@ -80,7 +103,7 @@ var ( Name: "argocd_app_k8s_request_total", Help: "Number of kubernetes requests executed during application reconciliation.", }, - append(descAppDefaultLabels, "server", "response_code", "verb", "resource_kind", "resource_namespace", "dry_run"), + append(descAppDefaultLabels, "server", "response_code", "verb", "resource_kind", "resource_namespace"), ) kubectlExecCounter = prometheus.NewCounterVec(prometheus.CounterOpts{ @@ -149,7 +172,7 @@ var ( ) // NewMetricsServer returns a new prometheus server which collects application metrics -func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFilter func(obj any) bool, healthCheck func(r *http.Request) error, appLabels []string, appConditions []string) (*MetricsServer, error) { +func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFilter func(obj interface{}) bool, healthCheck func(r *http.Request) error, appLabels []string, appConditions []string) (*MetricsServer, error) { hostname, err := os.Hostname() if err != nil { return nil, err @@ -181,7 +204,7 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFil // contains app controller specific metrics registry, // contains workqueue metrics, process and golang metrics - ctrlmetrics.Registry, + ctrl_metrics.Registry, }, promhttp.HandlerOpts{})) profile.RegisterProfiler(mux) healthz.ServeHealthCheck(mux, healthCheck) @@ -198,11 +221,7 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFil registry.MustRegister(resourceEventsProcessingHistogram) registry.MustRegister(resourceEventsNumberGauge) - kubectlMetricsServer := kubectl.NewKubectlMetrics() - kubectlMetricsServer.RegisterWithClientGo() - kubectl.RegisterWithPrometheus(registry) - - metricsServer := &MetricsServer{ + return &MetricsServer{ registry: registry, Server: &http.Server{ Addr: addr, @@ -224,13 +243,12 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFil // Currently clearing the metrics cache is logging and deleting from the map // so there is no possibility of panic, but we will add a chain to keep robfig/cron v1 behavior. cron: cron.New(cron.WithChain(cron.Recover(cron.PrintfLogger(log.StandardLogger())))), - } - - return metricsServer, nil + }, nil } -func (m *MetricsServer) RegisterClustersInfoSource(ctx context.Context, source HasClustersInfo, db db.ArgoDB, clusterLabels []string) { - collector := NewClusterCollector(ctx, source, db.ListClusters, clusterLabels) +func (m *MetricsServer) RegisterClustersInfoSource(ctx context.Context, source HasClustersInfo) { + collector := &clusterCollector{infoSource: source} + go collector.Run(ctx) m.registry.MustRegister(collector) } @@ -239,8 +257,7 @@ func (m *MetricsServer) IncSync(app *argoappv1.Application, state *argoappv1.Ope if !state.Phase.Completed() { return } - isDryRun := app.Operation != nil && app.Operation.DryRun() - m.syncCounter.WithLabelValues(app.Namespace, app.Name, app.Spec.GetProject(), app.Spec.Destination.Server, string(state.Phase), strconv.FormatBool(isDryRun)).Inc() + m.syncCounter.WithLabelValues(app.Namespace, app.Name, app.Spec.GetProject(), app.Spec.Destination.Server, string(state.Phase)).Inc() } func (m *MetricsServer) IncKubectlExec(command string) { @@ -267,16 +284,14 @@ func (m *MetricsServer) IncClusterEventsCount(server, group, kind string) { // IncKubernetesRequest increments the kubernetes requests counter for an application func (m *MetricsServer) IncKubernetesRequest(app *argoappv1.Application, server, statusCode, verb, resourceKind, resourceNamespace string) { var namespace, name, project string - isDryRun := false if app != nil { namespace = app.Namespace name = app.Name project = app.Spec.GetProject() - isDryRun = app.Operation != nil && app.Operation.DryRun() } m.k8sRequestCounter.WithLabelValues( namespace, name, project, server, statusCode, - verb, resourceKind, resourceNamespace, strconv.FormatBool(isDryRun), + verb, resourceKind, resourceNamespace, ).Inc() } @@ -308,7 +323,7 @@ func (m *MetricsServer) HasExpiration() bool { // SetExpiration reset Prometheus metrics based on time duration interval func (m *MetricsServer) SetExpiration(cacheExpiration time.Duration) error { if m.HasExpiration() { - return errors.New("expiration is already set") + return errors.New("Expiration is already set") } _, err := m.cron.AddFunc(fmt.Sprintf("@every %s", cacheExpiration), func() { @@ -324,7 +339,6 @@ func (m *MetricsServer) SetExpiration(cacheExpiration time.Duration) error { m.redisRequestHistogram.Reset() m.resourceEventsProcessingHistogram.Reset() m.resourceEventsNumberGauge.Reset() - kubectl.ResetAll() }) if err != nil { return err @@ -336,13 +350,13 @@ func (m *MetricsServer) SetExpiration(cacheExpiration time.Duration) error { type appCollector struct { store applister.ApplicationLister - appFilter func(obj any) bool + appFilter func(obj interface{}) bool appLabels []string appConditions []string } // NewAppCollector returns a prometheus collector for application metrics -func NewAppCollector(appLister applister.ApplicationLister, appFilter func(obj any) bool, appLabels []string, appConditions []string) prometheus.Collector { +func NewAppCollector(appLister applister.ApplicationLister, appFilter func(obj interface{}) bool, appLabels []string, appConditions []string) prometheus.Collector { return &appCollector{ store: appLister, appFilter: appFilter, @@ -352,7 +366,7 @@ func NewAppCollector(appLister applister.ApplicationLister, appFilter func(obj a } // NewAppRegistry creates a new prometheus registry that collects applications -func NewAppRegistry(appLister applister.ApplicationLister, appFilter func(obj any) bool, appLabels []string, appConditions []string) *prometheus.Registry { +func NewAppRegistry(appLister applister.ApplicationLister, appFilter func(obj interface{}) bool, appLabels []string, appConditions []string) *prometheus.Registry { registry := prometheus.NewRegistry() registry.MustRegister(NewAppCollector(appLister, appFilter, appLabels, appConditions)) return registry @@ -367,6 +381,8 @@ func (c *appCollector) Describe(ch chan<- *prometheus.Desc) { ch <- descAppConditions } ch <- descAppInfo + ch <- descAppSyncStatusCode + ch <- descAppHealthStatus } // Collect implements the prometheus.Collector interface @@ -415,7 +431,7 @@ func (c *appCollector) collectApps(ch chan<- prometheus.Metric, app *argoappv1.A healthStatus = health.HealthStatusUnknown } - autoSyncEnabled := app.Spec.SyncPolicy != nil && app.Spec.SyncPolicy.IsAutomatedSyncEnabled() + autoSyncEnabled := app.Spec.SyncPolicy != nil && app.Spec.SyncPolicy.Automated != nil addGauge(descAppInfo, 1, strconv.FormatBool(autoSyncEnabled), git.NormalizeGitURL(app.Spec.GetSource().RepoURL), app.Spec.Destination.Server, app.Spec.Destination.Namespace, string(syncStatus), string(healthStatus), operation) @@ -440,4 +456,21 @@ func (c *appCollector) collectApps(ch chan<- prometheus.Metric, app *argoappv1.A addGauge(descAppConditions, float64(count), conditionType) } } + + // Deprecated controller metrics + if os.Getenv(EnvVarLegacyControllerMetrics) == "true" { + addGauge(descAppCreated, float64(app.CreationTimestamp.Unix())) + + addGauge(descAppSyncStatusCode, boolFloat64(syncStatus == argoappv1.SyncStatusCodeSynced), string(argoappv1.SyncStatusCodeSynced)) + addGauge(descAppSyncStatusCode, boolFloat64(syncStatus == argoappv1.SyncStatusCodeOutOfSync), string(argoappv1.SyncStatusCodeOutOfSync)) + addGauge(descAppSyncStatusCode, boolFloat64(syncStatus == argoappv1.SyncStatusCodeUnknown || syncStatus == ""), string(argoappv1.SyncStatusCodeUnknown)) + + healthStatus := app.Status.Health.Status + addGauge(descAppHealthStatus, boolFloat64(healthStatus == health.HealthStatusUnknown || healthStatus == ""), string(health.HealthStatusUnknown)) + addGauge(descAppHealthStatus, boolFloat64(healthStatus == health.HealthStatusProgressing), string(health.HealthStatusProgressing)) + addGauge(descAppHealthStatus, boolFloat64(healthStatus == health.HealthStatusSuspended), string(health.HealthStatusSuspended)) + addGauge(descAppHealthStatus, boolFloat64(healthStatus == health.HealthStatusHealthy), string(health.HealthStatusHealthy)) + addGauge(descAppHealthStatus, boolFloat64(healthStatus == health.HealthStatusDegraded), string(health.HealthStatusDegraded)) + addGauge(descAppHealthStatus, boolFloat64(healthStatus == health.HealthStatusMissing), string(health.HealthStatusMissing)) + } } diff --git a/controller/metrics/metrics_test.go b/controller/metrics/metrics_test.go index 7b66feb24f..383cb0c0c3 100644 --- a/controller/metrics/metrics_test.go +++ b/controller/metrics/metrics_test.go @@ -19,10 +19,10 @@ import ( "k8s.io/client-go/util/workqueue" "sigs.k8s.io/yaml" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - appinformer "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions" - applister "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions" + applister "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" "sigs.k8s.io/controller-runtime/pkg/controller" ) @@ -81,7 +81,6 @@ status: status: Healthy operation: sync: - dryRun: true revision: 041eab7439ece92c99b043f0e171788185b8fc1d syncStrategy: hook: {} @@ -172,11 +171,11 @@ status: status: Healthy ` -var noOpHealthCheck = func(_ *http.Request) error { +var noOpHealthCheck = func(r *http.Request) error { return nil } -var appFilter = func(_ any) bool { +var appFilter = func(obj interface{}) bool { return true } @@ -204,7 +203,7 @@ func newFakeLister(fakeAppYAMLs ...string) (context.CancelFunc, applister.Applic fakeApps = append(fakeApps, a) } appClientset := appclientset.NewSimpleClientset(fakeApps...) - factory := appinformer.NewSharedInformerFactoryWithOptions(appClientset, 0, appinformer.WithNamespace("argocd"), appinformer.WithTweakListOptions(func(_ *metav1.ListOptions) {})) + factory := appinformer.NewSharedInformerFactoryWithOptions(appClientset, 0, appinformer.WithNamespace("argocd"), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) appInformer := factory.Argoproj().V1alpha1().Applications().Informer() go appInformer.Run(ctx.Done()) if !cache.WaitForCacheSync(ctx.Done(), appInformer.HasSynced) { @@ -231,9 +230,7 @@ type TestMetricServerConfig struct { ExpectedResponse string AppLabels []string AppConditions []string - ClusterLabels []string ClustersInfo []gitopsCache.ClusterInfo - ClusterLister ClusterLister } func testMetricServer(t *testing.T, fakeAppYAMLs []string, expectedResponse string, appLabels []string, appConditions []string) { @@ -243,7 +240,6 @@ func testMetricServer(t *testing.T, fakeAppYAMLs []string, expectedResponse stri ExpectedResponse: expectedResponse, AppLabels: appLabels, AppConditions: appConditions, - ClusterLabels: []string{}, ClustersInfo: []gitopsCache.ClusterInfo{}, } runTest(t, cfg) @@ -258,7 +254,10 @@ func runTest(t *testing.T, cfg TestMetricServerConfig) { if len(cfg.ClustersInfo) > 0 { ci := &fakeClusterInfo{clustersInfo: cfg.ClustersInfo} - collector := NewClusterCollector(t.Context(), ci, cfg.ClusterLister, cfg.ClusterLabels) + collector := &clusterCollector{ + infoSource: ci, + info: ci.GetClustersInfo(), + } metricsServ.registry.MustRegister(collector) } @@ -400,6 +399,30 @@ argocd_app_condition{condition="ExcludedResourceWarning",name="my-app-4",namespa } } +func TestLegacyMetrics(t *testing.T) { + t.Setenv(EnvVarLegacyControllerMetrics, "true") + + expectedResponse := ` +# HELP argocd_app_created_time Creation time in unix timestamp for an application. +# TYPE argocd_app_created_time gauge +argocd_app_created_time{name="my-app",namespace="argocd",project="important-project"} -6.21355968e+10 +# HELP argocd_app_health_status The application current health status. +# TYPE argocd_app_health_status gauge +argocd_app_health_status{health_status="Degraded",name="my-app",namespace="argocd",project="important-project"} 0 +argocd_app_health_status{health_status="Healthy",name="my-app",namespace="argocd",project="important-project"} 1 +argocd_app_health_status{health_status="Missing",name="my-app",namespace="argocd",project="important-project"} 0 +argocd_app_health_status{health_status="Progressing",name="my-app",namespace="argocd",project="important-project"} 0 +argocd_app_health_status{health_status="Suspended",name="my-app",namespace="argocd",project="important-project"} 0 +argocd_app_health_status{health_status="Unknown",name="my-app",namespace="argocd",project="important-project"} 0 +# HELP argocd_app_sync_status The application current sync status. +# TYPE argocd_app_sync_status gauge +argocd_app_sync_status{name="my-app",namespace="argocd",project="important-project",sync_status="OutOfSync"} 0 +argocd_app_sync_status{name="my-app",namespace="argocd",project="important-project",sync_status="Synced"} 1 +argocd_app_sync_status{name="my-app",namespace="argocd",project="important-project",sync_status="Unknown"} 0 +` + testApp(t, []string{fakeApp}, expectedResponse) +} + func TestMetricsSyncCounter(t *testing.T) { cancel, appLister := newFakeLister() defer cancel() @@ -409,9 +432,9 @@ func TestMetricsSyncCounter(t *testing.T) { appSyncTotal := ` # HELP argocd_app_sync_total Number of application syncs. # TYPE argocd_app_sync_total counter -argocd_app_sync_total{dest_server="https://localhost:6443",dry_run="false",name="my-app",namespace="argocd",phase="Error",project="important-project"} 1 -argocd_app_sync_total{dest_server="https://localhost:6443",dry_run="false",name="my-app",namespace="argocd",phase="Failed",project="important-project"} 1 -argocd_app_sync_total{dest_server="https://localhost:6443",dry_run="false",name="my-app",namespace="argocd",phase="Succeeded",project="important-project"} 2 +argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespace="argocd",phase="Error",project="important-project"} 1 +argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespace="argocd",phase="Failed",project="important-project"} 1 +argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespace="argocd",phase="Succeeded",project="important-project"} 2 ` fakeApp := newFakeApp(fakeApp) @@ -520,9 +543,9 @@ func TestMetricsReset(t *testing.T) { appSyncTotal := ` # HELP argocd_app_sync_total Number of application syncs. # TYPE argocd_app_sync_total counter -argocd_app_sync_total{dest_server="https://localhost:6443",dry_run="false",name="my-app",namespace="argocd",phase="Error",project="important-project"} 1 -argocd_app_sync_total{dest_server="https://localhost:6443",dry_run="false",name="my-app",namespace="argocd",phase="Failed",project="important-project"} 1 -argocd_app_sync_total{dest_server="https://localhost:6443",dry_run="false",name="my-app",namespace="argocd",phase="Succeeded",project="important-project"} 2 +argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespace="argocd",phase="Error",project="important-project"} 1 +argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespace="argocd",phase="Failed",project="important-project"} 1 +argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespace="argocd",phase="Succeeded",project="important-project"} 2 ` req, err := http.NewRequest(http.MethodGet, "/metrics", nil) diff --git a/controller/metrics/transportwrapper.go b/controller/metrics/transportwrapper.go index 01371c7710..637619bcd2 100644 --- a/controller/metrics/transportwrapper.go +++ b/controller/metrics/transportwrapper.go @@ -3,10 +3,10 @@ package metrics import ( "strconv" - "github.com/argoproj/pkg/v2/kubeclientmetrics" + "github.com/argoproj/pkg/kubeclientmetrics" "k8s.io/client-go/rest" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) // AddMetricsTransportWrapper adds a transport wrapper which increments 'argocd_app_k8s_request_total' counter on each kubernetes request diff --git a/controller/sharding/cache.go b/controller/sharding/cache.go index 346145543a..4a750e3545 100644 --- a/controller/sharding/cache.go +++ b/controller/sharding/cache.go @@ -5,8 +5,8 @@ import ( log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/db" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/db" ) type ClusterShardingCache interface { @@ -20,7 +20,6 @@ type ClusterShardingCache interface { IsManagedCluster(c *v1alpha1.Cluster) bool GetDistribution() map[string]int GetAppDistribution() map[string]int - UpdateShard(shard int) bool } type ClusterSharding struct { @@ -54,20 +53,20 @@ func NewClusterSharding(_ db.ArgoDB, shard, replicas int, shardingAlgorithm stri } // IsManagedCluster returns whether or not the cluster should be processed by a given shard. -func (sharding *ClusterSharding) IsManagedCluster(c *v1alpha1.Cluster) bool { - sharding.lock.RLock() - defer sharding.lock.RUnlock() +func (s *ClusterSharding) IsManagedCluster(c *v1alpha1.Cluster) bool { + s.lock.RLock() + defer s.lock.RUnlock() if c == nil { // nil cluster (in-cluster) is always managed by current clusterShard return true } clusterShard := 0 - if shard, ok := sharding.Shards[c.Server]; ok { + if shard, ok := s.Shards[c.Server]; ok { clusterShard = shard } else { log.Warnf("The cluster %s has no assigned shard.", c.Server) } - log.Debugf("Checking if cluster %s with clusterShard %d should be processed by shard %d", c.Server, clusterShard, sharding.Shard) - return clusterShard == sharding.Shard + log.Debugf("Checking if cluster %s with clusterShard %d should be processed by shard %d", c.Server, clusterShard, s.Shard) + return clusterShard == s.Shard } func (sharding *ClusterSharding) Init(clusters *v1alpha1.ClusterList, apps *v1alpha1.ApplicationList) { @@ -155,12 +154,11 @@ func (sharding *ClusterSharding) updateDistribution() { } existingShard, ok := sharding.Shards[k] - switch { - case ok && existingShard != shard: + if ok && existingShard != shard { log.Infof("Cluster %s has changed shard from %d to %d", k, existingShard, shard) - case !ok: + } else if !ok { log.Infof("Cluster %s has been assigned to shard %d", k, shard) - default: + } else { log.Debugf("Cluster %s has not changed shard", k) } sharding.Shards[k] = shard @@ -190,11 +188,11 @@ func hasShardingUpdates(old, new *v1alpha1.Cluster) bool { } // A read lock should be acquired before calling getClusterAccessor. -func (sharding *ClusterSharding) getClusterAccessor() clusterAccessor { +func (d *ClusterSharding) getClusterAccessor() clusterAccessor { return func() []*v1alpha1.Cluster { // no need to lock, as this is only called from the updateDistribution function - clusters := make([]*v1alpha1.Cluster, 0, len(sharding.Clusters)) - for _, c := range sharding.Clusters { + clusters := make([]*v1alpha1.Cluster, 0, len(d.Clusters)) + for _, c := range d.Clusters { clusters = append(clusters, c) } return clusters @@ -202,10 +200,10 @@ func (sharding *ClusterSharding) getClusterAccessor() clusterAccessor { } // A read lock should be acquired before calling getAppAccessor. -func (sharding *ClusterSharding) getAppAccessor() appAccessor { +func (d *ClusterSharding) getAppAccessor() appAccessor { return func() []*v1alpha1.Application { - apps := make([]*v1alpha1.Application, 0, len(sharding.Apps)) - for _, a := range sharding.Apps { + apps := make([]*v1alpha1.Application, 0, len(d.Apps)) + for _, a := range d.Apps { apps = append(apps, a) } return apps @@ -265,14 +263,3 @@ func (sharding *ClusterSharding) GetAppDistribution() map[string]int { } return appDistribution } - -// UpdateShard will update the shard of ClusterSharding when the shard has changed. -func (sharding *ClusterSharding) UpdateShard(shard int) bool { - if shard != sharding.Shard { - sharding.lock.RLock() - sharding.Shard = shard - sharding.lock.RUnlock() - return true - } - return false -} diff --git a/controller/sharding/cache_test.go b/controller/sharding/cache_test.go index b8d5962703..34318ec259 100644 --- a/controller/sharding/cache_test.go +++ b/controller/sharding/cache_test.go @@ -5,8 +5,8 @@ import ( "github.com/stretchr/testify/assert" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - dbmocks "github.com/argoproj/argo-cd/v3/util/db/mocks" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" ) func setupTestSharding(shard int, replicas int) *ClusterSharding { diff --git a/controller/sharding/consistent/consistent.go b/controller/sharding/consistent/consistent.go index 9055525eb6..bb9a549926 100644 --- a/controller/sharding/consistent/consistent.go +++ b/controller/sharding/consistent/consistent.go @@ -138,14 +138,15 @@ func (c *Consistent) GetLeast(client string) (string, error) { foundItem = c.clients.Min() } key := c.clients.Get(foundItem) - if key == nil { + if key != nil { + host := c.servers[key.(item).value] + if c.loadOK(host) { + return host, nil + } + h = key.(item).value + } else { return client, nil } - host := c.servers[key.(item).value] - if c.loadOK(host) { - return host, nil - } - h = key.(item).value } } diff --git a/controller/sharding/sharding.go b/controller/sharding/sharding.go index a09cb3d429..e593547b00 100644 --- a/controller/sharding/sharding.go +++ b/controller/sharding/sharding.go @@ -3,32 +3,31 @@ package sharding import ( "context" "encoding/json" - stderrors "errors" "fmt" "hash/fnv" "math" "os" - "slices" "sort" "strconv" "strings" "time" - corev1 "k8s.io/api/core/v1" + slices "golang.org/x/exp/slices" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/controller/sharding/consistent" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/controller/sharding/consistent" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" log "github.com/sirupsen/logrus" - apierrors "k8s.io/apimachinery/pkg/api/errors" + kubeerrors "k8s.io/apimachinery/pkg/api/errors" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/settings" ) // Make it overridable for testing @@ -63,7 +62,7 @@ type shardApplicationControllerMapping struct { // and returns whether or not the cluster should be processed by a given shard. It calls the distributionFunction // to determine which shard will process the cluster, and if the given shard is equal to the calculated shard // the function will return true. -func GetClusterFilter(_ db.ArgoDB, distributionFunction DistributionFunction, replicas, shard int) ClusterFilterFunction { +func GetClusterFilter(db db.ArgoDB, distributionFunction DistributionFunction, replicas, shard int) ClusterFilterFunction { return func(c *v1alpha1.Cluster) bool { clusterShard := 0 if c != nil && c.Shard != nil { @@ -122,12 +121,13 @@ func LegacyDistributionFunction(replicas int) DistributionFunction { log.Debugf("Calculating cluster shard for cluster id: %s", id) if id == "" { return 0 + } else { + h := fnv.New32a() + _, _ = h.Write([]byte(id)) + shard := int32(h.Sum32() % uint32(replicas)) + log.Debugf("Cluster with id=%s will be processed by shard %d", id, shard) + return int(shard) } - h := fnv.New32a() - _, _ = h.Write([]byte(id)) - shard := int32(h.Sum32() % uint32(replicas)) - log.Debugf("Cluster with id=%s will be processed by shard %d", id, shard) - return int(shard) } } @@ -148,16 +148,17 @@ func RoundRobinDistributionFunction(clusters clusterAccessor, replicas int) Dist // then its value is returned otherwise it is the default calculated value if c.Shard != nil && int(*c.Shard) < replicas { return int(*c.Shard) + } else { + clusterIndexdByClusterIdMap := createClusterIndexByClusterIdMap(clusters) + clusterIndex, ok := clusterIndexdByClusterIdMap[c.ID] + if !ok { + log.Warnf("Cluster with id=%s not found in cluster map.", c.ID) + return -1 + } + shard := int(clusterIndex % replicas) + log.Debugf("Cluster with id=%s will be processed by shard %d", c.ID, shard) + return shard } - clusterIndexdByClusterIdMap := createClusterIndexByClusterIdMap(clusters) - clusterIndex, ok := clusterIndexdByClusterIdMap[c.ID] - if !ok { - log.Warnf("Cluster with id=%s not found in cluster map.", c.ID) - return -1 - } - shard := int(clusterIndex % replicas) - log.Debugf("Cluster with id=%s will be processed by shard %d", c.ID, shard) - return shard } log.Warnf("The number of replicas (%d) is lower than 1", replicas) return -1 @@ -179,21 +180,22 @@ func ConsistentHashingWithBoundedLoadsDistributionFunction(clusters clusterAcces // then its value is returned otherwise it is the default calculated value if c.Shard != nil && int(*c.Shard) < replicas { return int(*c.Shard) + } else { + // if the cluster is not in the clusters list anymore, we should unassign it from any shard, so we + // return the reserved value of -1 + if !slices.Contains(clusters(), c) { + log.Warnf("Cluster with id=%s not found in cluster map.", c.ID) + return -1 + } + shardIndexedByCluster := createConsistentHashingWithBoundLoads(replicas, clusters, apps) + shard, ok := shardIndexedByCluster[c.ID] + if !ok { + log.Warnf("Cluster with id=%s not found in cluster map.", c.ID) + return -1 + } + log.Debugf("Cluster with id=%s will be processed by shard %d", c.ID, shard) + return shard } - // if the cluster is not in the clusters list anymore, we should unassign it from any shard, so we - // return the reserved value of -1 - if !slices.Contains(clusters(), c) { - log.Warnf("Cluster with id=%s not found in cluster map.", c.ID) - return -1 - } - shardIndexedByCluster := createConsistentHashingWithBoundLoads(replicas, clusters, apps) - shard, ok := shardIndexedByCluster[c.ID] - if !ok { - log.Warnf("Cluster with id=%s not found in cluster map.", c.ID) - return -1 - } - log.Debugf("Cluster with id=%s will be processed by shard %d", c.ID, shard) - return shard } log.Warnf("The number of replicas (%d) is lower than 1", replicas) return -1 @@ -252,7 +254,7 @@ func getAppDistribution(getCluster clusterAccessor, getApps appAccessor) map[str // NoShardingDistributionFunction returns a DistributionFunction that will process all cluster by shard 0 // the function is created for API compatibility purposes and is not supposed to be activated. func NoShardingDistributionFunction() DistributionFunction { - return func(_ *v1alpha1.Cluster) int { return 0 } + return func(c *v1alpha1.Cluster) int { return 0 } } // InferShard extracts the shard index based on its hostname. @@ -308,8 +310,9 @@ func GetOrUpdateShardFromConfigMap(kubeClient kubernetes.Interface, settingsMgr // fetch the shard mapping configMap shardMappingCM, err := kubeClient.CoreV1().ConfigMaps(settingsMgr.GetNamespace()).Get(context.Background(), common.ArgoCDAppControllerShardConfigMapName, metav1.GetOptions{}) + if err != nil { - if !apierrors.IsNotFound(err) { + if !kubeerrors.IsNotFound(err) { return -1, fmt.Errorf("error getting sharding config map: %w", err) } log.Infof("shard mapping configmap %s not found. Creating default shard mapping configmap.", common.ArgoCDAppControllerShardConfigMapName) @@ -327,27 +330,28 @@ func GetOrUpdateShardFromConfigMap(kubeClient kubernetes.Interface, settingsMgr } // return 0 as the controller is assigned to shard 0 while generating default shard mapping ConfigMap return shard, nil - } - // Identify the available shard and update the ConfigMap - data := shardMappingCM.Data[ShardControllerMappingKey] - var shardMappingData []shardApplicationControllerMapping - err = json.Unmarshal([]byte(data), &shardMappingData) - if err != nil { - return -1, fmt.Errorf("error unmarshalling shard config map data: %w", err) - } + } else { + // Identify the available shard and update the ConfigMap + data := shardMappingCM.Data[ShardControllerMappingKey] + var shardMappingData []shardApplicationControllerMapping + err := json.Unmarshal([]byte(data), &shardMappingData) + if err != nil { + return -1, fmt.Errorf("error unmarshalling shard config map data: %w", err) + } - shard, shardMappingData = getOrUpdateShardNumberForController(shardMappingData, hostname, replicas, shard) - updatedShardMappingData, err := json.Marshal(shardMappingData) - if err != nil { - return -1, fmt.Errorf("error marshalling data of shard mapping ConfigMap: %w", err) - } - shardMappingCM.Data[ShardControllerMappingKey] = string(updatedShardMappingData) + shard, shardMappingData := getOrUpdateShardNumberForController(shardMappingData, hostname, replicas, shard) + updatedShardMappingData, err := json.Marshal(shardMappingData) + if err != nil { + return -1, fmt.Errorf("error marshalling data of shard mapping ConfigMap: %w", err) + } + shardMappingCM.Data[ShardControllerMappingKey] = string(updatedShardMappingData) - _, err = kubeClient.CoreV1().ConfigMaps(settingsMgr.GetNamespace()).Update(context.Background(), shardMappingCM, metav1.UpdateOptions{}) - if err != nil { - return -1, err + _, err = kubeClient.CoreV1().ConfigMaps(settingsMgr.GetNamespace()).Update(context.Background(), shardMappingCM, metav1.UpdateOptions{}) + if err != nil { + return -1, err + } + return shard, nil } - return shard, nil } // getOrUpdateShardNumberForController takes list of shardApplicationControllerMapping and performs computation to find the matching or empty shard number @@ -415,8 +419,8 @@ func getOrUpdateShardNumberForController(shardMappingData []shardApplicationCont } // generateDefaultShardMappingCM creates a default shard mapping configMap. Assigns current controller to shard 0. -func generateDefaultShardMappingCM(namespace, hostname string, replicas, shard int) (*corev1.ConfigMap, error) { - shardingCM := &corev1.ConfigMap{ +func generateDefaultShardMappingCM(namespace, hostname string, replicas, shard int) (*v1.ConfigMap, error) { + shardingCM := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDAppControllerShardConfigMapName, Namespace: namespace, @@ -464,10 +468,11 @@ func GetClusterSharding(kubeClient kubernetes.Interface, settingsMgr *settings.S return nil, fmt.Errorf("(dynamic cluster distribution) failed to get app controller deployment: %w", err) } - if appControllerDeployment == nil || appControllerDeployment.Spec.Replicas == nil { - return nil, stderrors.New("(dynamic cluster distribution) failed to get app controller deployment replica count") + if appControllerDeployment != nil && appControllerDeployment.Spec.Replicas != nil { + replicasCount = int(*appControllerDeployment.Spec.Replicas) + } else { + return nil, fmt.Errorf("(dynamic cluster distribution) failed to get app controller deployment replica count") } - replicasCount = int(*appControllerDeployment.Spec.Replicas) } else { replicasCount = env.ParseNumFromEnv(common.EnvControllerReplicas, 0, 0, math.MaxInt32) } @@ -481,14 +486,11 @@ func GetClusterSharding(kubeClient kubernetes.Interface, settingsMgr *settings.S // If we still see conflicts after the retries, wait for next iteration of heartbeat process. for i := 0; i <= common.AppControllerHeartbeatUpdateRetryCount; i++ { shardNumber, err = GetOrUpdateShardFromConfigMap(kubeClient, settingsMgr, replicasCount, shardNumber) - if err != nil && !apierrors.IsConflict(err) { + if err != nil && !kubeerrors.IsConflict(err) { err = fmt.Errorf("unable to get shard due to error updating the sharding config map: %w", err) break } - // if `err == nil`, should not log the following warning message - if err != nil { - log.Warnf("conflict when getting shard from shard mapping configMap. Retrying (%d/3)", i) - } + log.Warnf("conflict when getting shard from shard mapping configMap. Retrying (%d/3)", i) } errors.CheckError(err) } else { diff --git a/controller/sharding/sharding_test.go b/controller/sharding/sharding_test.go index 64aa2010aa..b76741be92 100644 --- a/controller/sharding/sharding_test.go +++ b/controller/sharding/sharding_test.go @@ -1,6 +1,7 @@ package sharding import ( + "context" "encoding/json" "errors" "fmt" @@ -13,16 +14,16 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" kubefake "k8s.io/client-go/kubernetes/fake" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - dbmocks "github.com/argoproj/argo-cd/v3/util/db/mocks" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" + "github.com/argoproj/argo-cd/v2/util/settings" ) func TestGetShardByID_NotEmptyID(t *testing.T) { @@ -390,8 +391,12 @@ func TestGetShardByIndexModuloReplicasCountDistributionFunction(t *testing.T) { shardForCluster1 := distributionFunction(&cluster1) shardForCluster2 := distributionFunction(&cluster2) - assert.Equal(t, expectedShardForCluster1, shardForCluster1, "Expected shard for cluster1 to be %d but got %d", expectedShardForCluster1, shardForCluster1) - assert.Equal(t, expectedShardForCluster2, shardForCluster2, "Expected shard for cluster2 to be %d but got %d", expectedShardForCluster2, shardForCluster2) + if shardForCluster1 != expectedShardForCluster1 { + t.Errorf("Expected shard for cluster1 to be %d but got %d", expectedShardForCluster1, shardForCluster1) + } + if shardForCluster2 != expectedShardForCluster2 { + t.Errorf("Expected shard for cluster2 to be %d but got %d", expectedShardForCluster2, shardForCluster2) + } } func TestInferShard(t *testing.T) { @@ -492,7 +497,7 @@ func Test_generateDefaultShardMappingCM_NoPredefinedShard(t *testing.T) { expectedMappingCM, err := json.Marshal(expectedMapping) require.NoError(t, err) - expectedShadingCM := &corev1.ConfigMap{ + expectedShadingCM := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDAppControllerShardConfigMapName, Namespace: "test", @@ -527,7 +532,7 @@ func Test_generateDefaultShardMappingCM_PredefinedShard(t *testing.T) { expectedMappingCM, err := json.Marshal(expectedMapping) require.NoError(t, err) - expectedShadingCM := &corev1.ConfigMap{ + expectedShadingCM := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDAppControllerShardConfigMapName, Namespace: "test", @@ -816,7 +821,7 @@ func TestGetClusterSharding(t *testing.T) { objects := append([]runtime.Object{}, deployment, deploymentMultiReplicas) kubeclientset := kubefake.NewSimpleClientset(objects...) - settingsMgr := settings.NewSettingsManager(t.Context(), kubeclientset, "argocd", settings.WithRepoOrClusterChangedHandler(func() { + settingsMgr := settings.NewSettingsManager(context.TODO(), kubeclientset, "argocd", settings.WithRepoOrClusterChangedHandler(func() { })) testCases := []struct { @@ -953,7 +958,7 @@ func TestGetClusterSharding(t *testing.T) { useDynamicSharding: true, expectedShard: 0, expectedReplicas: 1, - expectedErr: errors.New("(dynamic cluster distribution) failed to get app controller deployment: deployments.apps \"missing-deployment\" not found"), + expectedErr: fmt.Errorf("(dynamic cluster distribution) failed to get app controller deployment: deployments.apps \"missing-deployment\" not found"), }, } @@ -970,7 +975,11 @@ func TestGetClusterSharding(t *testing.T) { } if tc.expectedErr != nil { - assert.EqualError(t, err, tc.expectedErr.Error()) + if err != nil { + assert.Equal(t, tc.expectedErr.Error(), err.Error()) + } else { + t.Errorf("Expected error %v but got nil", tc.expectedErr) + } } else { require.NoError(t, err) } @@ -979,37 +988,35 @@ func TestGetClusterSharding(t *testing.T) { } func TestAppAwareCache(t *testing.T) { - _, _, cluster1, cluster2, cluster3, cluster4, cluster5 := createTestClusters() + _, db, cluster1, cluster2, cluster3, cluster4, cluster5 := createTestClusters() _, app1, app2, app3, app4, app5 := createTestApps() - clusterList := getClusterPointers([]v1alpha1.Cluster{cluster1, cluster2, cluster3, cluster4, cluster5}) - appList := getAppPointers([]v1alpha1.Application{app1, app2, app3, app4, app5}) + clusterSharding := NewClusterSharding(db, 0, 1, "legacy") - getClusters := func() []*v1alpha1.Cluster { return clusterList } - getApps := func() []*v1alpha1.Application { return appList } + clusterList := &v1alpha1.ClusterList{Items: []v1alpha1.Cluster{cluster1, cluster2, cluster3, cluster4, cluster5}} + appList := &v1alpha1.ApplicationList{Items: []v1alpha1.Application{app1, app2, app3, app4, app5}} + clusterSharding.Init(clusterList, appList) - appDistribution := getAppDistribution(getClusters, getApps) + appDistribution := clusterSharding.GetAppDistribution() - assert.Equal(t, int64(2), appDistribution["cluster1"]) - assert.Equal(t, int64(2), appDistribution["cluster2"]) - assert.Equal(t, int64(1), appDistribution["cluster3"]) + assert.Equal(t, 2, appDistribution["cluster1"]) + assert.Equal(t, 2, appDistribution["cluster2"]) + assert.Equal(t, 1, appDistribution["cluster3"]) app6 := createApp("app6", "cluster4") - appList = append(appList, &app6) + clusterSharding.AddApp(&app6) app1Update := createApp("app1", "cluster2") - // replace app 1 - appList[0] = &app1Update + clusterSharding.UpdateApp(&app1Update) - // Remove app 3 - appList = append(appList[:2], appList[3:]...) + clusterSharding.DeleteApp(&app3) - appDistribution = getAppDistribution(getClusters, getApps) + appDistribution = clusterSharding.GetAppDistribution() - assert.Equal(t, int64(1), appDistribution["cluster1"]) - assert.Equal(t, int64(2), appDistribution["cluster2"]) - assert.Equal(t, int64(1), appDistribution["cluster3"]) - assert.Equal(t, int64(1), appDistribution["cluster4"]) + assert.Equal(t, 1, appDistribution["cluster1"]) + assert.Equal(t, 2, appDistribution["cluster2"]) + assert.Equal(t, 1, appDistribution["cluster3"]) + assert.Equal(t, 1, appDistribution["cluster4"]) } func createTestApps() (appAccessor, v1alpha1.Application, v1alpha1.Application, v1alpha1.Application, v1alpha1.Application, v1alpha1.Application) { diff --git a/controller/sharding/shuffle_test.go b/controller/sharding/shuffle_test.go index 0fa6f5f548..390b822545 100644 --- a/controller/sharding/shuffle_test.go +++ b/controller/sharding/shuffle_test.go @@ -9,9 +9,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - dbmocks "github.com/argoproj/argo-cd/v3/util/db/mocks" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" ) func TestLargeShuffle(t *testing.T) { diff --git a/controller/sort_delete_test.go b/controller/sort_delete_test.go index e3a89c0280..83b90ec47d 100644 --- a/controller/sort_delete_test.go +++ b/controller/sort_delete_test.go @@ -4,8 +4,6 @@ import ( "reflect" "testing" - "github.com/stretchr/testify/assert" - "github.com/argoproj/gitops-engine/pkg/sync/common" . "github.com/argoproj/gitops-engine/pkg/utils/testing" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -24,8 +22,9 @@ func TestFilterObjectsForDeletion(t *testing.T) { for _, tt := range tests { in := sliceOfObjectsWithSyncWaves(tt.input) need := sliceOfObjectsWithSyncWaves(tt.want) - got := FilterObjectsForDeletion(in) - assert.True(t, reflect.DeepEqual(got, need), "Received unexpected objects for deletion") + if got := FilterObjectsForDeletion(in); !reflect.DeepEqual(got, need) { + t.Errorf("Received unexpected objects for deletion = %v, want %v", got, need) + } } } diff --git a/controller/state.go b/controller/state.go index b0a63d1b81..054b5d51a1 100644 --- a/controller/state.go +++ b/controller/state.go @@ -11,7 +11,7 @@ import ( "time" synccommon "github.com/argoproj/gitops-engine/pkg/sync/common" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "github.com/argoproj/gitops-engine/pkg/diff" "github.com/argoproj/gitops-engine/pkg/health" @@ -28,26 +28,25 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/tools/cache" - "github.com/argoproj/argo-cd/v3/common" - statecache "github.com/argoproj/argo-cd/v3/controller/cache" - "github.com/argoproj/argo-cd/v3/controller/metrics" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - applog "github.com/argoproj/argo-cd/v3/util/app/log" - "github.com/argoproj/argo-cd/v3/util/app/path" - "github.com/argoproj/argo-cd/v3/util/argo" - argodiff "github.com/argoproj/argo-cd/v3/util/argo/diff" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/gpg" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/settings" - "github.com/argoproj/argo-cd/v3/util/stats" + "github.com/argoproj/argo-cd/v2/common" + statecache "github.com/argoproj/argo-cd/v2/controller/cache" + "github.com/argoproj/argo-cd/v2/controller/metrics" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/app/path" + "github.com/argoproj/argo-cd/v2/util/argo" + argodiff "github.com/argoproj/argo-cd/v2/util/argo/diff" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" + appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/gpg" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/settings" + "github.com/argoproj/argo-cd/v2/util/stats" ) -var ErrCompareStateRepo = errors.New("failed to get repo objects") +var CompareStateRepoError = errors.New("failed to get repo objects") type resourceInfoProviderStub struct{} @@ -78,7 +77,7 @@ type AppStateManager interface { // comparisonResult holds the state of an application after the reconciliation type comparisonResult struct { syncStatus *v1alpha1.SyncStatus - healthStatus health.HealthStatusCode + healthStatus *v1alpha1.HealthStatus resources []v1alpha1.ResourceStatus managedResources []managedResource reconciliationResult sync.ReconciliationResult @@ -97,7 +96,7 @@ func (res *comparisonResult) GetSyncStatus() *v1alpha1.SyncStatus { return res.syncStatus } -func (res *comparisonResult) GetHealthStatus() health.HealthStatusCode { +func (res *comparisonResult) GetHealthStatus() *v1alpha1.HealthStatus { return res.healthStatus } @@ -164,35 +163,25 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp return nil, nil, false, fmt.Errorf("failed to get Helm settings: %w", err) } - trackingMethod, err := m.settingsMgr.GetTrackingMethod() - if err != nil { - return nil, nil, false, fmt.Errorf("failed to get trackingMethod: %w", err) - } - installationID, err := m.settingsMgr.GetInstallationID() if err != nil { return nil, nil, false, fmt.Errorf("failed to get installation ID: %w", err) } - destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, m.db) - if err != nil { - return nil, nil, false, fmt.Errorf("failed to get destination cluster: %w", err) - } - ts.AddCheckpoint("build_options_ms") var serverVersion string var apiResources []kubeutil.APIResourceInfo if sendRuntimeState { - serverVersion, apiResources, err = m.liveStateCache.GetVersionsInfo(destCluster) + serverVersion, apiResources, err = m.liveStateCache.GetVersionsInfo(app.Spec.Destination.Server) if err != nil { - return nil, nil, false, fmt.Errorf("failed to get cluster version for cluster %q: %w", destCluster.Server, err) + return nil, nil, false, fmt.Errorf("failed to get cluster version for cluster %q: %w", app.Spec.Destination.Server, err) } } conn, repoClient, err := m.repoClientset.NewRepoServerClient() if err != nil { return nil, nil, false, fmt.Errorf("failed to connect to repo server: %w", err) } - defer utilio.Close(conn) + defer io.Close(conn) manifestInfos := make([]*apiclient.ManifestResponse, 0) targetObjs := make([]*unstructured.Unstructured, 0) @@ -255,7 +244,7 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp ApplicationSource: &source, KubeVersion: serverVersion, ApiVersions: apiVersions, - TrackingMethod: trackingMethod, + TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)), RefSources: refSources, HasMultipleSources: app.Spec.HasMultipleSources(), InstallationID: installationID, @@ -292,7 +281,7 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp ApiVersions: apiVersions, VerifySignature: verifySignature, HelmRepoCreds: permittedHelmCredentials, - TrackingMethod: trackingMethod, + TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)), EnabledSourceTypes: enabledSourceTypes, HelmOptions: helmOptions, HasMultipleSources: app.Spec.HasMultipleSources(), @@ -315,7 +304,7 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp } ts.AddCheckpoint("manifests_ms") - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := log.WithField("application", app.QualifiedName()) for k, v := range ts.Timings() { logCtx = logCtx.WithField(k, v.Milliseconds()) } @@ -337,7 +326,7 @@ func (m *appStateManager) ResolveGitRevision(repoURL string, revision string) (s if err != nil { return "", fmt.Errorf("failed to connect to repo server: %w", err) } - defer utilio.Close(conn) + defer io.Close(conn) repo, err := m.db.GetRepository(context.Background(), repoURL, "") if err != nil { @@ -416,53 +405,26 @@ func DeduplicateTargetObjects( return result, conditions, nil } -// normalizeClusterScopeTracking will set the app instance tracking metadata on malformed cluster-scoped resources where -// metadata.namespace is not empty. The repo-server doesn't know which resources are cluster-scoped, so it may apply -// an incorrect tracking annotation using the metadata.namespace. This function will correct that. -func normalizeClusterScopeTracking(targetObjs []*unstructured.Unstructured, infoProvider kubeutil.ResourceInfoProvider, setAppInstance func(*unstructured.Unstructured) error) error { - for i := len(targetObjs) - 1; i >= 0; i-- { - targetObj := targetObjs[i] - if targetObj == nil { - continue - } - gvk := targetObj.GroupVersionKind() - if !kubeutil.IsNamespacedOrUnknown(infoProvider, gvk.GroupKind()) { - if targetObj.GetNamespace() != "" { - targetObj.SetNamespace("") - err := setAppInstance(targetObj) - if err != nil { - return fmt.Errorf("failed to set app instance label on cluster-scoped resource %s/%s: %w", gvk.String(), targetObj.GetName(), err) - } - } - } - } - return nil -} - // getComparisonSettings will return the system level settings related to the // diff/normalization process. -func (m *appStateManager) getComparisonSettings() (string, map[string]v1alpha1.ResourceOverride, *settings.ResourcesFilter, string, string, error) { +func (m *appStateManager) getComparisonSettings() (string, map[string]v1alpha1.ResourceOverride, *settings.ResourcesFilter, string, error) { resourceOverrides, err := m.settingsMgr.GetResourceOverrides() if err != nil { - return "", nil, nil, "", "", err + return "", nil, nil, "", err } appLabelKey, err := m.settingsMgr.GetAppInstanceLabelKey() if err != nil { - return "", nil, nil, "", "", err + return "", nil, nil, "", err } resFilter, err := m.settingsMgr.GetResourcesFilter() if err != nil { - return "", nil, nil, "", "", err + return "", nil, nil, "", err } installationID, err := m.settingsMgr.GetInstallationID() if err != nil { - return "", nil, nil, "", "", err + return "", nil, nil, "", err } - trackingMethod, err := m.settingsMgr.GetTrackingMethod() - if err != nil { - return "", nil, nil, "", "", err - } - return appLabelKey, resourceOverrides, resFilter, installationID, trackingMethod, nil + return appLabelKey, resourceOverrides, resFilter, installationID, nil } // verifyGnuPGSignature verifies the result of a GnuPG operation for a given git @@ -513,7 +475,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, installationID, trackingMethod, err := m.getComparisonSettings() + appLabelKey, resourceOverrides, resFilter, installationID, err := m.getComparisonSettings() ts.AddCheckpoint("settings_ms") @@ -526,32 +488,31 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 Status: v1alpha1.SyncStatusCodeUnknown, Revisions: revisions, }, - healthStatus: health.HealthStatusUnknown, + healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown}, + }, nil + } else { + return &comparisonResult{ + syncStatus: &v1alpha1.SyncStatus{ + ComparedTo: app.Spec.BuildComparedToStatus(), + Status: v1alpha1.SyncStatusCodeUnknown, + Revision: revisions[0], + }, + healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown}, }, nil } - return &comparisonResult{ - syncStatus: &v1alpha1.SyncStatus{ - ComparedTo: app.Spec.BuildComparedToStatus(), - Status: v1alpha1.SyncStatusCodeUnknown, - Revision: revisions[0], - }, - healthStatus: health.HealthStatusUnknown, - }, nil } // When signature keys are defined in the project spec, we need to verify the signature on the Git revision - verifySignature := len(project.Spec.SignatureKeys) > 0 && gpg.IsGPGEnabled() + verifySignature := false + if len(project.Spec.SignatureKeys) > 0 && gpg.IsGPGEnabled() { + verifySignature = true + } // do best effort loading live and target state to present as much information about app state as possible failedToLoadObjs := false conditions := make([]v1alpha1.ApplicationCondition, 0) - destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, m.db) - if err != nil { - return nil, err - } - - logCtx := log.WithFields(applog.GetAppLogFields(app)) + logCtx := log.WithField("application", app.QualifiedName()) logCtx.Infof("Comparing app state (cluster: %s, namespace: %s)", app.Spec.Destination.Server, app.Spec.Destination.Namespace) var targetObjs []*unstructured.Unstructured @@ -575,19 +536,19 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 targetObjs, manifestInfos, revisionUpdated, err = m.GetRepoObjs(app, sources, appLabelKey, revisions, noCache, noRevisionCache, verifySignature, project, rollback, true) if err != nil { targetObjs = make([]*unstructured.Unstructured, 0) - msg := "Failed to load target state: " + err.Error() + msg := fmt.Sprintf("Failed to load target state: %s", err.Error()) conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: msg, LastTransitionTime: &now}) if firstSeen, ok := m.repoErrorCache.Load(app.Name); ok { if time.Since(firstSeen.(time.Time)) <= m.repoErrorGracePeriod && !noRevisionCache { // if first seen is less than grace period and it's not a Level 3 comparison, // ignore error and short circuit logCtx.Debugf("Ignoring repo error %v, already encountered error in grace period", err.Error()) - return nil, ErrCompareStateRepo + return nil, CompareStateRepoError } } else if !noRevisionCache { logCtx.Debugf("Ignoring repo error %v, new occurrence", err.Error()) m.repoErrorCache.Store(app.Name, time.Now()) - return nil, ErrCompareStateRepo + return nil, CompareStateRepoError } failedToLoadObjs = true } else { @@ -605,7 +566,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 targetObjs, err = unmarshalManifests(localManifests) if err != nil { targetObjs = make([]*unstructured.Unstructured, 0) - msg := "Failed to load local manifests: " + err.Error() + msg := fmt.Sprintf("Failed to load local manifests: %s", err.Error()) conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: msg, LastTransitionTime: &now}) failedToLoadObjs = true } @@ -616,30 +577,20 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 ts.AddCheckpoint("git_ms") var infoProvider kubeutil.ResourceInfoProvider - infoProvider, err = m.liveStateCache.GetClusterCache(destCluster) + infoProvider, err = m.liveStateCache.GetClusterCache(app.Spec.Destination.Server) if err != nil { infoProvider = &resourceInfoProviderStub{} } - - err = normalizeClusterScopeTracking(targetObjs, infoProvider, func(u *unstructured.Unstructured) error { - return m.resourceTracking.SetAppInstance(u, appLabelKey, app.InstanceName(m.namespace), app.Spec.Destination.Namespace, v1alpha1.TrackingMethod(trackingMethod), installationID) - }) - if err != nil { - msg := "Failed to normalize cluster-scoped resource tracking: " + err.Error() - conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: msg, LastTransitionTime: &now}) - } - targetObjs, dedupConditions, err := DeduplicateTargetObjects(app.Spec.Destination.Namespace, targetObjs, infoProvider) if err != nil { - msg := "Failed to deduplicate target state: " + err.Error() + msg := fmt.Sprintf("Failed to deduplicate target state: %s", err.Error()) conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: msg, LastTransitionTime: &now}) } conditions = append(conditions, dedupConditions...) - for i := len(targetObjs) - 1; i >= 0; i-- { targetObj := targetObjs[i] gvk := targetObj.GroupVersionKind() - if resFilter.IsExcludedResource(gvk.Group, gvk.Kind, destCluster.Server) { + if resFilter.IsExcludedResource(gvk.Group, gvk.Kind, app.Spec.Destination.Server) { targetObjs = append(targetObjs[:i], targetObjs[i+1:]...) conditions = append(conditions, v1alpha1.ApplicationCondition{ Type: v1alpha1.ApplicationConditionExcludedResourceWarning, @@ -657,18 +608,19 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 } ts.AddCheckpoint("dedup_ms") - liveObjByKey, err := m.liveStateCache.GetManagedLiveObjs(destCluster, app, targetObjs) + liveObjByKey, err := m.liveStateCache.GetManagedLiveObjs(app, targetObjs) if err != nil { liveObjByKey = make(map[kubeutil.ResourceKey]*unstructured.Unstructured) - msg := "Failed to load live state: " + err.Error() + msg := fmt.Sprintf("Failed to load live state: %s", err.Error()) conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: msg, LastTransitionTime: &now}) failedToLoadObjs = true } logCtx.Debugf("Retrieved live manifests") + // filter out all resources which are not permitted in the application project for k, v := range liveObjByKey { - permitted, err := project.IsLiveResourcePermitted(v, destCluster, func(project string) ([]*v1alpha1.Cluster, error) { + permitted, err := project.IsLiveResourcePermitted(v, app.Spec.Destination.Server, app.Spec.Destination.Name, func(project string) ([]*v1alpha1.Cluster, error) { clusters, err := m.db.GetProjectClusters(context.TODO(), project) if err != nil { return nil, fmt.Errorf("failed to get clusters for project %q: %w", project, err) @@ -687,9 +639,11 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 } } + trackingMethod := argo.GetTrackingMethod(m.settingsMgr) + for _, liveObj := range liveObjByKey { if liveObj != nil { - appInstanceName := m.resourceTracking.GetAppName(liveObj, appLabelKey, v1alpha1.TrackingMethod(trackingMethod), installationID) + appInstanceName := m.resourceTracking.GetAppName(liveObj, appLabelKey, trackingMethod, installationID) if appInstanceName != "" && appInstanceName != app.InstanceName(m.namespace) { fqInstanceName := strings.ReplaceAll(appInstanceName, "_", "/") conditions = append(conditions, v1alpha1.ApplicationCondition{ @@ -712,7 +666,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 // targetNsExists == true implies that it already exists as a target, so no need to add the namespace to the // targetObjs array. if isManagedNamespace(liveObj, app) && !targetNsExists { - nsSpec := &corev1.Namespace{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: kubeutil.NamespaceKind}, ObjectMeta: metav1.ObjectMeta{Name: liveObj.GetName()}} + nsSpec := &v1.Namespace{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: kubeutil.NamespaceKind}, ObjectMeta: metav1.ObjectMeta{Name: liveObj.GetName()}} managedNs, err := kubeutil.ToUnstructured(nsSpec) if err != nil { conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now}) @@ -777,7 +731,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 diffConfigBuilder.WithIgnoreMutationWebhook(false) } - gvkParser, err := m.getGVKParser(destCluster) + gvkParser, err := m.getGVKParser(app.Spec.Destination.Server) if err != nil { conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionUnknownError, Message: err.Error(), LastTransitionTime: &now}) } @@ -787,7 +741,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 diffConfigBuilder.WithServerSideDiff(serverSideDiff) if serverSideDiff { - applier, cleanup, err := m.getServerSideDiffDryRunApplier(destCluster) + applier, cleanup, err := m.getServerSideDiffDryRunApplier(app.Spec.Destination.Server) if err != nil { log.Errorf("CompareAppState error getting server side diff dry run applier: %s", err) conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionUnknownError, Message: err.Error(), LastTransitionTime: &now}) @@ -809,7 +763,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 if err != nil { diffResults = &diff.DiffResultList{} failedToLoadObjs = true - msg := "Failed to compare desired state to live state: " + err.Error() + msg := fmt.Sprintf("Failed to compare desired state to live state: %s", err.Error()) conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: msg, LastTransitionTime: &now}) } ts.AddCheckpoint("diff_ms") @@ -828,7 +782,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 } gvk := obj.GroupVersionKind() - isSelfReferencedObj := m.isSelfReferencedObj(liveObj, targetObj, app.GetName(), v1alpha1.TrackingMethod(trackingMethod), installationID) + isSelfReferencedObj := m.isSelfReferencedObj(liveObj, targetObj, app.GetName(), appLabelKey, trackingMethod, installationID) resState := v1alpha1.ResourceStatus{ Namespace: obj.GetNamespace(), @@ -861,13 +815,12 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 // namespace from being pruned. isManagedNs := isManagedNamespace(targetObj, app) && liveObj == nil - switch { - case resState.Hook || ignore.Ignore(obj) || (targetObj != nil && hookutil.Skip(targetObj)) || !isSelfReferencedObj: + if resState.Hook || ignore.Ignore(obj) || (targetObj != nil && hookutil.Skip(targetObj)) || !isSelfReferencedObj { // For resource hooks, skipped resources or objects that may have // been created by another controller with annotations copied from // the source object, don't store sync status, and do not affect // overall sync status - case !isManagedNs && (diffResult.Modified || targetObj == nil || liveObj == nil): + } else if !isManagedNs && (diffResult.Modified || targetObj == nil || liveObj == nil) { // Set resource state to OutOfSync since one of the following is true: // * target and live resource are different // * target resource not defined and live resource is extra @@ -875,14 +828,14 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 resState.Status = v1alpha1.SyncStatusCodeOutOfSync // we ignore the status if the obj needs pruning AND we have the annotation needsPruning := targetObj == nil && liveObj != nil - if !needsPruning || !resourceutil.HasAnnotationOption(obj, common.AnnotationCompareOptions, "IgnoreExtraneous") { + if !(needsPruning && resourceutil.HasAnnotationOption(obj, common.AnnotationCompareOptions, "IgnoreExtraneous")) { syncCode = v1alpha1.SyncStatusCodeOutOfSync } - default: + } else { resState.Status = v1alpha1.SyncStatusCodeSynced } // set unknown status to all resource that are not permitted in the app project - isNamespaced, err := m.liveStateCache.IsNamespaced(destCluster, gvk.GroupKind()) + isNamespaced, err := m.liveStateCache.IsNamespaced(app.Spec.Destination.Server, gvk.GroupKind()) if !project.IsGroupKindPermitted(gvk.GroupKind(), isNamespaced && err == nil) { resState.Status = v1alpha1.SyncStatusCodeUnknown } @@ -952,7 +905,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 healthStatus, err := setApplicationHealth(managedResources, resourceSummaries, resourceOverrides, app, m.persistResourceHealth) if err != nil { - conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: "error setting app health: " + err.Error(), LastTransitionTime: &now}) + conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: fmt.Sprintf("error setting app health: %s", err.Error()), LastTransitionTime: &now}) } // Git has already performed the signature verification via its GPG interface, and the result is available @@ -1046,6 +999,20 @@ func specEqualsCompareTo(spec v1alpha1.ApplicationSpec, comparedTo v1alpha1.Comp // 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) } @@ -1145,14 +1112,14 @@ 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 string, trackingMethod v1alpha1.TrackingMethod, installationID string) bool { +func (m *appStateManager) isSelfReferencedObj(live, config *unstructured.Unstructured, appName, appLabelKey string, trackingMethod v1alpha1.TrackingMethod, installationID string) bool { if live == nil { return true } // If tracking method doesn't contain required metadata for this check, // we are not able to determine and just assume the object to be managed. - if trackingMethod == v1alpha1.TrackingMethodLabel { + if trackingMethod == argo.TrackingMethodLabel { return true } @@ -1178,7 +1145,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, trackingMethod, installationID) + 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 3795238c33..4c6ab69f5f 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -2,41 +2,38 @@ package controller import ( "encoding/json" - "errors" + "fmt" "os" "testing" "time" - "dario.cat/mergo" - cachemocks "github.com/argoproj/gitops-engine/pkg/cache/mocks" "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/argoproj/gitops-engine/pkg/utils/testing" + "github.com/imdario/mergo" "github.com/sirupsen/logrus" logrustest "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" - rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/controller/testdata" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/test" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/controller/testdata" + "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" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/argo" ) // TestCompareAppStateEmpty tests comparison when both git and live have no objects func TestCompareAppStateEmpty(t *testing.T) { - t.Parallel() - app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ @@ -48,7 +45,7 @@ func TestCompareAppStateEmpty(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -56,7 +53,7 @@ func TestCompareAppStateEmpty(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Empty(t, app.Status.Conditions) @@ -65,32 +62,32 @@ func TestCompareAppStateEmpty(t *testing.T) { // TestCompareAppStateRepoError tests the case when CompareAppState notices a repo error func TestCompareAppStateRepoError(t *testing.T) { app := newFakeApp() - ctrl := newFakeController(&fakeData{manifestResponses: make([]*apiclient.ManifestResponse, 3)}, errors.New("test repo error")) - sources := make([]v1alpha1.ApplicationSource, 0) + ctrl := newFakeController(&fakeData{manifestResponses: make([]*apiclient.ManifestResponse, 3)}, fmt.Errorf("test repo error")) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) assert.Nil(t, compRes) - require.EqualError(t, err, ErrCompareStateRepo.Error()) + require.EqualError(t, err, CompareStateRepoError.Error()) // expect to still get compare state error to as inside grace period compRes, err = ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) assert.Nil(t, compRes) - require.EqualError(t, err, ErrCompareStateRepo.Error()) + require.EqualError(t, err, CompareStateRepoError.Error()) time.Sleep(10 * time.Second) // expect to not get error as outside of grace period, but status should be unknown compRes, err = ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) assert.NotNil(t, compRes) require.NoError(t, err) - assert.Equal(t, v1alpha1.SyncStatusCodeUnknown, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status) } // TestCompareAppStateNamespaceMetadataDiffers tests comparison when managed namespace metadata differs func TestCompareAppStateNamespaceMetadataDiffers(t *testing.T) { app := newFakeApp() - app.Spec.SyncPolicy.ManagedNamespaceMetadata = &v1alpha1.ManagedNamespaceMetadata{ + app.Spec.SyncPolicy.ManagedNamespaceMetadata = &argoappv1.ManagedNamespaceMetadata{ Labels: map[string]string{ "foo": "bar", }, @@ -98,8 +95,8 @@ func TestCompareAppStateNamespaceMetadataDiffers(t *testing.T) { "foo": "bar", }, } - app.Status.OperationState = &v1alpha1.OperationState{ - SyncResult: &v1alpha1.SyncOperationResult{}, + app.Status.OperationState = &argoappv1.OperationState{ + SyncResult: &argoappv1.SyncOperationResult{}, } data := fakeData{ @@ -112,7 +109,7 @@ func TestCompareAppStateNamespaceMetadataDiffers(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -120,7 +117,7 @@ func TestCompareAppStateNamespaceMetadataDiffers(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Empty(t, app.Status.Conditions) @@ -134,7 +131,7 @@ func TestCompareAppStateNamespaceMetadataDiffersToManifest(t *testing.T) { ns.SetAnnotations(map[string]string{"bar": "bat"}) app := newFakeApp() - app.Spec.SyncPolicy.ManagedNamespaceMetadata = &v1alpha1.ManagedNamespaceMetadata{ + app.Spec.SyncPolicy.ManagedNamespaceMetadata = &argoappv1.ManagedNamespaceMetadata{ Labels: map[string]string{ "foo": "bar", }, @@ -142,8 +139,8 @@ func TestCompareAppStateNamespaceMetadataDiffersToManifest(t *testing.T) { "foo": "bar", }, } - app.Status.OperationState = &v1alpha1.OperationState{ - SyncResult: &v1alpha1.SyncOperationResult{}, + app.Status.OperationState = &argoappv1.OperationState{ + SyncResult: &argoappv1.SyncOperationResult{}, } liveNs := ns.DeepCopy() @@ -161,7 +158,7 @@ func TestCompareAppStateNamespaceMetadataDiffersToManifest(t *testing.T) { }, } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -169,7 +166,7 @@ func TestCompareAppStateNamespaceMetadataDiffersToManifest(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) assert.Len(t, compRes.resources, 1) assert.Len(t, compRes.managedResources, 1) assert.NotNil(t, compRes.diffResultList) @@ -195,7 +192,7 @@ func TestCompareAppStateNamespaceMetadata(t *testing.T) { ns.SetAnnotations(map[string]string{"bar": "bat"}) app := newFakeApp() - app.Spec.SyncPolicy.ManagedNamespaceMetadata = &v1alpha1.ManagedNamespaceMetadata{ + app.Spec.SyncPolicy.ManagedNamespaceMetadata = &argoappv1.ManagedNamespaceMetadata{ Labels: map[string]string{ "foo": "bar", }, @@ -203,8 +200,8 @@ func TestCompareAppStateNamespaceMetadata(t *testing.T) { "foo": "bar", }, } - app.Status.OperationState = &v1alpha1.OperationState{ - SyncResult: &v1alpha1.SyncOperationResult{}, + app.Status.OperationState = &argoappv1.OperationState{ + SyncResult: &argoappv1.SyncOperationResult{}, } data := fakeData{ @@ -219,7 +216,7 @@ func TestCompareAppStateNamespaceMetadata(t *testing.T) { }, } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -227,7 +224,7 @@ func TestCompareAppStateNamespaceMetadata(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) assert.Len(t, compRes.resources, 1) assert.Len(t, compRes.managedResources, 1) assert.NotNil(t, compRes.diffResultList) @@ -247,7 +244,7 @@ func TestCompareAppStateNamespaceMetadata(t *testing.T) { // TestCompareAppStateNamespaceMetadataIsTheSame tests comparison when managed namespace metadata is the same func TestCompareAppStateNamespaceMetadataIsTheSame(t *testing.T) { app := newFakeApp() - app.Spec.SyncPolicy.ManagedNamespaceMetadata = &v1alpha1.ManagedNamespaceMetadata{ + app.Spec.SyncPolicy.ManagedNamespaceMetadata = &argoappv1.ManagedNamespaceMetadata{ Labels: map[string]string{ "foo": "bar", }, @@ -255,9 +252,9 @@ func TestCompareAppStateNamespaceMetadataIsTheSame(t *testing.T) { "foo": "bar", }, } - app.Status.OperationState = &v1alpha1.OperationState{ - SyncResult: &v1alpha1.SyncOperationResult{ - ManagedNamespaceMetadata: &v1alpha1.ManagedNamespaceMetadata{ + app.Status.OperationState = &argoappv1.OperationState{ + SyncResult: &argoappv1.SyncOperationResult{ + ManagedNamespaceMetadata: &argoappv1.ManagedNamespaceMetadata{ Labels: map[string]string{ "foo": "bar", }, @@ -278,7 +275,7 @@ func TestCompareAppStateNamespaceMetadataIsTheSame(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -286,7 +283,7 @@ func TestCompareAppStateNamespaceMetadataIsTheSame(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Empty(t, app.Status.Conditions) @@ -306,7 +303,7 @@ func TestCompareAppStateMissing(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -314,7 +311,7 @@ func TestCompareAppStateMissing(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) assert.Len(t, compRes.resources, 1) assert.Len(t, compRes.managedResources, 1) assert.Empty(t, app.Status.Conditions) @@ -338,14 +335,14 @@ func TestCompareAppStateExtra(t *testing.T) { }, } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) require.NoError(t, err) assert.NotNil(t, compRes) - assert.Equal(t, v1alpha1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) assert.Len(t, compRes.resources, 1) assert.Len(t, compRes.managedResources, 1) assert.Empty(t, app.Status.Conditions) @@ -369,14 +366,14 @@ func TestCompareAppStateHook(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) require.NoError(t, err) assert.NotNil(t, compRes) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Len(t, compRes.reconciliationResult.Hooks, 1) @@ -401,14 +398,14 @@ func TestCompareAppStateSkipHook(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) require.NoError(t, err) assert.NotNil(t, compRes) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Len(t, compRes.resources, 1) assert.Len(t, compRes.managedResources, 1) assert.Empty(t, compRes.reconciliationResult.Hooks) @@ -432,7 +429,7 @@ func TestCompareAppStateCompareOptionIgnoreExtraneous(t *testing.T) { } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -440,7 +437,7 @@ func TestCompareAppStateCompareOptionIgnoreExtraneous(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Empty(t, app.Status.Conditions) @@ -465,7 +462,7 @@ func TestCompareAppStateExtraHook(t *testing.T) { }, } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -473,7 +470,7 @@ func TestCompareAppStateExtraHook(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Len(t, compRes.resources, 1) assert.Len(t, compRes.managedResources, 1) assert.Empty(t, compRes.reconciliationResult.Hooks) @@ -583,7 +580,7 @@ func TestCompareAppStateDuplicatedNamespacedResources(t *testing.T) { }, } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -593,15 +590,15 @@ func TestCompareAppStateDuplicatedNamespacedResources(t *testing.T) { assert.NotNil(t, compRes) assert.Len(t, app.Status.Conditions, 1) assert.NotNil(t, app.Status.Conditions[0].LastTransitionTime) - assert.Equal(t, v1alpha1.ApplicationConditionRepeatedResourceWarning, app.Status.Conditions[0].Type) + assert.Equal(t, argoappv1.ApplicationConditionRepeatedResourceWarning, app.Status.Conditions[0].Type) assert.Equal(t, "Resource /Pod/fake-dest-ns/my-pod appeared 2 times among application resources.", app.Status.Conditions[0].Message) assert.Len(t, compRes.resources, 4) } func TestCompareAppStateManagedNamespaceMetadataWithLiveNsDoesNotGetPruned(t *testing.T) { app := newFakeApp() - app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{ - ManagedNamespaceMetadata: &v1alpha1.ManagedNamespaceMetadata{ + app.Spec.SyncPolicy = &argoappv1.SyncPolicy{ + ManagedNamespaceMetadata: &argoappv1.ManagedNamespaceMetadata{ Labels: nil, Annotations: nil, }, @@ -640,14 +637,14 @@ func TestCompareAppStateManagedNamespaceMetadataWithLiveNsDoesNotGetPruned(t *te assert.Len(t, compRes.managedResources, 1) } -var defaultProj = v1alpha1.AppProject{ +var defaultProj = argoappv1.AppProject{ ObjectMeta: metav1.ObjectMeta{ Name: "default", Namespace: test.FakeArgoCDNamespace, }, - Spec: v1alpha1.AppProjectSpec{ + Spec: argoappv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{ + Destinations: []argoappv1.ApplicationDestination{ { Server: "*", Namespace: "*", @@ -659,10 +656,10 @@ var defaultProj = v1alpha1.AppProject{ // TestCompareAppStateWithManifestGeneratePath tests that it compares revisions when the manifest-generate-path annotation is set. func TestCompareAppStateWithManifestGeneratePath(t *testing.T) { app := newFakeApp() - app.SetAnnotations(map[string]string{v1alpha1.AnnotationKeyManifestGeneratePaths: "."}) - app.Status.Sync = v1alpha1.SyncStatus{ + app.SetAnnotations(map[string]string{argoappv1.AnnotationKeyManifestGeneratePaths: "."}) + app.Status.Sync = argoappv1.SyncStatus{ Revision: "abc123", - Status: v1alpha1.SyncStatusCodeSynced, + Status: argoappv1.SyncStatusCodeSynced, } data := fakeData{ @@ -681,13 +678,13 @@ func TestCompareAppStateWithManifestGeneratePath(t *testing.T) { compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, app.Spec.GetSources(), false, false, nil, false, false) require.NoError(t, err) assert.NotNil(t, compRes) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Equal(t, "abc123", compRes.syncStatus.Revision) } func TestSetHealth(t *testing.T) { app := newFakeApp() - deployment := kube.MustToUnstructured(&appsv1.Deployment{ + deployment := kube.MustToUnstructured(&v1.Deployment{ TypeMeta: metav1.TypeMeta{ APIVersion: "apps/v1", Kind: "Deployment", @@ -710,20 +707,21 @@ func TestSetHealth(t *testing.T) { }, }, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) require.NoError(t, err) - assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus) + assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status) + assert.Equal(t, app.Status.Health.LastTransitionTime, compRes.healthStatus.LastTransitionTime) } func TestPreserveStatusTimestamp(t *testing.T) { timestamp := metav1.Now() app := newFakeAppWithHealthAndTime(health.HealthStatusHealthy, timestamp) - deployment := kube.MustToUnstructured(&appsv1.Deployment{ + deployment := kube.MustToUnstructured(&v1.Deployment{ TypeMeta: metav1.TypeMeta{ APIVersion: "apps/v1", Kind: "Deployment", @@ -746,20 +744,21 @@ func TestPreserveStatusTimestamp(t *testing.T) { }, }, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) require.NoError(t, err) - assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus) + assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status) + assert.Equal(t, timestamp, *compRes.healthStatus.LastTransitionTime) } func TestSetHealthSelfReferencedApp(t *testing.T) { app := newFakeApp() unstructuredApp := kube.MustToUnstructured(app) - deployment := kube.MustToUnstructured(&appsv1.Deployment{ + deployment := kube.MustToUnstructured(&v1.Deployment{ TypeMeta: metav1.TypeMeta{ APIVersion: "apps/v1", Kind: "Deployment", @@ -783,34 +782,35 @@ func TestSetHealthSelfReferencedApp(t *testing.T) { }, }, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) require.NoError(t, err) - assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus) + assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status) + assert.Equal(t, app.Status.Health.LastTransitionTime, compRes.healthStatus.LastTransitionTime) } func TestSetManagedResourcesWithOrphanedResources(t *testing.T) { proj := defaultProj.DeepCopy() - proj.Spec.OrphanedResources = &v1alpha1.OrphanedResourcesMonitorSettings{} + proj.Spec.OrphanedResources = &argoappv1.OrphanedResourcesMonitorSettings{} app := newFakeApp() ctrl := newFakeController(&fakeData{ apps: []runtime.Object{app, proj}, namespacedResources: map[kube.ResourceKey]namespacedResource{ kube.NewResourceKey("apps", kube.DeploymentKind, app.Namespace, "guestbook"): { - ResourceNode: v1alpha1.ResourceNode{ - ResourceRef: v1alpha1.ResourceRef{Kind: kube.DeploymentKind, Name: "guestbook", Namespace: app.Namespace}, + ResourceNode: argoappv1.ResourceNode{ + ResourceRef: argoappv1.ResourceRef{Kind: kube.DeploymentKind, Name: "guestbook", Namespace: app.Namespace}, }, AppName: "", }, }, }, nil) - tree, err := ctrl.setAppManagedResources(&v1alpha1.Cluster{Server: "test", Name: "test"}, app, &comparisonResult{managedResources: make([]managedResource, 0)}) + tree, err := ctrl.setAppManagedResources(app, &comparisonResult{managedResources: make([]managedResource, 0)}) require.NoError(t, err) assert.Len(t, tree.OrphanedNodes, 1) @@ -820,7 +820,7 @@ func TestSetManagedResourcesWithOrphanedResources(t *testing.T) { func TestSetManagedResourcesWithResourcesOfAnotherApp(t *testing.T) { proj := defaultProj.DeepCopy() - proj.Spec.OrphanedResources = &v1alpha1.OrphanedResourcesMonitorSettings{} + proj.Spec.OrphanedResources = &argoappv1.OrphanedResourcesMonitorSettings{} app1 := newFakeApp() app1.Name = "app1" @@ -831,15 +831,15 @@ func TestSetManagedResourcesWithResourcesOfAnotherApp(t *testing.T) { apps: []runtime.Object{app1, app2, proj}, namespacedResources: map[kube.ResourceKey]namespacedResource{ kube.NewResourceKey("apps", kube.DeploymentKind, app2.Namespace, "guestbook"): { - ResourceNode: v1alpha1.ResourceNode{ - ResourceRef: v1alpha1.ResourceRef{Kind: kube.DeploymentKind, Name: "guestbook", Namespace: app2.Namespace}, + ResourceNode: argoappv1.ResourceNode{ + ResourceRef: argoappv1.ResourceRef{Kind: kube.DeploymentKind, Name: "guestbook", Namespace: app2.Namespace}, }, AppName: "app2", }, }, }, nil) - tree, err := ctrl.setAppManagedResources(&v1alpha1.Cluster{Server: "test", Name: "test"}, app1, &comparisonResult{managedResources: make([]managedResource, 0)}) + tree, err := ctrl.setAppManagedResources(app1, &comparisonResult{managedResources: make([]managedResource, 0)}) require.NoError(t, err) assert.Empty(t, tree.OrphanedNodes) @@ -847,7 +847,7 @@ func TestSetManagedResourcesWithResourcesOfAnotherApp(t *testing.T) { func TestReturnUnknownComparisonStateOnSettingLoadError(t *testing.T) { proj := defaultProj.DeepCopy() - proj.Spec.OrphanedResources = &v1alpha1.OrphanedResourcesMonitorSettings{} + proj.Spec.OrphanedResources = &argoappv1.OrphanedResourcesMonitorSettings{} app := newFakeApp() @@ -858,20 +858,21 @@ func TestReturnUnknownComparisonStateOnSettingLoadError(t *testing.T) { }, }, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) require.NoError(t, err) - assert.Equal(t, health.HealthStatusUnknown, compRes.healthStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeUnknown, compRes.syncStatus.Status) + assert.Equal(t, health.HealthStatusUnknown, compRes.healthStatus.Status) + assert.Equal(t, app.Status.Health.LastTransitionTime, compRes.healthStatus.LastTransitionTime) + assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status) } func TestSetManagedResourcesKnownOrphanedResourceExceptions(t *testing.T) { proj := defaultProj.DeepCopy() - proj.Spec.OrphanedResources = &v1alpha1.OrphanedResourcesMonitorSettings{} + proj.Spec.OrphanedResources = &argoappv1.OrphanedResourcesMonitorSettings{} proj.Spec.SourceNamespaces = []string{"default"} app := newFakeApp() @@ -881,18 +882,18 @@ func TestSetManagedResourcesKnownOrphanedResourceExceptions(t *testing.T) { apps: []runtime.Object{app, proj}, namespacedResources: map[kube.ResourceKey]namespacedResource{ kube.NewResourceKey("apps", kube.DeploymentKind, app.Namespace, "guestbook"): { - ResourceNode: v1alpha1.ResourceNode{ResourceRef: v1alpha1.ResourceRef{Group: "apps", Kind: kube.DeploymentKind, Name: "guestbook", Namespace: app.Namespace}}, + ResourceNode: argoappv1.ResourceNode{ResourceRef: argoappv1.ResourceRef{Group: "apps", Kind: kube.DeploymentKind, Name: "guestbook", Namespace: app.Namespace}}, }, kube.NewResourceKey("", kube.ServiceAccountKind, app.Namespace, "default"): { - ResourceNode: v1alpha1.ResourceNode{ResourceRef: v1alpha1.ResourceRef{Kind: kube.ServiceAccountKind, Name: "default", Namespace: app.Namespace}}, + ResourceNode: argoappv1.ResourceNode{ResourceRef: argoappv1.ResourceRef{Kind: kube.ServiceAccountKind, Name: "default", Namespace: app.Namespace}}, }, kube.NewResourceKey("", kube.ServiceKind, app.Namespace, "kubernetes"): { - ResourceNode: v1alpha1.ResourceNode{ResourceRef: v1alpha1.ResourceRef{Kind: kube.ServiceAccountKind, Name: "kubernetes", Namespace: app.Namespace}}, + ResourceNode: argoappv1.ResourceNode{ResourceRef: argoappv1.ResourceRef{Kind: kube.ServiceAccountKind, Name: "kubernetes", Namespace: app.Namespace}}, }, }, }, nil) - tree, err := ctrl.setAppManagedResources(&v1alpha1.Cluster{Server: "test", Name: "test"}, app, &comparisonResult{managedResources: make([]managedResource, 0)}) + tree, err := ctrl.setAppManagedResources(app, &comparisonResult{managedResources: make([]managedResource, 0)}) require.NoError(t, err) assert.Len(t, tree.OrphanedNodes, 1) @@ -906,14 +907,11 @@ func Test_appStateManager_persistRevisionHistory(t *testing.T) { }, nil) manager := ctrl.appStateManager.(*appStateManager) setRevisionHistoryLimit := func(value int) { - if value < 0 { - value = 0 - } i := int64(value) app.Spec.RevisionHistoryLimit = &i } addHistory := func() { - err := manager.persistRevisionHistory(app, "my-revision", v1alpha1.ApplicationSource{}, []string{}, []v1alpha1.ApplicationSource{}, false, metav1.Time{}, v1alpha1.OperationInitiator{}) + err := manager.persistRevisionHistory(app, "my-revision", argoappv1.ApplicationSource{}, []string{}, []argoappv1.ApplicationSource{}, false, metav1.Time{}, v1alpha1.OperationInitiator{}) require.NoError(t, err) } addHistory() @@ -949,14 +947,9 @@ func Test_appStateManager_persistRevisionHistory(t *testing.T) { assert.Len(t, app.Status.History, 9) metav1NowTime := metav1.NewTime(time.Now()) - err := manager.persistRevisionHistory(app, "my-revision", v1alpha1.ApplicationSource{}, []string{}, []v1alpha1.ApplicationSource{}, false, metav1NowTime, v1alpha1.OperationInitiator{}) + err := manager.persistRevisionHistory(app, "my-revision", argoappv1.ApplicationSource{}, []string{}, []argoappv1.ApplicationSource{}, false, metav1NowTime, v1alpha1.OperationInitiator{}) require.NoError(t, err) assert.Equal(t, app.Status.History.LastRevisionHistory().DeployStartedAt, &metav1NowTime) - - // negative limit to 0 - setRevisionHistoryLimit(-1) - addHistory() - assert.Empty(t, app.Status.History) } // helper function to read contents of a file to string @@ -969,20 +962,20 @@ func mustReadFile(path string) string { return string(b) } -var signedProj = v1alpha1.AppProject{ +var signedProj = argoappv1.AppProject{ ObjectMeta: metav1.ObjectMeta{ Name: "default", Namespace: test.FakeArgoCDNamespace, }, - Spec: v1alpha1.AppProjectSpec{ + Spec: argoappv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{ + Destinations: []argoappv1.ApplicationDestination{ { Server: "*", Namespace: "*", }, }, - SignatureKeys: []v1alpha1.SignatureKey{ + SignatureKeys: []argoappv1.SignatureKey{ { KeyID: "4AEE18F83AFDEB23", }, @@ -1007,7 +1000,7 @@ func TestSignedResponseNoSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -1015,7 +1008,7 @@ func TestSignedResponseNoSignatureRequired(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Empty(t, app.Status.Conditions) @@ -1034,7 +1027,7 @@ func TestSignedResponseNoSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -1042,7 +1035,7 @@ func TestSignedResponseNoSignatureRequired(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Empty(t, app.Status.Conditions) @@ -1066,7 +1059,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -1074,7 +1067,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Empty(t, app.Status.Conditions) @@ -1093,7 +1086,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") @@ -1101,7 +1094,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Len(t, app.Status.Conditions, 1) @@ -1120,7 +1113,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") @@ -1128,7 +1121,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Len(t, app.Status.Conditions, 1) @@ -1147,7 +1140,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") @@ -1155,7 +1148,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Len(t, app.Status.Conditions, 1) @@ -1177,7 +1170,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { ctrl := newFakeController(&data, nil) testProj := signedProj testProj.Spec.SignatureKeys[0].KeyID = "4AEE18F83AFDEB24" - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") @@ -1185,7 +1178,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Len(t, app.Status.Conditions, 1) @@ -1207,7 +1200,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { // it doesn't matter for our test whether local manifests are valid localManifests := []string{"foobar"} ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") @@ -1215,7 +1208,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeUnknown, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Len(t, app.Status.Conditions, 1) @@ -1237,7 +1230,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") @@ -1245,7 +1238,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Empty(t, app.Status.Conditions) @@ -1267,7 +1260,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { // it doesn't matter for our test whether local manifests are valid localManifests := []string{""} ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") @@ -1275,7 +1268,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, v1alpha1.SyncStatusCodeSynced, compRes.syncStatus.Status) + assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) assert.Empty(t, compRes.managedResources) assert.Empty(t, app.Status.Conditions) @@ -1283,7 +1276,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { } func TestComparisonResult_GetHealthStatus(t *testing.T) { - status := health.HealthStatusMissing + status := &argoappv1.HealthStatus{Status: health.HealthStatusMissing} res := comparisonResult{ healthStatus: status, } @@ -1292,7 +1285,7 @@ func TestComparisonResult_GetHealthStatus(t *testing.T) { } func TestComparisonResult_GetSyncStatus(t *testing.T) { - status := &v1alpha1.SyncStatus{Status: v1alpha1.SyncStatusCodeOutOfSync} + status := &argoappv1.SyncStatus{Status: argoappv1.SyncStatusCodeOutOfSync} res := comparisonResult{ syncStatus: status, } @@ -1418,8 +1411,8 @@ func TestIsLiveResourceManaged(t *testing.T) { configObj := managedObj.DeepCopy() // then - assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, v1alpha1.TrackingMethodLabel, "")) - assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, v1alpha1.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 @@ -1427,43 +1420,43 @@ func TestIsLiveResourceManaged(t *testing.T) { configObj := managedObjWithLabel.DeepCopy() // then - assert.True(t, manager.isSelfReferencedObj(managedObjWithLabel, configObj, appName, v1alpha1.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, v1alpha1.TrackingMethodLabel, "")) - assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, v1alpha1.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, v1alpha1.TrackingMethodLabel, "")) - assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, v1alpha1.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, v1alpha1.TrackingMethodLabel, "")) - assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, v1alpha1.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, v1alpha1.TrackingMethodLabel, "")) - assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, v1alpha1.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, v1alpha1.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) { @@ -1473,7 +1466,7 @@ func TestIsLiveResourceManaged(t *testing.T) { delete(config.GetAnnotations(), common.AnnotationKeyAppInstance) // then - assert.True(t, manager.isSelfReferencedObj(managedWrongAPIGroup, config, appName, v1alpha1.TrackingMethodAnnotation, "")) + assert.True(t, manager.isSelfReferencedObj(managedWrongAPIGroup, config, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation, "")) }) } @@ -1484,8 +1477,8 @@ func TestUseDiffCache(t *testing.T) { testName string noCache bool manifestInfos []*apiclient.ManifestResponse - sources []v1alpha1.ApplicationSource - app *v1alpha1.Application + sources []argoappv1.ApplicationSource + app *argoappv1.Application manifestRevisions []string statusRefreshTimeout time.Duration expectedUseCache bool @@ -1507,8 +1500,8 @@ func TestUseDiffCache(t *testing.T) { }, } } - sources := func() []v1alpha1.ApplicationSource { - return []v1alpha1.ApplicationSource{ + sources := func() []argoappv1.ApplicationSource { + return []argoappv1.ApplicationSource{ { RepoURL: "https://some-repo.com", Path: "argocd/httpbin", @@ -1517,41 +1510,41 @@ func TestUseDiffCache(t *testing.T) { } } - app := func(namespace string, revision string, refresh bool, a *v1alpha1.Application) *v1alpha1.Application { - app := &v1alpha1.Application{ + app := func(namespace string, revision string, refresh bool, a *argoappv1.Application) *argoappv1.Application { + app := &argoappv1.Application{ ObjectMeta: metav1.ObjectMeta{ Name: "httpbin", Namespace: namespace, }, - Spec: v1alpha1.ApplicationSpec{ - Source: &v1alpha1.ApplicationSource{ + Spec: argoappv1.ApplicationSpec{ + Source: &argoappv1.ApplicationSource{ RepoURL: "https://some-repo.com", Path: "argocd/httpbin", TargetRevision: "HEAD", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argoappv1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "httpbin", }, Project: "default", - SyncPolicy: &v1alpha1.SyncPolicy{ + SyncPolicy: &argoappv1.SyncPolicy{ SyncOptions: []string{ "CreateNamespace=true", "ServerSideApply=true", }, }, }, - Status: v1alpha1.ApplicationStatus{ - Resources: []v1alpha1.ResourceStatus{}, - Sync: v1alpha1.SyncStatus{ - Status: v1alpha1.SyncStatusCodeSynced, - ComparedTo: v1alpha1.ComparedTo{ - Source: v1alpha1.ApplicationSource{ + Status: argoappv1.ApplicationStatus{ + Resources: []argoappv1.ResourceStatus{}, + Sync: argoappv1.SyncStatus{ + Status: argoappv1.SyncStatusCodeSynced, + ComparedTo: argoappv1.ComparedTo{ + Source: argoappv1.ApplicationSource{ RepoURL: "https://some-repo.com", Path: "argocd/httpbin", TargetRevision: "HEAD", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argoappv1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "httpbin", }, @@ -1566,12 +1559,18 @@ func TestUseDiffCache(t *testing.T) { } if refresh { annotations := make(map[string]string) - annotations[v1alpha1.AnnotationKeyRefresh] = string(v1alpha1.RefreshTypeNormal) + annotations[argoappv1.AnnotationKeyRefresh] = string(argoappv1.RefreshTypeNormal) app.SetAnnotations(annotations) } if a != nil { err := mergo.Merge(app, a, mergo.WithOverride, mergo.WithOverwriteWithEmptyValue) - require.NoErrorf(t, err, "error merging app") + if err != nil { + 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 } @@ -1604,10 +1603,10 @@ func TestUseDiffCache(t *testing.T) { noCache: false, manifestInfos: manifestInfos("rev1"), sources: sources(), - app: app("httpbin", "", false, &v1alpha1.Application{ - Spec: v1alpha1.ApplicationSpec{ + app: app("httpbin", "", false, &argoappv1.Application{ + Spec: argoappv1.ApplicationSpec{ Source: nil, - Sources: v1alpha1.ApplicationSources{ + Sources: argoappv1.ApplicationSources{ { RepoURL: "multisource repo1", }, @@ -1616,13 +1615,13 @@ func TestUseDiffCache(t *testing.T) { }, }, }, - Status: v1alpha1.ApplicationStatus{ - Resources: []v1alpha1.ResourceStatus{}, - Sync: v1alpha1.SyncStatus{ - Status: v1alpha1.SyncStatusCodeSynced, - ComparedTo: v1alpha1.ComparedTo{ - Source: v1alpha1.ApplicationSource{}, - Sources: v1alpha1.ApplicationSources{ + Status: argoappv1.ApplicationStatus{ + Resources: []argoappv1.ResourceStatus{}, + Sync: argoappv1.SyncStatus{ + Status: argoappv1.SyncStatusCodeSynced, + ComparedTo: argoappv1.ComparedTo{ + Source: argoappv1.ApplicationSource{}, + Sources: argoappv1.ApplicationSources{ { RepoURL: "multisource repo1", }, @@ -1703,9 +1702,9 @@ func TestUseDiffCache(t *testing.T) { noCache: false, manifestInfos: manifestInfos("rev1"), sources: sources(), - app: app("httpbin", "rev1", false, &v1alpha1.Application{ - Spec: v1alpha1.ApplicationSpec{ - Source: &v1alpha1.ApplicationSource{ + app: app("httpbin", "rev1", false, &argoappv1.Application{ + Spec: argoappv1.ApplicationSpec{ + Source: &argoappv1.ApplicationSource{ RepoURL: "new-repo", }, }, @@ -1720,9 +1719,9 @@ func TestUseDiffCache(t *testing.T) { noCache: false, manifestInfos: manifestInfos("rev1"), sources: sources(), - app: app("httpbin", "rev1", false, &v1alpha1.Application{ - Spec: v1alpha1.ApplicationSpec{ - IgnoreDifferences: []v1alpha1.ResourceIgnoreDifferences{ + app: app("httpbin", "rev1", false, &argoappv1.Application{ + Spec: argoappv1.ApplicationSpec{ + IgnoreDifferences: []argoappv1.ResourceIgnoreDifferences{ { Group: "app/v1", Kind: "application", @@ -1738,6 +1737,44 @@ func TestUseDiffCache(t *testing.T) { expectedUseCache: false, serverSideDiff: false, }, + { + // There are code paths that modify the ApplicationSpec and augment the destination field with both the + // destination server and name. Since both fields are populated in the app spec but not in the comparedTo, + // we need to make sure we correctly compare the fields and don't miss the cache. + testName: "will return true if the app spec destination contains both server and name, but otherwise matches comparedTo", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, &argoappv1.Application{ + Spec: argoappv1.ApplicationSpec{ + Destination: argoappv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Name: "httpbin", + Namespace: "httpbin", + }, + }, + Status: argoappv1.ApplicationStatus{ + Resources: []argoappv1.ResourceStatus{}, + Sync: argoappv1.SyncStatus{ + Status: argoappv1.SyncStatusCodeSynced, + ComparedTo: argoappv1.ComparedTo{ + Destination: argoappv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "httpbin", + }, + }, + Revision: "rev1", + }, + ReconciledAt: &metav1.Time{ + Time: time.Now().Add(-time.Hour), + }, + }, + }), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: true, + serverSideDiff: true, + }, } for _, tc := range cases { @@ -1769,7 +1806,7 @@ func TestCompareAppStateDefaultRevisionUpdated(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -1792,7 +1829,7 @@ func TestCompareAppStateRevisionUpdatedWithHelmSource(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data, nil) - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") @@ -1802,24 +1839,3 @@ func TestCompareAppStateRevisionUpdatedWithHelmSource(t *testing.T) { assert.NotNil(t, compRes.syncStatus) assert.True(t, compRes.revisionUpdated) } - -func Test_normalizeClusterScopeTracking(t *testing.T) { - obj := kube.MustToUnstructured(&rbacv1.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - Namespace: "test", - }, - }) - c := cachemocks.ClusterCache{} - c.On("IsNamespaced", mock.Anything).Return(false, nil) - var called bool - err := normalizeClusterScopeTracking([]*unstructured.Unstructured{obj}, &c, func(u *unstructured.Unstructured) error { - // We expect that the normalization function will call this callback with an obj that has had the namespace set - // to empty. - called = true - assert.Empty(t, u.GetNamespace()) - return nil - }) - require.NoError(t, err) - require.True(t, called, "normalization function should have called the callback function") -} diff --git a/controller/sync.go b/controller/sync.go index c1bacdafb9..9aed51682c 100644 --- a/controller/sync.go +++ b/controller/sync.go @@ -2,7 +2,7 @@ package controller import ( "context" - stderrors "errors" + goerrors "errors" "fmt" "os" "strconv" @@ -12,7 +12,7 @@ import ( "k8s.io/apimachinery/pkg/util/strategicpatch" - cdcommon "github.com/argoproj/argo-cd/v3/common" + cdcommon "github.com/argoproj/argo-cd/v2/common" gitopsDiff "github.com/argoproj/gitops-engine/pkg/diff" "github.com/argoproj/gitops-engine/pkg/sync" @@ -20,7 +20,7 @@ import ( "github.com/argoproj/gitops-engine/pkg/utils/kube" jsonpatch "github.com/evanphx/json-patch" log "github.com/sirupsen/logrus" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/managedfields" @@ -28,20 +28,19 @@ import ( "k8s.io/client-go/rest" "k8s.io/kubectl/pkg/util/openapi" - "github.com/argoproj/argo-cd/v3/controller/metrics" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - listersv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - applog "github.com/argoproj/argo-cd/v3/util/app/log" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/argo/diff" - "github.com/argoproj/argo-cd/v3/util/glob" - kubeutil "github.com/argoproj/argo-cd/v3/util/kube" - logutils "github.com/argoproj/argo-cd/v3/util/log" - "github.com/argoproj/argo-cd/v3/util/lua" - "github.com/argoproj/argo-cd/v3/util/rand" + "github.com/argoproj/argo-cd/v2/controller/metrics" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + listersv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/argo/diff" + "github.com/argoproj/argo-cd/v2/util/glob" + kubeutil "github.com/argoproj/argo-cd/v2/util/kube" + logutils "github.com/argoproj/argo-cd/v2/util/log" + "github.com/argoproj/argo-cd/v2/util/lua" + "github.com/argoproj/argo-cd/v2/util/rand" ) -var syncIdPrefix uint64 +var syncIdPrefix uint64 = 0 const ( // EnvVarSyncWaveDelay is an environment variable which controls the delay in seconds between @@ -53,7 +52,7 @@ const ( serviceAccountDisallowedCharSet = "!*[]{}\\/" ) -func (m *appStateManager) getOpenAPISchema(server *v1alpha1.Cluster) (openapi.Resources, error) { +func (m *appStateManager) getOpenAPISchema(server string) (openapi.Resources, error) { cluster, err := m.liveStateCache.GetClusterCache(server) if err != nil { return nil, err @@ -61,7 +60,7 @@ func (m *appStateManager) getOpenAPISchema(server *v1alpha1.Cluster) (openapi.Re return cluster.GetOpenAPISchema(), nil } -func (m *appStateManager) getGVKParser(server *v1alpha1.Cluster) (*managedfields.GvkParser, error) { +func (m *appStateManager) getGVKParser(server string) (*managedfields.GvkParser, error) { cluster, err := m.liveStateCache.GetClusterCache(server) if err != nil { return nil, err @@ -73,12 +72,17 @@ func (m *appStateManager) getGVKParser(server *v1alpha1.Cluster) (*managedfields // interface that provides functionality to dry run apply kubernetes resources. Returns a // cleanup function that must be called to remove the generated kube config for this // server. -func (m *appStateManager) getServerSideDiffDryRunApplier(cluster *v1alpha1.Cluster) (gitopsDiff.KubeApplier, func(), error) { - clusterCache, err := m.liveStateCache.GetClusterCache(cluster) +func (m *appStateManager) getServerSideDiffDryRunApplier(server string) (gitopsDiff.KubeApplier, func(), error) { + clusterCache, err := m.liveStateCache.GetClusterCache(server) if err != nil { return nil, nil, fmt.Errorf("error getting cluster cache: %w", err) } + cluster, err := m.db.GetCluster(context.Background(), server) + if err != nil { + return nil, nil, fmt.Errorf("error getting cluster: %w", err) + } + rawConfig, err := cluster.RawRestConfig() if err != nil { return nil, nil, fmt.Errorf("error getting cluster REST config: %w", err) @@ -110,15 +114,6 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha } syncOp = *state.Operation.Sync - // validates if it should fail the sync if it finds shared resources - hasSharedResource, sharedResourceMessage := hasSharedResourceCondition(app) - if syncOp.SyncOptions.HasOption("FailOnSharedResource=true") && - hasSharedResource { - state.Phase = common.OperationFailed - state.Message = "Shared resource found: " + sharedResourceMessage - return - } - isMultiSourceRevision := app.Spec.HasMultipleSources() rollback := len(syncOp.Sources) > 0 || syncOp.Source != nil if rollback { @@ -172,7 +167,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha } } - proj, err := argo.GetAppProject(context.TODO(), app, listersv1alpha1.NewAppProjectLister(m.projInformer.GetIndexer()), m.namespace, m.settingsMgr, m.db) + proj, err := argo.GetAppProject(app, listersv1alpha1.NewAppProjectLister(m.projInformer.GetIndexer()), m.namespace, m.settingsMgr, m.db, context.TODO()) if err != nil { state.Phase = common.OperationError state.Message = fmt.Sprintf("Failed to load application project: %v", err) @@ -198,7 +193,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha // ignore error if CompareStateRepoError, this shouldn't happen as noRevisionCache is true compareResult, err := m.CompareAppState(app, proj, revisions, sources, false, true, syncOp.Manifests, isMultiSourceRevision, rollback) - if err != nil && !stderrors.Is(err, ErrCompareStateRepo) { + if err != nil && !goerrors.Is(err, CompareStateRepoError) { state.Phase = common.OperationError state.Message = err.Error() return @@ -209,6 +204,15 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha syncRes.Revision = compareResult.syncStatus.Revision syncRes.Revisions = compareResult.syncStatus.Revisions + // validates if it should fail the sync if it finds shared resources + hasSharedResource, sharedResourceMessage := hasSharedResourceCondition(app) + if syncOp.SyncOptions.HasOption("FailOnSharedResource=true") && + hasSharedResource { + state.Phase = common.OperationFailed + state.Message = fmt.Sprintf("Shared resource found: %s", sharedResourceMessage) + return + } + // If there are any comparison or spec errors error conditions do not perform the operation if errConditions := app.Status.GetConditions(map[v1alpha1.ApplicationConditionType]bool{ v1alpha1.ApplicationConditionComparisonError: true, @@ -219,21 +223,21 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha return } - destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, m.db) - if err != nil { - state.Phase = common.OperationError - state.Message = fmt.Sprintf("Failed to get destination cluster: %v", err) - return - } - - rawConfig, err := destCluster.RawRestConfig() + clst, err := m.db.GetCluster(context.Background(), app.Spec.Destination.Server) if err != nil { state.Phase = common.OperationError state.Message = err.Error() return } - clusterRESTConfig, err := destCluster.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() @@ -257,11 +261,11 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha } syncId := fmt.Sprintf("%05d-%s", syncIdPrefix, randSuffix) - logEntry := log.WithFields(applog.GetAppLogFields(app)).WithField("syncId", syncId) - initialResourcesRes := make([]common.ResourceSyncResult, len(syncRes.Resources)) + logEntry := log.WithFields(log.Fields{"application": app.QualifiedName(), "syncId": syncId}) + initialResourcesRes := make([]common.ResourceSyncResult, 0) for i, res := range syncRes.Resources { key := kube.ResourceKey{Group: res.Group, Kind: res.Kind, Namespace: res.Namespace, Name: res.Name} - initialResourcesRes[i] = common.ResourceSyncResult{ + initialResourcesRes = append(initialResourcesRes, common.ResourceSyncResult{ ResourceKey: key, Message: res.Message, Status: res.Status, @@ -270,20 +274,20 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha SyncPhase: res.SyncPhase, Version: res.Version, Order: i + 1, - } + }) } - prunePropagationPolicy := metav1.DeletePropagationForeground + prunePropagationPolicy := v1.DeletePropagationForeground switch { case syncOp.SyncOptions.HasOption("PrunePropagationPolicy=background"): - prunePropagationPolicy = metav1.DeletePropagationBackground + prunePropagationPolicy = v1.DeletePropagationBackground case syncOp.SyncOptions.HasOption("PrunePropagationPolicy=foreground"): - prunePropagationPolicy = metav1.DeletePropagationForeground + prunePropagationPolicy = v1.DeletePropagationForeground case syncOp.SyncOptions.HasOption("PrunePropagationPolicy=orphan"): - prunePropagationPolicy = metav1.DeletePropagationOrphan + prunePropagationPolicy = v1.DeletePropagationOrphan } - openAPISchema, err := m.getOpenAPISchema(destCluster) + openAPISchema, err := m.getOpenAPISchema(clst.Server) if err != nil { state.Phase = common.OperationError state.Message = fmt.Sprintf("failed to load openAPISchema: %v", err) @@ -305,16 +309,17 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha reconciliationResult.Target = patchedTargets } + appLabelKey, err := m.settingsMgr.GetAppInstanceLabelKey() + if err != nil { + 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, err := m.settingsMgr.GetTrackingMethod() - if err != nil { - log.Errorf("Could not get trackingMethod: %v", err) - return - } + trackingMethod := argo.GetTrackingMethod(m.settingsMgr) impersonationEnabled, err := m.settingsMgr.IsImpersonationEnabled() if err != nil { @@ -341,12 +346,12 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha opts := []sync.SyncOpt{ sync.WithLogr(logutils.NewLogrusLogger(logEntry)), sync.WithHealthOverride(lua.ResourceHealthOverrides(resourceOverrides)), - sync.WithPermissionValidator(func(un *unstructured.Unstructured, res *metav1.APIResource) error { + sync.WithPermissionValidator(func(un *unstructured.Unstructured, res *v1.APIResource) error { if !proj.IsGroupKindPermitted(un.GroupVersionKind().GroupKind(), res.Namespaced) { return fmt.Errorf("resource %s:%s is not permitted in project %s", un.GroupVersionKind().Group, un.GroupVersionKind().Kind, proj.Name) } if res.Namespaced { - permitted, err := proj.IsDestinationPermitted(destCluster, un.GetNamespace(), func(project string) ([]*v1alpha1.Cluster, error) { + permitted, err := proj.IsDestinationPermitted(v1alpha1.ApplicationDestination{Namespace: un.GetNamespace(), Server: app.Spec.Destination.Server, Name: app.Spec.Destination.Name}, func(project string) ([]*v1alpha1.Cluster, error) { return m.db.GetProjectClusters(context.TODO(), project) }) if err != nil { @@ -365,7 +370,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(), v1alpha1.TrackingMethod(trackingMethod), installationID) + m.isSelfReferencedObj(live, target, app.GetName(), appLabelKey, trackingMethod, installationID) }), sync.WithManifestValidation(!syncOp.SyncOptions.HasOption(common.SyncOptionsDisableValidation)), sync.WithSyncWaveHook(delayBetweenSyncWaves), @@ -376,7 +381,6 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha sync.WithServerSideApply(syncOp.SyncOptions.HasOption(common.SyncOptionServerSideApply)), sync.WithServerSideApplyManager(cdcommon.ArgoCDSSAManager), sync.WithPruneConfirmed(app.IsDeletionConfirmed(state.StartedAt.Time)), - sync.WithSkipDryRunOnMissingResource(syncOp.SyncOptions.HasOption(common.SyncOptionSkipDryRunOnMissingResource)), } if syncOp.SyncOptions.HasOption("CreateNamespace=true") { @@ -420,9 +424,9 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha for _, res := range resState { augmentedMsg, err := argo.AugmentSyncMsg(res, func() ([]kube.APIResourceInfo, error) { if apiVersion == nil { - _, apiVersion, err = m.liveStateCache.GetVersionsInfo(destCluster) + _, apiVersion, err = m.liveStateCache.GetVersionsInfo(app.Spec.Destination.Server) if err != nil { - return nil, fmt.Errorf("failed to get version info from the target cluster %q", destCluster.Server) + return nil, fmt.Errorf("failed to get version info from the target cluster %q", app.Spec.Destination.Server) } } return apiVersion, nil @@ -527,7 +531,7 @@ func getMergePatch(original, modified *unstructured.Unstructured, lookupPatchMet // applyMergePatch will apply the given patch in the obj and return the patched // unstructure. -func applyMergePatch(obj *unstructured.Unstructured, patch []byte, versionedObject any) (*unstructured.Unstructured, error) { +func applyMergePatch(obj *unstructured.Unstructured, patch []byte, versionedObject interface{}) (*unstructured.Unstructured, error) { originalJSON, err := obj.MarshalJSON() if err != nil { return nil, err @@ -570,7 +574,7 @@ func hasSharedResourceCondition(app *v1alpha1.Application) (bool, string) { // Note, this is not foolproof, since a proper fix would require the CRD record // status.observedGeneration coupled with a health.lua that verifies // status.observedGeneration == metadata.generation -func delayBetweenSyncWaves(_ common.SyncPhase, _ int, finalWave bool) error { +func delayBetweenSyncWaves(phase common.SyncPhase, wave int, finalWave bool) error { if !finalWave { delaySec := 2 if delaySecStr := os.Getenv(EnvVarSyncWaveDelay); delaySecStr != "" { @@ -623,10 +627,11 @@ func deriveServiceAccountToImpersonate(project *v1alpha1.AppProject, application 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 "system:serviceaccount:" + item.DefaultServiceAccount, nil + return fmt.Sprintf("system:serviceaccount:%s", item.DefaultServiceAccount), nil + } else { + // service account needs to be prefixed with a namespace + return fmt.Sprintf("system:serviceaccount:%s:%s", serviceAccountNamespace, item.DefaultServiceAccount), nil } - // service account needs to be prefixed with a namespace - return fmt.Sprintf("system:serviceaccount:%s:%s", serviceAccountNamespace, item.DefaultServiceAccount), nil } } // if there is no match found in the AppProject.Spec.DestinationServiceAccounts, use the default service account of the destination namespace. diff --git a/controller/sync_namespace.go b/controller/sync_namespace.go index 2acf31654c..43e0dc6170 100644 --- a/controller/sync_namespace.go +++ b/controller/sync_namespace.go @@ -4,7 +4,7 @@ import ( gitopscommon "github.com/argoproj/gitops-engine/pkg/sync/common" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) // syncNamespace determine if Argo CD should create and/or manage the namespace diff --git a/controller/sync_namespace_test.go b/controller/sync_namespace_test.go index f8b045cbc5..0124d99532 100644 --- a/controller/sync_namespace_test.go +++ b/controller/sync_namespace_test.go @@ -8,7 +8,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/types" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func createFakeNamespace(uid string, resourceVersion string, labels map[string]string, annotations map[string]string) *unstructured.Unstructured { diff --git a/controller/sync_test.go b/controller/sync_test.go index 135b57f356..b171fb8061 100644 --- a/controller/sync_test.go +++ b/controller/sync_test.go @@ -1,6 +1,7 @@ package controller import ( + "context" "strconv" "testing" @@ -10,16 +11,17 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" - "github.com/argoproj/argo-cd/v3/controller/testdata" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/argo/diff" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" + argocommon "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/controller/testdata" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/argo/diff" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" ) func TestPersistRevisionHistory(t *testing.T) { @@ -28,7 +30,7 @@ func TestPersistRevisionHistory(t *testing.T) { app.Status.History = nil defaultProject := &v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: test.FakeArgoCDNamespace, Name: "default", }, @@ -53,7 +55,7 @@ func TestPersistRevisionHistory(t *testing.T) { // Ensure we record spec.source into sync result assert.Equal(t, app.Spec.GetSource(), opState.SyncResult.Source) - updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(t.Context(), app.Name, metav1.GetOptions{}) + updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(context.Background(), app.Name, v1.GetOptions{}) require.NoError(t, err) require.Len(t, updatedApp.Status.History, 1) assert.Equal(t, app.Spec.GetSource(), updatedApp.Status.History[0].Source) @@ -74,7 +76,7 @@ func TestPersistManagedNamespaceMetadataState(t *testing.T) { } defaultProject := &v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: test.FakeArgoCDNamespace, Name: "default", }, @@ -105,7 +107,7 @@ func TestPersistRevisionHistoryRollback(t *testing.T) { app.Status.OperationState = nil app.Status.History = nil defaultProject := &v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: test.FakeArgoCDNamespace, Name: "default", }, @@ -142,7 +144,7 @@ func TestPersistRevisionHistoryRollback(t *testing.T) { // Ensure we record opState's source into sync result assert.Equal(t, source, opState.SyncResult.Source) - updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(t.Context(), app.Name, metav1.GetOptions{}) + updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(context.Background(), app.Name, v1.GetOptions{}) require.NoError(t, err) assert.Len(t, updatedApp.Status.History, 1) assert.Equal(t, source, updatedApp.Status.History[0].Source) @@ -155,7 +157,7 @@ func TestSyncComparisonError(t *testing.T) { app.Status.History = nil defaultProject := &v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: test.FakeArgoCDNamespace, Name: "default", }, @@ -189,24 +191,36 @@ func TestSyncComparisonError(t *testing.T) { } func TestAppStateManager_SyncAppState(t *testing.T) { + t.Parallel() + type fixture struct { - project *v1alpha1.AppProject application *v1alpha1.Application + project *v1alpha1.AppProject controller *ApplicationController } - setup := func() *fixture { + setup := func(liveObjects map[kube.ResourceKey]*unstructured.Unstructured) *fixture { app := newFakeApp() app.Status.OperationState = nil app.Status.History = nil + if liveObjects == nil { + liveObjects = make(map[kube.ResourceKey]*unstructured.Unstructured) + } + project := &v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: test.FakeArgoCDNamespace, Name: "default", }, Spec: v1alpha1.AppProjectSpec{ SignatureKeys: []v1alpha1.SignatureKey{{KeyID: "test"}}, + Destinations: []v1alpha1.ApplicationDestination{ + { + Namespace: "*", + Server: "*", + }, + }, }, } data := fakeData{ @@ -217,13 +231,13 @@ func TestAppStateManager_SyncAppState(t *testing.T) { Server: test.FakeClusterURL, Revision: "abc123", }, - managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), + managedLiveObjs: liveObjects, } ctrl := newFakeController(&data, nil) return &fixture{ - project: project, application: app, + project: project, controller: ctrl, } } @@ -231,13 +245,23 @@ func TestAppStateManager_SyncAppState(t *testing.T) { t.Run("will fail the sync if finds shared resources", func(t *testing.T) { // given t.Parallel() - f := setup() - syncErrorMsg := "deployment already applied by another application" - condition := v1alpha1.ApplicationCondition{ - Type: v1alpha1.ApplicationConditionSharedResourceWarning, - Message: syncErrorMsg, - } - f.application.Status.Conditions = append(f.application.Status.Conditions, condition) + + sharedObject := kube.MustToUnstructured(&corev1.ConfigMap{ + TypeMeta: v1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: v1.ObjectMeta{ + Name: "configmap1", + Namespace: "default", + Labels: map[string]string{ + argocommon.LabelKeyAppInstance: "another-app", + }, + }, + }) + liveObjects := make(map[kube.ResourceKey]*unstructured.Unstructured) + liveObjects[kube.GetResourceKey(sharedObject)] = sharedObject + f := setup(liveObjects) // Sync with source unspecified opState := &v1alpha1.OperationState{Operation: v1alpha1.Operation{ @@ -252,7 +276,7 @@ func TestAppStateManager_SyncAppState(t *testing.T) { // then assert.Equal(t, common.OperationFailed, opState.Phase) - assert.Contains(t, opState.Message, syncErrorMsg) + assert.Contains(t, opState.Message, "ConfigMap/configmap1 is part of applications fake-argocd-ns/my-app and another-app") }) } @@ -269,7 +293,7 @@ func TestSyncWindowDeniesSync(t *testing.T) { app.Status.History = nil project := &v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: test.FakeArgoCDNamespace, Name: "default", }, @@ -463,7 +487,7 @@ func TestNormalizeTargetResourcesWithList(t *testing.T) { type fixture struct { comparisonResult *comparisonResult } - setupHTTPProxy := func(t *testing.T, ignores []v1alpha1.ResourceIgnoreDifferences) *fixture { + setupHttpProxy := func(t *testing.T, ignores []v1alpha1.ResourceIgnoreDifferences) *fixture { t.Helper() dc, err := diff.NewDiffConfigBuilder(). WithDiffSettings(ignores, nil, true, normalizers.IgnoreNormalizerOpts{}). @@ -493,7 +517,7 @@ func TestNormalizeTargetResourcesWithList(t *testing.T) { // JSONPointers: []string{"/spec/routes"}, }, } - f := setupHTTPProxy(t, ignores) + f := setupHttpProxy(t, ignores) target := test.YamlToUnstructured(testdata.TargetHTTPProxy) f.comparisonResult.reconciliationResult.Target = []*unstructured.Unstructured{target} @@ -507,19 +531,19 @@ func TestNormalizeTargetResourcesWithList(t *testing.T) { require.Len(t, patchedTargets, 1) // live should have 1 entry - require.Len(t, dig[[]any](f.comparisonResult.reconciliationResult.Live[0].Object, []any{"spec", "routes", 0, "rateLimitPolicy", "global", "descriptors"}), 1) + require.Len(t, dig[[]any](f.comparisonResult.reconciliationResult.Live[0].Object, []interface{}{"spec", "routes", 0, "rateLimitPolicy", "global", "descriptors"}), 1) // assert some arbitrary field to show `entries[0]` is not an empty object - require.Equal(t, "sample-header", dig[string](f.comparisonResult.reconciliationResult.Live[0].Object, []any{"spec", "routes", 0, "rateLimitPolicy", "global", "descriptors", 0, "entries", 0, "requestHeader", "headerName"})) + require.Equal(t, "sample-header", dig[string](f.comparisonResult.reconciliationResult.Live[0].Object, []interface{}{"spec", "routes", 0, "rateLimitPolicy", "global", "descriptors", 0, "entries", 0, "requestHeader", "headerName"})) // target has 2 entries - require.Len(t, dig[[]any](f.comparisonResult.reconciliationResult.Target[0].Object, []any{"spec", "routes", 0, "rateLimitPolicy", "global", "descriptors", 0, "entries"}), 2) + require.Len(t, dig[[]any](f.comparisonResult.reconciliationResult.Target[0].Object, []interface{}{"spec", "routes", 0, "rateLimitPolicy", "global", "descriptors", 0, "entries"}), 2) // assert some arbitrary field to show `entries[0]` is not an empty object - require.Equal(t, "sample-header", dig[string](f.comparisonResult.reconciliationResult.Target[0].Object, []any{"spec", "routes", 0, "rateLimitPolicy", "global", "descriptors", 0, "entries", 0, "requestHeaderValueMatch", "headers", 0, "name"})) + require.Equal(t, "sample-header", dig[string](f.comparisonResult.reconciliationResult.Target[0].Object, []interface{}{"spec", "routes", 0, "rateLimitPolicy", "global", "descriptors", 0, "entries", 0, "requestHeaderValueMatch", "headers", 0, "name"})) // It should be *1* entries in the array - require.Len(t, dig[[]any](patchedTargets[0].Object, []any{"spec", "routes", 0, "rateLimitPolicy", "global", "descriptors"}), 1) + require.Len(t, dig[[]any](patchedTargets[0].Object, []interface{}{"spec", "routes", 0, "rateLimitPolicy", "global", "descriptors"}), 1) // and it should NOT equal an empty object - require.Len(t, dig[any](patchedTargets[0].Object, []any{"spec", "routes", 0, "rateLimitPolicy", "global", "descriptors", 0, "entries", 0}), 1) + require.Len(t, dig[any](patchedTargets[0].Object, []interface{}{"spec", "routes", 0, "rateLimitPolicy", "global", "descriptors", 0, "entries", 0}), 1) }) t.Run("will correctly set array entries if new entries have been added", func(t *testing.T) { // given @@ -530,7 +554,7 @@ func TestNormalizeTargetResourcesWithList(t *testing.T) { JQPathExpressions: []string{".spec.template.spec.containers[].env[] | select(.name == \"SOME_ENV_VAR\")"}, }, } - f := setupHTTPProxy(t, ignores) + f := setupHttpProxy(t, ignores) live := test.YamlToUnstructured(testdata.LiveDeploymentEnvVarsYaml) target := test.YamlToUnstructured(testdata.TargetDeploymentEnvVarsYaml) f.comparisonResult.reconciliationResult.Live = []*unstructured.Unstructured{live} @@ -547,10 +571,10 @@ func TestNormalizeTargetResourcesWithList(t *testing.T) { require.True(t, ok) assert.Len(t, containers, 1) - ports := containers[0].(map[string]any)["ports"].([]any) + ports := containers[0].(map[string]interface{})["ports"].([]interface{}) assert.Len(t, ports, 1) - env := containers[0].(map[string]any)["env"].([]any) + env := containers[0].(map[string]interface{})["env"].([]interface{}) assert.Len(t, env, 3) first := env[0] @@ -558,14 +582,14 @@ func TestNormalizeTargetResourcesWithList(t *testing.T) { third := env[2] // Currently the defined order at this time is the insertion order of the target manifest. - assert.Equal(t, "SOME_ENV_VAR", first.(map[string]any)["name"]) - assert.Equal(t, "some_value", first.(map[string]any)["value"]) + assert.Equal(t, "SOME_ENV_VAR", first.(map[string]interface{})["name"]) + assert.Equal(t, "some_value", first.(map[string]interface{})["value"]) - assert.Equal(t, "SOME_OTHER_ENV_VAR", second.(map[string]any)["name"]) - assert.Equal(t, "some_other_value", second.(map[string]any)["value"]) + assert.Equal(t, "SOME_OTHER_ENV_VAR", second.(map[string]interface{})["name"]) + assert.Equal(t, "some_other_value", second.(map[string]interface{})["value"]) - assert.Equal(t, "YET_ANOTHER_ENV_VAR", third.(map[string]any)["name"]) - assert.Equal(t, "yet_another_value", third.(map[string]any)["value"]) + assert.Equal(t, "YET_ANOTHER_ENV_VAR", third.(map[string]interface{})["name"]) + assert.Equal(t, "yet_another_value", third.(map[string]interface{})["value"]) }) t.Run("ignore-deployment-image-replicas-changes-additive", func(t *testing.T) { @@ -582,7 +606,7 @@ func TestNormalizeTargetResourcesWithList(t *testing.T) { JQPathExpressions: []string{".spec.template.spec.containers[].image"}, }, } - f := setupHTTPProxy(t, ignores) + f := setupHttpProxy(t, ignores) live := test.YamlToUnstructured(testdata.MinimalImageReplicaDeploymentYaml) target := test.YamlToUnstructured(testdata.AdditionalImageReplicaDeploymentYaml) f.comparisonResult.reconciliationResult.Live = []*unstructured.Unstructured{live} @@ -597,7 +621,7 @@ func TestNormalizeTargetResourcesWithList(t *testing.T) { metadata, ok, err := unstructured.NestedMap(targets[0].Object, "metadata") require.NoError(t, err) require.True(t, ok) - labels, ok := metadata["labels"].(map[string]any) + labels, ok := metadata["labels"].(map[string]interface{}) require.True(t, ok) assert.Len(t, labels, 2) assert.Equal(t, "web", labels["appProcess"]) @@ -608,29 +632,29 @@ func TestNormalizeTargetResourcesWithList(t *testing.T) { assert.Equal(t, int64(1), spec["replicas"]) - template, ok := spec["template"].(map[string]any) + template, ok := spec["template"].(map[string]interface{}) require.True(t, ok) - tMetadata, ok := template["metadata"].(map[string]any) + tMetadata, ok := template["metadata"].(map[string]interface{}) require.True(t, ok) - tLabels, ok := tMetadata["labels"].(map[string]any) + tLabels, ok := tMetadata["labels"].(map[string]interface{}) require.True(t, ok) assert.Len(t, tLabels, 2) assert.Equal(t, "web", tLabels["appProcess"]) - tSpec, ok := template["spec"].(map[string]any) + tSpec, ok := template["spec"].(map[string]interface{}) require.True(t, ok) containers, ok, err := unstructured.NestedSlice(tSpec, "containers") require.NoError(t, err) require.True(t, ok) assert.Len(t, containers, 1) - first := containers[0].(map[string]any) + first := containers[0].(map[string]interface{}) assert.Equal(t, "alpine:3", first["image"]) - resources, ok := first["resources"].(map[string]any) + resources, ok := first["resources"].(map[string]interface{}) require.True(t, ok) - requests, ok := resources["requests"].(map[string]any) + requests, ok := resources["requests"].(map[string]interface{}) require.True(t, ok) assert.Equal(t, "400m", requests["cpu"]) @@ -639,7 +663,7 @@ func TestNormalizeTargetResourcesWithList(t *testing.T) { require.True(t, ok) assert.Len(t, env, 1) - env0 := env[0].(map[string]any) + env0 := env[0].(map[string]interface{}) assert.Equal(t, "EV", env0["name"]) assert.Equal(t, "here", env0["value"]) }) @@ -653,7 +677,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) { setup := func(destinationServiceAccounts []v1alpha1.ApplicationDestinationServiceAccount, destinationNamespace, destinationServerURL, applicationNamespace string) *fixture { project := &v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd-ns", Name: "testProj", }, @@ -662,7 +686,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) { }, } app := &v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: applicationNamespace, Name: "testApp", }, @@ -999,7 +1023,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) { setup := func(destinationServiceAccounts []v1alpha1.ApplicationDestinationServiceAccount, destinationNamespace, destinationServerURL, applicationNamespace string) *fixture { project := &v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: "argocd-ns", Name: "testProj", }, @@ -1008,7 +1032,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) { }, } app := &v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: applicationNamespace, Name: "testApp", }, @@ -1278,7 +1302,7 @@ func TestSyncWithImpersonate(t *testing.T) { app.Status.OperationState = nil app.Status.History = nil project := &v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: test.FakeArgoCDNamespace, Name: "default", }, @@ -1296,7 +1320,7 @@ func TestSyncWithImpersonate(t *testing.T) { additionalObjs := []runtime.Object{} if serviceAccountName != "" { syncServiceAccount := &corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: serviceAccountName, Namespace: test.FakeDestNamespace, }, @@ -1410,15 +1434,15 @@ func TestSyncWithImpersonate(t *testing.T) { }) } -func dig[T any](obj any, path []any) T { +func dig[T any](obj interface{}, path []interface{}) T { i := obj for _, segment := range path { switch segment.(type) { case int: - i = i.([]any)[segment.(int)] + i = i.([]interface{})[segment.(int)] case string: - i = i.(map[string]any)[segment.(string)] + i = i.(map[string]interface{})[segment.(string)] default: panic("invalid path for object") } diff --git a/controller/testdata/diff-cache.yaml b/controller/testdata/diff-cache.yaml index 18523c8595..41a1e8a4bb 100644 --- a/controller/testdata/diff-cache.yaml +++ b/controller/testdata/diff-cache.yaml @@ -51,7 +51,7 @@ spec: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -67,7 +67,7 @@ spec: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla syncPolicy: retry: @@ -98,7 +98,7 @@ status: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -114,7 +114,7 @@ status: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla - deployStartedAt: "2024-03-04T22:08:29Z" deployedAt: "2024-03-04T22:08:30Z" @@ -127,7 +127,7 @@ status: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -143,7 +143,7 @@ status: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla - deployStartedAt: "2024-03-04T22:09:16Z" deployedAt: "2024-03-04T22:09:16Z" @@ -156,7 +156,7 @@ status: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -172,7 +172,7 @@ status: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla - deployStartedAt: "2024-03-04T22:11:41Z" deployedAt: "2024-03-04T22:11:41Z" @@ -185,7 +185,7 @@ status: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -201,7 +201,7 @@ status: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla - deployStartedAt: "2024-03-04T22:50:55Z" deployedAt: "2024-03-04T22:50:55Z" @@ -214,7 +214,7 @@ status: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -230,7 +230,7 @@ status: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla - deployStartedAt: "2024-03-04T22:52:56Z" deployedAt: "2024-03-04T22:52:56Z" @@ -243,7 +243,7 @@ status: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -259,7 +259,7 @@ status: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla - deployStartedAt: "2024-03-04T22:56:15Z" deployedAt: "2024-03-04T22:56:15Z" @@ -272,7 +272,7 @@ status: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -288,7 +288,7 @@ status: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla - deployStartedAt: "2024-03-05T07:31:56Z" deployedAt: "2024-03-05T07:31:57Z" @@ -301,7 +301,7 @@ status: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -317,7 +317,7 @@ status: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla - deployStartedAt: "2024-03-05T07:32:44Z" deployedAt: "2024-03-05T07:32:44Z" @@ -330,7 +330,7 @@ status: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -346,7 +346,7 @@ status: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla - deployStartedAt: "2024-03-05T07:33:03Z" deployedAt: "2024-03-05T07:33:04Z" @@ -359,7 +359,7 @@ status: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -375,14 +375,14 @@ status: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla operationState: finishedAt: "2024-03-05T07:33:04Z" message: successfully synced (all tasks run) operation: initiatedBy: - username: foo@example.com + username: laurent.lavaud@mirakl.com retry: backoff: duration: 5s @@ -425,7 +425,7 @@ status: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -441,7 +441,7 @@ status: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla reconciledAt: "2024-03-05T07:33:04Z" resources: @@ -476,7 +476,7 @@ status: - name: RELEASE_NAME value: test-lla - name: CHART_REPOSITORY - value: oci://europe-west1-docker.pkg.dev/foo/charts + value: oci://europe-west1-docker.pkg.dev/platform-89be/charts - name: CHART_NAME value: velero - name: PREVIEW @@ -492,7 +492,7 @@ status: - name: HELM_ARGS value: "" name: cmp-helm-v2 - repoURL: https://github.com/foo/manifests-velero.git + repoURL: https://github.com/mirakl/manifests-velero.git targetRevision: test-lla revision: rev1 status: Synced diff --git a/controller/testdata/live-deployment-env-vars.yaml b/controller/testdata/live-deployment-env-vars.yaml index b72cfad3f8..c4d917b640 100644 --- a/controller/testdata/live-deployment-env-vars.yaml +++ b/controller/testdata/live-deployment-env-vars.yaml @@ -6,7 +6,7 @@ metadata: deployment.kubernetes.io/revision: '9' iksm-version: '2.0' kubectl.kubernetes.io/last-applied-configuration: > - {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"guestbook:apps/Deployment:default/kustomize-guestbook-ui","iksm-version":"2.0"},"name":"kustomize-guestbook-ui","namespace":"default"},"spec":{"replicas":4,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui"}},"spec":{"containers":[{"env":[{"name":"SOME_ENV_VAR","value":"some_value"}],"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook-ui","ports":[{"containerPort":80}],"resources":{"requests":{"cpu":"50m","memory":"100Mi"}}}]}}}} + {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"guestbook:apps/Deployment:default/kustomize-guestbook-ui","iksm-version":"2.0"},"name":"kustomize-guestbook-ui","namespace":"default"},"spec":{"replicas":4,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui"}},"spec":{"containers":[{"env":[{"name":"SOME_ENV_VAR","value":"some_value"}],"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-ui","ports":[{"containerPort":80}],"resources":{"requests":{"cpu":"50m","memory":"100Mi"}}}]}}}} creationTimestamp: '2022-01-05T15:45:21Z' generation: 119 managedFields: @@ -137,7 +137,7 @@ spec: - env: - name: SOME_ENV_VAR value: some_value - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1' + image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1' imagePullPolicy: IfNotPresent name: guestbook-ui ports: diff --git a/controller/testdata/live-deployment.yaml b/controller/testdata/live-deployment.yaml index 898dbfaade..731b5b7207 100644 --- a/controller/testdata/live-deployment.yaml +++ b/controller/testdata/live-deployment.yaml @@ -6,7 +6,7 @@ metadata: deployment.kubernetes.io/revision: '9' iksm-version: '2.0' kubectl.kubernetes.io/last-applied-configuration: > - {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"guestbook:apps/Deployment:default/kustomize-guestbook-ui","iksm-version":"2.0"},"name":"kustomize-guestbook-ui","namespace":"default"},"spec":{"replicas":4,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui"}},"spec":{"containers":[{"env":[{"name":"SOME_ENV_VAR","value":"some_value"}],"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook-ui","ports":[{"containerPort":80}],"resources":{"requests":{"cpu":"50m","memory":"100Mi"}}}]}}}} + {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"guestbook:apps/Deployment:default/kustomize-guestbook-ui","iksm-version":"2.0"},"name":"kustomize-guestbook-ui","namespace":"default"},"spec":{"replicas":4,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui"}},"spec":{"containers":[{"env":[{"name":"SOME_ENV_VAR","value":"some_value"}],"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-ui","ports":[{"containerPort":80}],"resources":{"requests":{"cpu":"50m","memory":"100Mi"}}}]}}}} creationTimestamp: '2022-01-05T15:45:21Z' generation: 119 managedFields: @@ -137,7 +137,7 @@ spec: - env: - name: SOME_ENV_VAR value: some_value - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1' + image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1' imagePullPolicy: IfNotPresent name: guestbook-ui ports: diff --git a/controller/testdata/target-deployment-env-vars.yaml b/controller/testdata/target-deployment-env-vars.yaml index b01a4ac77e..d4b55561ad 100644 --- a/controller/testdata/target-deployment-env-vars.yaml +++ b/controller/testdata/target-deployment-env-vars.yaml @@ -25,7 +25,7 @@ spec: value: yet_another_value - name: SOME_ENV_VAR value: different_value! - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1' + image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1' name: guestbook-ui ports: - containerPort: 80 diff --git a/controller/testdata/target-deployment-new-entries.yaml b/controller/testdata/target-deployment-new-entries.yaml index 8cda879efe..b09ca1c9fb 100644 --- a/controller/testdata/target-deployment-new-entries.yaml +++ b/controller/testdata/target-deployment-new-entries.yaml @@ -19,7 +19,7 @@ spec: spec: containers: - name: guestbook-ui - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1' + image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1' env: - name: SOME_ENV_VAR value: some_value diff --git a/controller/testdata/target-deployment.yaml b/controller/testdata/target-deployment.yaml index 9e66f17cc7..111647f9ac 100644 --- a/controller/testdata/target-deployment.yaml +++ b/controller/testdata/target-deployment.yaml @@ -21,7 +21,7 @@ spec: - env: - name: SOME_ENV_VAR value: some_value - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1' + image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1' name: guestbook-ui ports: - containerPort: 80 diff --git a/controller/utils/log.go b/controller/utils/log.go new file mode 100644 index 0000000000..3c5a244e73 --- /dev/null +++ b/controller/utils/log.go @@ -0,0 +1,17 @@ +package utils + +import ( + "github.com/sirupsen/logrus" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +// GetAppLog returns a logrus entry with fields set for the given application. +func GetAppLog(app *v1alpha1.Application) *logrus.Entry { + return logrus.WithFields(logrus.Fields{ + "application": app.Name, + "app-namespace": app.Namespace, + "app-qualified-name": app.QualifiedName(), + "project": app.Spec.Project, + }) +} diff --git a/docs/assets/identity-center-1.png b/docs/assets/identity-center-1.png index 1e308dd461..0cd49528d9 100644 Binary files a/docs/assets/identity-center-1.png and b/docs/assets/identity-center-1.png differ diff --git a/docs/assets/repo-add-azure-workload-identity.png b/docs/assets/repo-add-azure-workload-identity.png deleted file mode 100755 index 3a844c0c68..0000000000 Binary files a/docs/assets/repo-add-azure-workload-identity.png and /dev/null differ diff --git a/docs/assets/scale_resources_1.png b/docs/assets/scale_resources_1.png deleted file mode 100644 index 73b7fb45a8..0000000000 Binary files a/docs/assets/scale_resources_1.png and /dev/null differ diff --git a/docs/assets/scale_resources_2.png b/docs/assets/scale_resources_2.png deleted file mode 100644 index e88d3aee6f..0000000000 Binary files a/docs/assets/scale_resources_2.png and /dev/null differ diff --git a/docs/assets/scale_resources_3.png b/docs/assets/scale_resources_3.png deleted file mode 100644 index 04f62e4a24..0000000000 Binary files a/docs/assets/scale_resources_3.png and /dev/null differ diff --git a/docs/cli_installation.md b/docs/cli_installation.md index e5d92ed1ed..5a314d4ce6 100644 --- a/docs/cli_installation.md +++ b/docs/cli_installation.md @@ -51,19 +51,9 @@ rm argocd-linux-amd64 You should now be able to run `argocd` commands. -## Mac (Apple Silicon) +## Mac (M1) -### Install via Homebrew or Curl - -You can install the CLI using `Homebrew` or a `Curl` command: - -#### Homebrew - -```bash -brew install argocd -``` - -#### Download With Curl +### Download With Curl You can view the latest version of Argo CD at the link above or run the following command to grab the version: @@ -74,14 +64,44 @@ VERSION=$(curl --silent "https://api.github.com/repos/argoproj/argo-cd/releases/ Replace `VERSION` in the command below with the version of Argo CD you would like to download: ```bash -curl -sSL -o argocd https://github.com/argoproj/argo-cd/releases/download/$VERSION/argocd-darwin-arm64 +curl -sSL -o argocd-darwin-arm64 https://github.com/argoproj/argo-cd/releases/download/$VERSION/argocd-darwin-arm64 ``` Install the Argo CD CLI binary: ```bash -sudo install -m 555 argocd /usr/local/bin/argocd -rm argocd +sudo install -m 555 argocd-darwin-arm64 /usr/local/bin/argocd +rm argocd-darwin-arm64 +``` + + +## Mac + +### Homebrew + +```bash +brew install argocd +``` + +### Download With Curl + +You can view the latest version of Argo CD at the link above or run the following command to grab the version: + +```bash +VERSION=$(curl --silent "https://api.github.com/repos/argoproj/argo-cd/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/') +``` + +Replace `VERSION` in the command below with the version of Argo CD you would like to download: + +```bash +curl -sSL -o argocd-darwin-amd64 https://github.com/argoproj/argo-cd/releases/download/$VERSION/argocd-darwin-amd64 +``` + +Install the Argo CD CLI binary: + +```bash +sudo install -m 555 argocd-darwin-amd64 /usr/local/bin/argocd +rm argocd-darwin-amd64 ``` After finishing either of the instructions above, you should now be able to run `argocd` commands. diff --git a/docs/developer-guide/architecture/authz-authn.md b/docs/developer-guide/architecture/authz-authn.md index 5359073ed7..921b744f2e 100644 --- a/docs/developer-guide/architecture/authz-authn.md +++ b/docs/developer-guide/architecture/authz-authn.md @@ -104,6 +104,6 @@ elements are described below with their respective numbers: [3]: https://en.wikipedia.org/wiki/Representational_state_transfer [4]: https://grpc.io/ [5]: https://casbin.org/ -[6]: https://go.dev/wiki/LearnServerProgramming#middleware +[6]: https://github.com/golang/go/wiki/LearnServerProgramming#middleware [7]: https://en.wikipedia.org/wiki/Role-based_access_control [8]: https://pkg.go.dev/net/http#ServeMux diff --git a/docs/developer-guide/contributors-quickstart.md b/docs/developer-guide/contributors-quickstart.md index 3a9de03de8..5544742b7a 100644 --- a/docs/developer-guide/contributors-quickstart.md +++ b/docs/developer-guide/contributors-quickstart.md @@ -20,15 +20,15 @@ Before starting, ensure you have the following tools installed with the specifie ### Fork and Clone the Repository -1. Fork the Argo CD repository to your personal GitHub Account +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 ``` -Please note that the local build process uses GOPATH and that path should not be used, unless the Argo CD repository was directly cloned in it. - 3. Add the upstream remote for rebasing: ```shell cd argo-cd @@ -40,7 +40,7 @@ git remote add upstream https://github.com/argoproj/argo-cd.git 1. Install development tools: ```shell make install-go-tools-local -make install-codegen-tools-local +make install-code-gen-tools-local ``` ### Install Go @@ -134,31 +134,15 @@ DOCKER=podman make start-local ARGOCD_GPG_ENABLED=false ## Common Make Targets -Here are some frequently used make targets (all will run on your machine): +Here are some frequently used make targets: -### Local Toolchain Make Targets - -* `make build-local` - Build Argo CD binaries -* `make test-local` - Run unit tests -* `make codegen-local` - Re-generate auto generated Swagger and Protobuf (after changing API code) -* `make lint-local` - Run linting -* `make pre-commit-local` - Run pre-commit checks -* `make start-e2e-local` - Start server for end-to-end tests -* `make test-e2e-local` - Run end-to-end tests -* `make serve-docs-local` - Serve documentation -* `make start-local` - Start Argo CD - -### Virtualized Toolchain Make Targets - -* `make build` - Build Argo CD binaries +* `make start-local` - Start Argo CD locally * `make test` - Run unit tests -* `make codegen` - Re-generate auto generated Swagger and Protobuf (after changing API code) -* `make lint` - Run linting -* `make pre-commit` - Run pre-commit checks -* `make start-e2e` - Start server for end-to-end tests * `make test-e2e` - Run end-to-end tests -* `make serve-docs` - Serve documentation -* `make start` - Start Argo CD +* `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 diff --git a/docs/developer-guide/dependencies.md b/docs/developer-guide/dependencies.md index e609a23e16..2a4c869825 100644 --- a/docs/developer-guide/dependencies.md +++ b/docs/developer-guide/dependencies.md @@ -47,7 +47,7 @@ If you make changes to the Argo UI component, and your Argo CD changes depend on 2. Also, prepare your Argo CD changes, but don't create the PR just yet. 3. **After** the Argo UI PR has been merged to master, then as part of your Argo CD changes: - Run `yarn add git+https://github.com/argoproj/argo-ui.git` in the `ui/` directory, and then, - - Check in the regenerated `yarn.lock` file as part of your Argo CD commit + - Check in the regenerated yarn.lock file as part of your Argo CD commit 4. Create the Argo CD PR when you are ready. The PR build and test checks should pass. -If your Argo UI change is a 'stand-alone' fix, and you simply want Argo CD to pull in your change, then simply create an Argo CD PR with the `yarn.lock` file change. +If your Argo UI change is a 'stand-alone' fix, and you simply want Argo CD to pull in your change, then simply create an Argo CD PR with the yarn.lock file change. diff --git a/docs/developer-guide/extensions/proxy-extensions.md b/docs/developer-guide/extensions/proxy-extensions.md index e47c25b081..cd41452fbc 100644 --- a/docs/developer-guide/extensions/proxy-extensions.md +++ b/docs/developer-guide/extensions/proxy-extensions.md @@ -1,8 +1,8 @@ # Proxy Extensions -!!! warning "Beta Feature (Since 2.7.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 "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 diff --git a/docs/developer-guide/release-process-and-cadence.md b/docs/developer-guide/release-process-and-cadence.md index 415ac10ede..bda586a97e 100644 --- a/docs/developer-guide/release-process-and-cadence.md +++ b/docs/developer-guide/release-process-and-cadence.md @@ -17,7 +17,7 @@ These are the upcoming releases dates: | v2.12 | Monday, Jun. 17, 2024 | Monday, Aug. 5, 2024 | [Ishita Sequeira](https://github.com/ishitasequeira) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/19063) | | v2.13 | Monday, Sep. 16, 2024 | Monday, Nov. 4, 2024 | [Regina Voloshin](https://github.com/reggie-k) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/19513) | | v2.14 | Monday, Dec. 16, 2024 | Monday, Feb. 3, 2025 | [Ryan Umstead](https://github.com/rumstead) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/20869) | -| v3.0 | Monday, Mar. 17, 2025 | Tuesday, May 6, 2025 | [Regina Voloshin](https://github.com/reggie-k) | | [checklist](https://github.com/argoproj/argo-cd/issues/21735) | +| v2.15 | Monday, Mar. 17, 2025 | Monday, May 5, 2025 | | | | Actual release dates might differ from the plan by a few days. @@ -88,4 +88,4 @@ These evaluations vary from dependency to dependencies. Dependencies are also scheduled for removal if the project has been deprecated or if the project is no longer maintained. CVEs in dependencies will be patched for all supported versions if the CVE is applicable and is assessed by Snyk to be -of high or critical severity. Automation generates a [new Snyk scan weekly](../snyk/index.md). +of high or critical severity. Automation generates a [new Snyk scan weekly](../snyk). diff --git a/docs/developer-guide/releasing.md b/docs/developer-guide/releasing.md index 4764539ee2..bb51ebfa8d 100644 --- a/docs/developer-guide/releasing.md +++ b/docs/developer-guide/releasing.md @@ -20,9 +20,8 @@ triggered. This will be automated in the very near future. * Update `CHANGELOG.md` with changes for this release * Commit & push changes to `CHANGELOG.md` -* Update `goreleaser.yaml` with the updated blog post link in the `Release Notes Blog Post` section. -**The `Init ArgoCD Release` workflow will perform the following steps:** +**The `Init ARGOCD Release` workflow will perform the following steps:** * Update `VERSION` file in the release branch * Update manifests with image tags of the new version in the release branch diff --git a/docs/developer-guide/running-locally.md b/docs/developer-guide/running-locally.md index f1e6db9b88..25f4510e9e 100644 --- a/docs/developer-guide/running-locally.md +++ b/docs/developer-guide/running-locally.md @@ -123,7 +123,7 @@ $ goreman run status [...] ``` -If some of the processes fail to start (not marked with `*`), check logs to see why they are not running. +If not all critical processes run (marked with `*`), check logs to see why they terminated. In case of an error like `gpg: key generation failed: Unknown elliptic curve` (a [gnupg bug](https://dev.gnupg.org/T5444)), disable GPG verification before running `make start-local`: diff --git a/docs/developer-guide/static-code-analysis.md b/docs/developer-guide/static-code-analysis.md index bdc331c02e..90798a70f5 100644 --- a/docs/developer-guide/static-code-analysis.md +++ b/docs/developer-guide/static-code-analysis.md @@ -2,9 +2,9 @@ We use the following static code analysis tools: -* `golangci-lint` and `eslint` for compile time linting +* golangci-lint and eslint for compile time linting * [codecov.io](https://codecov.io/gh/argoproj/argo-cd) - for code coverage * [snyk.io](https://app.snyk.io/org/argoproj/projects) - for image scanning * [sonarcloud.io](https://sonarcloud.io/organizations/argoproj/projects) - for code scans and security alerts -These are at least run daily or on each pull request. +These are at least run daily or on each pull request. \ No newline at end of file diff --git a/docs/developer-guide/test-e2e.md b/docs/developer-guide/test-e2e.md index e3c50934e9..a1ddec8058 100644 --- a/docs/developer-guide/test-e2e.md +++ b/docs/developer-guide/test-e2e.md @@ -3,26 +3,15 @@ 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](https://github.com/argoproj/argo-cd/tree/master/test/e2e/testdata) directory contains various Argo CD applications. Before test execution, the directory is copied into `/tmp/argo-e2e***` temp directory and used in tests as a -Git repository via file url: `file:///tmp/argo-e2e***`. - -!!! note "Rancher Desktop Volume Sharing" - The e2e git server runs in a container. If you are using Rancher Desktop, you will need to enable volume sharing for - the e2e container to access the testdata directory. To do this, add the following to - `~/Library/Application\ Support/rancher-desktop/lima/_config/override.yaml` and restart Rancher Desktop: - - ```yaml - mounts: - - location: /private/tmp - writable: true - ``` +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` 2. Run the tests: `make test-e2e` -You can observe the tests by using the UI [http://localhost:4000/applications](http://localhost:4000/applications) with username `"admin"` and password `"password"`. +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 @@ -42,7 +31,7 @@ If you have changed the port for `argocd-server`, be sure to also set `ARGOCD_SE Some effort has been made to balance test isolation with speed. Tests are isolated as follows as each test gets: * A random 5 character ID. -* A unique Git repository containing the `testdata` in `/tmp/argo-e2e/${id}`. +* A unique Git repository containing the `testdata` in `/tmp/argocd-e2e/${id}`. * A namespace `argocd-e2e-ns-${id}`. * A primary name for the app `argocd-e2e-${id}`. diff --git a/docs/developer-guide/toolchain-guide.md b/docs/developer-guide/toolchain-guide.md index c2e1c3f960..9bba72b456 100644 --- a/docs/developer-guide/toolchain-guide.md +++ b/docs/developer-guide/toolchain-guide.md @@ -16,7 +16,7 @@ If you want to submit a PR, please read this document carefully, as it contains As is the case with the development process, this document is under constant change. If you notice any error, or if you think this document is out-of-date, or if you think it is missing something: Feel free to submit a PR or submit a bug to our GitHub issue tracker. -If you need guidance with submitting a PR, or have any other questions regarding development of Argo CD, do not hesitate to [join our Slack](https://argoproj.github.io/community/join-slack) and get in touch with us in the `#argo-cd-contributors` channel! +If you need guidance with submitting a PR, or have any other questions regarding development of Argo CD, do not hesitate to [join our Slack](https://argoproj.github.io/community/join-slack) and get in touch with us in the `#argo-contributors` channel! ## Before you start @@ -42,6 +42,7 @@ You will need at least the following things in your toolchain in order to develo When you submit a PR against Argo CD's GitHub repository, a couple of CI checks will be run automatically to ensure your changes will build fine and meet certain quality standards. Your contribution needs to pass those checks in order to be merged into the repository. !!!note + Please make sure that you always create PRs from a branch that is up-to-date with the latest changes from Argo CD's master branch. Depending on how long it takes for the maintainers to review and merge your PR, it might be necessary to pull in latest changes into your branch again. Please understand that we, as an Open Source project, have limited capacities for reviewing and merging PRs to Argo CD. We will do our best to review your PR and give you feedback as soon as possible, but please bear with us if it takes a little longer as expected. @@ -94,7 +95,7 @@ ok github.com/argoproj/argo-cd/server/cache 0.029s coverage: 89.3% ## Local vs Virtualized toolchain -Argo CD provides a fully virtualized development and testing toolchain using Docker images. It is recommended to use those images, as they provide the same runtime environment as the final product, and it is much easier to keep up-to-date with changes to the toolchain and dependencies. But as using Docker comes with a slight performance penalty, you might want to set up a local toolchain. +Argo CD provides a fully virtualized development and testing toolchain using Docker images. It is recommended to use those images, as they provide the same runtime environment as the final product and it is much easier to keep up-to-date with changes to the toolchain and dependencies. But as using Docker comes with a slight performance penalty, you might want to setup a local toolchain. Most relevant targets for the build & test cycles in the `Makefile` provide two variants, one of them suffixed with `-local`. For example, `make test` will run unit tests in the Docker container, `make test-local` will run it natively on your local system. @@ -103,7 +104,7 @@ If you are going to use the virtualized toolchain, please bear in mind the follo * Your Kubernetes API server must listen on the interface of your local machine or VM, and not on `127.0.0.1` only. * Your Kubernetes client configuration (`~/.kube/config`) must not use an API URL that points to `localhost` or `127.0.0.1`. -You can test whether the virtualized toolchain has access to your Kubernetes cluster by running `make verify-kube-connect` (*after* you have set up your development environment, as described below), which will run `kubectl version` inside the Docker container used for running all tests. +You can test whether the virtualized toolchain has access to your Kubernetes cluster by running `make verify-kube-connect` (*after* you have setup your development environment, as described below), which will run `kubectl version` inside the Docker container used for running all tests. The Docker container for the virtualized toolchain will use the following local mounts from your workstation, and possibly modify its contents: @@ -147,10 +148,12 @@ The following steps are required no matter whether you chose to use a virtualize ### Clone the Argo CD repository from your personal fork on GitHub -* `git clone https://github.com/YOUR-USERNAME/argo-cd` +* `mkdir -p ~/go/src/github.com/argoproj` +* `cd ~/go/src/github.com/argoproj` +* `git clone https://github.com/yourghuser/argo-cd` * `cd argo-cd` -### Optional: Set up an additional Git remote +### Optional: Setup an additional Git remote While everyone has their own Git workflow, the author of this document recommends to create a remote called `upstream` in your local copy pointing to the original Argo CD repository. This way, you can easily keep your local branches up-to-date by merging in latest changes from the Argo CD repository, i.e. by doing a `git pull upstream master` in your locally checked out branch. To create the remote, run `git remote add upstream https://github.com/argoproj/argo-cd` @@ -214,7 +217,7 @@ k3d cluster create my-cluster --wait --k3s-arg '--disable=traefik@server:*' --ap ``` !!!note - For k3d versions less than v5.0.0, the example command flags `--k3s-arg` and `'--disable=traefik@server:*'` should change to `--k3s-server-arg` and `'--disable=traefik'`, respectively. +For k3d versions less than v5.0.0, the example command flags `--k3s-arg` and `'--disable=traefik@server:*'` should change to `--k3s-server-arg` and `'--disable=traefik'`, respectively. ## The development cycle @@ -249,7 +252,7 @@ After the code glue has been generated, your code should build and the unit test * `make build` * `make test` -These steps are non-modifying, so there's no need to check for changes afterward. +These steps are non-modifying, so there's no need to check for changes afterwards. ### Lint your code base @@ -326,7 +329,7 @@ You need to pull in all required Go dependencies. To do so, run ### Test your build toolchain -The first thing you can do to test whether your build toolchain is set up correctly is by generating the glue code for the API and after that, run a normal build: +The first thing you can do to test whether your build toolchain is setup correctly is by generating the glue code for the API and after that, run a normal build: * `make codegen-local` * `make build-local` @@ -335,7 +338,7 @@ This should return without any error. ### Run unit-tests -The next thing is to make sure that unit tests are running correctly on your system. These will require that all dependencies, such as Helm, Kustomize, Git, GnuPG, etc. are correctly installed and fully functioning: +The next thing is to make sure that unit tests are running correctly on your system. These will require that all dependencies, such as Helm, Kustomize, Git, GnuPG, etc are correctly installed and fully functioning: * `make test-local` @@ -346,6 +349,4 @@ The final step is running the End-to-End testsuite, which makes sure that your K * First, start the End-to-End server: `make start-e2e-local`. This will spawn a number of processes and services on your system. * When all components have started, run `make test-e2e-local` to run the end-to-end tests against your local services. -To run a single test, you can use `TEST_FLAGS="-run TestName" make test-e2e-local`. - For more information about End-to-End tests, refer to the [End-to-End test documentation](test-e2e.md). diff --git a/docs/developer-guide/use-gitpod.md b/docs/developer-guide/use-gitpod.md index 5c9d0f2146..36f783bdc9 100644 --- a/docs/developer-guide/use-gitpod.md +++ b/docs/developer-guide/use-gitpod.md @@ -29,7 +29,7 @@ access Argo CD API/UI from your laptop. Gitpod is a perfect tool in following cases: * you are a first-time contributor and eager to start coding; -* you are traveling and don't want to set up development tools on your laptop; +* you are traveling and don't want to setup development tools on your laptop; * you want to review pull request and need to quickly run code from the PR without changing your local setup; ## Limitations diff --git a/docs/faq.md b/docs/faq.md index f5f4374433..44c3e25902 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -147,7 +147,7 @@ See [#1482](https://github.com/argoproj/argo-cd/issues/1482). ## How often does Argo CD check for changes to my Git or Helm repository ? -The default maximum polling interval is 3 minutes (120 seconds + 60 seconds jitter). +The default polling interval is 3 minutes (180 seconds) with a configurable jitter. You can change the setting by updating the `timeout.reconciliation` value and the `timeout.reconciliation.jitter` in the [argocd-cm](https://github.com/argoproj/argo-cd/blob/2d6ce088acd4fb29271ffb6f6023dbb27594d59b/docs/operator-manual/argocd-cm.yaml#L279-L282) config map. If there are any Git changes, Argo CD will only update applications with the [auto-sync setting](user-guide/auto_sync.md) enabled. If you set it to `0` then Argo CD will stop polling Git repositories automatically and you can only use alternative methods such as [webhooks](operator-manual/webhook.md) and/or manual syncs for deploying applications. diff --git a/docs/getting_started.md b/docs/getting_started.md index 5d3667fd1c..596251b3c2 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -64,11 +64,6 @@ Change the argocd-server service type to `LoadBalancer`: ```bash kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}' ``` -After a short wait, your cloud provider will assign an external IP address to the service. You can retrieve this IP with: - -```bash -kubectl get svc argocd-server -n argocd -o=jsonpath='{.status.loadBalancer.ingress[0].ip}' -``` ### Ingress Follow the [ingress documentation](operator-manual/ingress.md) on how to configure Argo CD with ingress. diff --git a/docs/operator-manual/application.yaml b/docs/operator-manual/application.yaml index adfb29d076..b38d7fddd5 100644 --- a/docs/operator-manual/application.yaml +++ b/docs/operator-manual/application.yaml @@ -119,15 +119,10 @@ spec: beep: boop-${ARGOCD_APP_REVISION} # Toggle which enables/disables env variables substitution in commonAnnotations commonAnnotationsEnvsubst: true - # Defines if the common label(s) should be applied to resource selectors. It also excludes common labels from - # templates unless `labelIncludeTemplates` is set to true. - labelWithoutSelector: false - # Defines if the common label(s) should be applied to resource templates. - labelIncludeTemplates: false forceCommonLabels: false forceCommonAnnotations: false images: - - quay.io/argoprojlabs/argocd-e2e-container:0.2 + - gcr.io/heptio-images/ks-guestbook-demo:0.2 - my-app=gcr.io/my-repo/my-app:0.1 namespace: custom-namespace replicas: @@ -135,8 +130,6 @@ spec: count: 4 components: - ../component # relative to the kustomization.yaml (`source.path`). - # Ignore locally missing component directories when using Kustomize Components. Defaults to false - ignoreMissingComponents: true patches: - target: kind: Deployment @@ -236,7 +229,6 @@ spec: - PruneLast=true # Allow the ability for resource pruning to happen as a final, implicit wave of a sync operation - RespectIgnoreDifferences=true # When syncing changes, respect fields ignored by the ignoreDifferences configuration - ApplyOutOfSyncOnly=true # Only sync out-of-sync resources, rather than applying every object in the application - - SkipDryRunOnMissingResource=true # Allow skip dry run on missing resource managedNamespaceMetadata: # Sets the metadata for the application namespace. Only valid if CreateNamespace=true (see above), otherwise it's a no-op. labels: # The labels to set on the application namespace any: label diff --git a/docs/operator-manual/applicationset/Appset-Any-Namespace.md b/docs/operator-manual/applicationset/Appset-Any-Namespace.md index 9bc0eaf360..01efe576d0 100644 --- a/docs/operator-manual/applicationset/Appset-Any-Namespace.md +++ b/docs/operator-manual/applicationset/Appset-Any-Namespace.md @@ -117,7 +117,7 @@ It can be achieved by setting the environment variable `ARGOCD_APPLICATIONSET_CO #### Change workload startup parameters -In order to enable this feature, the Argo CD administrator must reconfigure the `argocd-applicationset-controller` workloads to add the `--applicationset-namespaces` parameter to the container's startup command. +In order to enable this feature, the Argo CD administrator must reconfigure the and `argocd-applicationset-controller` workloads to add the `--applicationset-namespaces` parameter to the container's startup command. ### Safely template project @@ -256,4 +256,4 @@ spec: - clusters: {} # Automatically use all clusters defined within Argo CD ``` -If you don't want to allow users to discover all clusters with ApplicationSets from other namespaces you may consider deploying ArgoCD in namespace scope or use OPA rules. +If you don't want to allow users to discover all clusters with ApplicationSets from other namespaces you may consider deploying ArgoCD in namespace scope or use OPA rules. \ No newline at end of file diff --git a/docs/operator-manual/applicationset/Controlling-Resource-Modification.md b/docs/operator-manual/applicationset/Controlling-Resource-Modification.md index c42a6e3265..1636d348cb 100644 --- a/docs/operator-manual/applicationset/Controlling-Resource-Modification.md +++ b/docs/operator-manual/applicationset/Controlling-Resource-Modification.md @@ -35,7 +35,7 @@ spec: - Policy `create-only`: Prevents ApplicationSet controller from modifying or deleting Applications. **WARNING**: It doesn't prevent Application controller from deleting Applications according to [ownerReferences](https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/) when deleting ApplicationSet. - Policy `create-update`: Prevents ApplicationSet controller from deleting Applications. Update is allowed. **WARNING**: It doesn't prevent Application controller from deleting Applications according to [ownerReferences](https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/) when deleting ApplicationSet. - Policy `create-delete`: Prevents ApplicationSet controller from modifying Applications. Delete is allowed. -- Policy `sync`: Create, Update and Delete are allowed. +- Policy `sync`: Update and Delete are allowed. If the controller parameter `--policy` is set, it takes precedence on the field `applicationsSync`. It is possible to allow per ApplicationSet sync policy by setting variable `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_POLICY_OVERRIDE` to argocd-cmd-params-cm `applicationsetcontroller.enable.policy.override` or directly with controller parameter `--enable-policy-override` (default to `false`). diff --git a/docs/operator-manual/applicationset/Generators-Git.md b/docs/operator-manual/applicationset/Generators-Git.md index a03d10e7eb..569eb60034 100644 --- a/docs/operator-manual/applicationset/Generators-Git.md +++ b/docs/operator-manual/applicationset/Generators-Git.md @@ -8,7 +8,6 @@ The Git generator contains two subtypes: the Git directory generator, and Git fi For ApplicationSets with a templated `project` field, [the source of truth _must_ be controlled by admins](./Security.md#templated-project-field) - in the case of git generators, PRs must require admin approval. - Git generator does not support Signature Verification For ApplicationSets with a templated `project` field. - - You must only use "non-scoped" repositories for ApplicationSets with a templated `project` field (see ["Repository Credentials for Applicationsets" below](#repository-credentials-for-applicationsets)). ## Git Generator: Directories @@ -205,7 +204,7 @@ spec: You may pass additional, arbitrary string key-value pairs via the `values` field of the git directory generator. Values added via the `values` field are added as `values.(field)`. -In this example, a `cluster` parameter value is passed. It is interpolated from the `path` variable, to then be used to determine the destination namespace. +In this example, a `cluster` parameter value is passed. It is interpolated from the `branch` and `path` variable, to then be used to determine the destination namespace. ```yaml apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet @@ -222,7 +221,7 @@ spec: directories: - path: '*' values: - cluster: '{{.path.basename}}' + cluster: '{{.branch}}-{{.path.basename}}' template: metadata: name: '{{.path.basename}}' @@ -342,45 +341,6 @@ The filename can always be accessed using `{{.path.filename}}`. **Note**: The default behavior of the Git file generator is very greedy. Please see [Git File Generator Globbing](./Generators-Git-File-Globbing.md) for more information. -### Exclude files - -The Git file generator also supports an `exclude` option in order to exclude files in the repository from being scanned by the ApplicationSet controller: - -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: ApplicationSet -metadata: - name: guestbook -spec: - goTemplate: true - goTemplateOptions: ["missingkey=error"] - generators: - - git: - repoURL: https://github.com/argoproj/argo-cd.git - revision: HEAD - files: - - path: "applicationset/examples/git-generator-files-discovery/cluster-config/**/config.json" - - path: "applicationset/examples/git-generator-files-discovery/cluster-config/*/dev/config.json" - exclude: true - template: - metadata: - name: '{{.cluster.name}}-guestbook' - spec: - project: default - source: - repoURL: https://github.com/argoproj/argo-cd.git - targetRevision: HEAD - path: "applicationset/examples/git-generator-files-discovery/apps/guestbook" - destination: - server: https://kubernetes.default.svc - #server: '{{.cluster.address}}' - namespace: guestbook -``` - -This example excludes the `config.json` file in the `dev` directory from the list of files scanned for this `ApplicationSet` resource. - -(*The full example can be found [here](https://github.com/argoproj/argo-cd/tree/master/applicationset/examples/git-generator-files-discovery/excludes).*) - ### Pass additional key-value pairs via `values` field You may pass additional, arbitrary string key-value pairs via the `values` field of the git files generator. Values added via the `values` field are added as `values.(field)`. @@ -424,28 +384,10 @@ In `values` we can also interpolate all fields set by the git files generator as ## Webhook Configuration -When using a Git generator, the ApplicationSet controller polls Git repositories every 3 minutes (this can be customized per ApplicationSet with `requeueAfterSeconds`) to detect changes. To eliminate +When using a Git generator, ApplicationSet polls Git repositories every three minutes to detect changes. To eliminate this delay from polling, the ApplicationSet webhook server can be configured to receive webhook events. ApplicationSet supports Git webhook notifications from GitHub and GitLab. The following explains how to configure a Git webhook for GitHub, but the same process should be applicable to other providers. -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: ApplicationSet -metadata: - name: guestbook - namespace: argocd -spec: - goTemplate: true - goTemplateOptions: ["missingkey=error"] - generators: - - git: - # When using a Git generator, the ApplicationSet controller polls every `requeueAfterSeconds` interval (defaulting to every 3 minutes) to detect changes. - requeueAfterSeconds: 180 - repoURL: https://github.com/argoproj/argo-cd.git - revision: HEAD - # ... -``` - !!! note The ApplicationSet controller webhook does not use the same webhook as the API server as defined [here](../webhook.md). ApplicationSet exposes a webhook server as a service of type ClusterIP. An ApplicationSet specific Ingress resource needs to be created to expose this service to the webhook source. @@ -503,8 +445,7 @@ 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 _and_ if the -ApplicationSet project field is templated (i.e. the `project` field of the ApplicationSet contains `{{ ... }}`), you need to add the repository as a "non project scoped" repository. +If your [ApplicationSets](index.md) uses a repository where you need credentials to be able to access it, you need to add the repository as a "non project scoped" repository. - When doing that through the UI, set this to a **blank** value in the dropdown menu. - When doing that through the CLI, make sure you **DO NOT** supply the parameter `--project` ([argocd repo add docs](../../user-guide/commands/argocd_repo_add.md)) - When doing that declaratively, make sure you **DO NOT** have `project:` defined under `stringData:` ([complete yaml example](../argocd-repositories-yaml.md)) diff --git a/docs/operator-manual/applicationset/Generators-Matrix.md b/docs/operator-manual/applicationset/Generators-Matrix.md index ca6afdfd66..91b1bb3abb 100644 --- a/docs/operator-manual/applicationset/Generators-Matrix.md +++ b/docs/operator-manual/applicationset/Generators-Matrix.md @@ -420,3 +420,14 @@ For example, the below example would be invalid (cluster-generator must come aft revision: HEAD files: - path: "examples/git-generator-files-discovery/cluster-config/engineering/{{.name}}**/config.json" # {{.name}} is produced by cluster generator + +1. When using a Matrix generator nested inside another Matrix or Merge generator, [Post Selectors](Generators-Post-Selector.md) for this nested generator's generators will only be applied when enabled via `spec.applyNestedSelectors`. You may also need to enable this even if your Post Selectors are not within the nested matrix or Merge generator, but are instead a sibling of a nested Matrix or Merge generator. + + - matrix: + generators: + - matrix: + generators: + - list + elements: + - # (...) + selector: { } # Only applied when applyNestedSelectors is true diff --git a/docs/operator-manual/applicationset/Generators-Merge.md b/docs/operator-manual/applicationset/Generators-Merge.md index 8b15302d0d..b2ccfe86fb 100644 --- a/docs/operator-manual/applicationset/Generators-Merge.md +++ b/docs/operator-manual/applicationset/Generators-Merge.md @@ -219,3 +219,14 @@ Assuming a cluster named `germany01` with the label `metadata.labels.location=Ge - merge: mergeKeys: - values.merge + +1. When using a Merge generator nested inside another Matrix or Merge generator, [Post Selectors](Generators-Post-Selector.md) for this nested generator's generators will only be applied when enabled via `spec.applyNestedSelectors`. + + - merge: + generators: + - merge: + generators: + - list + elements: + - # (...) + selector: { } # Only applied when applyNestedSelectors is true diff --git a/docs/operator-manual/applicationset/Generators-Pull-Request.md b/docs/operator-manual/applicationset/Generators-Pull-Request.md index 054d72cb33..2e6dffaaf5 100644 --- a/docs/operator-manual/applicationset/Generators-Pull-Request.md +++ b/docs/operator-manual/applicationset/Generators-Pull-Request.md @@ -112,7 +112,7 @@ spec: * `api`: If using self-hosted GitLab, the URL to access it. (Optional) * `tokenRef`: A `Secret` name and key containing the GitLab access token to use for requests. If not specified, will make anonymous requests which have a lower rate limit and can only see public repositories. (Optional) * `labels`: Labels is used to filter the MRs that you want to target. (Optional) -* `pullRequestState`: PullRequestState is an additional MRs filter to get only those with a certain state. By default all states. Default: "" (all states). Valid values: `""`, `opened`, `closed`, `merged` or `locked`. (Optional) +* `pullRequestState`: PullRequestState is an additional MRs filter to get only those with a certain state. Default: "" (all states) * `insecure`: By default (false) - Skip checking the validity of the SCM's certificate - useful for self-signed TLS certificates. * `caRef`: Optional `ConfigMap` name and key containing the GitLab certificates to trust - useful for self-signed TLS certificates. Possibly reference the ArgoCD CM holding the trusted certs. @@ -262,14 +262,6 @@ spec: # Filter PRs using the source branch name. (optional) filters: - branchMatch: ".*-argocd" - - # If you need to filter destination branch too, you can use this - - targetBranchMatch: "master" - - # Also you can combine source and target branch filters like - # This case will match any pull-request where source branch ends with "-argocd" and destination branch is master - - branchMatch: ".*-argocd" - targetBranchMatch: "master" template: # ... ``` @@ -277,12 +269,7 @@ spec: - `owner`: Required name of the Bitbucket workspace - `repo`: Required name of the Bitbucket repository. - `api`: Optional URL to access the Bitbucket REST API. For the example above, an API request would be made to `https://api.bitbucket.org/2.0/repositories/{workspace}/{repo_slug}/pullrequests`. If not set, defaults to `https://api.bitbucket.org/2.0` - -You can use branch `filters` like -- `branchMatch`: Optional regexp filter which should match the source branch name. -- `targetBranchMatch`: Optional regexp filter which should match destination branch name. - -> Note: Labels are not supported by Bitbucket. +- `branchMatch`: Optional regexp filter which should match the source branch name. This is an alternative to labels which are not supported by Bitbucket server. If you want to access a private repository, Argo CD will need credentials to access repository in Bitbucket Cloud. You can use Bitbucket App Password (generated per user, with access to whole workspace), or Bitbucket App Token (generated per repository, with access limited to repository scope only). If both App Password and App Token are defined, App Token will be used. @@ -493,39 +480,3 @@ For more information about each event, please refer to the [official documentati ## Lifecycle An Application will be generated when a Pull Request is discovered when the configured criteria is met - i.e. for GitHub when a Pull Request matches the specified `labels` and/or `pullRequestState`. Application will be removed when a Pull Request no longer meets the specified criteria. - -## Pass additional key-value pairs via `values` field - -You may pass additional, arbitrary string key-value pairs via the `values` field of any Pull Request generator. Values added via the `values` field are added as `values.(field)`. - -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: ApplicationSet -metadata: - name: myapps -spec: - goTemplate: true - goTemplateOptions: ["missingkey=error"] - generators: - - pullRequest: - # ... - values: - pr_branch: '{{ .branch }}' - template: - metadata: - name: '{{ .values.name }}' - spec: - source: - repoURL: '{{ .url }}' - targetRevision: '{{ .branch }}' - path: kubernetes/ - project: default - destination: - server: https://kubernetes.default.svc - namespace: default -``` - -!!! note - The `values.` prefix is always prepended to values provided via `generators.pullRequest.values` field. Ensure you include this prefix in the parameter name within the `template` when using it. - -In `values` we can also interpolate all fields set by the Pull Request generator as mentioned above. diff --git a/docs/operator-manual/applicationset/Generators-SCM-Provider.md b/docs/operator-manual/applicationset/Generators-SCM-Provider.md index a816618780..d48c074035 100644 --- a/docs/operator-manual/applicationset/Generators-SCM-Provider.md +++ b/docs/operator-manual/applicationset/Generators-SCM-Provider.md @@ -442,7 +442,6 @@ spec: * `organization`: The name of the organization the repository is in. * `repository`: The name of the repository. -* `repository_id`: The id of the repository. * `url`: The clone URL for the repository. * `branch`: The default branch of the repository. * `sha`: The Git commit SHA for the branch. diff --git a/docs/operator-manual/applicationset/Template.md b/docs/operator-manual/applicationset/Template.md index ba15753f6b..6bc6f24dc0 100644 --- a/docs/operator-manual/applicationset/Template.md +++ b/docs/operator-manual/applicationset/Template.md @@ -169,10 +169,6 @@ spec: {{- end }} ``` -!!! important - `templatePatch` only works when [go templating](../applicationset/GoTemplate.md) is enabled. - This means that the `goTemplate` field under `spec` needs to be set to `true` for template patching to work. - !!! important The `templatePatch` can apply arbitrary changes to the template. If parameters include untrustworthy user input, it may be possible to inject malicious changes into the template. It is recommended to use `templatePatch` only with diff --git a/docs/operator-manual/argocd-cm.yaml b/docs/operator-manual/argocd-cm.yaml index e2fb98cd93..68b4c0c730 100644 --- a/docs/operator-manual/argocd-cm.yaml +++ b/docs/operator-manual/argocd-cm.yaml @@ -88,8 +88,8 @@ data: # Configuration to customize resource behavior (optional) can be configured via splitted sub keys. # Keys are in the form: resource.customizations.ignoreDifferences., resource.customizations.health. - # resource.customizations.actions., resource.customizations.knownTypeFields. - # resource.customizations.ignoreResourceUpdates. + # resource.customizations.actions., resource.customizations.knownTypeFields. + # resource.customizations.ignoreResourceUpdates. resource.customizations.ignoreDifferences.admissionregistration.k8s.io_MutatingWebhookConfiguration: | jsonPointers: - /webhooks/0/clientConfig/caBundle @@ -133,7 +133,7 @@ data: - /metadata/annotations/autoscaling.alpha.kubernetes.io~1metrics - /metadata/annotations/autoscaling.alpha.kubernetes.io~1current-metrics - resource.customizations.health.certmanager.k8s.io_Certificate: | + resource.customizations.health.certmanager.k8s.io-Certificate: | hs = {} if obj.status ~= nil then if obj.status.conditions ~= nil then @@ -237,15 +237,16 @@ data: # An optional comma-separated list of metadata.labels keys to exclude from Kubernetes events generated for Applications. Supports wildcards. resource.excludeEventLabelKeys: environment,bu + resource.compareoptions: | # if ignoreAggregatedRoles set to true then differences caused by aggregated roles in RBAC resources are ignored. ignoreAggregatedRoles: true # disables status field diffing in specified resource types - # 'crd' - CustomResourceDefinitions - # 'all' - all resources (default) + # 'crd' - CustomResourceDefinitions (default) + # 'all' - all resources # 'none' - disabled - ignoreResourceStatusField: all + ignoreResourceStatusField: crd # configuration to instruct controller to only watch for resources that it has permissions to list # can be either empty, "normal" or "strict". By default, it is empty i.e. disabled. @@ -280,9 +281,9 @@ data: # You can change the resource tracking method Argo CD uses by changing the # setting application.resourceTrackingMethod to the desired method. # The following methods are available: + # - label : Uses the application.instanceLabelKey label for tracking # - annotation : Uses an annotation with additional metadata for tracking instead of the label # - annotation+label : Also uses an annotation for tracking, but additionally labels the resource with the application name - # - label : Uses the application.instanceLabelKey label for tracking application.resourceTrackingMethod: annotation # Optional installation id. Allows to have multiple installations of Argo CD in the same cluster. @@ -325,18 +326,17 @@ data: # at the bottom of the page. Change the value as needed. # ui.bannerposition: "bottom" - # Application reconciliation timeout is the amount of time spent before Argo tries to discover if a new manifests version got - # published to the repository. Reconciliation by timeout is disabled if timeout is set to 0. Two minutes by default with additional jitter. + # 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: 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: 120s - + 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 1 minute. - timeout.reconciliation.jitter: 60s + # be between 3 and 4 minutes. Disabled when the value is 0, defaults to 0. + timeout.reconciliation.jitter: "0" # cluster.inClusterEnabled indicates whether to allow in-cluster server address. This is enabled by default. cluster.inClusterEnabled: "true" @@ -345,6 +345,12 @@ data: # This is to prevent the UI from becoming unresponsive when rendering a large number of logs. Default is 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. + # When you enable the switch, viewing pod logs for other roles/users will require explicit RBAC allow policies (allow get on logs subresource). + # When you disable the switch (either add it to the configmap with a "false" value or do not add it to the configmap), no actual RBAC enforcement will take place. + server.rbac.log.enforce.enable: "false" + # exec.enabled indicates whether the UI exec feature is enabled. It is disabled by default. exec.enabled: "false" @@ -429,4 +435,4 @@ data: webhook.maxPayloadSizeMB: "50" # 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" \ No newline at end of file + 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 33e0e7c4b3..59382a30e9 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -28,8 +28,6 @@ data: otlp.insecure: "true" # Open-Telemetry collector headers: (e.g. "key1=value1,key2=value2") otlp.headers: "" - # Open-Telemetry collector attrs: (e.g. "key1:value1,key2:value2") - otlp.attrs: "" # List of additional namespaces where applications may be created in and # reconciled from. The namespace where Argo CD is installed to will always @@ -38,11 +36,6 @@ data: # Feature state: Beta application.namespaces: ns1, ns2, ns3 - # Set the logging timestamp format. The default is "" which means "2006-01-02T15:04:05Z07:00" (RFC3339). - # See https://pkg.go.dev/time#pkg-constants for more options. - # This option is used for all components. - log.format.timestamp: "" - ## Controller Properties # Repo server RPC call timeout seconds. controller.repo.server.timeout.seconds: "60" @@ -54,8 +47,8 @@ data: controller.status.processors: "20" # Number of application operation processors (default 10) controller.operation.processors: "10" - # Set the logging format. One of: json|text (default "json") - controller.log.format: "json" + # Set the logging format. One of: text|json (default "text") + controller.log.format: "text" # Set the logging level. One of: debug|info|warn|error (default "info") controller.log.level: "info" # Prometheus metrics cache expiration (disabled by default. e.g. 24h0m0s) @@ -69,10 +62,11 @@ data: # Cache expiration for app state (default 1h0m0s) controller.app.state.cache.expiration: "1h0m0s" - # Specifies if resource health should be persisted in the application CR (default false). - # Setting this to true will store the health status of each resource in the application CR, - # increasing the number of updates to the CR and putting more load on the application controller - controller.resource.health.persist: "false" + # Specifies if resource health should be persisted in app CRD (default true) + # Changing this to `false` significantly reduce number of Application CRD updates and improves controller performance. + # However, disabling resource health by default might affect applications that communicate with Applications CRD directly + # so we have to defer switching this to `false` by default till v3.0 release. + controller.resource.health.persist: "true" # Cache expiration default (default 24h0m0s) controller.default.cache.expiration: "24h0m0s" # Sharding algorithm used to balance clusters across application controller shards (default "legacy") @@ -93,7 +87,7 @@ data: controller.profile.enabled: "false" # Enables batch-processing mode in the controller's cluster cache. This can help improve performance for clusters that # have high "churn," i.e. lots of resource modifications. - controller.cluster.cache.batch.events.processing: "true" + controller.cluster.cache.batch.events.processing: "false" # This sets the interval at which the controller's cluster cache processes a batch of cluster events. A lower value # will increase the speed at which Argo CD becomes aware of external cluster state. A higher value will reduce cluster # cache lock contention and better handle high-churn clusters. @@ -121,11 +115,9 @@ data: server.api.content.types: "application/json" # Number of webhook requests processed concurrently (default 50) server.webhook.parallelism.limit: "50" - # Whether to allow sync with replace checked to go through. Resource-level annotation to replace override this setting, i.e. it's only enforced on the API server level. - server.sync.replace.allowed: "true" - # Set the logging format. One of: json|text (default "json") - server.log.format: "json" + # Set the logging format. One of: text|json (default "text") + server.log.format: "text" # Set the logging level. One of: debug|info|warn|error (default "info") server.log.level: "info" # Repo server RPC call timeout seconds. (default 60) @@ -172,8 +164,8 @@ data: reposerver.listen.address: "0.0.0.0" # Listen on given address for metrics (default "0.0.0.0") reposerver.metrics.listen.address: "0.0.0.0" - # Set the logging format. One of: json|text (default "json") - reposerver.log.format: "json" + # Set the logging format. One of: text|json (default "text") + reposerver.log.format: "text" # Set the logging level. One of: debug|info|warn|error (default "info") reposerver.log.level: "info" # Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit. @@ -219,15 +211,15 @@ data: ## Commit-server properties # Listen on given address for incoming connections (default "0.0.0.0") commitserver.listen.address: "0.0.0.0" - # Set the logging format. One of: json|text (default "json") - commitserver.log.format: "json" + # Set the logging format. One of: text|json (default "text") + commitserver.log.format: "text" # Set the logging level. One of: debug|info|warn|error (default "info") commitserver.log.level: "info" # Listen on given address for metrics (default "0.0.0.0") commitserver.metrics.listen.address: "0.0.0.0" - # Set the logging format. One of: json|text (default "json") - dexserver.log.format: "json" + # Set the logging format. One of: text|json (default "text") + dexserver.log.format: "text" # Set the logging level. One of: debug|info|warn|error (default "info") dexserver.log.level: "info" # Disable TLS on the HTTP endpoint @@ -253,8 +245,8 @@ data: applicationsetcontroller.enable.new.git.file.globbing: "false" # Print debug logs. Takes precedence over loglevel applicationsetcontroller.debug: "false" - # Set the logging format. One of: json|text (default "json") - applicationsetcontroller.log.format: "json" + # Set the logging format. One of: text|json (default "text") + applicationsetcontroller.log.format: "text" # Set the logging level. One of: debug|info|warn|error (default "info") applicationsetcontroller.log.level: "info" # Enable dry run mode @@ -280,16 +272,12 @@ data: 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" - # Comma delimited list of annotations to preserve in generated applications - applicationsetcontroller.global.preserved.annotations: "acme.com/annotation1,acme.com/annotation2" - # Comma delimited list of labels to preserve in generated applications - applicationsetcontroller.global.preserved.labels: "acme.com/label1,acme.com/label2" ## Argo CD Notifications Controller Properties # Set the logging level. One of: debug|info|warn|error (default "info") notificationscontroller.log.level: "info" - # Set the logging format. One of: json|text (default "json") - notificationscontroller.log.format: "json" + # Set the logging format. One of: text|json (default "text") + notificationscontroller.log.format: "text" # Enable self-service notifications config. Used in conjunction with apps-in-any-namespace. (default "false") notificationscontroller.selfservice.enabled: "false" # Disable TLS on connections to repo server diff --git a/docs/operator-manual/argocd-rbac-cm-yaml.md b/docs/operator-manual/argocd-rbac-cm-yaml.md index bafd65bbe3..c0dbcde428 100644 --- a/docs/operator-manual/argocd-rbac-cm-yaml.md +++ b/docs/operator-manual/argocd-rbac-cm-yaml.md @@ -1,7 +1,5 @@ # argocd-rbac-cm.yaml example -**Note**: While policy files are CSV files, ArgoCD ignores lines starting with `#` when parsing the file, allowing for line comments starting with #. - An example of an argocd-rbac-cm.yaml file: ```yaml diff --git a/docs/operator-manual/argocd-repositories.yaml b/docs/operator-manual/argocd-repositories.yaml index 66f7980fb4..8f48429ebd 100644 --- a/docs/operator-manual/argocd-repositories.yaml +++ b/docs/operator-manual/argocd-repositories.yaml @@ -12,7 +12,6 @@ stringData: url: https://github.com/argoproj/argocd-example-apps password: my-password username: my-username - bearerToken: my-token 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" @@ -69,19 +68,4 @@ metadata: labels: argocd.argoproj.io/secret-type: repository stringData: - url: https://github.com/argoproj/private-repo ---- -apiVersion: v1 -kind: Secret -metadata: - name: aci-private-repo - namespace: argocd - labels: - argocd.argoproj.io/secret-type: repository -stringData: - type: helm - url: contoso.azurecr.io/charts - name: contosocharts - enableOCI: "true" - useAzureWorkloadIdentity: "true" - \ No newline at end of file + url: https://github.com/argoproj/private-repo \ No newline at end of file diff --git a/docs/operator-manual/config-management-plugins.md b/docs/operator-manual/config-management-plugins.md index 9cc14df34f..b38635feb8 100644 --- a/docs/operator-manual/config-management-plugins.md +++ b/docs/operator-manual/config-management-plugins.md @@ -519,10 +519,6 @@ call from the config management sidecar container to the reposerver to retrieve Utilizing `ASKPASS` means that credentials are not proactively shared, but rather only provided when an operation requires them. -`ASKPASS` requires a socket to be shared between the config management plugin and the reposerver. To mitigate path traversal -attacks, it's recommended to use a dedicated volume to share the socket, and mount it in the reposerver and sidecar. -To change the socket path, you must set the `ARGOCD_ASK_PASS_SOCK` environment variable for both containers. - To allow the plugin to access the reposerver git credentials, you can set `provideGitCreds` to `true` in the plugin spec: !!! warning diff --git a/docs/operator-manual/core.md b/docs/operator-manual/core.md index edf6025318..79b2530cfe 100644 --- a/docs/operator-manual/core.md +++ b/docs/operator-manual/core.md @@ -78,9 +78,8 @@ the process) invoking the CLI needs to have access to the Argo CD namespace with the proper permission in the `Application` and `ApplicationSet` resources for executing a given command. -To use [Argo CD CLI](https://argo-cd.readthedocs.io/en/stable/cli_installation) in core mode, it is required to pass the `--core` -flag with the `login` subcommand. The `--core` flag is responsible for spawning a local Argo CD API server -process that handles CLI and Web UI requests. +To use Argo CD CLI in core mode, it is required to pass the `--core` +flag with the `login` subcommand. Example: @@ -98,3 +97,4 @@ argocd admin dashboard -n argocd ``` Argo CD Web UI will be available at `http://localhost:8080` + diff --git a/docs/operator-manual/custom_tools.md b/docs/operator-manual/custom_tools.md index d23b0a23fa..e94a1d5ac6 100644 --- a/docs/operator-manual/custom_tools.md +++ b/docs/operator-manual/custom_tools.md @@ -30,7 +30,7 @@ the helm binary with a different version than what is bundled in Argo CD: image: alpine:3.8 command: [sh, -c] args: - - wget -qO- https://get.helm.sh/helm-v2.12.3-linux-amd64.tar.gz | tar -xvzf - && + - wget -qO- https://storage.googleapis.com/kubernetes-helm/helm-v2.12.3-linux-amd64.tar.gz | tar -xvzf - && mv linux-amd64/helm /custom-tools/ volumeMounts: - mountPath: /custom-tools diff --git a/docs/operator-manual/declarative-setup.md b/docs/operator-manual/declarative-setup.md index aea5e3835a..d3b93d27c1 100644 --- a/docs/operator-manual/declarative-setup.md +++ b/docs/operator-manual/declarative-setup.md @@ -71,7 +71,6 @@ See [application.yaml](application.yaml) for additional fields. As long as you h ```yaml spec: - project: default source: repoURL: https://argoproj.github.io/argo-helm chart: argo @@ -288,10 +287,6 @@ stringData: !!! tip The Kubernetes documentation has [instructions for creating a secret containing a private key](https://kubernetes.io/docs/concepts/configuration/secret/#use-case-pod-with-ssh-keys). -Example for Azure Container Registry/ Azure Devops repositories using Azure workload identity: - -Refer to [Azure Container Registry/Azure Repos using Azure Workload Identity](../user-guide/private-repositories.md#azure-container-registryazure-repos-using-azure-workload-identity) - ### Repository Credentials If you want to use the same credentials for multiple repositories, you can configure credential templates. Credential templates can carry the same credentials information as repositories. @@ -498,6 +493,43 @@ stringData: A note on noProxy: Argo CD uses exec to interact with different tools such as helm and kustomize. Not all of these tools support the same noProxy syntax as the [httpproxy go package](https://cs.opensource.google/go/x/net/+/internal-branch.go1.21-vendor:http/httpproxy/proxy.go;l=38-50) does. In case you run in trouble with noProxy not beeing respected you might want to try using the full domain instead of a wildcard pattern or IP range to find a common syntax that all tools support. +### Legacy behaviour + +In Argo CD version 2.0 and earlier, repositories were stored as part of the `argocd-cm` config map. For +backward-compatibility, Argo CD will still honor repositories in the config map, but this style of repository +configuration is deprecated and support for it will be removed in a future version. + +```yaml +apiVersion: v1 +kind: ConfigMap +data: + repositories: | + - url: https://github.com/argoproj/my-private-repository + passwordSecret: + name: my-secret + key: password + usernameSecret: + name: my-secret + key: username + repository.credentials: | + - url: https://github.com/argoproj + passwordSecret: + name: my-secret + key: password + usernameSecret: + name: my-secret + key: username +--- +apiVersion: v1 +kind: Secret +metadata: + name: my-secret + namespace: argocd +stringData: + password: my-password + username: my-username +``` + ## Clusters Cluster credentials are stored in secrets same as repositories or repository credentials. Each secret must have label @@ -507,10 +539,10 @@ The secret data must include following fields: * `name` - cluster name * `server` - cluster api server url -* `namespaces` - optional comma-separated list of namespaces which are accessible in that cluster. Setting namespace values will cause cluster-level resources to be ignored unless `clusterResources` is set to `true`. -* `clusterResources` - optional boolean string (`"true"` or `"false"`) determining whether Argo CD can manage cluster-level resources on this cluster. This setting is only used when namespaces are restricted using the `namespaces` list. +* `namespaces` - optional comma-separated list of namespaces which are accessible in that cluster. Cluster level resources would be ignored if namespace list is not empty. +* `clusterResources` - optional boolean string (`"true"` or `"false"`) determining whether Argo CD can manage cluster-level resources on this cluster. This setting is used only if the list of managed namespaces is not empty. * `project` - optional string to designate this as a project-scoped cluster. -* `config` - JSON representation of the following data structure: +* `config` - JSON representation of following data structure: ```yaml # Basic authentication settings @@ -555,14 +587,7 @@ tlsClientConfig: disableCompression: boolean ``` -!!! important - When `namespaces` is set, Argo CD will perform a separate list/watch operation for each namespace. This can cause - the Application controller to exceed the maximum number of idle connections allowed for the Kubernetes API server. - To resolve this issue, you can increase the `ARGOCD_K8S_CLIENT_MAX_IDLE_CONNECTIONS` environment variable in the - Application controller. - -!!! important - 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). +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). Cluster secret example: @@ -791,7 +816,7 @@ The above role is granted cluster admin permissions via `AmazonEKSClusterAdminPo 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 (Deprecated)** +**AWS Auth (Depreciated)** Instead of using Access Entries, you may need to use the depreciated `aws-auth`. @@ -1199,7 +1224,6 @@ Notes: * Quote globs in your YAML to avoid parsing errors. * 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`. -* Some excluded objects may already be in the controller cache. A restart of the controller will be necessary to remove them from the Application View. ## Mask sensitive Annotations on Secrets diff --git a/docs/operator-manual/feature-maturity.md b/docs/operator-manual/feature-maturity.md index 84f2677238..7db255b1b0 100644 --- a/docs/operator-manual/feature-maturity.md +++ b/docs/operator-manual/feature-maturity.md @@ -17,7 +17,7 @@ to indicate their stability and maturity. These are the statuses of non-stable f | Feature | Introduced | Status | |-------------------------------------------|------------|--------| | [AppSet Progressive Syncs][2] | v2.6.0 | Alpha | -| [Proxy Extensions][3] | v2.7.0 | Beta | +| [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 | diff --git a/docs/operator-manual/health.md b/docs/operator-manual/health.md index cdaf053ea3..ffce008b1f 100644 --- a/docs/operator-manual/health.md +++ b/docs/operator-manual/health.md @@ -118,7 +118,7 @@ specify a wildcard in the resource kind, and anywhere in the resource group, lik !!!important 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. +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: @@ -168,33 +168,7 @@ To test the implemented custom health checks, run `go test -v ./util/lua/`. The [PR#1139](https://github.com/argoproj/argo-cd/pull/1139) is an example of Cert Manager CRDs custom health check. -#### Wildcard Support for Built-in Health Checks - -You can use a single health check for multiple resources by using a wildcard in the group or kind directory names. - -The `_` character behaves like a `*` wildcard. For example, consider the following directory structure: - -``` -argo-cd -|-- resource_customizations -| |-- _.group.io # CRD group -| | |-- _ # Resource kind -| | | |-- health.lua # Health check -``` - -Any resource with a group that ends with `.group.io` will use the health check in `health.lua`. - -Wildcard checks are only evaluated if there is no specific check for the resource. - -If multiple wildcard checks match, the first one in the directory structure is used. - -We use the [doublestar](https://github.com/bmatcuk/doublestar) glob library to match the wildcard checks. We currently -only treat a path as a wildcard if it contains a `_` character, but this may change in the future. - -!!!important "Avoid Massive Scripts" - - Avoid writing massive scripts to handle multiple resources. They'll get hard to read and maintain. Instead, just - duplicate the relevant parts in resource-specific scripts. +Please note that bundled health checks with wildcards are not supported. ## Overriding Go-Based Health Checks @@ -267,4 +241,4 @@ metadata: argocd.argoproj.io/ignore-healthcheck: "true" ``` -By doing this, the health status of the Deployment will not affect the health of its parent Application. +By doing this, the health status of the Deployment will not affect the health of its parent Application. \ No newline at end of file diff --git a/docs/operator-manual/high_availability.md b/docs/operator-manual/high_availability.md index 1a7f3c21c8..a05edf547d 100644 --- a/docs/operator-manual/high_availability.md +++ b/docs/operator-manual/high_availability.md @@ -132,8 +132,8 @@ stringData: * `ARGOCD_CLUSTER_CACHE_BATCH_EVENTS_PROCESSING` - environment variable that enables the controller to collect events for Kubernetes resources and process them in a batch. This is useful when the cluster contains a large number of resources, - and the controller is overwhelmed by the number of events. The default value is `true`. `false` would mean that the controller - would process events one by one. + and the controller is overwhelmed by the number of events. The default value is `false`, which means that the controller + processes events one by one. * `ARGOCD_CLUSTER_CACHE_EVENTS_PROCESSING_INTERVAL` - environment variable controlling the interval for processing events in a batch. The valid value is in the format of Go time duration string, e.g. `1ms`, `1s`, `1m`, `1h`. The default value is `100ms`. @@ -189,7 +189,8 @@ Argo CD repo server maintains one repository clone locally and uses it for appli Argo CD determines if manifest generation might change local files in the local repository clone based on the config management tool and application settings. If the manifest generation has no side effects then requests are processed in parallel without a performance penalty. The following are known cases that might cause slowness and their workarounds: - * **Multiple Helm based applications pointing to the same directory in one Git repository:** for historical reasons Argo CD used to generate Helm manifests sequentially. Starting v3.0, Argo CD performs a parallel generation of Helm manifests by default. + * **Multiple Helm based applications pointing to the same directory in one Git repository:** for historical reasons Argo CD generates Helm manifests sequentially. To enable parallel generation set `ARGOCD_HELM_ALLOW_CONCURRENCY=true` to `argocd-repo-server` deployment or create `.argocd-allow-concurrency` file. + Future versions of Argo CD will enable this by default. * **Multiple Custom plugin based applications:** avoid creating temporal files during manifest generation and create `.argocd-allow-concurrency` file in the app directory, or use the sidecar plugin option, which processes each application using a temporary copy of the repository. diff --git a/docs/operator-manual/ingress.md b/docs/operator-manual/ingress.md index 5037d77203..b3a477252f 100644 --- a/docs/operator-manual/ingress.md +++ b/docs/operator-manual/ingress.md @@ -408,7 +408,7 @@ spec: ## AWS Application Load Balancers (ALBs) And Classic ELB (HTTP Mode) AWS ALBs can be used as an L7 Load Balancer for both UI and gRPC traffic, whereas Classic ELBs and NLBs can be used as L4 Load Balancers for both. -When using an ALB, you'll want to create a second service for argocd-server. This is necessary because we need to tell the ALB to send the GRPC traffic to a different target group than the UI traffic, since the backend protocol is HTTP2 instead of HTTP1. +When using an ALB, you'll want to create a second service for argocd-server. This is necessary because we need to tell the ALB to send the GRPC traffic to a different target group then the UI traffic, since the backend protocol is HTTP2 instead of HTTP1. ```yaml apiVersion: v1 diff --git a/docs/operator-manual/installation.md b/docs/operator-manual/installation.md index 35e4d6bb07..70494298c1 100644 --- a/docs/operator-manual/installation.md +++ b/docs/operator-manual/installation.md @@ -31,10 +31,6 @@ Not recommended for production use. This type of installation is typically used Argo CD instances for different teams, where each instance will be deploying applications to external clusters. It will still be possible to deploy to the same cluster (kubernetes.svc.default) with inputted credentials (i.e. `argocd cluster add --in-cluster --namespace `). - With the default roles included, you will only be able to deploy Argo CD resources (Applications, ApplicationSets - and AppProjects) in the same cluster, as it's only supporting the GitOps mode with real deployments being - done to external clusters. - You can modify that by defining new roles and binding them to the `argocd-application-controller` service account. > Note: Argo CD CRDs are not included into [namespace-install.yaml](https://github.com/argoproj/argo-cd/blob/master/manifests/namespace-install.yaml). > and have to be installed separately. The CRD manifests are located in the [manifests/crds](https://github.com/argoproj/argo-cd/blob/master/manifests/crds) directory. diff --git a/docs/operator-manual/metrics.md b/docs/operator-manual/metrics.md index 8a65325ac8..deb6037aab 100644 --- a/docs/operator-manual/metrics.md +++ b/docs/operator-manual/metrics.md @@ -5,66 +5,27 @@ Argo CD exposes different sets of Prometheus metrics per server. ## Application Controller Metrics Metrics about applications. Scraped at the `argocd-metrics:8082/metrics` endpoint. -| Metric | Type | Description | -|---------------------------------------------------|:---------:|---------------------------------------------------------------------------------------------------------------------------------------------| -| `argocd_app_info` | gauge | Information about Applications. It contains labels such as `sync_status` and `health_status` that reflect the application state in Argo CD. | -| `argocd_app_condition` | gauge | Report Applications conditions. It contains the conditions currently present in the application status. | -| `argocd_app_k8s_request_total` | counter | Number of Kubernetes requests executed during application reconciliation | -| `argocd_app_labels` | gauge | Argo Application labels converted to Prometheus labels. Disabled by default. See section below about how to enable it. | -| `argocd_app_orphaned_resources_count` | gauge | Number of orphaned resources per application. | -| `argocd_app_reconcile` | histogram | Application reconciliation performance in seconds. | -| `argocd_app_sync_total` | counter | Counter for application sync history | -| `argocd_cluster_api_resource_objects` | gauge | Number of k8s resource objects in the cache. | -| `argocd_cluster_api_resources` | gauge | Number of monitored Kubernetes API resources. | -| `argocd_cluster_cache_age_seconds` | gauge | Cluster cache age in seconds. | -| `argocd_cluster_connection_status` | gauge | The k8s cluster current connection status. | -| `argocd_cluster_events_total` | counter | Number of processes k8s resource events. | -| `argocd_cluster_info` | gauge | Information about cluster. | -| `argocd_redis_request_duration` | histogram | Redis requests duration. | -| `argocd_redis_request_total` | counter | Number of redis requests executed during application reconciliation | -| `argocd_resource_events_processing` | histogram | Time to process resource events in batch in seconds | -| `argocd_resource_events_processed_in_batch` | gauge | Number of resource events processed in batch | -| `argocd_kubectl_exec_pending` | gauge | Number of pending kubectl executions | -| `argocd_kubectl_exec_total` | counter | Number of kubectl executions | -| `argocd_kubectl_client_cert_rotation_age_seconds` | gauge | Age of kubectl client certificate rotation. | -| `argocd_kubectl_request_duration_seconds` | histogram | Latency of kubectl requests. | -| `argocd_kubectl_dns_resolution_duration_seconds` | histogram | Latency of kubectl resolver. | -| `argocd_kubectl_request_size_bytes` | histogram | Size of kubectl requests. | -| `argocd_kubectl_response_size_bytes` | histogram | Size of kubectl responses. | -| `argocd_kubectl_rate_limiter_duration_seconds` | histogram | Latency of kubectl rate limiter. | -| `argocd_kubectl_requests_total` | counter | Result of kubectl requests. | -| `argocd_kubectl_exec_plugin_call_total` | counter | Number of kubectl exec plugin calls. | -| `argocd_kubectl_request_retries_total` | counter | Number of kubectl request retries. | -| `argocd_kubectl_transport_cache_entries` | gauge | Number of kubectl transport cache entries. | -| `argocd_kubectl_transport_create_calls_total` | counter | Number of kubectl transport create calls. | - -### Labels - -| Label Name | Example Value | Description | -|--------------------|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| call_status | no_error | Status of the kubectl exec plugin call. Possible values are: no_error, plugin_execution_error, plugin_not_found_error, client_internal_error. | -| code | 200 | HTTP status code returned by the request or exit code of a command. kubectl metrics produced by client-go use `code` for HTTP responses, while metrics produced by Argo CD use `response_code`. | -| command | apply | kubectl command executed. Possible values are: apply, auth, create, replace. | -| dest_server | https://example.com | Destination server for an Application. | -| failed | false | Indicates if the Redis request failed. Possible values are: true, false. | -| group | apps | Group name of a Kubernetes resource being monitored. | -| host | example.com | Hostname of the Kubernetes API to which the request was made. | -| hostname | argocd-application-controller-0 | Hostname of the Argo CD component that initiated the request to Redis. | -| initiator | argocd-server | Name of the Argo CD component that initiated the request to Redis. Possible values are: argocd-application-controller, argocd-repo-server, argocd-server. | -| kind | Deployment | Kind name of a Kubernetes resource being monitored. | -| method | GET | HTTP method used for the request. Possible values are: GET, DELETE, PATCH, POST, PUT. | -| name | my-app | Name of an Application. | -| namespace | default | Namespace of an Application (namespace where the Application CR is located, not the destination namespace). | -| phase | Succeeded | Phase of a sync operation. Possible values are: Error, Failed, Running, Succeeded, Terminating. | -| project | my-project | AppProject of an Application. | -| resource_kind | Pod | Kind of Kubernetes resource being synced. | -| resource_namespace | default | Namespace of Kubernetes resource being synced. | -| response_code | 404 | HTTP response code from the server. | -| result | hit | Result of an attempt to get a transport from the kubectl (client-go) transport cache. Possible values are: hit, miss, unreachable. | -| server | https://example.com | Server where the operation is performed. | -| verb | List | Kubernetes API verb used in the request. Possible values are: Get, Watch, List, Create, Delete, Patch, Update. | - -### Metrics Cache Expiration +| Metric | Type | Description | +|--------|:----:|-------------| +| `argocd_app_info` | gauge | Information about Applications. It contains labels such as `sync_status` and `health_status` that reflect the application state in Argo CD. | +| `argocd_app_condition` | gauge | Report Applications conditions. It contains the conditions currently present in the application status. | +| `argocd_app_k8s_request_total` | counter | Number of Kubernetes requests executed during application reconciliation | +| `argocd_app_labels` | gauge | Argo Application labels converted to Prometheus labels. Disabled by default. See section below about how to enable it. | +| `argocd_app_orphaned_resources_count` | gauge | Number of orphaned resources per application. | +| `argocd_app_reconcile` | histogram | Application reconciliation performance in seconds. | +| `argocd_app_sync_total` | counter | Counter for application sync history | +| `argocd_cluster_api_resource_objects` | gauge | Number of k8s resource objects in the cache. | +| `argocd_cluster_api_resources` | gauge | Number of monitored Kubernetes API resources. | +| `argocd_cluster_cache_age_seconds` | gauge | Cluster cache age in seconds. | +| `argocd_cluster_connection_status` | gauge | The k8s cluster current connection status. | +| `argocd_cluster_events_total` | counter | Number of processes k8s resource events. | +| `argocd_cluster_info` | gauge | Information about cluster. | +| `argocd_kubectl_exec_pending` | gauge | Number of pending kubectl executions | +| `argocd_kubectl_exec_total` | counter | Number of kubectl executions | +| `argocd_redis_request_duration` | histogram | Redis requests duration. | +| `argocd_redis_request_total` | counter | Number of redis requests executed during application reconciliation | +| `argocd_resource_events_processing` | histogram | Time to process resource events in batch in seconds | +| `argocd_resource_events_processed_in_batch` | gauge | Number of resource events processed in batch | If you use Argo CD with many application and project creation and deletion, the metrics page will keep in cache your application and project's history. @@ -73,6 +34,8 @@ to deleted resources, you can schedule a metrics reset to clean the history with an application controller flag. Example: `--metrics-cache-expiration="24h0m0s"`. + + ### Exposing Application labels as Prometheus metrics There are use-cases where Argo CD Applications contain labels that are desired to be exposed as Prometheus metrics. @@ -130,105 +93,30 @@ The example below will expose the Argo CD Application condition `OrphanedResourc The Application Set controller exposes the following metrics for application sets. -| Metric | Type | Description | -|---------------------------------------------------|:---------:|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `argocd_appset_info` | gauge | Information about Application Sets. It contains labels for the name and namespace of an application set as well as `Resource_update_status` that reflects the `ResourcesUpToDate` property | -| `argocd_appset_reconcile` | histogram | Application reconciliation performance in seconds. It contains labels for the name and namespace of an applicationset | -| `argocd_appset_labels` | gauge | Applicationset labels translated to Prometheus labels. Disabled by default | -| `argocd_appset_owned_applications` | gauge | Number of applications owned by the applicationset. It contains labels for the name and namespace of an applicationset. | -| `argocd_kubectl_client_cert_rotation_age_seconds` | gauge | Age of kubectl client certificate rotation. | -| `argocd_kubectl_request_duration_seconds` | histogram | Latency of kubectl requests. | -| `argocd_kubectl_dns_resolution_duration_seconds` | histogram | Latency of kubectl resolver. | -| `argocd_kubectl_request_size_bytes` | histogram | Size of kubectl requests. | -| `argocd_kubectl_response_size_bytes` | histogram | Size of kubectl responses. | -| `argocd_kubectl_rate_limiter_duration_seconds` | histogram | Latency of kubectl rate limiter. | -| `argocd_kubectl_requests_total` | counter | Result of kubectl requests. | -| `argocd_kubectl_exec_plugin_call_total` | counter | Number of kubectl exec plugin calls. | -| `argocd_kubectl_request_retries_total` | counter | Number of kubectl request retries. | -| `argocd_kubectl_transport_cache_entries` | gauge | Number of kubectl transport cache entries. | -| `argocd_kubectl_transport_create_calls_total` | counter | Number of kubectl transport create calls. | +| Metric | Type | Description | +|--------|:----:|-------------| +| `argocd_appset_info` | gauge | Information about Application Sets. It contains labels for the name and namespace of an application set as well as `Resource_update_status` that reflects the `ResourcesUpToDate` property | +| `argocd_appset_reconcile` | histogram | Application reconciliation performance in seconds. It contains labels for the name and namespace of an applicationset | +| `argocd_appset_labels` | gauge | Applicationset labels translated to Prometheus labels. Disabled by default | +| `argocd_appset_owned_applications` | gauge | Number of applications owned by the applicationset. It contains labels for the name and namespace of an applicationset. | Similar to the same metric in application controller (`argocd_app_labels`) the metric `argocd_appset_labels` is disabled by default. You can enable it by providing the `–metrics-applicationset-labels` argument to the applicationset controller. Once enabled it works exactly the same as application controller metrics (label_ appended to normalized label name). Available labels include Name, Namespace + all labels enabled by the command line options and their value (exactly like application controller metrics described in the previous section). -### Labels - -| Label Name | Example Value | Description | -|--------------------|---------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------| -| call_status | no_error | Status of the kubectl exec plugin call. Possible values are: no_error, plugin_execution_error, plugin_not_found_error, client_internal_error. | -| code | 200 | HTTP status code returned by the request or exit code of a command. | -| host | example.com | Hostname of the Kubernetes API to which the request was made. | -| method | GET | HTTP method used for the request. Possible values are: GET, DELETE, PATCH, POST, PUT. | -| name | my-app | Name of an ApplicationSet. | -| namespace | default | Namespace of an ApplicationSet (namespace where the ApplicationSet CR is located, not the destination namespace). | -| result | hit | Result of an attempt to get a transport from the kubectl (client-go) transport cache. Possible values are: hit, miss, unreachable. | -| verb | List | Kubernetes API verb used in the request. Possible values are: Get, Watch, List, Create, Delete, Patch, Update. | - -### Exposing Cluster labels as Prometheus metrics - -As the Cluster labels are specific to each company, this feature is disabled by default. To enable it, add the -`--metrics-cluster-labels` flag to the Argo CD application controller. - -The example below will expose the Argo CD Application labels `team-name` and `environment` to Prometheus: - - containers: - - command: - - argocd-application-controller - - --metrics-cluster-labels - - team-name - - --metrics-cluster-labels - - environment - -In this case, the metric would look like: - -``` -# TYPE argocd_app_labels gauge -argocd_cluster_labels{label_environment="dev",label_team_name="team1",name="cluster1",server="server1"} 1 -argocd_cluster_labels{label_environment="staging",label_team_name="team2",name="cluster2",server="server2"} 1 -argocd_cluster_labels{label_environment="production",label_team_name="team3",name="cluster3",server="server3"} 1 -``` - ## API Server Metrics Metrics about API Server API request and response activity (request totals, response codes, etc...). Scraped at the `argocd-server-metrics:8083/metrics` endpoint. -| Metric | Type | Description | -|---------------------------------------------------|:---------:|---------------------------------------------------------------------------------------------| -| `argocd_redis_request_duration` | histogram | Redis requests duration. | -| `argocd_redis_request_total` | counter | Number of Kubernetes requests executed during application reconciliation. | -| `grpc_server_handled_total` | counter | Total number of RPCs completed on the server, regardless of success or failure. | -| `grpc_server_msg_sent_total` | counter | Total number of gRPC stream messages sent by the server. | -| `argocd_proxy_extension_request_total` | counter | Number of requests sent to the configured proxy extensions. | +| Metric | Type | Description | +|--------|:----:|-------------| +| `argocd_redis_request_duration` | histogram | Redis requests duration. | +| `argocd_redis_request_total` | counter | Number of Kubernetes requests executed during application reconciliation. | +| `grpc_server_handled_total` | counter | Total number of RPCs completed on the server, regardless of success or failure. | +| `grpc_server_msg_sent_total` | counter | Total number of gRPC stream messages sent by the server. | +| `argocd_proxy_extension_request_total` | counter | Number of requests sent to the configured proxy extensions. | | `argocd_proxy_extension_request_duration_seconds` | histogram | Request duration in seconds between the Argo CD API server and the proxy extension backend. | -| `argocd_kubectl_client_cert_rotation_age_seconds` | gauge | Age of kubectl client certificate rotation. | -| `argocd_kubectl_request_duration_seconds` | histogram | Latency of kubectl requests. | -| `argocd_kubectl_dns_resolution_duration_seconds` | histogram | Latency of kubectl resolver. | -| `argocd_kubectl_request_size_bytes` | histogram | Size of kubectl requests. | -| `argocd_kubectl_response_size_bytes` | histogram | Size of kubectl responses. | -| `argocd_kubectl_rate_limiter_duration_seconds` | histogram | Latency of kubectl rate limiter. | -| `argocd_kubectl_requests_total` | counter | Result of kubectl requests. | -| `argocd_kubectl_exec_plugin_call_total` | counter | Number of kubectl exec plugin calls. | -| `argocd_kubectl_request_retries_total` | counter | Number of kubectl request retries. | -| `argocd_kubectl_transport_cache_entries` | gauge | Number of kubectl transport cache entries. | -| `argocd_kubectl_transport_create_calls_total` | counter | Number of kubectl transport create calls. | - -### Labels - -| Label Name | Example Value | Description | -|--------------------|---------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| call_status | no_error | Status of the kubectl exec plugin call. Possible values are: no_error, plugin_execution_error, plugin_not_found_error, client_internal_error. | -| code | 200 | HTTP status code returned by the request or exit code of a command. kubectl metrics produced by client-go use `code` for HTTP responses, while metrics produced by Argo CD proxy extensions use `status`. | -| extension | metrics | Name of the proxy extension being called. | -| failed | false | Indicates if the Redis request failed. Possible values are: true, false. | -| host | example.com | Hostname of the Kubernetes API to which the request was made. | -| initiator | argocd-server | Name of the Argo CD component that initiated the request to Redis. Possible values are: argocd-application-controller, argocd-repo-server, argocd-server. | -| method | GET | HTTP method used for the request. Possible values are: GET, DELETE, PATCH, POST, PUT. | -| result | hit | Result of an attempt to get a transport from the kubectl (client-go) transport cache. Possible values are: hit, miss, unreachable. | -| status | 200 | HTTP response code from the extension. | -| verb | List | Kubernetes API verb used in the request. Possible values are: Get, Watch, List, Create, Delete, Patch, Update. | -| version | v2.13.3 | Argo CD version. | ## Repo Server Metrics Metrics about the Repo Server. diff --git a/docs/operator-manual/notifications/catalog.md b/docs/operator-manual/notifications/catalog.md index a5385889f8..d92561f67a 100644 --- a/docs/operator-manual/notifications/catalog.md +++ b/docs/operator-manual/notifications/catalog.md @@ -87,7 +87,7 @@ teams: }, { "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 }} + "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", @@ -115,7 +115,7 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "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 }} + "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' @@ -168,7 +168,7 @@ teams: }, { "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 }} + "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":{{- 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 }} + "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' @@ -249,7 +249,7 @@ teams: }, { "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 }} + "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}} , @@ -273,7 +273,7 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "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 }} + "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' @@ -330,7 +330,7 @@ teams: }, { "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 }} + "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}} , @@ -354,7 +354,7 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "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 }} + "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}}. @@ -411,7 +411,7 @@ teams: }, { "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 }} + "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}} , @@ -435,7 +435,7 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "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 }} + "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' @@ -491,7 +491,7 @@ teams: }, { "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 }} + "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}} , @@ -515,7 +515,7 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "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 }} + "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/examples.md b/docs/operator-manual/notifications/examples.md deleted file mode 100644 index b86a0a2b9a..0000000000 --- a/docs/operator-manual/notifications/examples.md +++ /dev/null @@ -1,133 +0,0 @@ -Here you can find some examples of what you can do with the notifications service in Argo CD. - -## Getting notified when a sync occurs and understanding how your resources changed - -With Argo CD you can build a notification system that tells you when a sync occurred and what it changed. -To get notified via webhook when a sync occurs you can add the following trigger: - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: argocd-notifications-cm -data: - service.webhook.on-deployed-webhook: | - url: - headers: - - name: "Content-Type" - value: "application/json" - - template.on-deployed-template: | - webhook: - on-deployed-webhook: - method: POST - body: | - {{toJson .app.status.operationState.syncResult}} - - - trigger.on-deployed-trigger: | - when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy' - oncePer: app.status.sync.revision - send: [on-deployed-template] -``` - -This, as explained in the [triggers section](triggers/#avoid-sending-same-notification-too-often), will generate a notification when the app is synced and healthy. We then need to create a subscription for the webhook integration: - -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - annotations: - notifications.argoproj.io/subscribe.on-deployed-trigger.on-deployed-webhook: "" -``` - -You can test that this works and see how the response looks by adding any webhook site and syncing our application. Here you can see that we receive a list of resources, with a message and some properties of them. For example: - -```json -{ - "resources": [ - { - "group": "apps", - "hookPhase": "Running", - # The images array follows the same order as in the resource yaml - "images": [ - "nginx:1.27.1" - ], - "kind": "Deployment", - "message": "deployment.apps/test configured", - "name": "test", - "namespace": "argocd", - "status": "Synced", - "syncPhase": "Sync", - "version": "v1" - }, - { - "group": "autoscaling", - "hookPhase": "Running", - "kind": "HorizontalPodAutoscaler", - "message": "horizontalpodautoscaler.autoscaling/test-hpa unchanged", - "name": "test-hpa", - "namespace": "argocd", - "status": "Synced", - "syncPhase": "Sync", - "version": "v2" - } - ], - "revision": "f3937462080c6946ff5ec4b5fa393e7c22388e4c", - ... -} -``` - -We can leverage this information to know: - -1. What resources have changed (not valid for Server Side Apply) -2. How they changed - -To understand what resources changed we can check the message associated with each resource. Those that say that are unchanged were not affected during the sync operation. With the list of changed resources, we can understand how they changed by looking into the images array. - -With this information you can, for example: - -1. Monitor the version of your image being deployed -2. Rollback deployments with images that are known to be faulty within your organisation -3. Detect unexpected image changes: by monitoring the images array in the webhook payload, you can verify that only expected container images are being deployed - -This helps you build a notification system that allows you to understand the status of your deployments in a more advanced manner. - -## Send the list of images to Slack - -Here we can use a similar setup as the one above, but change the receiver to be Slack: - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: argocd-notifications-cm -data: -data: - service.slack: | - token: - - template.on-deployed-template: | - slack: - message: | - *Deployment Notification* - *Application:* `{{.app.metadata.name}}` - *Namespace:* `{{.app.spec.destination.namespace}}` - *Revision:* `{{.app.status.sync.revision}}` - *Deployed Images:* - {{- range $resource := .app.status.operationState.syncResult.resources -}} - {{- range $image := $resource.images -}} - - "{{$image}}" - {{- end }} - {{- end }} - trigger.on-deployed-trigger: | - when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy' - oncePer: app.status.sync.revision - send: [on-deployed-template] -``` - -Now, with the setup above, a sync will send the list of images to your Slack application. For more information about integratin with Slack, see the [Slack integration guide](/operator-manual/notifications/services/slack/). - -### Deduplicating images - -Although the field in `syncResult.resources` contains only resources declared by the user in the GitOps repository you might end up with duplicated images depending on your setup. To avoid having duplicated images, you need to create an external webhook receiver that deduplicates the images, and then send the message to Slack. diff --git a/docs/operator-manual/notifications/index.md b/docs/operator-manual/notifications/index.md index 13e7170c47..002f67249c 100644 --- a/docs/operator-manual/notifications/index.md +++ b/docs/operator-manual/notifications/index.md @@ -112,4 +112,4 @@ metadata: When the same notification service and trigger are defined in controller level configuration and application level configuration, both notifications will be sent according to its own configuration. -[Defining and using secrets within notification templates](templates/#defining-and-using-secrets-within-notification-templates) function is not available when flag `--self-service-notification-enable` is on. +[Defining and using secrets within notification templates](templates.md/#defining-and-using-secrets-within-notification-templates) function is not available when flag `--self-service-notification-enable` is on. diff --git a/docs/operator-manual/notifications/services/github.md b/docs/operator-manual/notifications/services/github.md index 1dc72d83e1..4cd2523908 100755 --- a/docs/operator-manual/notifications/services/github.md +++ b/docs/operator-manual/notifications/services/github.md @@ -84,19 +84,6 @@ template.app-deployed: | content: | Application {{.app.metadata.name}} is now running new version of deployments manifests. See more here: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true - checkRun: - name: "continuous-delivery/{{.app.metadata.name}}" - details_url: "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true" - status: completed - conclusion: success - started_at: "YYYY-MM-DDTHH:MM:SSZ" - completed_at: "YYYY-MM-DDTHH:MM:SSZ" - output: - title: "Deployment of {{.app.metadata.name}} on ArgoCD" - summary: "Application {{.app.metadata.name}} is now running new version of deployments manifests." - text: | - Application {{.app.metadata.name}} is now running new version of deployments manifests. - See more here: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true ``` **Notes**: diff --git a/docs/operator-manual/project.yaml b/docs/operator-manual/project.yaml index ec8dd4d654..c4d93f5362 100644 --- a/docs/operator-manual/project.yaml +++ b/docs/operator-manual/project.yaml @@ -14,16 +14,12 @@ spec: sourceRepos: - '*' - # Only permit applications to deploy to the 'guestbook' namespace or any namespace starting with 'guestbook-' in the same cluster + # Only permit applications to deploy to the guestbook namespace in the same cluster # Destination clusters can be identified by 'server', 'name', or both. destinations: - namespace: guestbook server: https://kubernetes.default.svc name: in-cluster - # Destinations also allow wildcard globbing - - namespace: guestbook-* - server: https://kubernetes.default.svc - name: in-cluster # Deny all cluster-scoped resources from being created, except for Namespace clusterResourceWhitelist: diff --git a/docs/operator-manual/rbac.md b/docs/operator-manual/rbac.md index 8648448f49..eb45f92bec 100644 --- a/docs/operator-manual/rbac.md +++ b/docs/operator-manual/rbac.md @@ -42,7 +42,7 @@ The anonymous access to Argo CD can be enabled using the `users.anonymous.enable ## RBAC Model Structure -The model syntax is based on [Casbin](https://casbin.org/docs/overview) (an open source ACL/ACLs). There are two different types of syntax: one for assigning policies, and another one for assigning users to internal roles. +The model syntax is based on [Casbin](https://casbin.org/docs/overview). There are two different types of syntax: one for assigning policies, and another one for assigning users to internal roles. **Group**: Allows to assign authenticated users/groups to internal roles. @@ -114,8 +114,8 @@ The `applications` resource is an [Application-Specific Policy](#application-spe #### Fine-grained Permissions for `update`/`delete` action -The `update` and `delete` actions, when granted on an application, will allow the user to perform the operation on the application itself, -but not on its resources. +The `update` and `delete` actions, when granted on an application, will allow the user to perform the operation on the application itself **and** all of its resources. +It can be desirable to only allow `update` or `delete` on specific resources within an application. To do so, when the action if performed on an application's resource, the `` will have the `////` format. @@ -148,30 +148,28 @@ p, example-user, applications, delete, default/prod-app, deny p, example-user, applications, delete/*/Pod/*/*, default/prod-app, allow ``` -If we want to explicitly allow updates to the application, but deny updates to any sub-resources: +!!! note "Disable Application permission Inheritance" -```csv -p, example-user, applications, update, default/prod-app, allow -p, example-user, applications, update/*, default/prod-app, deny -``` - -!!! note "Preserve Application permission Inheritance (Since v3.0.0)" - - Prior to v3, `update` and `delete` actions (without a `/*`) were also evaluated - on sub-resources. - - To preserve this behavior, you can set the config value - `server.rbac.disableApplicationFineGrainedRBACInheritance` to `false` in - the Argo CD ConfigMap `argocd-cm`. - - When disabled, it is not possible to deny fine-grained permissions for a sub-resource - if the action was **explicitly allowed on the application**. - For instance, the following policies will **allow** a user to delete the Pod and any - other resources in the application: + By default, it is not possible to deny fine-grained permissions for a sub-resource if the action was **explicitly allowed on the application**. + For instance, the following policies will **allow** a user to delete the Pod and any other resources in the application: ```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 + ``` + + To change this behavior, you can set the config value + `server.rbac.disableApplicationFineGrainedRBACInheritance` to `true` in + the Argo CD ConfigMap `argocd-cm`. + + When inheritance is disabled, it is now possible to deny fine-grained permissions for a sub-resource + if the action was **explicitly allowed on the application**. + + For instance, if we want to explicitly allow updates to the application, but deny updates to any sub-resources: + + ```csv + p, example-user, applications, update, default/prod-app, allow + p, example-user, applications, update/*, default/prod-app, deny ``` #### The `action` action diff --git a/docs/operator-manual/reconcile.md b/docs/operator-manual/reconcile.md index 699b4335ab..21394af5c7 100644 --- a/docs/operator-manual/reconcile.md +++ b/docs/operator-manual/reconcile.md @@ -4,7 +4,7 @@ By default, an Argo CD Application is refreshed every time a resource that belon Kubernetes controllers often update the resources they watch periodically, causing continuous reconcile operation on the Application and a high CPU usage on the `argocd-application-controller`. Argo CD allows you to optionally ignore resource updates on specific fields -for [tracked resources](../user-guide/resource_tracking.md). +for [tracked resources](../user-guide/resource_tracking.md). For untracked resources, you can [use the argocd.argoproj.io/ignore-resource-updates annotations](#ignoring-updates-for-untracked-resources) When a resource update is ignored, if the resource's [health status](./health.md) does not change, the Application that this resource belongs to will not be reconciled. @@ -20,18 +20,17 @@ metadata: name: argocd-cm namespace: argocd data: - resource.ignoreResourceUpdatesEnabled: 'false' + 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](). It can be configured for a specified group and kind +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. 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 data: - resource.customizations.ignoreResourceUpdates.external-secrets.io_ExternalSecret: - | + resource.customizations.ignoreResourceUpdates.external-secrets.io_ExternalSecret: | jsonPointers: - /status/refreshTime # JQ equivalent of the above: @@ -50,9 +49,8 @@ data: ### Using ignoreDifferences to ignore reconcile -By default, the existing system-level `ignoreDifferences` customizations will be added to ignore resource updates as well. This helps reduce config management by preventing you to copy all existing ignore differences configurations. - -To disable this behavior, the `ignoreDifferencesOnResourceUpdates` setting can be disabled: +It is possible to use existing system-level `ignoreDifferences` customizations to ignore resource updates as well. Instead of copying all configurations, +the `ignoreDifferencesOnResourceUpdates` setting can be used to add all ignored differences as ignored resource updates: ```yaml apiVersion: v1 @@ -61,7 +59,7 @@ metadata: name: argocd-cm data: resource.compareoptions: | - ignoreDifferencesOnResourceUpdates: false + ignoreDifferencesOnResourceUpdates: true ``` ## Default Configuration @@ -74,11 +72,11 @@ The application controller logs when a resource change triggers a refresh. You c high-churn resource kinds and then inspect those resources to find which fields to ignore. To find these logs, search for `"Requesting app refresh caused by object update"`. The logs include structured -fields for `api-version` and `kind`. Counting the number of refreshes triggered, by api-version/kind should +fields for `api-version` and `kind`. Counting the number of refreshes triggered, by api-version/kind should reveal the high-churn resource kinds. -!!!note -These logs are at the `debug` level. Configure the application-controller's log level to `debug`. +!!!note + These logs are at the `debug` level. Configure the application-controller's log level to `debug`. Once you have identified some resources which change often, you can try to determine which fields are changing. Here is one approach: @@ -100,7 +98,7 @@ Whenever Argo CD skips a refresh due to an ignored resource update, the controll Search the application-controller logs for this line to confirm that your resource ignore rules are being applied. !!!note -These logs are at the `debug` level. Configure the application-controller's log level to `debug`. + These logs are at the `debug` level. Configure the application-controller's log level to `debug`. ## Examples @@ -142,37 +140,36 @@ metadata: name: hello namespace: test-cronjob spec: - schedule: '* * * * *' + schedule: "* * * * *" jobTemplate: metadata: annotations: - argocd.argoproj.io/ignore-resource-updates: 'true' + argocd.argoproj.io/ignore-resource-updates: "true" spec: template: metadata: annotations: - argocd.argoproj.io/ignore-resource-updates: 'true' + argocd.argoproj.io/ignore-resource-updates: "true" spec: containers: - - name: hello - image: busybox:1.28 - imagePullPolicy: IfNotPresent - command: - - /bin/sh - - -c - - date; echo Hello from the Kubernetes cluster + - name: hello + image: busybox:1.28 + imagePullPolicy: IfNotPresent + command: + - /bin/sh + - -c + - date; echo Hello from the Kubernetes cluster restartPolicy: OnFailure ``` The resource updates will be ignored based on your the `ignoreResourceUpdates` configuration in the `argocd-cm` configMap: `argocd-cm`: - ```yaml resource.customizations.ignoreResourceUpdates.batch_Job: | - jsonPointers: - - /status + jsonPointers: + - /status resource.customizations.ignoreResourceUpdates.Pod: | - jsonPointers: - - /status + jsonPointers: + - /status ``` diff --git a/docs/operator-manual/resource_actions.md b/docs/operator-manual/resource_actions.md index a76225316d..8de2984ce0 100644 --- a/docs/operator-manual/resource_actions.md +++ b/docs/operator-manual/resource_actions.md @@ -203,21 +203,3 @@ resource.customizations.actions.ConfigMap: | result[2] = impactedResource2 return result ``` - -### Action Icons and Display Names - -By default, an action will appear in the UI by the name specified in the `actions` key, and it will have no icon. You -can customize the display name and icon of an action by adding the `iconClass` and `displayName` keys to the action -definition. - -The icon class name is the name of a FontAwesome icon from [the set of free icons](https://fontawesome.com/search?ic=free). -The `fa-fw` class ensures that the icon is displayed with a fixed width, to avoid alignment issues with other icons. - -```lua -local actions = {} -actions["create-workflow"] = { - ["iconClass"] = "fa fa-fw fa-play", - ["displayName"] = "Create Workflow" -} -return actions -``` diff --git a/docs/operator-manual/resource_actions_builtin.md b/docs/operator-manual/resource_actions_builtin.md index c3ebbff5d1..9708dcbd1e 100644 --- a/docs/operator-manual/resource_actions_builtin.md +++ b/docs/operator-manual/resource_actions_builtin.md @@ -2,18 +2,14 @@ - [apps/Deployment/pause](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/apps/Deployment/actions/pause/action.lua) - [apps/Deployment/restart](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/apps/Deployment/actions/restart/action.lua) - [apps/Deployment/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/apps/Deployment/actions/resume/action.lua) -- [apps/Deployment/scale](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/apps/Deployment/actions/scale/action.lua) - [apps/StatefulSet/restart](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/apps/StatefulSet/actions/restart/action.lua) -- [apps/StatefulSet/scale](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/apps/StatefulSet/actions/scale/action.lua) - [argoproj.io/AnalysisRun/terminate](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/argoproj.io/AnalysisRun/actions/terminate/action.lua) - [argoproj.io/CronWorkflow/create-workflow](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/argoproj.io/CronWorkflow/actions/create-workflow/action.lua) - [argoproj.io/Rollout/abort](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/argoproj.io/Rollout/actions/abort/action.lua) -- [argoproj.io/Rollout/pause](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/argoproj.io/Rollout/actions/pause/action.lua) - [argoproj.io/Rollout/promote-full](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/argoproj.io/Rollout/actions/promote-full/action.lua) - [argoproj.io/Rollout/restart](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/argoproj.io/Rollout/actions/restart/action.lua) - [argoproj.io/Rollout/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/argoproj.io/Rollout/actions/resume/action.lua) - [argoproj.io/Rollout/retry](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/argoproj.io/Rollout/actions/retry/action.lua) -- [argoproj.io/Rollout/skip-current-step](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/argoproj.io/Rollout/actions/skip-current-step/action.lua) - [argoproj.io/WorkflowTemplate/create-workflow](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/argoproj.io/WorkflowTemplate/actions/create-workflow/action.lua) - [batch/CronJob/create-job](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/batch/CronJob/actions/create-job/action.lua) - [external-secrets.io/ExternalSecret/refresh](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/external-secrets.io/ExternalSecret/actions/refresh/action.lua) @@ -41,16 +37,10 @@ - [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/ISBServiceRollout/disable-force-promote](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/disable-force-promote/action.lua) -- [numaplane.numaproj.io/ISBServiceRollout/enable-force-promote](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/enable-force-promote/action.lua) -- [numaplane.numaproj.io/MonoVertexRollout/disable-force-promote](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/disable-force-promote/action.lua) -- [numaplane.numaproj.io/MonoVertexRollout/enable-force-promote](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/enable-force-promote/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/disable-force-promote](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/disable-force-promote/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/enable-force-promote](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/enable-force-promote/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) diff --git a/docs/operator-manual/secret-management.md b/docs/operator-manual/secret-management.md index e141e952c3..95343789c4 100644 --- a/docs/operator-manual/secret-management.md +++ b/docs/operator-manual/secret-management.md @@ -1,47 +1,29 @@ # Secret Management -There are two general ways to populate secrets when doing GitOps: on the destination cluster, or in Argo CD during -manifest generation. We strongly recommend the former, as it is more secure and provides a better user experience. +Argo CD is un-opinionated about how secrets are managed. There are many ways to do it, and there's no one-size-fits-all solution. -For further discussion, see [#1364](https://github.com/argoproj/argo-cd/issues/1364). +Many solutions use plugins to inject secrets into the application manifests. See [Mitigating Risks of Secret-Injection Plugins](#mitigating-risks-of-secret-injection-plugins) +below to make sure you use those plugins securely. -## Destination Cluster Secret Management +Here are some ways people are doing GitOps secrets: -In this approach, secrets are populated on the destination cluster, and Argo CD does not need to directly manage them. -[Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets), [External Secrets Operator](https://github.com/external-secrets/external-secrets), -and [Kubernetes Secrets Store CSI Driver](https://github.com/kubernetes-sigs/secrets-store-csi-driver) are examples of this style of secret management. - -This approach has two main advantages: - -1) Security: Argo CD does not need to have access to the secrets, which reduces the risk of leaking them. -2) User Experience: Secret updates are decoupled from app sync operations, which reduces the risk of unintentionally - applying Secret updates during an unrelated release. - -We strongly recommend this style of secret management. - -Other examples of this style of secret management include: +* [Bitnami Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets) +* [External Secrets Operator](https://github.com/external-secrets/external-secrets) +* [Hashicorp Vault](https://www.vaultproject.io) +* [Bank-Vaults](https://bank-vaults.dev/) +* [Helm Secrets](https://github.com/jkroepke/helm-secrets) +* [Kustomize secret generator plugins](https://github.com/kubernetes-sigs/kustomize/blob/fd7a353df6cece4629b8e8ad56b71e30636f38fc/examples/kvSourceGoPlugin.md#secret-values-from-anywhere) * [aws-secret-operator](https://github.com/mumoshu/aws-secret-operator) -* [Vault Secrets Operator](https://developer.hashicorp.com/vault/docs/platform/k8s/vso) +* [KSOPS](https://github.com/viaduct-ai/kustomize-sops#argo-cd-integration) +* [argocd-vault-plugin](https://github.com/argoproj-labs/argocd-vault-plugin) +* [argocd-vault-replacer](https://github.com/crumbhole/argocd-vault-replacer) +* [Kubernetes Secrets Store CSI Driver](https://github.com/kubernetes-sigs/secrets-store-csi-driver) +* [Vals-Operator](https://github.com/digitalis-io/vals-operator) +* [argocd-secret-replacer](https://github.com/mmalyska/argocd-secret-replacer) -## Argo CD Manifest Generation-Based Secret Management +For discussion, see [#1364](https://github.com/argoproj/argo-cd/issues/1364) -In this approach, Argo CD's manifest generation step is used to inject secrets. This may be done using a -[Config Management Plugin](config-management-plugins.md) like [argocd-vault-plugin](https://github.com/argoproj-labs/argocd-vault-plugin). - -**We strongly caution against this style of secret management**, as it has several disadvantages: - -1) Security: Argo CD needs access to the secrets, which increases the risk of leaking them. Argo CD stores generated - manifests in plaintext in its Redis cache, so injecting secrets into the manifests increases risk. -2) User Experience: Secret updates are coupled with app sync operations, which increases the risk of unintentionally - applying Secret updates during an unrelated release. -3) Rendered Manifests Pattern: This approach is incompatible with the "Rendered Manifests" pattern, which is - increasingly becoming a best practice for GitOps. - -Many users have already adopted generation-based solutions, and we understand that migrating to an operator-based -solution can be a significant effort. Argo CD will continue to support generation-based secret management, but we will -not prioritize new features or improvements that solely support this style of secret management. - -### Mitigating Risks of Secret-Injection Plugins +## Mitigating Risks of Secret-Injection Plugins Argo CD caches the manifests generated by plugins, along with the injected secrets, in its Redis instance. Those manifests are also available via the repo-server API (a gRPC service). This means that the secrets are available to @@ -52,3 +34,4 @@ Consider these steps to mitigate the risks of secret-injection plugins: 1. Set up network policies to prevent direct access to Argo CD components (Redis and the repo-server). Make sure your cluster supports those network policies and can actually enforce them. 2. Consider running Argo CD on its own cluster, with no other applications running on it. + diff --git a/docs/operator-manual/security.md b/docs/operator-manual/security.md index afee322551..9d05c45cb7 100644 --- a/docs/operator-manual/security.md +++ b/docs/operator-manual/security.md @@ -238,14 +238,6 @@ can be found in [server/server.go](https://github.com/argoproj/argo-cd/blob/abba Argo CD does not log IP addresses of clients requesting API endpoints, since the API server is typically behind a proxy. Instead, it is recommended to configure IP addresses logging in the proxy server that sits in front of the API server. -### Standard Application log fields - -For logs related to an Application, Argo CD will log the following standard fields : - -* *application*: the Application name, without the namespace -* *app-namespace*: the Application's namespace -* *project*: the Application's project - ## ApplicationSets Argo CD's ApplicationSets feature has its own [security considerations](./applicationset/Security.md). Be aware of those diff --git a/docs/operator-manual/server-commands/additional-configuration-method.md b/docs/operator-manual/server-commands/additional-configuration-method.md index d570393310..cc80ed3aeb 100644 --- a/docs/operator-manual/server-commands/additional-configuration-method.md +++ b/docs/operator-manual/server-commands/additional-configuration-method.md @@ -23,6 +23,6 @@ To set `logformat` of `argocd-application-controller`, add below entry to the co ``` data: - controller.log.format: "json" + controller.log.format: "text" ``` diff --git a/docs/operator-manual/server-commands/argocd-application-controller.md b/docs/operator-manual/server-commands/argocd-application-controller.md index 29c6b95d7f..f4c6776bc7 100644 --- a/docs/operator-manual/server-commands/argocd-application-controller.md +++ b/docs/operator-manual/server-commands/argocd-application-controller.md @@ -16,8 +16,8 @@ argocd-application-controller [flags] ``` --app-hard-resync int Time period in seconds for application hard resync. - --app-resync int Time period in seconds for application resync. (default 120) - --app-resync-jitter int Maximum time period in seconds to add as a delay jitter for application resync. (default 60) + --app-resync int Time period in seconds for application resync. (default 180) + --app-resync-jitter int Maximum time period in seconds to add as a delay jitter for application resync. --app-state-cache-expiration duration Cache expiration for app state (default 1h0m0s) --application-namespaces strings List of additional namespaces that applications are allowed to be reconciled from --as string Username to impersonate for the operation @@ -40,12 +40,11 @@ argocd-application-controller [flags] --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 --kubectl-parallelism-limit int Number of allowed concurrent kubectl fork/execs. Any value less than 1 means no limit. (default 20) - --logformat string Set the logging format. One of: json|text (default "json") + --logformat string Set the logging format. One of: text|json (default "text") --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") --metrics-application-conditions strings List of Application conditions that will be added to the argocd_application_conditions metric --metrics-application-labels strings List of Application labels that will be added to the argocd_application_labels metric --metrics-cache-expiration duration Prometheus metrics cache expiration (disabled by default. e.g. 24h0m0s) - --metrics-cluster-labels strings List of Cluster labels that will be added to the argocd_cluster_labels metric --metrics-port int Start metrics server on given port (default 8082) -n, --namespace string If present, the namespace scope for this CLI request --operation-processors int Number of application operation processors (default 10) @@ -54,7 +53,7 @@ argocd-application-controller [flags] --otlp-headers stringToString List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2) (default []) --otlp-insecure OpenTelemetry collector insecure mode (default true) --password string Password for basic authentication to the API server - --persist-resource-health Enables storing the managed resources health in the Application CRD + --persist-resource-health Enables storing the managed resources health in the Application CRD (default true) --proxy-url string If provided, this URL will be used to connect via proxy --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-applicationset-controller.md b/docs/operator-manual/server-commands/argocd-applicationset-controller.md deleted file mode 100644 index 4fbe98d324..0000000000 --- a/docs/operator-manual/server-commands/argocd-applicationset-controller.md +++ /dev/null @@ -1,62 +0,0 @@ -# `argocd-applicationset-controller` Command Reference - -## argocd-applicationset-controller - -Starts Argo CD ApplicationSet controller - -``` -argocd-applicationset-controller [flags] -``` - -### Options - -``` - --allowed-scm-providers strings 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) - --applicationset-namespaces strings Argo CD applicationset namespaces - --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") - --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 - --concurrent-reconciliations int Max concurrent reconciliations limit for the controller (default 10) - --context string The name of the kubeconfig context to use - --debug Print debug logs. Takes precedence over loglevel - --disable-compression If true, opt-out of response compression for all requests to the server - --dry-run Enable dry run mode - --enable-leader-election Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager. - --enable-new-git-file-globbing Enable new globbing in Git files generator. - --enable-policy-override For security reason if 'policy' is set, it is not possible to override it at applicationSet level. 'allow-policy-override' allows user to define their own policy (default true) - --enable-progressive-syncs Enable use of the experimental progressive syncs feature. - --enable-scm-providers Enable retrieving information from SCM providers, used by the SCM and PR generators (Default: true) (default true) - -h, --help help for argocd-applicationset-controller - --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 - --logformat string Set the logging format. One of: json|text (default "json") - --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") - --metrics-addr string The address the metric endpoint binds to. (default ":8080") - --metrics-applicationset-labels strings List of Application labels that will be added to the argocd_applicationset_labels metric - -n, --namespace string If present, the namespace scope for this CLI request - --password string Password for basic authentication to the API server - --policy string Modify how application is synced between the generator and the cluster. Default is '' (empty), which means AppSets default to 'sync', but they may override that default. Setting an explicit value prevents AppSet-level overrides, unless --allow-policy-override is enabled. Explicit options are: 'sync' (create & update & delete), 'create-only', 'create-update' (no deletion), 'create-delete' (no update) - --preserved-annotations strings Sets global preserved field values for annotations - --preserved-labels strings Sets global preserved field values for labels - --probe-addr string The address the probe endpoint binds to. (default ":8081") - --proxy-url string If provided, this URL will be used to connect via proxy - --repo-server-plaintext Disable TLS on connections to repo server - --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") - --scm-root-ca-path string Provide Root CA Path for self-signed TLS Certificates - --server string The address and port of the Kubernetes API server - --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 - --token-ref-strict-mode Set to true to require secrets referenced by SCM providers to have the argocd.argoproj.io/secret-type=scm-creds label set (Default: false) - --user string The name of the kubeconfig user to use - --username string Username for basic authentication to the API server - --webhook-addr string The address the webhook endpoint binds to. (default ":7000") - --webhook-parallelism-limit int Number of webhook requests processed concurrently (default 50) -``` - diff --git a/docs/operator-manual/server-commands/argocd-dex_gendexcfg.md b/docs/operator-manual/server-commands/argocd-dex_gendexcfg.md index 6de925f1f1..a889b64133 100644 --- a/docs/operator-manual/server-commands/argocd-dex_gendexcfg.md +++ b/docs/operator-manual/server-commands/argocd-dex_gendexcfg.md @@ -24,7 +24,7 @@ argocd-dex gendexcfg [flags] -h, --help help for gendexcfg --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 - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request -o, --out string Output to the specified file instead of stdout diff --git a/docs/operator-manual/server-commands/argocd-dex_rundex.md b/docs/operator-manual/server-commands/argocd-dex_rundex.md index dc1d44ddd9..b2d453feba 100644 --- a/docs/operator-manual/server-commands/argocd-dex_rundex.md +++ b/docs/operator-manual/server-commands/argocd-dex_rundex.md @@ -24,7 +24,7 @@ argocd-dex rundex [flags] -h, --help help for rundex --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 - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the 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 bd3d5602b7..12e4d34d14 100644 --- a/docs/operator-manual/server-commands/argocd-repo-server.md +++ b/docs/operator-manual/server-commands/argocd-repo-server.md @@ -24,7 +24,7 @@ argocd-repo-server [flags] --helm-registry-max-index-size string Maximum size of registry index file (default "1G") -h, --help help for argocd-repo-server --include-hidden-directories Include hidden directories from Git - --logformat string Set the logging format. One of: json|text (default "json") + --logformat string Set the logging format. One of: text|json (default "text") --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") --max-combined-directory-manifests-size string Max combined size of manifest files in a directory-type Application (default "10M") --metrics-address string Listen on given address for metrics (default "0.0.0.0") diff --git a/docs/operator-manual/server-commands/argocd-server.md b/docs/operator-manual/server-commands/argocd-server.md index ba4e9fccfe..fe284a5940 100644 --- a/docs/operator-manual/server-commands/argocd-server.md +++ b/docs/operator-manual/server-commands/argocd-server.md @@ -59,7 +59,7 @@ argocd-server [flags] --insecure Run server without TLS --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster - --logformat string Set the logging format. One of: json|text (default "json") + --logformat string Set the logging format. One of: text|json (default "text") --login-attempts-expiration duration Cache expiration for failed login attempts (default 24h0m0s) --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") --metrics-address string Listen for metrics on given address (default "0.0.0.0") @@ -105,7 +105,6 @@ argocd-server [flags] --sentinelmaster string Redis sentinel master group name. (default "master") --server string The address and port of the Kubernetes API server --staticassets string Directory path that contains additional static assets (default "/shared/app") - --sync-with-replace-allowed Whether to allow users to select replace for syncs from UI/CLI (default true) --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. --tlsciphers string The list of acceptable ciphers to be used when establishing TLS connections. Use 'list' to list available ciphers. (default "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") --tlsmaxversion string The maximum SSL/TLS version that is acceptable (one of: 1.0|1.1|1.2|1.3) (default "1.3") diff --git a/docs/operator-manual/tested-kubernetes-versions.md b/docs/operator-manual/tested-kubernetes-versions.md index 73475e8523..174ce6e051 100644 --- a/docs/operator-manual/tested-kubernetes-versions.md +++ b/docs/operator-manual/tested-kubernetes-versions.md @@ -1,2 +1,5 @@ -This page is populated for released Argo CD versions. Use the version selector to view this table for a specific -version. +| Argo CD version | Kubernetes versions | +|-----------------|---------------------| +| 2.14 | v1.31, v1.30, v1.29, v1.28 | +| 2.13 | v1.30, v1.29, v1.28, v1.27 | +| 2.12 | v1.29, v1.28, v1.27, v1.26 | diff --git a/docs/operator-manual/tls.md b/docs/operator-manual/tls.md index 4a094c59fc..43409fc568 100644 --- a/docs/operator-manual/tls.md +++ b/docs/operator-manual/tls.md @@ -2,7 +2,7 @@ Argo CD provides three inbound TLS endpoints that can be configured: -* The user-facing endpoint of the `argocd-server` workload, which serves the UI +* The user-facing endpoint of the `argocd-server` workload which serves the UI and the API * The endpoint of the `argocd-repo-server`, which is accessed by `argocd-server` and `argocd-application-controller` workloads to request repository @@ -11,7 +11,7 @@ Argo CD provides three inbound TLS endpoints that can be configured: to handle OIDC authentication. By default, and without further configuration, these endpoints will be -set up to use an automatically generated, self-signed certificate. However, +set-up to use an automatically generated, self-signed certificate. However, most users will want to explicitly configure the certificates for these TLS endpoints, possibly using automated means such as `cert-manager` or using their own dedicated Certificate Authority. @@ -39,7 +39,7 @@ There are two ways to configure the TLS certificates used by `argocd-server`: `argocd-server-tls` secret may be of type `tls`, but does not have to be. * Setting the `tls.crt` and `tls.key` keys in the `argocd-secret` secret to hold PEM data of the certificate and the corresponding private key. This - method is considered deprecated and only exists for purposes of backwards + method is considered deprecated, and only exists for purposes of backwards compatibility. Changing `argocd-secret` should not be used to override the TLS certificate anymore. @@ -50,7 +50,7 @@ Argo CD decides which TLS certificate to use for the endpoint of `tls.crt` and `tls.key` keys, this will be used for the certificate of the endpoint of `argocd-server`. * Otherwise, if the `argocd-secret` secret contains a valid key pair in the - `tls.crt` and `tls.key` keys, this will be used as the certificate for the + `tls.crt` and `tls.key` keys, this will be used as certificate for the endpoint of `argocd-server`. * If no `tls.crt` and `tls.key` keys are found in neither of the two mentioned secrets, Argo CD will generate a self-signed certificate and persist it in @@ -69,7 +69,7 @@ kubectl create -n argocd secret tls argocd-server-tls \ ``` Argo CD will pick up changes to the `argocd-server-tls` secret automatically -and will not require restarting to use a renewed certificate. +and will not require restart of the pods to use a renewed certificate. ## Configuring inbound TLS for argocd-repo-server @@ -83,7 +83,7 @@ setting command line parameters. The following parameters are available: |`--disable-tls`|`false`|Disables TLS completely| |`--tlsminversion`|`1.2`|The minimum TLS version to be offered to clients| |`--tlsmaxversion`|`1.3`|The maximum TLS version to be offered to clients| -|`--tlsciphers`|`TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_GCM_SHA384`|A colon-separated list of TLS cipher suites to be offered to clients| +|`--tlsciphers`|`TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_GCM_SHA384`|A colon separated list of TLS cipher suites to be offered to clients| ### Inbound TLS certificates used by argocd-repo-server @@ -158,10 +158,10 @@ on how your workloads connect to the repository server. Both `argocd-server` and `argocd-application-controller` communicate with the `argocd-repo-server` using a gRPC API over TLS. By default, -`argocd-repo-server` generates a non-persistent, self-signed certificate +`argocd-repo-server` generates a non-persistent, self signed certificate to use for its gRPC endpoint on startup. Because the `argocd-repo-server` has -no means to connect to the K8s control plane API, this certificate is not available -to outside consumers for verification. Both, +no means to connect to the K8s control plane API, this certificate is not +being available to outside consumers for verification. Both, the `argocd-server` and `argocd-application-server` will use a non-validating connection to the `argocd-repo-server` for this reason. @@ -181,18 +181,19 @@ validate the TLS certificate of the `argocd-repo-server` by using the certificate stored in the `argocd-repo-server-tls` secret. !!!note "Certificate expiry" - Please make sure that the certificate has a proper lifetime. Remember, - when replacing certificates, all workloads must be restarted to pick up - the certificate and work properly. + Please make sure that the certificate has a proper life time. Keep in + mind that when you have to replace the certificate, all workloads have + to be restarted in order to properly work again. ### Configuring TLS to argocd-dex-server `argocd-server` communicates with the `argocd-dex-server` using an HTTPS API -over TLS. By default, `argocd-dex-server` generates a non-persistent, self-signed -certificate for its HTTPS endpoint on startup. Because `argocd-dex-server` -has no means to connect to the K8s control plane API, this certificate is not -available to outside consumers for verification. `argocd-server` will use a -non-validating connection to `argocd-dex-server` for this reason. +over TLS. By default, `argocd-dex-server` generates a non-persistent, self +signed certificate to use for its HTTPS endpoint on startup. Because the +`argocd-dex-server` has no means to connect to the K8s control plane API, +this certificate is not being available to outside consumers for verification. +The `argocd-server` will use a non-validating connection to the `argocd-dex-server` +for this reason. To change this behavior to be more secure by having the `argocd-server` validate the TLS certificate of the `argocd-dex-server` endpoint, the following steps need @@ -209,14 +210,14 @@ The `argocd-server` workload will now validate the TLS certificate of the secret. !!!note "Certificate expiry" - Please make sure that the certificate has a proper lifetime. Remember, - when replacing certificates, all workloads must be restarted to pick up - the certificate and work properly. + Please make sure that the certificate has a proper life time. Keep in + mind that when you have to replace the certificate, all workloads have + to be restarted in order to properly work again. ### Disabling TLS to argocd-repo-server -In some scenarios where mTLS through sidecar proxies is involved (e.g. -in a service mesh), you may want to configure the connections between the +In some scenarios where mTLS through side-car proxies is involved (e.g. +in a service mesh), you may want configure the connections between the `argocd-server` and `argocd-application-controller` to `argocd-repo-server` to not use TLS at all. @@ -225,36 +226,36 @@ In this case, you will need to: * Configure `argocd-repo-server` with TLS on the gRPC API disabled by specifying the `--disable-tls` parameter to the pod container's startup arguments. Also, consider restricting listening addresses to the loopback interface by specifying - `--listen 127.0.0.1` parameter, so that the insecure endpoint is not exposed on - the pod's network interfaces, but still available to the sidecar container. + `--listen 127.0.0.1` parameter, so that insecure endpoint is not exposed on + the pod's network interfaces, but still available to the side-car container. * Configure `argocd-server` and `argocd-application-controller` to not use TLS for connections to the `argocd-repo-server` by specifying the parameter `--repo-server-plaintext` to the pod container's startup arguments * Configure `argocd-server` and `argocd-application-controller` to connect to - the sidecar instead of directly to the `argocd-repo-server` service by + the side-car instead of directly to the `argocd-repo-server` service by specifying its address via the `--repo-server
` parameter -After this change, `argocd-server` and `argocd-application-controller` will -use a plain text connection to the sidecar proxy, which will handle all aspects -of TLS to `argocd-repo-server`'s TLS sidecar proxy. +After this change, the `argocd-server` and `argocd-application-controller` will +use a plain text connection to the side-car proxy, that will handle all aspects +of TLS to the `argocd-repo-server`'s TLS side-car proxy. ### Disabling TLS to argocd-dex-server -In some scenarios where mTLS through sidecar proxies is involved (e.g. -in a service mesh), you may want to configure the connections between +In some scenarios where mTLS through side-car proxies is involved (e.g. +in a service mesh), you may want configure the connections between `argocd-server` to `argocd-dex-server` to not use TLS at all. In this case, you will need to: * Configure `argocd-dex-server` with TLS on the HTTPS API disabled by specifying the `--disable-tls` parameter to the pod container's startup arguments -* Configure `argocd-server` to not use TLS for connections to `argocd-dex-server` +* Configure `argocd-server` to not use TLS for connections to the `argocd-dex-server` by specifying the parameter `--dex-server-plaintext` to the pod container's startup arguments -* Configure `argocd-server` to connect to the sidecar instead of directly to the +* Configure `argocd-server` to connect to the side-car instead of directly to the `argocd-dex-server` service by specifying its address via the `--dex-server
` parameter -After this change, `argocd-server` will use a plain text connection to the sidecar -proxy, that will handle all aspects of TLS to the `argocd-dex-server`'s TLS sidecar proxy. +After this change, the `argocd-server` will use a plain text connection to the side-car +proxy, that will handle all aspects of TLS to the `argocd-dex-server`'s TLS side-car proxy. diff --git a/docs/operator-manual/upgrading/2.13-2.14.md b/docs/operator-manual/upgrading/2.13-2.14.md index 3b8a473fb4..4ee50fd1c1 100644 --- a/docs/operator-manual/upgrading/2.13-2.14.md +++ b/docs/operator-manual/upgrading/2.13-2.14.md @@ -1,13 +1,5 @@ # v2.13 to 2.14 -## Avoid v2.14.0 manifests and use v2.14.1 - -The tagged v2.14.0 manifests contain a nonexistent Argo CD image. If you are using the Argo CD manifests as a remote -base, use the v2.14.1 manifests instead. - -Eg, `https://github.com/argoproj/argo-cd/manifests/ha/cluster-install?ref=v2.14.1` or -`https://raw.githubusercontent.com/argoproj/argo-cd/v2.14.1/manifests/install.yaml` - ## Upgraded Helm Version Helm was upgraded to 3.16.2 and the skipSchemaValidation Flag was added to diff --git a/docs/operator-manual/upgrading/2.14-3.0.md b/docs/operator-manual/upgrading/2.14-3.0.md deleted file mode 100644 index fb9c16e1f2..0000000000 --- a/docs/operator-manual/upgrading/2.14-3.0.md +++ /dev/null @@ -1,466 +0,0 @@ -# v2.14 to 3.0 - -Argo CD 3.0 is meant to be a low-risk upgrade containing only minor breaking changes. For each change, the next -section will describe how to quickly determine if you are impacted, how to remediate the breaking change, and (if -applicable) restore Argo CD 2.x default behavior. - -Once 3.0 is released, no more 2.x minor versions will be released. We will continue to cut patch releases for the two -most recent minor versions (so 2.14 until 3.2 is released and 2.13 until 3.1 is released). - -## Breaking Changes - -### Fine-Grained RBAC for application `update` and `delete` sub-resources - -The default behavior of fine-grained policies have changed so they no longer apply to sub-resources. -Prior to v3, policies granting `update` or `delete` to an application also applied to any of its sub-resources. - -Starting with v3, the `update` or `delete` actions only apply to the application itself. New policies must be defined -to allow the `update/*` or `delete/*` actions on an Application's managed resources. - -The v2 behavior can be preserved by setting the config value `server.rbac.disableApplicationFineGrainedRBACInheritance` -to `false` in the Argo CD ConfigMap `argocd-cm`. - -Read the [RBAC documentation](../rbac.md#fine-grained-permissions-for-updatedelete-action) for more detailed -information. - -### Logs RBAC enforcement as a first-class RBAC citizen - -2.4 introduced `logs` as a new RBAC resource. In 2.3 and lower, users with `applications, get` access automatically got logs access. In 2.4, it became possible to enable logs RBAC enforcement with a flag in `argocd-cm` ConfigMap: - -```yaml -server.rbac.log.enforce.enable: 'true' -``` - -Starting from 3.0, this flag is removed and the logs RBAC is enforced by default, meaning the `logs` tab on `pod` view will not be visible without granting explicit `logs, get` permissions to the users/groups/roles requiring it. - -#### Detection - -Users who have `server.rbac.log.enforce.enable: "true"` in their `argocd-cm` ConfigMap, are unaffected by this change. - -Users who have `policy.default: role:readonly` or `policy.default: role:admin` in their `argocd-rbac-cm` ConfigMap, are unaffected. - -Users who don't have a `policy.default` in their `argocd-rbac-cm` ConfigMap, and either have `server.rbac.log.enforce.enable` set to `false` or don't have this setting at all in their `argocd-cm` ConfigMap are affected and should perform the below remediation steps. - -After the upgrade, it is recommended to remove the setting `server.rbac.log.enforce.enable` from `argocd-cm` ConfigMap, if it was there before the upgrade. - -#### Remediation - -##### Quick remediation (global change) - -For users with an existing default policy with a custom role, add this policy to `policy.csv` for your custom role: `p, role:, logs, get, */*, allow`. -For users without a default policy, add this policy to `policy.csv`: `p, role:global-log-viewer, logs, get, */*, allow` and add the default policy for this role: `policy.default: role:global-log-viewer` - -##### Recommended remediation (per-policy change) - -Explicitly add a `logs, get` policy to every role that has a policy for `applications, get` or for `applications, *`. -This is the recommended way to maintain the principle of least privilege. -Similar to the way access to Applications are currently managed, access to logs can be either granted on a Project scope level (Project resource) or on the `argocd-rbac-cm` ConfigMap level. -See this [example](../upgrading/2.3-2.4.md#example-1) for more details. - -### Default `resource.exclusions` configurations - -Argo CD manifest now contains a default configuration for `resource.exclusions` in the `argocd-cm` to exclude resources that -are known to be created by controllers and not usually managed in Git. The exclusions contain high volume and high churn objects -which we exclude for performance reasons, reducing connections and load to the K8s API servers of managed clusters. - -The excluded Kinds are: - -- **Kubernetes Resources**: `Endpoints`, `EndpointSlice`, `Lease`, `SelfSubjectReview`, `TokenReview`, `LocalSubjectAccessReview`, `SelfSubjectAccessReview`, `SelfSubjectRulesReview`, `SubjectAccessReview`, `CertificateSigningRequest`, `PolicyReport` and `ClusterPolicyReport`. -- **Cert Manager**: `CertificateRequest`. -- **Kyverno**: `EphemeralReport`, `ClusterEphemeralReport`, `AdmissionReport`, `ClusterAdmissionReport`, `BackgroundScanReport`, `ClusterBackgroundScanReport` and `UpdateRequest`. -- **Cilium**: `CiliumIdentity`, `CiliumEndpoint` and `CiliumEndpointSlice`. - -The default `resource.exclusions` can be overridden or removed in the configMap to preserve the v2 behavior. - -Read the [Declarative Setup](../declarative-setup.md) for more detailed information to configure `resource.exclusions`. - -### Removal of `argocd_app_sync_status`, `argocd_app_health_status` and `argocd_app_created_time` Metrics - -The `argocd_app_sync_status`, `argocd_app_health_status` and `argocd_app_created_time`, deprecated and disabled by -default since 1.5.0, have been removed. The information previously provided by these metrics is now available as labels -on the `argocd_app_info` metric. - -#### Detection - -Starting with 1.5.0, these metrics are only available if `ARGOCD_LEGACY_CONTROLLER_METRICS` is explicitly set to `true`. -If it is not set to true, you can safely upgrade with no changes. - -#### Migration - -If you are using these metrics, you will need to update your monitoring dashboards and alerts to use the new metric and -labels before upgrading. - -### Changes to RBAC with Dex SSO Authentication - -When using Dex, the `sub` claim returned in the authentication was used as the subject for RBAC. That value depends on -the Dex internal implementation and should not be considered an immutable value that represents the subject. - -The new behavior will request the -`federated:id` [scope](https://dexidp.io/docs/configuration/custom-scopes-claims-clients/) from Dex, and the new value -used as the RBAC subject will be based -on the `federated_claims.user_id` claim instead of the `sub` claim. - -If you were using the Dex sub claim in RBAC policies, you will need to update them to maintain the same access. - -You can know the correct `user_id` to use by decoding the current `sub` claims defined in your policies. You can also -configure which -value is used as `user_id` for some [connectors](https://dexidp.io/docs/connectors/). - -```sh -$> echo "ChdleGFtcGxlQGFyZ29wcm9qLmlvEgJkZXhfY29ubl9pZA" | base64 -d - -example@argoproj.iodex_conn_i% -``` - -```yaml -# Policies based on the Dex sub claim (wrong) -- g, ChdleGFtcGxlQGFyZ29wcm9qLmlvEgJkZXhfY29ubl9pZA, role:example -- p, ChdleGFtcGxlQGFyZ29wcm9qLmlvEgJkZXhfY29ubl9pZA, applications, *, *, allow - -# Policies now based on federated_claims.user_id claim (correct) -- g, example@argoproj.io, role:example -- p, example@argoproj.io, applications, *, *, allow -``` - -If authenticating with the CLI, make sure to use the new version as well to obtain an authentication token with the -appropriate claims. - -### Removed support for legacy repo config in argocd-cm - -Before repositories were managed as Secrets, they were configured in the argocd-cm ConfigMap. The argocd-cm option has -been deprecated for some time and is no longer available in Argo CD 3.0. - -#### Detection - -To check whether you have any repositories configured in argocd-cm, run the following command: - -```shell -kubectl get cm argocd-cm -o=jsonpath="[{.data.repositories}, {.data['repository\.credentials']}, {.data['helm\.repositories']}]" -``` - -If you have no repositories configured in argocd-cm, the output will be `[, , ]`, and you are not impacted by this -change. - -#### Migration - -To convert your repositories to Secrets, follow the documentation for -[declarative management of repositories](../declarative-setup.md#repositories). - -### Ignoring ApplicationSet `applyNestedSelectors` field - -Setting the `spec.applyNestedSelectors` field in an ApplicationSet resolves counter-intuitive behavior where filters in -nested selectors were not applied. Starting in Argo CD 3.0, the field is ignored, and behavior is always the same as if -`applyNestedSelectors` was set to `true`. In other words, nested selectors are always applied. - -#### Detection - -To detect if you are impacted, search your ApplicationSet controller logs for this string: `ignoring nested selector`. -If there are no logs with this string, you are not impacted. - -Another way to detect if you are impacted is to run the following command: - -```shell -kubectl get appsets -o=json | jq -r '.items[] | select( - .spec.applyNestedSelectors != true and - .spec.generators[][].generators[][].generators[].selector != null - ) | .metadata.name' -``` - -The command will print the name of any ApplicationSet that has `applyNestedSelectors` unset or set to `false` and has -one or more nested selectors. - -#### Remediation - -Since `applyNestedSelectors` is false by default, you can safely remove the nested selectors on ApplicationSets where -`applyNestedSelectors` has not been explicitly set to `true`. After the selectors are removed, you can safely upgrade. - -For example, you should remove the selector in this ApplicationSet before upgrading to Argo CD 3.0. - -```diff -apiVersion: argoproj.io/v1alpha1 -kind: ApplicationSet -metadata: - name: guestbook -spec: - goTemplate: true - goTemplateOptions: ["missingkey=error"] - generators: - - matrix: - mergeKeys: ['test-key'] - generators: - - list: - elements: - - test-key: 'test-value' - cluster: staging - - test-key: 'test-value' - cluster: production - - merge: - generators: - - list: - elements: - - another-key: 'another-value' - - cluster: {} -- selector: -- matchLabels: -- app: guestbook - - template: - metadata: - name: '{{.cluster}}-guestbook' - spec: - project: my-project - source: - repoURL: https://github.com/infra-team/cluster-deployments.git - targetRevision: HEAD - path: guestbook/{{.cluster}} - destination: - server: '{{.url}}' - namespace: guestbook -``` - -### Upgraded Helm version with breaking changes - -Helm was upgraded to 3.17.1. -This may require changing your `values.yaml` files for subcharts, if the `values.yaml` contain a section with a `null` object. -See related issue in [Helm GitHub repository](https://github.com/helm/helm/issues/12469) -See Helm 3.17.1 [release notes](https://github.com/helm/helm/releases/tag/v3.17.1) -Example of such a [problem and resolution](https://github.com/argoproj/argo-cd/pull/22035/files) -Explanation: - -- Prior to Helm 3.17.1, `null` object in `values.yaml` resulted in a warning: `cannot overwrite table with non table` upon performing `helm template`, and the resulting K8s object was not overridden with the invalid `null` value. -- In Helm 3.17.1, this behavior changed and `null` object in `values.yaml` still results in this warning upon performing `helm template`, but the resulting K8s object will be overridden with the invalid `null` value. -- To resolve the issue, identify `values.yaml` with `null` object values, and remove those `null` values. - -### Use Annotation-Based Tracking by Default - -The default behavior for [tracking resources](../../user-guide/resource_tracking.md) has changed to use annotation-based -tracking instead of label-based tracking. Annotation-based tracking is more reliable and less prone to errors caused by -external code copying tracking labels from one resource to another. - -#### Detection - -To detect if you are impacted, check the `argocd-cm` ConfigMap for the `application.resourceTrackingMethod` field. If it -unset or is set to `label`, you are using label-based tracking. If it is set to `annotation`, you are already using -annotation-based tracking and are not impacted by this change. - -```sh -kubectl get cm argocd-cm -n argocd -o jsonpath='{.data.application\.resourceTrackingMethod}' -``` - -#### Remediation - -For most users, it is safe to upgrade to Argo CD 3.0 and use annotation-based tracking. Labels will be replaced with -annotations on the next sync. Applications will not be marked as out-of-sync if labels are not present on the -resources. - -!!! warning "Potential for orphaned resources" - - There is a known edge case when switching from label-based tracking to annotation-based tracking that may cause - resources to be orphaned. If the first sync operation after switching to annotation-based tracking includes a - resource being deleted, Argo CD will fail to recognize that the resource is managed by the Application and will not - delete it. To avoid this edge case, it is recommended to perform a sync operation on your Applications, even if - they are not out of sync, so that orphan resource detection will work as expected on the next sync. - -Some users rely on label-based tracking to track resources that are not managed by Argo CD. They may set annotations -to have Argo CD ignore the resource as extraneous or to disable pruning. If you are using label-based tracking to track -resources that are not managed by Argo CD, you will need to construct tracking annotations instead of tracking labels -and apply them to the relevant resources. The format of the tracking annotation is: - -```yaml -argocd.argoproj.io/tracking-id: :/:/ -``` - -For cluster-scoped resources, the namespace is set to the value in the Application's `spec.destination.namespace` field. - -!!! warning - - Manually constructing and applying tracking labels and annotations is not an officially supported feature, and Argo - CD's behavior may change in the future. It is recommended to manage resources with Argo CD via GitOps. - -#### Opting Out - -If you are not ready to use annotation-based tracking, you can opt out of this change by setting the -`application.resourceTrackingMethod` field in the `argocd-cm` ConfigMap to `label`. There are no current plans to remove -label-based tracking. - -## Other changes - -### Using `cluster.inClusterEnabled: "false"` - -When `cluster.inClusterEnabled: "false"` is explicitly configured, Applications currently configured to -sync on the in-cluster cluster will now be in an Unknown state, without the possibility to sync resources. - -It will not be possible to create new Applications using the in-cluster cluster. When deleting existing -Application, it will not delete the previously managed resources. - -It is recommended to perform any cleanup or migration to existing in-cluster Application before upgrading -when in-cluster is disabled. To perform cleanup post-migration, the in-cluster will need to be enabled temporarily. - -### Ignoring all status updates and high churn mutations - -Argo CD manifest now contains a default configuration for `resource.customizations.ignoreResourceUpdates` in the `argocd-cm` -to exclude common resources that are often mutated in Kubernetes. These mutations are known to cause an unnecessary -load on Argo CD. When a watched resource is modified, Argo CD will always ignore the `.status` changes. - -The default `resource.customizations.ignoreResourceUpdates` configurations can be overridden or removed in the configMap to preserve the v2 behavior. - -### Health status in the Application CR - -The health status of each object used to be persisted under `/status` in the Application CR by default. -Any health churn in the resources deployed by the Application put load on the application controller. -Now, the health status is stored externally. - -You can revert this behavior by setting the `controller.resource.health.persist` to `true` in the Argo CD -`argocd-cmd-params-cm.yaml` Config Map. - -Example of a status field in the Application CR persisting health: - -```yaml -status: - health: - status: Healthy - lastTransitionTime: '2025-01-01T00:00:00Z' - resources: - - group: apps - health: - status: Healthy - kind: Deployment - name: my-app - namespace: foo - status: OutOfSync - version: v1 - sync: - status: OutOfSync -``` - -Example of a status field in the Application CR _not_ persisting health: - -```yaml -status: - health: - status: Healthy - lastTransitionTime: '2025-01-01T00:00:00Z' - resourceHealthSource: appTree - resources: - - group: apps - kind: Deployment - name: my-app - namespace: foo - status: OutOfSync - version: v1 - sync: - status: OutOfSync -``` - -#### Detection - -1. Check the `argocd-cmd-params-cm.yaml` ConfigMap for `controller.resource.health.persist`. - - If the value is empty or true, the health status is persisted in the Application CR. - -```sh -kubectl get cm argocd-cmd-params-cm -n argocd -o jsonpath='{.data.controller\.resource\.health\.persist}' -``` - -2. Check any Application CR for the `resourceHealthSource` field. - If you see a blank value, the health status is persisted in the Application CR. - -```sh -kubectl get applications.argoproj.io -n argocd -o jsonpath='{.status.resourceHealthSource}' -``` - -#### Migration - -Any tools or CLI commands parsing the `.status.resources[].health` need to be updated to use the argocd cli/API to get the health status. - -!!! note - The application list API (argocd app list) no longer returns the individual health status of resources. - -```sh -argocd app get -o json -``` - -### Empty Environment Variables in Plugins - -In Argo CD 3.0, empty environment variables are now passed to config management plugins. - -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Application -spec: - source: - plugin: - name: example-plugin - env: - - name: VERSION - value: '1.2.3' - - name: DATA # Even though this is empty, it will be passed to the plugin as ARGOCD_ENV_DATA="". - value: '' -``` - -### Ignoring resource updates configured in `ignoreDifferences` by default - -By default, the existing system-level `ignoreDifferences` customizations will be added to ignore resource updates as well. - -Logically, if differences to a field are configured to be ignored, there is no reason to generate the diff for the application -when that field changes. - -To disable this behavior and preserve the v2 default, the `ignoreDifferencesOnResourceUpdates` can be set to false: - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: argocd-cm -data: - resource.compareoptions: | - ignoreDifferencesOnResourceUpdates: false -``` - -More details for ignored resource updates in the [Reconcile Optimization](../reconcile.md) documentation. - -### Ignoring status field from differences by default - -By default, the compare options to ignore the status field has been changed from `crd` to `all` resources. - -This means that differences won't be detected anymore for fields that are part of the status. - -If you rely on the status field being part of your desired state, the `ignoreResourceStatusField` setting can be used to preserve the v2 default. - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: argocd-cm -data: - resource.compareoptions: | - ignoreResourceStatusField: crd -``` - -### Removing default ignores of `preserveUnknownFields` for CRD - -The `spec.preserveUnknownFields` has been deprecated in favor of `x-kubernetes-preserve-unknown-fields: true` in the CRD v1. - -This means that CRD deployed with Argo CD containing `spec.preserveUnknownFields: false` will be out of sync. To address this problem, -the `preserveUnknownFields` field can be removed from the CRD spec. - -Until this is completed, if you want your Application not to be out of sync, you can add the following configuration to the Application manifest. - -```yaml -spec: - ignoreDifferences: - - group: apiextensions.k8s.io - kind: CustomResourceDefinition - jsonPointers: - - /spec/preserveUnknownFields -``` - -You can also configure it globally in the `argocd-cm` ConfigMap. - -```yaml -resource.customizations.ignoreDifferences.apiextensions.k8s.io_CustomResourceDefinition: | - jsonPointers: - - /spec/preserveUnknownFields -``` - -More details for ignored resource updates in the [Diffing customization](../../user-guide/diffing.md) documentation. \ No newline at end of file diff --git a/docs/operator-manual/upgrading/3.0-3.1.md b/docs/operator-manual/upgrading/3.0-3.1.md deleted file mode 100644 index 408f46e8e0..0000000000 --- a/docs/operator-manual/upgrading/3.0-3.1.md +++ /dev/null @@ -1,7 +0,0 @@ -# v3.0 to 3.1 - -## Symlink protection in API `--staticassets` directory - -The `--staticassets` directory in the API server (`/app/shared` by default) is now protected against out-of-bounds -symlinks. This is to help protect against symlink attacks. If you have any symlinks in your `--staticassets` directory -to a location outside the directory, they will return a 500 error starting with 3.1. diff --git a/docs/operator-manual/upgrading/overview.md b/docs/operator-manual/upgrading/overview.md index 4a6f710287..290ef05638 100644 --- a/docs/operator-manual/upgrading/overview.md +++ b/docs/operator-manual/upgrading/overview.md @@ -8,12 +8,12 @@ Argo CD uses semver-like versioning that ensures the following rules: * The patch release does not introduce any breaking changes. So if you are upgrading from v1.5.1 to v1.5.3 - there should be no special instructions to follow. + there should be no special instructions to follow. * The minor release might introduce minor changes with a workaround. If you are upgrading from v1.3.0 to v1.5.2 - please make sure to check upgrading details in both [v1.3 to v1.4](./1.3-1.4.md) and [v1.4 to v1.5](./1.4-1.5.md) - upgrading instructions. -* The major release introduces backward incompatible behavior changes. It is recommended to take a backup of - Argo CD settings using disaster recovery [guide](../disaster_recovery.md). +please make sure to check upgrading details in both [v1.3 to v1.4](./1.3-1.4.md) and [v1.4 to v1.5](./1.4-1.5.md) + upgrading instructions. + * The major release introduces backward incompatible behavior changes. It is recommended to take a backup of + Argo CD settings using disaster recovery [guide](../disaster_recovery.md). After reading the relevant notes about possible breaking changes introduced in Argo CD version use the following command to upgrade Argo CD. Make sure to replace `` with the required version number: @@ -25,7 +25,6 @@ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd//manifests/ha/install.yaml ``` @@ -38,8 +37,6 @@ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/ -* [v2.14 to v3.0](./2.14-3.0.md) -* [v2.13 to v2.14](./2.13-2.14.md) * [v2.12 to v2.13](./2.12-2.13.md) * [v2.11 to v2.12](./2.11-2.12.md) * [v2.10 to v2.11](./2.10-2.11.md) diff --git a/docs/operator-manual/user-management/google.md b/docs/operator-manual/user-management/google.md index a23becd591..366a1e9863 100644 --- a/docs/operator-manual/user-management/google.md +++ b/docs/operator-manual/user-management/google.md @@ -2,11 +2,11 @@ There are three different ways to integrate Argo CD login with your Google Workspace users. Generally the OpenID Connect (_oidc_) method would be the recommended way of doing this integration (and easier, as well...), but depending on your needs, you may choose a different option. -- [OpenID Connect using Dex](#openid-connect-using-dex) - This is the recommended login method if you don't need information about the groups the user's belongs to. Google doesn't expose the `groups` claim via _oidc_, so you won't be able to use Google Groups membership information for RBAC. -- [SAML App Auth using Dex](#saml-app-auth-using-dex) +* [OpenID Connect using Dex](#openid-connect-using-dex) + This is the recommended login method if you don't need information about the groups the user's belongs to. Google doesn't expose the `groups` claim via _oidc_, so you won't be able to use Google Groups membership information for RBAC. +* [SAML App Auth using Dex](#saml-app-auth-using-dex) Dex [recommends avoiding this method](https://dexidp.io/docs/connectors/saml/#warning). Also, you won't get Google Groups membership information through this method. -- [OpenID Connect plus Google Groups using Dex](#openid-connect-plus-google-groups-using-dex) +* [OpenID Connect plus Google Groups using Dex](#openid-connect-plus-google-groups-using-dex) This is the recommended method if you need to use Google Groups membership in your RBAC configuration. Once you've set up one of the above integrations, be sure to edit `argo-rbac-cm` to configure permissions (as in the example below). See [RBAC Configurations](../rbac.md) for more detailed scenarios. @@ -27,7 +27,7 @@ data: If you've never configured this, you'll be redirected straight to this if you try to create an OAuth Client ID -1. Go to your [OAuth Consent](https://console.cloud.google.com/apis/credentials/consent) configuration. If you still haven't created one, select `Internal` or `External` and click `Create` +1. Go to your [OAuth Consent](https://console.cloud.google.com/apis/credentials/consent) configuration. If you still haven't created one, select `Internal` or `External` and click `Create` 2. Go and [edit your OAuth consent screen](https://console.cloud.google.com/apis/credentials/consent/edit) Verify you're in the correct project! 3. Configure a name for your login app and a user support email address 4. The app logo and filling the information links is not mandatory, but it's a nice touch for the login page @@ -44,7 +44,7 @@ If you've never configured this, you'll be redirected straight to this if you tr 4. Fill "Authorized JavaScript origins" with your Argo CD URL, e.g. `https://argocd.example.com` 5. Fill "Authorized redirect URIs" with your Argo CD URL plus `/api/dex/callback`, e.g. `https://argocd.example.com/api/dex/callback` - ![](../../assets/google-admin-oidc-uris.png) + ![](../../assets/google-admin-oidc-uris.png) 6. Click "Create" and save your "Client ID" and your "Client Secret" for later @@ -75,7 +75,6 @@ data: ### Configure a new SAML App --- - !!! warning "Deprecation Warning" Note that, according to [Dex documentation](https://dexidp.io/docs/connectors/saml/#warning), SAML is considered unsafe and they are planning to deprecate that module. @@ -84,32 +83,31 @@ data: 1. In the [Google admin console](https://admin.google.com), open the left-side menu and select `Apps` > `SAML Apps` - ![Google Admin Apps Menu](../../assets/google-admin-saml-apps-menu.png 'Google Admin menu with the Apps / SAML Apps path selected') + ![Google Admin Apps Menu](../../assets/google-admin-saml-apps-menu.png "Google Admin menu with the Apps / SAML Apps path selected") 2. Under `Add App` select `Add custom SAML app` - ![Google Admin Add Custom SAML App](../../assets/google-admin-saml-add-app-menu.png 'Add apps menu with add custom SAML app highlighted') + ![Google Admin Add Custom SAML App](../../assets/google-admin-saml-add-app-menu.png "Add apps menu with add custom SAML app highlighted") 3. Enter a `Name` for the application (e.g. `Argo CD`), then choose `Continue` - ![Google Admin Apps Menu](../../assets/google-admin-saml-app-details.png 'Add apps menu with add custom SAML app highlighted') + ![Google Admin Apps Menu](../../assets/google-admin-saml-app-details.png "Add apps menu with add custom SAML app highlighted") 4. Download the metadata or copy the `SSO URL`, `Certificate`, and optionally `Entity ID` from the identity provider details for use in the next section. Choose `continue`. + - Base64 encode the contents of the certificate file, for example: + - `$ cat ArgoCD.cer | base64` + - *Keep a copy of the encoded output to be used in the next section.* + - *Ensure that the certificate is in PEM format before base64 encoding* - - Base64 encode the contents of the certificate file, for example: - - `$ cat ArgoCD.cer | base64` - - _Keep a copy of the encoded output to be used in the next section._ - - _Ensure that the certificate is in PEM format before base64 encoding_ - - ![Google Admin IdP Metadata](../../assets/google-admin-idp-metadata.png 'A screenshot of the Google IdP metadata') + ![Google Admin IdP Metadata](../../assets/google-admin-idp-metadata.png "A screenshot of the Google IdP metadata") 5. For both the `ACS URL` and `Entity ID`, use your Argo Dex Callback URL, for example: `https://argocd.example.com/api/dex/callback` - ![Google Admin Service Provider Details](../../assets/google-admin-service-provider-details.png 'A screenshot of the Google Service Provider Details') + ![Google Admin Service Provider Details](../../assets/google-admin-service-provider-details.png "A screenshot of the Google Service Provider Details") 6. Add SAML Attribute Mapping, Map `Primary email` to `name` and `Primary Email` to `email`. and click `ADD MAPPING` button. - ![Google Admin SAML Attribute Mapping Details](../../assets/google-admin-saml-attribute-mapping-details.png 'A screenshot of the Google Admin SAML Attribute Mapping Details') + ![Google Admin SAML Attribute Mapping Details](../../assets/google-admin-saml-attribute-mapping-details.png "A screenshot of the Google Admin SAML Attribute Mapping Details") 7. Finish creating the application. @@ -148,9 +146,9 @@ We're going to use Dex's `google` connector to get additional Google Groups info This connector uses two different credentials: -- An oidc client ID and secret +- An oidc client ID and secret Same as when you're configuring an [OpenID connection](#openid-connect-using-dex), this authenticates your users -- A Google service account +- A Google service account This is used to connect to the Google Directory API and pull information about your user's group membership Also, you'll need the email address for an admin user on this domain. Dex will impersonate that user identity to fetch user information from the API. @@ -159,96 +157,81 @@ Also, you'll need the email address for an admin user on this domain. Dex will i Go through the same steps as in [OpenID Connect using Dex](#openid-connect-using-dex), except for configuring `argocd-cm`. We'll do that later. -### Set up Directory API access +### Set up Directory API access 1. Follow [Google instructions to create a service account with Domain-Wide Delegation](https://developers.google.com/admin-sdk/directory/v1/guides/delegation) - - When assigning API scopes to the service account assign **only** the `https://www.googleapis.com/auth/admin.directory.group.readonly` scope and nothing else. If you assign any other scopes, you won't be able to fetch information from the API - - Create the credentials in JSON format and store them in a safe place, we'll need them later + - When assigning API scopes to the service account assign **only** the `https://www.googleapis.com/auth/admin.directory.group.readonly` scope and nothing else. If you assign any other scopes, you won't be able to fetch information from the API + - Create the credentials in JSON format and store them in a safe place, we'll need them later 2. Enable the [Admin SDK](https://console.developers.google.com/apis/library/admin.googleapis.com/) ### Configure Dex 1. Create a secret with the contents of the previous json file encoded in base64, like this: - ```yaml - apiVersion: v1 - kind: Secret - metadata: - name: argocd-google-groups-json - namespace: argocd - data: - googleAuth.json: JSON_FILE_BASE64_ENCODED - ``` + apiVersion: v1 + kind: Secret + metadata: + name: argocd-google-groups-json + namespace: argocd + data: + googleAuth.json: JSON_FILE_BASE64_ENCODED -2. Edit your `argocd-dex-server` deployment to mount that secret as a file +2. Edit your `argocd-dex-server` deployment to mount that secret as a file + - Add a volume mount in `/spec/template/spec/containers/0/volumeMounts/` like this. Be aware of editing the running container and not the init container! - - Add a volume mount in `/spec/template/spec/containers/0/volumeMounts/` like this. Be aware of editing the running container and not the init container! + volumeMounts: + - mountPath: /shared + name: static-files + - mountPath: /tmp + name: dexconfig + - mountPath: /tmp/oidc + name: google-json + readOnly: true - ```yaml - volumeMounts: - - mountPath: /shared - name: static-files - - mountPath: /tmp - name: dexconfig - - mountPath: /tmp/oidc - name: google-json - readOnly: true - ``` + - Add a volume in `/spec/template/spec/volumes/` like this: - - Add a volume in `/spec/template/spec/volumes/` like this: + volumes: + - emptyDir: {} + name: static-files + - emptyDir: {} + name: dexconfig + - name: google-json + secret: + defaultMode: 420 + secretName: argocd-google-groups-json - ```yaml - volumes: - - emptyDir: {} - name: static-files - - emptyDir: {} - name: dexconfig - - name: google-json - secret: - defaultMode: 420 - secretName: argocd-google-groups-json - ``` +3. Edit `argocd-cm` and add the following `dex.config` to the data section, replacing `clientID` and `clientSecret` with the values you saved before, `adminEmail` with the address for the admin user you're going to impersonate, and editing `redirectURI` with your Argo CD domain (note that the `type` is now `google` instead of `oidc`): -3. Edit `argocd-cm` and add the following `url` and `dex.config` to the data section, replacing `clientID` and `clientSecret` with the values you saved before, `adminEmail` with the address for the admin user you're going to impersonate, and editing `redirectURI` with your Argo CD domain (note that the `type` is now `google` instead of `oidc`): - - ```yaml - data: - url: https://argocd.example.com - dex.config: | - connectors: - - config: - redirectURI: https://argocd.example.com/api/dex/callback - clientID: XXXXXXXXXXXXX.apps.googleusercontent.com - clientSecret: XXXXXXXXXXXXX - serviceAccountFilePath: /tmp/oidc/googleAuth.json - adminEmail: admin-email@example.com - type: google - id: google - name: Google - ``` + dex.config: | + connectors: + - config: + redirectURI: https://argocd.example.com/api/dex/callback + clientID: XXXXXXXXXXXXX.apps.googleusercontent.com + clientSecret: XXXXXXXXXXXXX + serviceAccountFilePath: /tmp/oidc/googleAuth.json + adminEmail: admin-email@example.com + type: google + id: google + name: Google 4. Restart your `argocd-dex-server` deployment to be sure it's using the latest configuration -5. Login to Argo CD and go to the "User info" section, were you should see the groups you're member - ![User info](../../assets/google-groups-membership.png) +5. Login to Argo CD and go to the "User info" section, were you should see the groups you're member + ![User info](../../assets/google-groups-membership.png) 6. Now you can use groups email addresses to give RBAC permissions -7. Dex (> v2.31.0) can also be configured in the `argocd-cm` to fetch transitive group membership as follows: +7. Dex (> v2.31.0) can also be configure to fetch transitive group membership as follows: - ```yaml - data: - url: https://argocd.example.com - dex.config: | - connectors: - - config: - redirectURI: https://argocd.example.com/api/dex/callback - clientID: XXXXXXXXXXXXX.apps.googleusercontent.com - clientSecret: XXXXXXXXXXXXX - serviceAccountFilePath: /tmp/oidc/googleAuth.json - adminEmail: admin-email@example.com - fetchTransitiveGroupMembership: True - type: google - id: google - name: Google - ``` + dex.config: | + connectors: + - config: + redirectURI: https://argocd.example.com/api/dex/callback + clientID: XXXXXXXXXXXXX.apps.googleusercontent.com + clientSecret: XXXXXXXXXXXXX + serviceAccountFilePath: /tmp/oidc/googleAuth.json + adminEmail: admin-email@example.com + fetchTransitiveGroupMembership: True + type: google + id: google + name: Google ### References diff --git a/docs/operator-manual/user-management/identity-center.md b/docs/operator-manual/user-management/identity-center.md index 62d381aec7..c4019964d7 100644 --- a/docs/operator-manual/user-management/identity-center.md +++ b/docs/operator-manual/user-management/identity-center.md @@ -10,15 +10,10 @@ A working Single Sign-On configuration using Identity Center (AWS SSO) has been ## SAML (with Dex) 1. Create a new SAML application in Identity Center and download the certificate. - -![Identity Center SAML App 1](../../assets/identity-center-1.png) - -![Identity Center SAML App 2](../../assets/identity-center-2.png) - + * ![Identity Center SAML App 1](../../assets/identity-center-1.png) + * ![Identity Center SAML App 2](../../assets/identity-center-2.png) 2. Click `Assign Users` after creating the application in Identity Center, and select the users or user groups you wish to grant access to this application. - -![Identity Center SAML App 3](../../assets/identity-center-3.png) - + * ![Identity Center SAML App 3](../../assets/identity-center-3.png) 3. Copy the Argo CD URL into the `data.url` field in the `argocd-cm` ConfigMap. data: @@ -29,20 +24,15 @@ A working Single Sign-On configuration using Identity Center (AWS SSO) has been !!! note "Group attribute mapping is not officially!" Group attribute mapping is not officially supported in the AWS docs, however the workaround is currently working. -![Identity Center SAML App 4](../../assets/identity-center-4.png) - -![Identity Center SAML App 5](../../assets/identity-center-5.png) + * ![Identity Center SAML App 4](../../assets/identity-center-4.png) + * ![Identity Center SAML App 5](../../assets/identity-center-5.png) 5. Download the CA certificate to use in the `argocd-cm` configuration. - * If using the `caData` field, you'll need to base64-encode the entire certificate, including the `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` stanzas (e.g., `base64 my_cert.pem`). - * If using the `ca` field and storing the CA certificate separately as a secret, you will need to mount the secret onto the `dex` container in the `argocd-dex-server` Deployment. - -![Identity Center SAML App 6](../../assets/identity-center-6.png) - + * ![Identity Center SAML App 6](../../assets/identity-center-6.png) 6. Edit the `argocd-cm` and configure the `data.dex.config` section: @@ -70,7 +60,6 @@ dex.config: | ### Connect Identity Center Groups to Argo CD Roles - Argo CD recognizes user memberships in Identity Center groups that match the **Group Attribute Statements** regex. In the example above, the regex `argocd-*` is used, making Argo CD aware of a group named `argocd-admins`. diff --git a/docs/operator-manual/user-management/microsoft.md b/docs/operator-manual/user-management/microsoft.md index ac431bdc78..72a3a3ce77 100644 --- a/docs/operator-manual/user-management/microsoft.md +++ b/docs/operator-manual/user-management/microsoft.md @@ -3,127 +3,10 @@ !!! note "" Entra ID was formerly known as Azure AD. -* [Entra ID App Registration Auth using OIDC](#entra-id-app-registration-auth-using-oidc) * [Entra ID SAML Enterprise App Auth using Dex](#entra-id-saml-enterprise-app-auth-using-dex) +* [Entra ID App Registration Auth using OIDC](#entra-id-app-registration-auth-using-oidc) * [Entra ID App Registration Auth using Dex](#entra-id-app-registration-auth-using-dex) -## Entra ID App Registration Auth using OIDC -### Configure a new Entra ID App registration -#### Add a new Entra ID App registration - -1. From the `Microsoft Entra ID` > `App registrations` menu, choose `+ New registration` -2. Enter a `Name` for the application (e.g. `Argo CD`). -3. Specify who can use the application (e.g. `Accounts in this organizational directory only`). -4. Enter Redirect URI (optional) as follows (replacing `my-argo-cd-url` with your Argo URL), then choose `Add`. - - **Platform:** `Web` - - **Redirect URI:** https://``/auth/callback -5. When registration finishes, the Azure portal displays the app registration's Overview pane. You see the Application (client) ID. - ![Azure App registration's Overview](../../assets/azure-app-registration-overview.png "Azure App registration's Overview") - -#### Configure additional platform settings for ArgoCD CLI - -1. In the Azure portal, in App registrations, select your application. -2. Under Manage, select Authentication. -3. Under Platform configurations, select Add a platform. -4. Under Configure platforms, select the "Mobile and desktop applications" tile. Use the below value. You shouldn't change it. - - **Redirect URI:** `http://localhost:8085/auth/callback` - ![Azure App registration's Authentication](../../assets/azure-app-registration-authentication.png "Azure App registration's Authentication") - -#### Add credentials a new Entra ID App registration -##### Using Workload Identity Federation (Recommended) -1. **Label the Pods:** Add the `azure.workload.identity/use: "true"` label to the `argocd-server` pods. -2. **Add Annotation to Service Account:** Add `azure.workload.identity/client-id: "$CLIENT_ID"` annotation to the `argocd-server` service account using the details from application created in previous step. -3. From the `Certificates & secrets` menu, navigate to `Federated credentials`, then choose `+ Add credential` -4. Choose `Federated credential scenario` as `Kubernetes Accessing Azure resources` - - Enter Cluster Issuer URL, refer to [retrieve the OIDC issuer URL](https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster#retrieve-the-oidc-issuer-url) documentation - - Enter namespace as the namespace where the argocd is deployed - - Enter service account name as `argocd-server` - - Enter a unique name - - Click Add. - -##### Using Client Secret -1. From the `Certificates & secrets` menu, choose `+ New client secret` -2. Enter a `Name` for the secret (e.g. `ArgoCD-SSO`). - - Make sure to copy and save generated value. This is a value for the `client_secret`. - ![Azure App registration's Secret](../../assets/azure-app-registration-secret.png "Azure App registration's Secret") - -#### Setup permissions for Entra ID Application - -1. From the `API permissions` menu, choose `+ Add a permission` -2. Find `User.Read` permission (under `Microsoft Graph`) and grant it to the created application: - ![Entra ID API permissions](../../assets/azure-api-permissions.png "Entra ID API permissions") -3. From the `Token Configuration` menu, choose `+ Add groups claim` - ![Entra ID token configuration](../../assets/azure-token-configuration.png "Entra ID token configuration") - -### Associate an Entra ID group to your Entra ID App registration - -1. From the `Microsoft Entra ID` > `Enterprise applications` menu, search the App that you created (e.g. `Argo CD`). - - An Enterprise application with the same name of the Entra ID App registration is created when you add a new Entra ID App registration. -2. From the `Users and groups` menu of the app, add any users or groups requiring access to the service. - ![Azure Enterprise SAML Users](../../assets/azure-enterprise-users.png "Azure Enterprise SAML Users") - -### Configure Argo to use the new Entra ID App registration - -1. Edit `argocd-cm` and configure the `data.oidc.config` and `data.url` section: - - ConfigMap -> argocd-cm - - data: - url: https://argocd.example.com/ # Replace with the external base URL of your Argo CD - oidc.config: | - name: Azure - issuer: https://login.microsoftonline.com/{directory_tenant_id}/v2.0 - clientID: {azure_ad_application_client_id} - clientSecret: $oidc.azure.clientSecret // if using client secret for authentication - azure: - useWorkloadIdentity: true // if using azure workload identity for authentication - requestedIDTokenClaims: - groups: - essential: true - value: "SecurityGroup" - requestedScopes: - - openid - - profile - - email - -2. Skip this step if using azure workload identity. Edit `argocd-secret` and configure the `data.oidc.azure.clientSecret` section: - - Secret -> argocd-secret - - data: - oidc.azure.clientSecret: {client_secret | base64_encoded} - -3. Edit `argocd-rbac-cm` to configure permissions. Use group ID from Azure for assigning roles - [RBAC Configurations](../rbac.md) - - ConfigMap -> argocd-rbac-cm - - policy.default: role:readonly - policy.csv: | - p, role:org-admin, applications, *, */*, allow - p, role:org-admin, clusters, get, *, allow - p, role:org-admin, repositories, get, *, allow - p, role:org-admin, repositories, create, *, allow - p, role:org-admin, repositories, update, *, allow - p, role:org-admin, repositories, delete, *, allow - g, "84ce98d1-e359-4f3b-85af-985b458de3c6", role:org-admin - -4. Mapping role from jwt token to argo. - If you want to map the roles from the jwt token to match the default roles (readonly and admin) then you must change the scope variable in the rbac-configmap. - - policy.default: role:readonly - policy.csv: | - p, role:org-admin, applications, *, */*, allow - p, role:org-admin, clusters, get, *, allow - p, role:org-admin, repositories, get, *, allow - p, role:org-admin, repositories, create, *, allow - p, role:org-admin, repositories, update, *, allow - p, role:org-admin, repositories, delete, *, allow - g, "84ce98d1-e359-4f3b-85af-985b458de3c6", role:org-admin - scopes: '[groups, email]' - - Refer to [operator-manual/argocd-rbac-cm.yaml](https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-rbac-cm.yaml) for all of the available variables. - ## Entra ID SAML Enterprise App Auth using Dex ### Configure a new Entra ID Enterprise App @@ -190,6 +73,110 @@ p, role:org-admin, repositories, delete, *, allow g, "84ce98d1-e359-4f3b-85af-985b458de3c6", role:org-admin # (azure group assigned to role) +## Entra ID App Registration Auth using OIDC +### Configure a new Entra ID App registration +#### Add a new Entra ID App registration + +1. From the `Microsoft Entra ID` > `App registrations` menu, choose `+ New registration` +2. Enter a `Name` for the application (e.g. `Argo CD`). +3. Specify who can use the application (e.g. `Accounts in this organizational directory only`). +4. Enter Redirect URI (optional) as follows (replacing `my-argo-cd-url` with your Argo URL), then choose `Add`. + - **Platform:** `Web` + - **Redirect URI:** https://``/auth/callback +5. When registration finishes, the Azure portal displays the app registration's Overview pane. You see the Application (client) ID. + ![Azure App registration's Overview](../../assets/azure-app-registration-overview.png "Azure App registration's Overview") + +#### Configure additional platform settings for ArgoCD CLI + +1. In the Azure portal, in App registrations, select your application. +2. Under Manage, select Authentication. +3. Under Platform configurations, select Add a platform. +4. Under Configure platforms, select the "Mobile and desktop applications" tile. Use the below value. You shouldn't change it. + - **Redirect URI:** `http://localhost:8085/auth/callback` + ![Azure App registration's Authentication](../../assets/azure-app-registration-authentication.png "Azure App registration's Authentication") + +#### Add credentials a new Entra ID App registration + +1. From the `Certificates & secrets` menu, choose `+ New client secret` +2. Enter a `Name` for the secret (e.g. `ArgoCD-SSO`). + - Make sure to copy and save generated value. This is a value for the `client_secret`. + ![Azure App registration's Secret](../../assets/azure-app-registration-secret.png "Azure App registration's Secret") + +#### Setup permissions for Entra ID Application + +1. From the `API permissions` menu, choose `+ Add a permission` +2. Find `User.Read` permission (under `Microsoft Graph`) and grant it to the created application: + ![Entra ID API permissions](../../assets/azure-api-permissions.png "Entra ID API permissions") +3. From the `Token Configuration` menu, choose `+ Add groups claim` + ![Entra ID token configuration](../../assets/azure-token-configuration.png "Entra ID token configuration") + +### Associate an Entra ID group to your Entra ID App registration + +1. From the `Microsoft Entra ID` > `Enterprise applications` menu, search the App that you created (e.g. `Argo CD`). + - An Enterprise application with the same name of the Entra ID App registration is created when you add a new Entra ID App registration. +2. From the `Users and groups` menu of the app, add any users or groups requiring access to the service. + ![Azure Enterprise SAML Users](../../assets/azure-enterprise-users.png "Azure Enterprise SAML Users") + +### Configure Argo to use the new Entra ID App registration + +1. Edit `argocd-cm` and configure the `data.oidc.config` and `data.url` section: + + ConfigMap -> argocd-cm + + data: + url: https://argocd.example.com/ # Replace with the external base URL of your Argo CD + oidc.config: | + name: Azure + issuer: https://login.microsoftonline.com/{directory_tenant_id}/v2.0 + clientID: {azure_ad_application_client_id} + clientSecret: $oidc.azure.clientSecret + requestedIDTokenClaims: + groups: + essential: true + value: "SecurityGroup" + requestedScopes: + - openid + - profile + - email + +2. Edit `argocd-secret` and configure the `data.oidc.azure.clientSecret` section: + + Secret -> argocd-secret + + data: + oidc.azure.clientSecret: {client_secret | base64_encoded} + +3. Edit `argocd-rbac-cm` to configure permissions. Use group ID from Azure for assigning roles + [RBAC Configurations](../rbac.md) + + ConfigMap -> argocd-rbac-cm + + policy.default: role:readonly + policy.csv: | + p, role:org-admin, applications, *, */*, allow + p, role:org-admin, clusters, get, *, allow + p, role:org-admin, repositories, get, *, allow + p, role:org-admin, repositories, create, *, allow + p, role:org-admin, repositories, update, *, allow + p, role:org-admin, repositories, delete, *, allow + g, "84ce98d1-e359-4f3b-85af-985b458de3c6", role:org-admin + +4. Mapping role from jwt token to argo. + If you want to map the roles from the jwt token to match the default roles (readonly and admin) then you must change the scope variable in the rbac-configmap. + + policy.default: role:readonly + policy.csv: | + p, role:org-admin, applications, *, */*, allow + p, role:org-admin, clusters, get, *, allow + p, role:org-admin, repositories, get, *, allow + p, role:org-admin, repositories, create, *, allow + p, role:org-admin, repositories, update, *, allow + p, role:org-admin, repositories, delete, *, allow + g, "84ce98d1-e359-4f3b-85af-985b458de3c6", role:org-admin + scopes: '[groups, email]' + + Refer to [operator-manual/argocd-rbac-cm.yaml](https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-rbac-cm.yaml) for all of the available variables. + ## Entra ID App Registration Auth using Dex Configure a new AD App Registration, as above. diff --git a/docs/operator-manual/webhook.md b/docs/operator-manual/webhook.md index d042fc7be9..f57918583e 100644 --- a/docs/operator-manual/webhook.md +++ b/docs/operator-manual/webhook.md @@ -109,17 +109,3 @@ Syntax: `$:` > NOTE: Secret must have label `app.kubernetes.io/part-of: argocd` For more information refer to the corresponding section in the [User Management Documentation](user-management/index.md#alternative). - -## Special handling for BitBucket Cloud -BitBucket does not include the list of changed files in the webhook request body. -This prevents the [Manifest Paths Annotation](high_availability.md#manifest-paths-annotation) feature from working with repositories hosted on BitBucket Cloud. -BitBucket provides the `diffstat` API to determine the list of changed files between two commits. -To address the missing changed files list in the webhook, the Argo CD webhook handler makes an API callback to the originating server. -To prevent Server-side request forgery (SSRF) attacks, Argo CD server supports the callback mechanism only for encrypted webhook requests. -The incoming webhook must include `X-Hook-UUID` request header. The corresponding UUID must be provided as `webhook.bitbucket.uuid` in `argocd-secret` for verification. -The callback mechanism supports both public and private repositories on BitBucket Cloud. -For public repositories, the Argo CD webhook handler uses a no-auth client for the API callback. -For private repositories, the Argo CD webhook handler searches for a valid repository OAuth token for the HTTP/HTTPS URL. -The webhook handler uses this OAuth token to make the API request to the originating server. -If the Argo CD webhook handler cannot find a matching repository credential, the list of changed files would remain empty. -If errors occur during the callback, the list of changed files will be empty. \ No newline at end of file diff --git a/docs/proposals/argocd-cli-pluin.md b/docs/proposals/argocd-cli-pluin.md deleted file mode 100644 index 4f38f22388..0000000000 --- a/docs/proposals/argocd-cli-pluin.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Argo CD CLI Plugin -authors: - - "@christianh814" - - "@alexmt" - - "@nitishfy" - -sponsors: - - TBD -reviewers: - - TBD -approvers: - - TBD - -creation-date: 2024-08-21 ---- - -# Argo CD CLI Plugin Support - -Support for `kubectl`-like plugins for the `argocd` CLI. - -## Summary - -Enhance the Argo CD `argocd` CLI client to support the ability to provide other CLI tools as "plugins" in a similar way that the Kubernetes `kubectl` CLI client provides. This will shift `argocd` to be more of a "building block" or "interface" for interacting with Argo CD and plugins can be a means to develop more complex workflows while leaving the baseline argocd use-case small. - -## Motivation - -Currently, the `argocd` CLI client is-getting/already-is pretty bloated. The solution has either been written-in the support for certain solutions (like ApplicationSets) or having a separate CLI tool in Argo Project Labs (like [Autopilot](https://github.com/argoproj-labs/argocd-autopilot) and [Vault Plugin](https://github.com/argoproj-labs/argocd-vault-plugin)). - -Having a plugin system makes sense, as we add more and more features down the line (OCI, Hydrator, GitOps Promoter, etc). In this way, we can keep the `argocd` CLI "lean" but also extensible and keep things "out of tree". As mentioned before, other tools that can benefit from this besides the Argo CD OCI cli is a tool like `argocd-autopilot`. Also, there is a potential for other Argo Project tools to have plugins, like a Rollouts plugin or an `argocd-image-updater` plugin for Argo CD. - -The idea initially came up during a discussion about [adding CLI support for the upcoming OCI integration](https://cloud-native.slack.com/archives/C06Q17QJPJR/p1721227926706059?thread_ts=1720731234.357799&cid=C06Q17QJPJR). - -## Goals - -The goal is to provide a plugin mechanism without changing the current behavior of `argocd`'s subcommands and options. - -## Non Goals - -Make any guarantees for any public `argocd` plugins provided by any third party. - -## Proposal - -Similarly to how `kubectl` plugins are handled, The `argocd` CLI tool will look in the end user's `$PATH` for any binaries that start with `argocd-` and execute that binary. For example if I had a binary called `argocd-mytool` in my `$PATH`, I could call it by running `argocd mytool`. Support for tab completion should also be taken into account. - -## Outstanding Questions - -Things to consider: - -* Should it act exactly like `kubectl` and just look in `$PATH` or be more stringent and have users store plugins in `~/.config/argocd/plugins`? Similar to [Tekton plugins](https://tekton.dev/vault/cli-main/tkn-plugins/#location) -* Is there a way to integrate this with [Krew](https://krew.sigs.k8s.io/) for installing plugins? -* Should we let each plugin manage its own configuration settings or make plugins use `~/.config/argocd/config` and provide a new field called `.pluginConfigs`? For example the `argocd-mytool` plugin's config will be under `.pluginConfigs.mytool` Should we even care/have an opinion? -* Should we provide any guidelines to submit a plugin? Do we only "accept" plugins that are in argoproj-labs? - diff --git a/docs/requirements.txt b/docs/requirements.txt index ff7dc98ae0..ad1dcf32ff 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -3,7 +3,7 @@ mkdocs==1.6.1 # Thus pointing to the older version of mkdocs-material. mkdocs-material==7.1.8 markdown_include==0.8.1 -pygments==2.19.1 -jinja2==3.1.6 -markdown==3.8 -pymdown-extensions==10.15 \ No newline at end of file +pygments==2.18.0 +jinja2==3.1.4 +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 8a004c4832..586bbaf6a7 100644 --- a/docs/snyk/index.md +++ b/docs/snyk/index.md @@ -14,53 +14,52 @@ recent minor releases. | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| | [go.mod](master/argocd-test.html) | 0 | 0 | 6 | 0 | -| [ui/yarn.lock](master/argocd-test.html) | 0 | 1 | 1 | 2 | -| [dex:v2.41.1](master/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 5 | -| [haproxy:3.0.8-alpine](master/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html) | 0 | 0 | 0 | 0 | -| [redis:7.2.7-alpine](master/public.ecr.aws_docker_library_redis_7.2.7-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 4 | 8 | -| [redis:7.2.7-alpine](master/redis_7.2.7-alpine.html) | 0 | 0 | 0 | 0 | +| [ui/yarn.lock](master/argocd-test.html) | 0 | 0 | 1 | 0 | +| [dex:v2.41.1](master/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 2 | +| [haproxy:2.6.17-alpine](master/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 4 | +| [redis:7.0.15-alpine](master/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 3 | 10 | +| [redis:7.0.15-alpine](master/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | | [install.yaml](master/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](master/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.14.5 +### v2.13.2 | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.14.5/argocd-test.html) | 0 | 4 | 9 | 0 | -| [ui/yarn.lock](v2.14.5/argocd-test.html) | 0 | 1 | 1 | 2 | -| [dex:v2.41.1](v2.14.5/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 5 | -| [haproxy:2.6.17-alpine](v2.14.5/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 7 | -| [redis:7.0.15-alpine](v2.14.5/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 4 | -| [argocd:v2.14.5](v2.14.5/quay.io_argoproj_argocd_v2.14.5.html) | 0 | 0 | 4 | 8 | -| [redis:7.0.15-alpine](v2.14.5/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 4 | -| [install.yaml](v2.14.5/argocd-iac-install.html) | - | - | - | - | -| [namespace-install.yaml](v2.14.5/argocd-iac-namespace-install.html) | - | - | - | - | +| [go.mod](v2.13.2/argocd-test.html) | 1 | 0 | 7 | 2 | +| [ui/yarn.lock](v2.13.2/argocd-test.html) | 0 | 0 | 1 | 0 | +| [dex:v2.41.1](v2.13.2/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 2 | +| [haproxy:2.6.17-alpine](v2.13.2/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 4 | +| [redis:7.0.15-alpine](v2.13.2/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:v2.13.2](v2.13.2/quay.io_argoproj_argocd_v2.13.2.html) | 0 | 0 | 3 | 10 | +| [redis:7.0.15-alpine](v2.13.2/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [install.yaml](v2.13.2/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.13.2/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.13.5 +### v2.12.8 | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.13.5/argocd-test.html) | 0 | 3 | 9 | 2 | -| [ui/yarn.lock](v2.13.5/argocd-test.html) | 0 | 1 | 1 | 2 | -| [dex:v2.41.1](v2.13.5/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 5 | -| [haproxy:2.6.17-alpine](v2.13.5/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 7 | -| [redis:7.0.15-alpine](v2.13.5/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 4 | -| [argocd:v2.13.5](v2.13.5/quay.io_argoproj_argocd_v2.13.5.html) | 0 | 0 | 12 | 12 | -| [redis:7.0.15-alpine](v2.13.5/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 4 | -| [install.yaml](v2.13.5/argocd-iac-install.html) | - | - | - | - | -| [namespace-install.yaml](v2.13.5/argocd-iac-namespace-install.html) | - | - | - | - | +| [go.mod](v2.12.8/argocd-test.html) | 1 | 0 | 8 | 2 | +| [ui/yarn.lock](v2.12.8/argocd-test.html) | 0 | 0 | 1 | 0 | +| [dex:v2.38.0](v2.12.8/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 7 | +| [haproxy:2.6.17-alpine](v2.12.8/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 4 | +| [redis:7.0.15-alpine](v2.12.8/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:v2.12.8](v2.12.8/quay.io_argoproj_argocd_v2.12.8.html) | 0 | 0 | 3 | 10 | +| [redis:7.0.15-alpine](v2.12.8/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [install.yaml](v2.12.8/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.12.8/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.12.10 +### v2.11.12 | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.12.10/argocd-test.html) | 0 | 2 | 9 | 2 | -| [ui/yarn.lock](v2.12.10/argocd-test.html) | 0 | 1 | 1 | 2 | -| [dex:v2.38.0](v2.12.10/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 9 | -| [haproxy:2.6.17-alpine](v2.12.10/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 7 | -| [redis:7.0.15-alpine](v2.12.10/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 4 | -| [argocd:v2.12.10](v2.12.10/quay.io_argoproj_argocd_v2.12.10.html) | 0 | 0 | 13 | 12 | -| [redis:7.0.15-alpine](v2.12.10/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 4 | -| [install.yaml](v2.12.10/argocd-iac-install.html) | - | - | - | - | -| [namespace-install.yaml](v2.12.10/argocd-iac-namespace-install.html) | - | - | - | - | +| [go.mod](v2.11.12/argocd-test.html) | 1 | 2 | 9 | 2 | +| [ui/yarn.lock](v2.11.12/argocd-test.html) | 0 | 0 | 1 | 0 | +| [dex:v2.38.0](v2.11.12/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 7 | +| [haproxy:2.6.14-alpine](v2.11.12/haproxy_2.6.14-alpine.html) | 0 | 1 | 7 | 7 | +| [argocd:v2.11.12](v2.11.12/quay.io_argoproj_argocd_v2.11.12.html) | 0 | 0 | 4 | 20 | +| [redis:7.0.15-alpine](v2.11.12/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [install.yaml](v2.11.12/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.11.12/argocd-iac-namespace-install.html) | - | - | - | - | diff --git a/docs/snyk/master/argocd-iac-install.html b/docs/snyk/master/argocd-iac-install.html index 700f094e1e..5c580258ab 100644 --- a/docs/snyk/master/argocd-iac-install.html +++ b/docs/snyk/master/argocd-iac-install.html @@ -456,7 +456,7 @@

Snyk test report

-

March 16th 2025, 12:23:13 am (UTC+00:00)

+

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

Scanned the following path: @@ -507,7 +507,7 @@
  • - Line number: 24296 + Line number: 22859
  • @@ -553,7 +553,7 @@
  • - Line number: 23976 + Line number: 22540
  • @@ -599,7 +599,7 @@
  • - Line number: 24064 + Line number: 22627
  • @@ -645,7 +645,7 @@
  • - Line number: 24092 + Line number: 22655
  • @@ -691,7 +691,7 @@
  • - Line number: 24122 + Line number: 22685
  • @@ -737,7 +737,7 @@
  • - Line number: 24140 + Line number: 22703
  • @@ -783,7 +783,7 @@
  • - Line number: 24158 + Line number: 22721
  • @@ -829,7 +829,7 @@
  • - Line number: 24180 + Line number: 22743
  • @@ -881,7 +881,7 @@
  • - Line number: 25386 + Line number: 23833
  • @@ -933,7 +933,7 @@
  • - Line number: 25705 + Line number: 24140
  • @@ -991,7 +991,7 @@
  • - Line number: 24887 + Line number: 23352
  • @@ -1049,7 +1049,7 @@
  • - Line number: 25182 + Line number: 23635
  • @@ -1107,7 +1107,7 @@
  • - Line number: 25130 + Line number: 23589
  • @@ -1165,7 +1165,7 @@
  • - Line number: 25244 + Line number: 23697
  • @@ -1223,7 +1223,7 @@
  • - Line number: 25357 + Line number: 23804
  • @@ -1281,7 +1281,7 @@
  • - Line number: 25381 + Line number: 23828
  • @@ -1339,7 +1339,7 @@
  • - Line number: 25705 + Line number: 24140
  • @@ -1397,7 +1397,7 @@
  • - Line number: 25440 + Line number: 23887
  • @@ -1455,7 +1455,7 @@
  • - Line number: 25792 + Line number: 24227
  • @@ -1513,7 +1513,7 @@
  • - Line number: 26202 + Line number: 24619
  • @@ -1565,7 +1565,7 @@
  • - Line number: 25162 + Line number: 23615
  • @@ -1617,7 +1617,7 @@
  • - Line number: 24887 + Line number: 23352
  • @@ -1669,7 +1669,7 @@
  • - Line number: 25130 + Line number: 23589
  • @@ -1721,7 +1721,7 @@
  • - Line number: 25357 + Line number: 23804
  • @@ -1779,7 +1779,7 @@
  • - Line number: 24887 + Line number: 23352
  • @@ -1837,7 +1837,7 @@
  • - Line number: 25130 + Line number: 23589
  • @@ -1895,7 +1895,7 @@
  • - Line number: 25182 + Line number: 23635
  • @@ -1953,7 +1953,7 @@
  • - Line number: 25244 + Line number: 23697
  • @@ -2011,7 +2011,7 @@
  • - Line number: 25357 + Line number: 23804
  • @@ -2069,7 +2069,7 @@
  • - Line number: 25381 + Line number: 23828
  • @@ -2127,7 +2127,7 @@
  • - Line number: 25705 + Line number: 24140
  • @@ -2185,7 +2185,7 @@
  • - Line number: 25440 + Line number: 23887
  • @@ -2243,7 +2243,7 @@
  • - Line number: 25792 + Line number: 24227
  • @@ -2301,7 +2301,7 @@
  • - Line number: 26202 + Line number: 24619
  • @@ -2357,7 +2357,7 @@
  • - Line number: 25052 + Line number: 23511
  • @@ -2413,7 +2413,7 @@
  • - Line number: 25190 + Line number: 23643
  • @@ -2469,7 +2469,7 @@
  • - Line number: 25165 + Line number: 23618
  • @@ -2525,7 +2525,7 @@
  • - Line number: 25289 + Line number: 23736
  • @@ -2581,7 +2581,7 @@
  • - Line number: 25374 + Line number: 23821
  • @@ -2637,7 +2637,7 @@
  • - Line number: 25388 + Line number: 23835
  • @@ -2693,7 +2693,7 @@
  • - Line number: 25712 + Line number: 24147
  • @@ -2749,7 +2749,7 @@
  • - Line number: 25678 + Line number: 24113
  • @@ -2805,7 +2805,7 @@
  • - Line number: 26101 + Line number: 24518
  • @@ -2861,7 +2861,7 @@
  • - Line number: 26459 + Line number: 24846
  • diff --git a/docs/snyk/master/argocd-iac-namespace-install.html b/docs/snyk/master/argocd-iac-namespace-install.html index a6370f91f4..acfee91c34 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

    -

    March 16th 2025, 12:23:24 am (UTC+00:00)

    +

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

    Scanned the following path: @@ -553,7 +553,7 @@
  • - Line number: 165 + Line number: 164
  • @@ -599,7 +599,7 @@
  • - Line number: 193 + Line number: 192
  • @@ -645,7 +645,7 @@
  • - Line number: 223 + Line number: 222
  • @@ -691,7 +691,7 @@
  • - Line number: 241 + Line number: 240
  • @@ -737,7 +737,7 @@
  • - Line number: 259 + Line number: 258
  • @@ -783,7 +783,7 @@
  • - Line number: 281 + Line number: 280
  • @@ -835,7 +835,7 @@
  • - Line number: 1273 + Line number: 1156
  • @@ -887,7 +887,7 @@
  • - Line number: 1592 + Line number: 1463
  • @@ -945,7 +945,7 @@
  • - Line number: 774 + Line number: 675
  • @@ -1003,7 +1003,7 @@
  • - Line number: 1069 + Line number: 958
  • @@ -1061,7 +1061,7 @@
  • - Line number: 1017 + Line number: 912
  • @@ -1119,7 +1119,7 @@
  • - Line number: 1131 + Line number: 1020
  • @@ -1177,7 +1177,7 @@
  • - Line number: 1244 + Line number: 1127
  • @@ -1235,7 +1235,7 @@
  • - Line number: 1268 + Line number: 1151
  • @@ -1293,7 +1293,7 @@
  • - Line number: 1592 + Line number: 1463
  • @@ -1351,7 +1351,7 @@
  • - Line number: 1327 + Line number: 1210
  • @@ -1409,7 +1409,7 @@
  • - Line number: 1679 + Line number: 1550
  • @@ -1467,7 +1467,7 @@
  • - Line number: 2089 + Line number: 1942
  • @@ -1519,7 +1519,7 @@
  • - Line number: 1049 + Line number: 938
  • @@ -1571,7 +1571,7 @@
  • - Line number: 774 + Line number: 675
  • @@ -1623,7 +1623,7 @@
  • - Line number: 1017 + Line number: 912
  • @@ -1675,7 +1675,7 @@
  • - Line number: 1244 + Line number: 1127
  • @@ -1733,7 +1733,7 @@
  • - Line number: 774 + Line number: 675
  • @@ -1791,7 +1791,7 @@
  • - Line number: 1017 + Line number: 912
  • @@ -1849,7 +1849,7 @@
  • - Line number: 1069 + Line number: 958
  • @@ -1907,7 +1907,7 @@
  • - Line number: 1131 + Line number: 1020
  • @@ -1965,7 +1965,7 @@
  • - Line number: 1244 + Line number: 1127
  • @@ -2023,7 +2023,7 @@
  • - Line number: 1268 + Line number: 1151
  • @@ -2081,7 +2081,7 @@
  • - Line number: 1592 + Line number: 1463
  • @@ -2139,7 +2139,7 @@
  • - Line number: 1327 + Line number: 1210
  • @@ -2197,7 +2197,7 @@
  • - Line number: 1679 + Line number: 1550
  • @@ -2255,7 +2255,7 @@
  • - Line number: 2089 + Line number: 1942
  • @@ -2311,7 +2311,7 @@
  • - Line number: 939 + Line number: 834
  • @@ -2367,7 +2367,7 @@
  • - Line number: 1077 + Line number: 966
  • @@ -2423,7 +2423,7 @@
  • - Line number: 1052 + Line number: 941
  • @@ -2479,7 +2479,7 @@
  • - Line number: 1176 + Line number: 1059
  • @@ -2535,7 +2535,7 @@
  • - Line number: 1261 + Line number: 1144
  • @@ -2591,7 +2591,7 @@
  • - Line number: 1275 + Line number: 1158
  • @@ -2647,7 +2647,7 @@
  • - Line number: 1599 + Line number: 1470
  • @@ -2703,7 +2703,7 @@
  • - Line number: 1565 + Line number: 1436
  • @@ -2759,7 +2759,7 @@
  • - Line number: 1988 + Line number: 1841
  • @@ -2815,7 +2815,7 @@
  • - Line number: 2346 + Line number: 2169
  • diff --git a/docs/snyk/master/argocd-test.html b/docs/snyk/master/argocd-test.html index 878aae9971..6f8eea772a 100644 --- a/docs/snyk/master/argocd-test.html +++ b/docs/snyk/master/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,21 +456,21 @@

    Snyk test report

    -

    March 16th 2025, 12:20:57 am (UTC+00:00)

    +

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

    Scanned the following paths:
      -
    • /argo-cd/argoproj/argo-cd/v3/go.mod (gomodules)
    • +
    • /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)
    -
    10 known vulnerabilities
    -
    29 vulnerable dependency paths
    -
    2079 dependencies
    +
    7 known vulnerabilities
    +
    26 vulnerable dependency paths
    +
    2160 dependencies
    @@ -478,172 +478,6 @@
    -
    -

    Prototype Pollution

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

    Detailed paths

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

    Overview

    -

    redoc is an OpenAPI/Swagger-generated API Reference Documentation.

    -

    Affected versions of this package are vulnerable to Prototype Pollution via the mergeObjects() method in utils/helpers.ts due to improper user input sanitization.

    -

    PoC

    -
    (async () => {
    -          const lib = await import('redoc');
    -        
    -        var BAD_JSON = JSON.parse('{"__proto__":{"polluted":true}}');
    -        var victim = {}
    -        console.log("Before Attack: ", JSON.stringify(victim.__proto__));
    -        try {
    -          lib.mergeObjects ({}, BAD_JSON)
    -        } catch (e) { }
    -        console.log("After Attack: ", JSON.stringify(victim.__proto__));
    -        delete Object.prototype.polluted;
    -        })();
    -        
    -

    Details

    -

    Prototype Pollution is a vulnerability affecting JavaScript. Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects. JavaScript allows all Object attributes to be altered, including their magical attributes such as __proto__, constructor and prototype. An attacker manipulates these attributes to overwrite, or pollute, a JavaScript application object prototype of the base object by injecting other values. Properties on the Object.prototype are then inherited by all the JavaScript objects through the prototype chain. When that happens, this leads to either denial of service by triggering JavaScript exceptions, or it tampers with the application source code to force the code path that the attacker injects, thereby leading to remote code execution.

    -

    There are two main ways in which the pollution of prototypes occurs:

    -
      -
    • Unsafe Object recursive merge

      -
    • -
    • Property definition by path

      -
    • -
    -

    Unsafe Object recursive merge

    -

    The logic of a vulnerable recursive merge function follows the following high-level model:

    -
    merge (target, source)
    -        
    -          foreach property of source
    -        
    -            if property exists and is an object on both the target and the source
    -        
    -              merge(target[property], source[property])
    -        
    -            else
    -        
    -              target[property] = source[property]
    -        
    -
    - -

    When the source object contains a property named __proto__ defined with Object.defineProperty() , the condition that checks if the property exists and is an object on both the target and the source passes and the merge recurses with the target, being the prototype of Object and the source of Object as defined by the attacker. Properties are then copied on the Object prototype.

    -

    Clone operations are a special sub-class of unsafe recursive merges, which occur when a recursive merge is conducted on an empty object: merge({},source).

    -

    lodash and Hoek are examples of libraries susceptible to recursive merge attacks.

    -

    Property definition by path

    -

    There are a few JavaScript libraries that use an API to define property values on an object based on a given path. The function that is generally affected contains this signature: theFunction(object, path, value)

    -

    If the attacker can control the value of “path”, they can set this value to __proto__.myValue. myValue is then assigned to the prototype of the class of the object.

    -

    Types of attacks

    -

    There are a few methods by which Prototype Pollution can be manipulated:

    - - - - - - - - - - - - - - - - - - - - - - - -
    TypeOriginShort description
    Denial of service (DoS)ClientThis is the most likely attack.
    DoS occurs when Object holds generic functions that are implicitly called for various operations (for example, toString and valueOf).
    The attacker pollutes Object.prototype.someattr and alters its state to an unexpected value such as Int or Object. In this case, the code fails and is likely to cause a denial of service.
    For example: if an attacker pollutes Object.prototype.toString by defining it as an integer, if the codebase at any point was reliant on someobject.toString() it would fail.
    Remote Code ExecutionClientRemote code execution is generally only possible in cases where the codebase evaluates a specific attribute of an object, and then executes that evaluation.
    For example: eval(someobject.someattr). In this case, if the attacker pollutes Object.prototype.someattr they are likely to be able to leverage this in order to execute code.
    Property InjectionClientThe attacker pollutes properties that the codebase relies on for their informative value, including security properties such as cookies or tokens.
    For example: if a codebase checks privileges for someuser.isAdmin, then when the attacker pollutes Object.prototype.isAdmin and sets it to equal true, they can then achieve admin privileges.
    -

    Affected environments

    -

    The following environments are susceptible to a Prototype Pollution attack:

    -
      -
    • Application server

      -
    • -
    • Web server

      -
    • -
    • Web browser

      -
    • -
    -

    How to prevent

    -
      -
    1. Freeze the prototype— use Object.freeze (Object.prototype).

      -
    2. -
    3. Require schema validation of JSON input.

      -
    4. -
    5. Avoid using unsafe recursive merge functions.

      -
    6. -
    7. Consider using objects without prototypes (for example, Object.create(null)), breaking the prototype chain and preventing pollution.

      -
    8. -
    9. As a best practice use Map instead of Object.

      -
    10. -
    -

    For more information on this vulnerability type:

    -

    Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018

    -

    Remediation

    -

    Upgrade redoc to version 2.4.0 or higher.

    -

    References

    - - -
    - - - -

    LGPL-3.0 license

    @@ -656,7 +490,7 @@
    • - Manifest file: /argo-cd/argoproj/argo-cd/v3 › go.mod + Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod
    • Package Manager: golang @@ -670,7 +504,7 @@
    • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0, github.com/Azure/kubelogin/pkg/token@0.1.9 and others + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.1.5 and others
    @@ -682,11 +516,11 @@
    • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/Azure/kubelogin/pkg/token@0.1.9 + github.com/Azure/kubelogin/pkg/token@0.1.5 › - github.com/Azure/kubelogin/pkg/internal/token@0.1.9 + github.com/Azure/kubelogin/pkg/internal/token@0.1.5 › gopkg.in/retry.v1@1.0.3 @@ -720,7 +554,7 @@
      • - Manifest file: /argo-cd/argoproj/argo-cd/v3 › go.mod + Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod
      • Package Manager: golang @@ -728,12 +562,12 @@
      • Module: - github.com/r3labs/diff/v3 + github.com/r3labs/diff
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 and github.com/r3labs/diff/v3@3.0.1 + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/r3labs/diff@1.1.0
      @@ -746,9 +580,9 @@
    @@ -780,7 +614,7 @@
    • - Manifest file: /argo-cd/argoproj/argo-cd/v3 › go.mod + Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod
    • Package Manager: golang @@ -794,7 +628,7 @@
    • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0, code.gitea.io/sdk/gitea@0.20.0 and others + github.com/argoproj/argo-cd/v2@0.0.0, code.gitea.io/sdk/gitea@0.19.0 and others
    @@ -806,9 +640,9 @@
    • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - code.gitea.io/sdk/gitea@0.20.0 + code.gitea.io/sdk/gitea@0.19.0 › github.com/hashicorp/go-version@1.6.0 @@ -842,7 +676,7 @@
      • - Manifest file: /argo-cd/argoproj/argo-cd/v3 › go.mod + Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod
      • Package Manager: golang @@ -855,7 +689,7 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.7 + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.7
      @@ -868,7 +702,7 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › github.com/hashicorp/go-retryablehttp@0.7.7 @@ -877,9 +711,9 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › github.com/hashicorp/go-retryablehttp@0.7.7 @@ -888,9 +722,9 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - gitlab.com/gitlab-org/api/client-go@0.116.0 + github.com/xanzy/go-gitlab@0.114.0 › github.com/hashicorp/go-retryablehttp@0.7.7 @@ -899,11 +733,11 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/subscriptions@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › github.com/hashicorp/go-retryablehttp@0.7.7 @@ -912,11 +746,11 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/cmd@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/cmd@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › github.com/hashicorp/go-retryablehttp@0.7.7 @@ -925,11 +759,11 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 › github.com/hashicorp/go-retryablehttp@0.7.7 @@ -938,13 +772,13 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/api@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/api@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/subscriptions@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › github.com/hashicorp/go-retryablehttp@0.7.7 @@ -953,13 +787,13 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/controller@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/controller@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/subscriptions@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › github.com/hashicorp/go-retryablehttp@0.7.7 @@ -968,13 +802,13 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/subscriptions@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 › github.com/hashicorp/go-retryablehttp@0.7.7 @@ -983,13 +817,13 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/cmd@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/cmd@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 › github.com/hashicorp/go-retryablehttp@0.7.7 @@ -998,15 +832,15 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/api@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/api@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/subscriptions@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 › github.com/hashicorp/go-retryablehttp@0.7.7 @@ -1015,15 +849,15 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/controller@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/controller@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/subscriptions@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 › github.com/hashicorp/go-retryablehttp@0.7.7 @@ -1057,7 +891,7 @@
        • - Manifest file: /argo-cd/argoproj/argo-cd/v3 › go.mod + Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod
        • Package Manager: golang @@ -1071,7 +905,7 @@
        • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0, github.com/hashicorp/go-retryablehttp@0.7.7 and others + github.com/argoproj/argo-cd/v2@0.0.0, github.com/hashicorp/go-retryablehttp@0.7.7 and others
        @@ -1083,7 +917,7 @@
        • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › github.com/hashicorp/go-retryablehttp@0.7.7 › @@ -1094,9 +928,9 @@
        • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - gitlab.com/gitlab-org/api/client-go@0.116.0 + github.com/xanzy/go-gitlab@0.114.0 › github.com/hashicorp/go-cleanhttp@0.5.2 @@ -1105,9 +939,9 @@
        • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - gitlab.com/gitlab-org/api/client-go@0.116.0 + github.com/xanzy/go-gitlab@0.114.0 › github.com/hashicorp/go-retryablehttp@0.7.7 › @@ -1118,11 +952,11 @@
        • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 › github.com/hashicorp/go-retryablehttp@0.7.7 › @@ -1133,13 +967,13 @@
        • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/subscriptions@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 › github.com/hashicorp/go-retryablehttp@0.7.7 › @@ -1150,13 +984,13 @@
        • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/cmd@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/cmd@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 › github.com/hashicorp/go-retryablehttp@0.7.7 › @@ -1167,15 +1001,15 @@
        • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/api@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/api@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/subscriptions@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 › github.com/hashicorp/go-retryablehttp@0.7.7 › @@ -1186,15 +1020,15 @@
        • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/argoproj/notifications-engine/pkg/controller@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/controller@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/subscriptions@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd › - github.com/argoproj/notifications-engine/pkg/services@#87bf0576a872 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd › - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 › github.com/hashicorp/go-retryablehttp@0.7.7 › @@ -1230,7 +1064,7 @@
          • - Manifest file: /argo-cd/argoproj/argo-cd/v3 › go.mod + Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod
          • Package Manager: golang @@ -1243,7 +1077,7 @@
          • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 and github.com/gosimple/slug@1.15.0 + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/gosimple/slug@1.14.0
          @@ -1256,9 +1090,9 @@
          • Introduced through: - github.com/argoproj/argo-cd/v3@0.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/gosimple/slug@1.15.0 + github.com/gosimple/slug@1.14.0 @@ -1423,226 +1257,6 @@
    -
    -

    Arbitrary Code Injection

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd › ui/yarn.lock -
    • -
    • - Package Manager: npm -
    • -
    • - Vulnerable module: - - prismjs -
    • - -
    • 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 - › - prismjs@1.27.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    prismjs is a lightweight, robust, elegant syntax highlighting library.

    -

    Affected versions of this package are vulnerable to Arbitrary Code Injection via the document.currentScript lookup process. An attacker can manipulate the web page content and execute unintended actions by injecting HTML elements that overshadow legitimate DOM elements.

    -

    Note:

    -

    This is only exploitable if the application accepts untrusted input containing HTML but not direct JavaScript.

    -

    Remediation

    -

    Upgrade prismjs to version 1.30.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Cross-site Scripting (XSS)

    -
    - -
    - low 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.5.6 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Cross-site Scripting (XSS) due to incorrect handling of template literals in regular expressions. An attacker can manipulate the output of the script by injecting malicious payloads that bypass the dompurify sanitization.

    -

    PoC

    -
    DOMPurify.sanitize(
    -          `<math><foo-test><mi><li><table><foo-test><li></li></foo-test><a>
    -              <style>
    -                <! \${
    -              </style>
    -              }
    -              <foo-b id="><img src onerror='alert(1)'>">hmm...</foo-b>
    -            </a></table></li></mi></foo-test></math>
    -          `,
    -          {
    -            SAFE_FOR_TEMPLATES: true,
    -            CUSTOM_ELEMENT_HANDLING: {
    -              tagNameCheck: /^foo-/,
    -            },
    -          }
    -        );
    -        
    -

    Details

    -

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

    -

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

    -

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

    -

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

    -

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

    -

    Types of attacks

    -

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

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

    Affected environments

    -

    The following environments are susceptible to an XSS attack:

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

    How to prevent

    -

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

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

    Remediation

    -

    Upgrade dompurify to version 3.2.4 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 1dbfa49be8..b67a18ff82 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

    -

    March 16th 2025, 12:21:05 am (UTC+00:00)

    +

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

    Scanned the following paths: @@ -469,8 +469,8 @@
    -
    31 known vulnerabilities
    -
    76 vulnerable dependency paths
    +
    23 known vulnerabilities
    +
    44 vulnerable dependency paths
    969 dependencies
    @@ -552,319 +552,6 @@

    More about this vulnerability

    - -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/oauth2/jws -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v4@* and golang.org/x/oauth2/jws@v0.21.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v4@* - › - golang.org/x/oauth2/jws@v0.21.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - › - golang.org/x/oauth2/jws@v0.21.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to improper parsing of malformed tokens which can lead to memory consumption.

    -

    Remediation

    -

    Upgrade golang.org/x/oauth2/jws to version 0.27.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Server-side Request Forgery (SSRF)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http/httpproxy -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v4@* and golang.org/x/net/http/httpproxy@v0.26.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v4@* - › - golang.org/x/net/http/httpproxy@v0.26.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - › - golang.org/x/net/http/httpproxy@v0.27.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http/httpproxy is a package for HTTP proxy determination based on environment variables, as provided by net/http's ProxyFromEnvironment function

    -

    Affected versions of this package are vulnerable to Server-side Request Forgery (SSRF) in proxy.go, because hostname matching against proxy patterns may treat an IPv6 zone ID as a hostname component. An environment variable value like *.example.com could be matched to a request intended for [::1%25.example.com]:80.

    -

    Remediation

    -

    Upgrade golang.org/x/net/http/httpproxy to version 0.36.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/dexidp/dex › /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/html -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and golang.org/x/net/html@v0.27.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - › - golang.org/x/net/html@v0.27.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) through the functions parseDoctype, htmlIntegrationPoint, inBodyIM and inTableIM due to inefficient usage of the method strings.ToLower combining with the == operator to convert strings to lowercase and then comparing them.

    -

    An attacker can cause the application to slow down significantly by crafting inputs that are processed non-linearly.

    -

    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 golang.org/x/net/html to version 0.33.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

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

    Detailed paths

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

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling in handshakeTransport in handshake.go. An internal queue gets populated with received packets during the key exchange process, while waiting for the client to send a SSH_MSG_KEXINIT. An attacker can cause the server to become unresponsive to new connections by delaying or withholding this message, or by causing the queue to consume all available memory.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - -

    Insertion of Sensitive Information into Log File

    @@ -2154,85 +1841,6 @@

    More about this vulnerability

    - -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-jose/go-jose/v4 -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v4@* and github.com/go-jose/go-jose/v4@v4.0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v4@* - › - github.com/go-jose/go-jose/v4@v4.0.2 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - › - github.com/go-jose/go-jose/v4@v4.0.4 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to the use of strings.Split to split JWT tokens. An attacker can cause memory exhaustion and service disruption by sending numerous malformed tokens with a large number of . characters.

    -

    Workaround

    -

    This vulnerability can be mitigated by pre-validating that payloads passed to Go JOSE do not contain an excessive number of . characters.

    -

    Remediation

    -

    Upgrade github.com/go-jose/go-jose/v4 to version 4.0.5 or higher.

    -

    References

    - - -
    - - -

    CVE-2024-6119

    @@ -2531,7 +2139,7 @@ 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-r3 or higher.

    +

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

    References

    -
    -

    CVE-2024-13176

    -
    - -
    - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

    -

    Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

    -

    There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-12797

    -
    - -
    - 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: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a - server may fail to notice that the server was not authenticated, because - handshakes don't abort as expected when the SSL_VERIFY_PEER verification mode - is set.

    -

    Impact summary: TLS and DTLS connections using raw public keys may be - vulnerable to man-in-middle attacks when server authentication failure is not - detected by clients.

    -

    RPKs are disabled by default in both TLS clients and TLS servers. The issue - only arises when TLS clients explicitly enable RPK use by the server, and the - server, likewise, enables sending of an RPK instead of an X.509 certificate - chain. The affected clients are those that then rely on the handshake to - fail when the server's RPK fails to match one of the expected public keys, - by setting the verification mode to SSL_VERIFY_PEER.

    -

    Clients that enable server-side raw public keys can still find out that raw - public key verification failed by calling SSL_get_verify_result(), and those - that do, and take appropriate action, are not affected. This issue was - introduced in the initial implementation of RPK support in OpenSSL 3.2.

    -

    The FIPS modules in 3.4, 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.3-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2025-26519

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.20 -
    • -
    • - Vulnerable module: - - musl/musl -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.41.1 and musl/musl@1.2.5-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - apk-tools/apk-tools@2.14.4-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - busybox/ssl_client@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - musl/musl-utils@1.2.5-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - 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 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - 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 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - apk-tools/apk-tools@2.14.4-r0 - › - zlib/zlib@1.3.1-r1 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - musl/musl-utils@1.2.5-r0 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - alpine-baselayout/alpine-baselayout@3.6.5-r0 - › - busybox/busybox-binsh@1.36.1-r29 - › - busybox/busybox@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - musl/musl-utils@1.2.5-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

    -

    Remediation

    -

    Upgrade Alpine:3.20 musl to version 1.2.5-r1 or higher.

    -

    References

    - - -
    - - - -
    diff --git a/docs/snyk/v2.13.5/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 similarity index 67% rename from docs/snyk/v2.13.5/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html rename to docs/snyk/master/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html index a6c4f64711..5dc1585aad 100644 --- a/docs/snyk/v2.13.5/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

    -

    March 16th 2025, 12:26:34 am (UTC+00:00)

    +

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

    Scanned the following path: @@ -466,8 +466,8 @@
    -
    9 known vulnerabilities
    -
    86 vulnerable dependency paths
    +
    6 known vulnerabilities
    +
    52 vulnerable dependency paths
    18 dependencies
    @@ -1508,7 +1508,7 @@ 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-r3 or higher.

    +

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

    References

    • https://github.com/openssl/openssl/commit/72ae83ad214d2eef262461365a1975707f862712
    • @@ -1531,611 +1531,6 @@ -
      -

      CVE-2024-13176

      -
      - -
      - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

      -

      Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

      -

      There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

      -

      Remediation

      -

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

      -

      References

      - - -
      - - - -
      -
      -

      CVE-2024-12797

      -
      - -
      - 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: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a - server may fail to notice that the server was not authenticated, because - handshakes don't abort as expected when the SSL_VERIFY_PEER verification mode - is set.

      -

      Impact summary: TLS and DTLS connections using raw public keys may be - vulnerable to man-in-middle attacks when server authentication failure is not - detected by clients.

      -

      RPKs are disabled by default in both TLS clients and TLS servers. The issue - only arises when TLS clients explicitly enable RPK use by the server, and the - server, likewise, enables sending of an RPK instead of an X.509 certificate - chain. The affected clients are those that then rely on the handshake to - fail when the server's RPK fails to match one of the expected public keys, - by setting the verification mode to SSL_VERIFY_PEER.

      -

      Clients that enable server-side raw public keys can still find out that raw - public key verification failed by calling SSL_get_verify_result(), and those - that do, and take appropriate action, are not affected. This issue was - introduced in the initial implementation of RPK support in OpenSSL 3.2.

      -

      The FIPS modules in 3.4, 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.3-r0 or higher.

      -

      References

      - - -
      - - - -
      -
      -

      CVE-2025-26519

      -
      - -
      - low severity -
      - -
      - -
        -
      • - Package Manager: alpine:3.20 -
      • -
      • - Vulnerable module: - - musl/musl -
      • - -
      • Introduced through: - - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and musl/musl@1.2.5-r0 - -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - busybox/ssl_client@1.36.1-r28 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - ca-certificates/ca-certificates@20240226-r0 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - musl/musl-utils@1.2.5-r0 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - lua5.3/lua5.3-libs@5.3.6-r6 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - openssl/libcrypto3@3.3.0-r2 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - openssl/libssl3@3.3.0-r2 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - pcre2/pcre2@10.43-r0 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - zlib/zlib@1.3.1-r1 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - musl/musl-utils@1.2.5-r0 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - 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 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - musl/musl-utils@1.2.5-r0 - - - -
      • -
      - -
      - -
      - -

      NVD Description

      -

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

      -

      musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

      -

      Remediation

      -

      Upgrade Alpine:3.20 musl to version 1.2.5-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 new file mode 100644 index 0000000000..43f65cad79 --- /dev/null +++ b/docs/snyk/master/public.ecr.aws_docker_library_redis_7.0.15-alpine.html @@ -0,0 +1,670 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
      +
      +
      +
      + + + Snyk - Open Source Security + + + + + + + +
      +

      Snyk test report

      + +

      December 15th 2024, 12: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/master/quay.io_argoproj_argocd_latest.html b/docs/snyk/master/quay.io_argoproj_argocd_latest.html index b6af39b86c..7617106e2e 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,13 +456,13 @@

      Snyk test report

      -

      March 16th 2025, 12:21:34 am (UTC+00:00)

      +

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

      Scanned the following paths:
      • quay.io/argoproj/argocd:latest/argoproj/argocd/Dockerfile (deb)
      • -
      • quay.io/argoproj/argocd:latest/argoproj/argo-cd/v3//usr/local/bin/argocd (gomodules)
      • +
      • quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
      • quay.io/argoproj/argocd:latest//usr/local/bin/kustomize (gomodules)
      • quay.io/argoproj/argocd:latest/helm/v3//usr/local/bin/helm (gomodules)
      • quay.io/argoproj/argocd:latest/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
      • @@ -470,9 +470,9 @@
      -
      21 known vulnerabilities
      -
      77 vulnerable dependency paths
      -
      2359 dependencies
      +
      20 known vulnerabilities
      +
      100 vulnerable dependency paths
      +
      2380 dependencies
      @@ -480,111 +480,6 @@
      -
      -

      CVE-2024-56433

      -
      - -
      - medium severity -
      - -
      - -
        -
      • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd › Dockerfile -
      • -
      • - Package Manager: ubuntu:24.04 -
      • -
      • - Vulnerable module: - - shadow/passwd -
      • - -
      • Introduced through: - - docker-image|quay.io/argoproj/argocd@latest and shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - - - -
      • -
      • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - › - openssh/openssh-client@1:9.6p1-3ubuntu13.8 - › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - - - -
      • -
      • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - › - apt@2.7.14build2 - › - adduser@3.137ubuntu1 - › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - - - -
      • -
      • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - › - shadow/login@1:4.13+dfsg1-4ubuntu3.2 - - - -
      • -
      - -
      - -
      - -

      NVD Description

      -

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

      -

      shadow-utils (aka shadow) 4.4 through 4.17.0 establishes a default /etc/subuid behavior (e.g., uid 100000 through 165535 for the first user account) that can realistically conflict with the uids of users defined on locally administered networks, potentially leading to account takeover, e.g., by leveraging newuidmap for access to an NFS home directory (or same-host resources in the case of remote logins by these local network users). NOTE: it may also be argued that system administrators should not have assigned uids, within local networks, that are within the range that can occur in /etc/subuid.

      -

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 shadow.

      -

      References

      - - -
      - - - -

      Insecure Storage of Sensitive Information

      @@ -645,7 +540,7 @@ Introduced through: docker-image|quay.io/argoproj/argocd@latest › - util-linux@2.39.3-9ubuntu6.2 + util-linux@2.39.3-9ubuntu6.1 › pam/libpam0g@1.5.3-5ubuntu5.1 @@ -814,7 +709,6 @@
    • https://bugzilla.redhat.com/show_bug.cgi?id=2319212
    • https://access.redhat.com/errata/RHSA-2024:9941
    • https://access.redhat.com/errata/RHSA-2024:10379
    • -
    • https://access.redhat.com/errata/RHSA-2024:11250

    @@ -884,7 +778,7 @@ Introduced through: docker-image|quay.io/argoproj/argocd@latest › - util-linux@2.39.3-9ubuntu6.2 + util-linux@2.39.3-9ubuntu6.1 › pam/libpam0g@1.5.3-5ubuntu5.1 @@ -1051,12 +945,6 @@
  • http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-10963
  • https://access.redhat.com/security/cve/CVE-2024-10963
  • https://bugzilla.redhat.com/show_bug.cgi?id=2324291
  • -
  • https://access.redhat.com/errata/RHSA-2024:10232
  • -
  • https://access.redhat.com/errata/RHSA-2024:10244
  • -
  • https://access.redhat.com/errata/RHSA-2024:10379
  • -
  • https://access.redhat.com/errata/RHSA-2024:10518
  • -
  • https://access.redhat.com/errata/RHSA-2024:10528
  • -
  • https://access.redhat.com/errata/RHSA-2024:10852

  • @@ -1065,6 +953,214 @@

    More about this vulnerability

    + +
    +

    CVE-2024-26462

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd › Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + krb5/libk5crypto3 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@latest, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + libssh/libssh-4@0.10.6-2build2 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + krb5/krb5-locales@1.20.1-6ubuntu2.2 + + + +
    • +
    + +
    + +
    + +

    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

    @@ -1078,7 +1174,7 @@
    • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v3 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • Package Manager: golang @@ -1091,7 +1187,7 @@
    • Introduced through: - github.com/argoproj/argo-cd/v3@* and gopkg.in/retry.v1@v1.0.3 + github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3
    @@ -1104,7 +1200,7 @@
    • Introduced through: - github.com/argoproj/argo-cd/v3@* + github.com/argoproj/argo-cd/v2@* › gopkg.in/retry.v1@v1.0.3 @@ -1138,7 +1234,7 @@
      • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v3 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 › /usr/local/bin/argocd
      • Package Manager: golang @@ -1146,12 +1242,12 @@
      • Module: - github.com/r3labs/diff/v3 + github.com/r3labs/diff
      • Introduced through: - github.com/argoproj/argo-cd/v3@* and github.com/r3labs/diff/v3@v3.0.1 + github.com/argoproj/argo-cd/v2@* and github.com/r3labs/diff@v1.1.0
      @@ -1164,9 +1260,9 @@
    @@ -1198,7 +1294,7 @@
    • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v3 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • Package Manager: golang @@ -1211,7 +1307,7 @@
    • Introduced through: - github.com/argoproj/argo-cd/v3@* and github.com/hashicorp/go-version@v1.6.0 + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-version@v1.6.0
    @@ -1224,7 +1320,7 @@
    • Introduced through: - github.com/argoproj/argo-cd/v3@* + github.com/argoproj/argo-cd/v2@* › github.com/hashicorp/go-version@v1.6.0 @@ -1258,7 +1354,7 @@
      • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v3 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 › /usr/local/bin/argocd
      • Package Manager: golang @@ -1271,7 +1367,7 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.7 + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.7
      @@ -1284,7 +1380,7 @@
      • Introduced through: - github.com/argoproj/argo-cd/v3@* + github.com/argoproj/argo-cd/v2@* › github.com/hashicorp/go-retryablehttp@v0.7.7 @@ -1378,7 +1474,7 @@
        • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v3 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 › /usr/local/bin/argocd
        • Package Manager: golang @@ -1391,7 +1487,7 @@
        • Introduced through: - github.com/argoproj/argo-cd/v3@* and github.com/hashicorp/go-cleanhttp@v0.5.2 + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-cleanhttp@v0.5.2
        @@ -1404,7 +1500,7 @@
        • Introduced through: - github.com/argoproj/argo-cd/v3@* + github.com/argoproj/argo-cd/v2@* › github.com/hashicorp/go-cleanhttp@v0.5.2 @@ -1438,7 +1534,7 @@
          • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v3 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 › /usr/local/bin/argocd
          • Package Manager: golang @@ -1451,7 +1547,7 @@
          • Introduced through: - github.com/argoproj/argo-cd/v3@* and github.com/gosimple/slug@v1.15.0 + github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.14.0
          @@ -1464,9 +1560,9 @@
          • Introduced through: - github.com/argoproj/argo-cd/v3@* + github.com/argoproj/argo-cd/v2@* › - github.com/gosimple/slug@v1.15.0 + github.com/gosimple/slug@v1.14.0 @@ -1485,237 +1581,6 @@

            More about this vulnerability

            - -
            -

            Generation of Error Message Containing Sensitive Information

            -
            - -
            - medium severity -
            - -
            - -
              -
            • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v3 › /usr/local/bin/argocd -
            • -
            • - Package Manager: golang -
            • -
            • - Vulnerable module: - - github.com/argoproj/gitops-engine/pkg/utils/kube -
            • - -
            • Introduced through: - - github.com/argoproj/argo-cd/v3@* and github.com/argoproj/gitops-engine/pkg/utils/kube@v0.7.1-0.20250314164314-7258614f5041 - -
            • -
            - -
            - - -

            Detailed paths

            - -
              -
            • - Introduced through: - github.com/argoproj/argo-cd/v3@* - › - github.com/argoproj/gitops-engine/pkg/utils/kube@v0.7.1-0.20250314164314-7258614f5041 - - - -
            • -
            - -
            - -
            - -

            Overview

            -

            Affected versions of this package are vulnerable to Generation of Error Message Containing Sensitive Information when syncing invalid Kubernetes Secret resources. An attacker with write access to the repository can expose secret values by committing an invalid Secret to repository and triggering a Sync, which then become visible to any user with read access to Argo CD.

            -

            Remediation

            -

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

            -

            References

            - - -
            - - - -
            -
            -

            Generation of Error Message Containing Sensitive Information

            -
            - -
            - medium severity -
            - -
            - -
              -
            • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v3 › /usr/local/bin/argocd -
            • -
            • - Package Manager: golang -
            • -
            • - Vulnerable module: - - github.com/argoproj/gitops-engine/pkg/diff -
            • - -
            • Introduced through: - - github.com/argoproj/argo-cd/v3@* and github.com/argoproj/gitops-engine/pkg/diff@v0.7.1-0.20250314164314-7258614f5041 - -
            • -
            - -
            - - -

            Detailed paths

            - -
              -
            • - Introduced through: - github.com/argoproj/argo-cd/v3@* - › - github.com/argoproj/gitops-engine/pkg/diff@v0.7.1-0.20250314164314-7258614f5041 - - - -
            • -
            - -
            - -
            - -

            Overview

            -

            Affected versions of this package are vulnerable to Generation of Error Message Containing Sensitive Information when syncing invalid Kubernetes Secret resources. An attacker with write access to the repository can expose secret values by committing an invalid Secret to repository and triggering a Sync, which then become visible to any user with read access to Argo CD.

            -

            Remediation

            -

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

            -

            References

            - - -
            - - - -
            -
            -

            Improper Encoding or Escaping of Output

            -
            - -
            - medium severity -
            - -
            - -
              -
            • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd › Dockerfile -
            • -
            • - Package Manager: ubuntu:24.04 -
            • -
            • - Vulnerable module: - - git/git-man -
            • - -
            • Introduced through: - - - docker-image|quay.io/argoproj/argocd@latest, git@1:2.43.0-1ubuntu7.2 and others -
            • -
            - -
            - - -

            Detailed paths

            - -
              -
            • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - › - git@1:2.43.0-1ubuntu7.2 - › - git/git-man@1:2.43.0-1ubuntu7.2 - - - -
            • -
            • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - › - git@1:2.43.0-1ubuntu7.2 - - - -
            • -
            • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - › - git-lfs@3.4.1-1ubuntu0.2 - › - git@1:2.43.0-1ubuntu7.2 - - - -
            • -
            - -
            - -
            - -

            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 is a source code management tool. When cloning from a server (or fetching, or pushing), informational or error messages are transported from the remote Git process to the client via the so-called "sideband channel". These messages will be prefixed with "remote:" and printed directly to the standard error output. Typically, this standard error output is connected to a terminal that understands ANSI escape sequences, which Git did not protect against. Most modern terminals support control sequences that can be used by a malicious actor to hide and misrepresent information, or to mislead the user into executing untrusted scripts. As requested on the git-security mailing list, the patches are under discussion on the public mailing list. Users are advised to update as soon as possible. Users unable to upgrade should avoid recursive clones unless they are from trusted sources.

            -

            Remediation

            -

            There is no fixed version for Ubuntu:24.04 git.

            -

            References

            - - -
            - - -

            Release of Invalid Pointer or Reference

            @@ -1887,7 +1752,7 @@
          • Introduced through: - docker-image|quay.io/argoproj/argocd@latest and openssl/libssl3t64@3.0.13-0ubuntu3.5 + docker-image|quay.io/argoproj/argocd@latest and openssl/libssl3t64@3.0.13-0ubuntu3.4
          @@ -1902,7 +1767,7 @@ Introduced through: docker-image|quay.io/argoproj/argocd@latest › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -1913,7 +1778,7 @@ › coreutils@9.4-3ubuntu6 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4
          @@ -1924,7 +1789,7 @@ › cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -1935,7 +1800,7 @@ › libfido2/libfido2-1@1.14.0-1build3 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -1944,9 +1809,9 @@ Introduced through: docker-image|quay.io/argoproj/argocd@latest › - openssh/openssh-client@1:9.6p1-3ubuntu13.8 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -1957,9 +1822,9 @@ › ca-certificates@20240203 › - openssl@3.0.13-0ubuntu3.5 + openssl@3.0.13-0ubuntu3.4 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -1968,13 +1833,13 @@ Introduced through: docker-image|quay.io/argoproj/argocd@latest › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › libssh/libssh-4@0.10.6-2build2 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -1983,15 +1848,15 @@ Introduced through: docker-image|quay.io/argoproj/argocd@latest › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.5 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.5 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -2000,15 +1865,15 @@ Introduced through: docker-image|quay.io/argoproj/argocd@latest › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.2 + openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 › cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -2017,7 +1882,7 @@ Introduced through: docker-image|quay.io/argoproj/argocd@latest › - openssl@3.0.13-0ubuntu3.5 + openssl@3.0.13-0ubuntu3.4 @@ -2028,7 +1893,7 @@ › ca-certificates@20240203 › - openssl@3.0.13-0ubuntu3.5 + openssl@3.0.13-0ubuntu3.4 @@ -2189,7 +2054,7 @@ › pam/libpam-modules@1.5.3-5ubuntu5.1 › - systemd/libsystemd0@255.4-1ubuntu8.5 + systemd/libsystemd0@255.4-1ubuntu8.4 › libgcrypt20@1.10.3-2build1 @@ -2223,6 +2088,422 @@

          More about this vulnerability

          + +
          +

          CVE-2024-26458

          +
          + +
          + low severity +
          + +
          + +
            +
          • + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd › Dockerfile +
          • +
          • + Package Manager: ubuntu:24.04 +
          • +
          • + Vulnerable module: + + krb5/libk5crypto3 +
          • + +
          • Introduced through: + + + docker-image|quay.io/argoproj/argocd@latest, git@1:2.43.0-1ubuntu7.1 and others +
          • +
          + +
          + + +

          Detailed paths

          + +
            +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + libssh/libssh-4@0.10.6-2build2 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + krb5/krb5-locales@1.20.1-6ubuntu2.2 + + + +
          • +
          + +
          + +
          + +

          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:latest/argoproj/argocd › Dockerfile +
          • +
          • + Package Manager: ubuntu:24.04 +
          • +
          • + Vulnerable module: + + krb5/libk5crypto3 +
          • + +
          • Introduced through: + + + docker-image|quay.io/argoproj/argocd@latest, git@1:2.43.0-1ubuntu7.1 and others +
          • +
          + +
          + + +

          Detailed paths

          + +
            +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + libssh/libssh-4@0.10.6-2build2 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
          • +
          • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + krb5/krb5-locales@1.20.1-6ubuntu2.2 + + + +
          • +
          + +
          + +
          + +

          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

          @@ -2395,7 +2676,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@latest and glibc/libc-bin@2.39-0ubuntu8.4 + docker-image|quay.io/argoproj/argocd@latest and glibc/libc-bin@2.39-0ubuntu8.3
        @@ -2410,7 +2691,7 @@ Introduced through: docker-image|quay.io/argoproj/argocd@latest › - glibc/libc-bin@2.39-0ubuntu8.4 + glibc/libc-bin@2.39-0ubuntu8.3 @@ -2419,7 +2700,7 @@ Introduced through: docker-image|quay.io/argoproj/argocd@latest › - glibc/libc6@2.39-0ubuntu8.4 + glibc/libc6@2.39-0ubuntu8.3 @@ -2452,7 +2733,7 @@
        -

        CVE-2025-0167

        +

        Improper Input Validation

        @@ -2471,13 +2752,13 @@
      • Vulnerable module: - curl/libcurl3t64-gnutls + git/git-man
      • Introduced through: - docker-image|quay.io/argoproj/argocd@latest, git@1:2.43.0-1ubuntu7.2 and others + docker-image|quay.io/argoproj/argocd@latest, git@1:2.43.0-1ubuntu7.1 and others
      @@ -2491,9 +2772,29 @@ Introduced through: docker-image|quay.io/argoproj/argocd@latest › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + git/git-man@1:2.43.0-1ubuntu7.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git@1:2.43.0-1ubuntu7.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + › + git-lfs@3.4.1-1ubuntu0.2 + › + git@1:2.43.0-1ubuntu7.1 @@ -2505,28 +2806,22 @@

      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 git package and not the git package as distributed by Ubuntu. See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      -

      When asked to use a .netrc file for credentials and to follow HTTP - redirects, curl could leak the password used for the first host to the - followed-to host under certain circumstances.

      -

      This flaw only manifests itself if the netrc file has a default entry that - omits both login and password. A rare circumstance.

      +

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

      +

      There is no fixed version for Ubuntu:24.04 git.

      References


      diff --git a/docs/snyk/master/redis_7.2.7-alpine.html b/docs/snyk/master/redis_7.0.15-alpine.html similarity index 51% rename from docs/snyk/master/redis_7.2.7-alpine.html rename to docs/snyk/master/redis_7.0.15-alpine.html index ab05e38d5f..08afe3592a 100644 --- a/docs/snyk/master/redis_7.2.7-alpine.html +++ b/docs/snyk/master/redis_7.0.15-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,27 +456,213 @@

      Snyk test report

      -

      March 16th 2025, 12:21:38 am (UTC+00:00)

      +

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

      Scanned the following paths:
        -
      • redis:7.2.7-alpine (apk)
      • -
      • redis:7.2.7-alpine/tianon/gosu//usr/local/bin/gosu (gomodules)
      • +
      • redis:7.0.15-alpine (apk)
      • +
      • redis:7.0.15-alpine/tianon/gosu//usr/local/bin/gosu (gomodules)
      -
      0 known vulnerabilities
      -
      0 vulnerable dependency paths
      -
      19 dependencies
      +
      1 known vulnerabilities
      +
      9 vulnerable dependency paths
      +
      18 dependencies
      - 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.14.5/argocd-iac-install.html b/docs/snyk/v2.11.12/argocd-iac-install.html similarity index 98% rename from docs/snyk/v2.14.5/argocd-iac-install.html rename to docs/snyk/v2.11.12/argocd-iac-install.html index 62e1fad369..77349b6faa 100644 --- a/docs/snyk/v2.14.5/argocd-iac-install.html +++ b/docs/snyk/v2.11.12/argocd-iac-install.html @@ -456,7 +456,7 @@

      Snyk test report

      -

      March 16th 2025, 12:26:00 am (UTC+00:00)

      +

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

      Scanned the following path: @@ -507,7 +507,7 @@
    • - Line number: 23952 + Line number: 21069
    @@ -553,7 +553,7 @@
  • - Line number: 23633 + Line number: 20754
  • @@ -599,7 +599,7 @@
  • - Line number: 23720 + Line number: 20839
  • @@ -645,7 +645,7 @@
  • - Line number: 23748 + Line number: 20867
  • @@ -691,7 +691,7 @@
  • - Line number: 23778 + Line number: 20897
  • @@ -737,7 +737,7 @@
  • - Line number: 23796 + Line number: 20915
  • @@ -783,7 +783,7 @@
  • - Line number: 23814 + Line number: 20933
  • @@ -829,7 +829,7 @@
  • - Line number: 23836 + Line number: 20955
  • @@ -881,7 +881,7 @@
  • - Line number: 24926 + Line number: 22001
  • @@ -933,7 +933,7 @@
  • - Line number: 25233 + Line number: 22288
  • @@ -991,7 +991,7 @@
  • - Line number: 24445 + Line number: 21562
  • @@ -1049,7 +1049,7 @@
  • - Line number: 24728 + Line number: 21813
  • @@ -1107,7 +1107,7 @@
  • - Line number: 24682 + Line number: 21779
  • @@ -1165,7 +1165,7 @@
  • - Line number: 24790 + Line number: 21873
  • @@ -1223,7 +1223,7 @@
  • - Line number: 24897 + Line number: 21972
  • @@ -1281,7 +1281,7 @@
  • - Line number: 24921 + Line number: 21996
  • @@ -1339,7 +1339,7 @@
  • - Line number: 25233 + Line number: 22288
  • @@ -1397,7 +1397,7 @@
  • - Line number: 24980 + Line number: 22053
  • @@ -1455,7 +1455,7 @@
  • - Line number: 25320 + Line number: 22373
  • @@ -1513,7 +1513,7 @@
  • - Line number: 25718 + Line number: 22724
  • @@ -1565,7 +1565,7 @@
  • - Line number: 24708 + Line number: 21793
  • @@ -1617,7 +1617,7 @@
  • - Line number: 24445 + Line number: 21562
  • @@ -1669,7 +1669,7 @@
  • - Line number: 24682 + Line number: 21779
  • @@ -1721,7 +1721,7 @@
  • - Line number: 24897 + Line number: 21972
  • @@ -1779,7 +1779,7 @@
  • - Line number: 24445 + Line number: 21562
  • @@ -1837,7 +1837,7 @@
  • - Line number: 24682 + Line number: 21779
  • @@ -1895,7 +1895,7 @@
  • - Line number: 24728 + Line number: 21813
  • @@ -1953,7 +1953,7 @@
  • - Line number: 24790 + Line number: 21873
  • @@ -2011,7 +2011,7 @@
  • - Line number: 24897 + Line number: 21972
  • @@ -2069,7 +2069,7 @@
  • - Line number: 24921 + Line number: 21996
  • @@ -2127,7 +2127,7 @@
  • - Line number: 25233 + Line number: 22288
  • @@ -2185,7 +2185,7 @@
  • - Line number: 24980 + Line number: 22053
  • @@ -2243,7 +2243,7 @@
  • - Line number: 25320 + Line number: 22373
  • @@ -2301,7 +2301,7 @@
  • - Line number: 25718 + Line number: 22724
  • @@ -2357,7 +2357,7 @@
  • - Line number: 24604 + Line number: 21703
  • @@ -2413,7 +2413,7 @@
  • - Line number: 24736 + Line number: 21821
  • @@ -2469,7 +2469,7 @@
  • - Line number: 24711 + Line number: 21796
  • @@ -2525,7 +2525,7 @@
  • - Line number: 24829 + Line number: 21906
  • @@ -2581,7 +2581,7 @@
  • - Line number: 24914 + Line number: 21989
  • @@ -2637,7 +2637,7 @@
  • - Line number: 24928 + Line number: 22003
  • @@ -2693,7 +2693,7 @@
  • - Line number: 25240 + Line number: 22295
  • @@ -2749,7 +2749,7 @@
  • - Line number: 25206 + Line number: 22261
  • @@ -2805,7 +2805,7 @@
  • - Line number: 25617 + Line number: 22634
  • @@ -2861,7 +2861,7 @@
  • - Line number: 25963 + Line number: 22943
  • diff --git a/docs/snyk/v2.14.5/argocd-iac-namespace-install.html b/docs/snyk/v2.11.12/argocd-iac-namespace-install.html similarity index 98% rename from docs/snyk/v2.14.5/argocd-iac-namespace-install.html rename to docs/snyk/v2.11.12/argocd-iac-namespace-install.html index 8ec5d734af..11b4414c6a 100644 --- a/docs/snyk/v2.14.5/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.11.12/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    March 16th 2025, 12:26:09 am (UTC+00:00)

    +

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

    Scanned the following path: @@ -553,7 +553,7 @@
  • - Line number: 164 + Line number: 162
  • @@ -599,7 +599,7 @@
  • - Line number: 192 + Line number: 190
  • @@ -645,7 +645,7 @@
  • - Line number: 222 + Line number: 220
  • @@ -691,7 +691,7 @@
  • - Line number: 240 + Line number: 238
  • @@ -737,7 +737,7 @@
  • - Line number: 258 + Line number: 256
  • @@ -783,7 +783,7 @@
  • - Line number: 280 + Line number: 278
  • @@ -835,7 +835,7 @@
  • - Line number: 1156 + Line number: 1112
  • @@ -887,7 +887,7 @@
  • - Line number: 1463 + Line number: 1399
  • @@ -945,7 +945,7 @@
  • - Line number: 675 + Line number: 673
  • @@ -1003,7 +1003,7 @@
  • - Line number: 958 + Line number: 924
  • @@ -1061,7 +1061,7 @@
  • - Line number: 912 + Line number: 890
  • @@ -1119,7 +1119,7 @@
  • - Line number: 1020 + Line number: 984
  • @@ -1177,7 +1177,7 @@
  • - Line number: 1127 + Line number: 1083
  • @@ -1235,7 +1235,7 @@
  • - Line number: 1151 + Line number: 1107
  • @@ -1293,7 +1293,7 @@
  • - Line number: 1463 + Line number: 1399
  • @@ -1351,7 +1351,7 @@
  • - Line number: 1210 + Line number: 1164
  • @@ -1409,7 +1409,7 @@
  • - Line number: 1550 + Line number: 1484
  • @@ -1467,7 +1467,7 @@
  • - Line number: 1948 + Line number: 1835
  • @@ -1519,7 +1519,7 @@
  • - Line number: 938 + Line number: 904
  • @@ -1571,7 +1571,7 @@
  • - Line number: 675 + Line number: 673
  • @@ -1623,7 +1623,7 @@
  • - Line number: 912 + Line number: 890
  • @@ -1675,7 +1675,7 @@
  • - Line number: 1127 + Line number: 1083
  • @@ -1733,7 +1733,7 @@
  • - Line number: 675 + Line number: 673
  • @@ -1791,7 +1791,7 @@
  • - Line number: 912 + Line number: 890
  • @@ -1849,7 +1849,7 @@
  • - Line number: 958 + Line number: 924
  • @@ -1907,7 +1907,7 @@
  • - Line number: 1020 + Line number: 984
  • @@ -1965,7 +1965,7 @@
  • - Line number: 1127 + Line number: 1083
  • @@ -2023,7 +2023,7 @@
  • - Line number: 1151 + Line number: 1107
  • @@ -2081,7 +2081,7 @@
  • - Line number: 1463 + Line number: 1399
  • @@ -2139,7 +2139,7 @@
  • - Line number: 1210 + Line number: 1164
  • @@ -2197,7 +2197,7 @@
  • - Line number: 1550 + Line number: 1484
  • @@ -2255,7 +2255,7 @@
  • - Line number: 1948 + Line number: 1835
  • @@ -2311,7 +2311,7 @@
  • - Line number: 834 + Line number: 814
  • @@ -2367,7 +2367,7 @@
  • - Line number: 966 + Line number: 932
  • @@ -2423,7 +2423,7 @@
  • - Line number: 941 + Line number: 907
  • @@ -2479,7 +2479,7 @@
  • - Line number: 1059 + Line number: 1017
  • @@ -2535,7 +2535,7 @@
  • - Line number: 1144 + Line number: 1100
  • @@ -2591,7 +2591,7 @@
  • - Line number: 1158 + Line number: 1114
  • @@ -2647,7 +2647,7 @@
  • - Line number: 1470 + Line number: 1406
  • @@ -2703,7 +2703,7 @@
  • - Line number: 1436 + Line number: 1372
  • @@ -2759,7 +2759,7 @@
  • - Line number: 1847 + Line number: 1745
  • @@ -2815,7 +2815,7 @@
  • - Line number: 2193 + Line number: 2054
  • diff --git a/docs/snyk/v2.11.12/argocd-test.html b/docs/snyk/v2.11.12/argocd-test.html new file mode 100644 index 0000000000..61dbff2086 --- /dev/null +++ b/docs/snyk/v2.11.12/argocd-test.html @@ -0,0 +1,21728 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

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

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

    Incorrect Implementation of Authentication Algorithm

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

    Detailed paths

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

    Overview

    +

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

    +

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

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

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

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/fake@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/record@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/portforward@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/api/rbac/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/api/equality@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/api/errors@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery/fake@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/apps/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/internal/controller@0.14.7 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/api/rbac/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/api/errors@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/util/retry@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/testing@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/util/managedfields@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/Azure/kubelogin/pkg/token@0.0.20 + › + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/testing@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/scheme@0.14.7 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/resource@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.26.11 + › + k8s.io/apimachinery/pkg/api/equality@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/util/retry@0.26.11 + › + k8s.io/apimachinery/pkg/api/errors@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/api/validation@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/util/managedfields@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/portforward@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/portforward@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/testing@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/util/managedfields@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/util/retry@0.26.11 + › + k8s.io/apimachinery/pkg/api/errors@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/api/rbac/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/api/errors@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/util/managedfields@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/record@0.26.11 + › + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/apps/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery/fake@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/apps/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/core/v1@0.26.11 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/scale@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/scale@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/scale@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/record@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/internal/controller@0.14.7 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/config@0.14.7 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/config@0.14.7 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/config@0.14.7 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/metadata@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/Azure/kubelogin/pkg/token@0.0.20 + › + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/clientcmd/api/v1@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/scheme@0.14.7 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/apps/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/resource@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/api/equality@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/core/v1@0.26.11 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/record@0.26.11 + › + k8s.io/client-go/tools/reference@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/apps/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/api/equality@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/Azure/kubelogin/pkg/token@0.0.20 + › + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/testing@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/scheme@0.14.7 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/resource@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/util/retry@0.26.11 + › + k8s.io/apimachinery/pkg/api/errors@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/util/managedfields@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/portforward@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/core/v1@0.26.11 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers@0.26.11 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/fake@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/apps/v1@0.26.11 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/core/v1@0.26.11 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/core/v1@0.26.11 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/record@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/scale@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/scale@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/scale@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/config@0.14.7 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/core/v1@0.26.11 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/record@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/auth@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/apps/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/record@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset@0.26.11 + › + k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1@0.26.11 + › + k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset@0.26.11 + › + k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1@0.26.11 + › + k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/recorder@0.14.7 + › + k8s.io/client-go/tools/record@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/recorder@0.14.7 + › + k8s.io/client-go/tools/record@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/recorder@0.14.7 + › + k8s.io/client-go/tools/record@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/internal/controller@0.14.7 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/metadata@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/metadata@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/metadata@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/metadata@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/conversion@0.14.7 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/conversion@0.14.7 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/api/validation@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/core/v1@0.26.11 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/record@0.26.11 + › + k8s.io/client-go/tools/reference@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.26.11 + › + k8s.io/apimachinery/pkg/api/equality@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.26.11 + › + k8s.io/apimachinery/pkg/api/equality@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/api/validation@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/core/v1@0.26.11 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/record@0.26.11 + › + k8s.io/client-go/tools/reference@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/apps/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apiserver/pkg/features@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/auth@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + › + k8s.io/client-go/discovery/cached/disk@0.26.11 + › + k8s.io/client-go/discovery/cached/memory@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + › + k8s.io/client-go/discovery/cached/disk@0.26.11 + › + k8s.io/client-go/discovery/cached/memory@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + › + k8s.io/client-go/discovery/cached/disk@0.26.11 + › + k8s.io/client-go/discovery/cached/memory@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/auth@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/apps/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/auth@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/core/v1@0.26.11 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/auth@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/apps/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/metadata@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/metadata@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/v1@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1alpha1@1.26.11 + › + k8s.io/api/storage/v1alpha1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/apps/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/rest/watch@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apiserver/pkg/features@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apiserver/pkg/features@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/auth@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/validation@0.26.11 + › + k8s.io/cli-runtime/pkg/resource@0.26.11 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers@0.26.11 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/apps/v1@0.26.11 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/core/v1@0.26.11 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/fake@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + › + k8s.io/client-go/discovery/cached/disk@0.26.11 + › + k8s.io/client-go/discovery/cached/memory@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + › + k8s.io/client-go/discovery/cached/disk@0.26.11 + › + k8s.io/client-go/discovery/cached/memory@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + › + k8s.io/client-go/discovery/cached/disk@0.26.11 + › + k8s.io/client-go/discovery/cached/memory@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/scale@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/scale@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/auth@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/core/v1@0.26.11 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/auth@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/auth@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/informers/core/v1@0.26.11 + › + k8s.io/client-go/listers/core/v1@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/metadata@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/v1@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1alpha1@1.26.11 + › + k8s.io/api/storage/v1alpha1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1alpha1@1.26.11 + › + k8s.io/api/storage/v1alpha1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/discovery/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes/fake@0.26.11 + › + k8s.io/client-go/testing@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/validation@0.26.11 + › + k8s.io/cli-runtime/pkg/resource@0.26.11 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apiserver/pkg/features@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apiserver/pkg/features@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apiserver/pkg/features@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apiserver/pkg/features@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/auth@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/kubernetes/typed/core/v1@0.26.11 + › + k8s.io/client-go/applyconfigurations/core/v1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/scale@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/auth@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/auth@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/metadata@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/kubernetes/typed/core/v1@0.26.11 + › + k8s.io/client-go/applyconfigurations/core/v1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + › + k8s.io/client-go/discovery/cached/disk@0.26.11 + › + k8s.io/client-go/discovery/cached/memory@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + › + k8s.io/client-go/discovery/cached/disk@0.26.11 + › + k8s.io/client-go/discovery/cached/memory@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/client-go/tools/clientcmd@0.26.11 + › + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/validation@0.26.11 + › + k8s.io/cli-runtime/pkg/resource@0.26.11 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + k8s.io/client-go/kubernetes@0.26.11 + › + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/metadata@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/metadata@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/runtime@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/api/storage/v1beta1@0.26.11 + › + k8s.io/api/core/v1@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apiserver/pkg/features@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apiserver/pkg/features@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/validation@0.26.11 + › + k8s.io/cli-runtime/pkg/resource@0.26.11 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + › + k8s.io/client-go/discovery/cached/disk@0.26.11 + › + k8s.io/client-go/discovery/cached/memory@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/validation@0.26.11 + › + k8s.io/cli-runtime/pkg/resource@0.26.11 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/validation@0.26.11 + › + k8s.io/cli-runtime/pkg/resource@0.26.11 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + › + k8s.io/apimachinery/pkg/watch@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + › + k8s.io/client-go/restmapper@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + › + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + › + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + › + k8s.io/kubernetes/pkg/features@1.26.11 + › + k8s.io/apiserver/pkg/features@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/apimachinery/pkg/util/wait@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/kubernetes/typed/core/v1@0.26.11 + › + k8s.io/client-go/applyconfigurations/core/v1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/util/openapi@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + › + k8s.io/client-go/dynamic@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/transport@0.26.11 + › + k8s.io/client-go/util/workqueue@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/kubernetes/typed/core/v1@0.26.11 + › + k8s.io/client-go/applyconfigurations/core/v1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/kubernetes/typed/core/v1@0.26.11 + › + k8s.io/client-go/applyconfigurations/core/v1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/util@0.26.11 + › + k8s.io/kubectl/pkg/util/templates@0.26.11 + › + k8s.io/kubectl/pkg/util/term@0.26.11 + › + k8s.io/client-go/tools/remotecommand@0.26.11 + › + k8s.io/client-go/transport/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/rest@0.26.11 + › + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + › + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + › + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + sigs.k8s.io/controller-runtime@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + › + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + › + k8s.io/client-go/tools/leaderelection@0.26.11 + › + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + › + k8s.io/client-go/kubernetes/typed/core/v1@0.26.11 + › + k8s.io/client-go/applyconfigurations/core/v1@0.26.11 + › + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + › + k8s.io/client-go/discovery@0.26.11 + › + k8s.io/client-go/kubernetes/scheme@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + › + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + › + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + › + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + › + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + › + k8s.io/kubectl/pkg/util/completion@0.26.11 + › + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + › + k8s.io/kubectl/pkg/describe@0.26.11 + › + k8s.io/client-go/util/certificate/csr@0.26.11 + › + k8s.io/client-go/tools/watch@0.26.11 + › + k8s.io/client-go/tools/cache@0.26.11 + › + k8s.io/client-go/tools/pager@0.26.11 + › + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

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

    +

    Details

    +

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

    +

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

    +

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

    +

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

    +

    Two common types of DoS vulnerabilities:

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

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

      +
    • +
    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Allocation of Resources Without Limits or Throttling

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

    Detailed paths

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

    Overview

    +

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

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    LGPL-3.0 license

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

    Detailed paths

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

    LGPL-3.0 license

    + +
    + + + +
    +
    +

    Denial of Service (DoS)

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

    Detailed paths

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

    Overview

    +

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

    +

    PoC

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

    Details

    +

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

    +

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

    +

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

    +

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

    +

    Two common types of DoS vulnerabilities:

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

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

      +
    • +
    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    + +
    + + + +
    +
    +

    Insertion of Sensitive Information into Log File

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

    Detailed paths

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

    Overview

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    + +
    + + + +
    +
    +

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

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

    Detailed paths

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

    Overview

    +

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

    +

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

    +

    Notes:

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

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

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

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

      +
    8. +
    +

    ManagedIdentityApplication (.NET)

    +

    ManagedIdentityApplication (Java)

    +

    ManagedIdentityApplication (Node.js)

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Regular Expression Denial of Service (ReDoS)

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

    Detailed paths

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

    Overview

    +

    foundation-sites is a responsive front-end framework

    +

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

    +

    PoC

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

    Details

    +

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

    +

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

    +

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

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

    This regular expression accomplishes the following:

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

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

    +

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

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

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

    +

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

    +

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

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

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

    +

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

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

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

    +

    Remediation

    +

    There is no fixed version for foundation-sites.

    +

    References

    + + +
    + + + +
    +
    +

    Insufficient Documentation of Error Handling Techniques

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

    Detailed paths

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

    Overview

    +

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

    +

    Workaround

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Insufficient Documentation of Error Handling Techniques

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

    Detailed paths

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

    Overview

    +

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

    +

    Workaround

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.12.10/ghcr.io_dexidp_dex_v2.38.0.html b/docs/snyk/v2.11.12/ghcr.io_dexidp_dex_v2.38.0.html similarity index 79% rename from docs/snyk/v2.12.10/ghcr.io_dexidp_dex_v2.38.0.html rename to docs/snyk/v2.11.12/ghcr.io_dexidp_dex_v2.38.0.html index 372d5e609c..fb7ec90e45 100644 --- a/docs/snyk/v2.12.10/ghcr.io_dexidp_dex_v2.38.0.html +++ b/docs/snyk/v2.11.12/ghcr.io_dexidp_dex_v2.38.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    March 16th 2025, 12:29:08 am (UTC+00:00)

    +

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

    Scanned the following paths: @@ -469,8 +469,8 @@
    -
    52 known vulnerabilities
    -
    158 vulnerable dependency paths
    +
    42 known vulnerabilities
    +
    130 vulnerable dependency paths
    829 dependencies
    @@ -552,86 +552,6 @@

    More about this vulnerability

    - -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/oauth2/jws -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and golang.org/x/oauth2/jws@v0.11.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - › - golang.org/x/oauth2/jws@v0.11.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - › - golang.org/x/oauth2/jws@v0.16.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to improper parsing of malformed tokens which can lead to memory consumption.

    -

    Remediation

    -

    Upgrade golang.org/x/oauth2/jws to version 0.27.0 or higher.

    -

    References

    - - -
    - - -

    Allocation of Resources Without Limits or Throttling

    @@ -713,239 +633,6 @@

    More about this vulnerability

    - -
    -

    Server-side Request Forgery (SSRF)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http/httpproxy -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http/httpproxy@v0.19.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - › - golang.org/x/net/http/httpproxy@v0.19.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - › - golang.org/x/net/http/httpproxy@v0.20.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http/httpproxy is a package for HTTP proxy determination based on environment variables, as provided by net/http's ProxyFromEnvironment function

    -

    Affected versions of this package are vulnerable to Server-side Request Forgery (SSRF) in proxy.go, because hostname matching against proxy patterns may treat an IPv6 zone ID as a hostname component. An environment variable value like *.example.com could be matched to a request intended for [::1%25.example.com]:80.

    -

    Remediation

    -

    Upgrade golang.org/x/net/http/httpproxy to version 0.36.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex › /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/html -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and golang.org/x/net/html@v0.20.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - › - golang.org/x/net/html@v0.20.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) through the functions parseDoctype, htmlIntegrationPoint, inBodyIM and inTableIM due to inefficient usage of the method strings.ToLower combining with the == operator to convert strings to lowercase and then comparing them.

    -

    An attacker can cause the application to slow down significantly by crafting inputs that are processed non-linearly.

    -

    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 golang.org/x/net/html to version 0.33.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/crypto/ssh -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and golang.org/x/crypto/ssh@v0.18.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - › - golang.org/x/crypto/ssh@v0.18.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling in handshakeTransport in handshake.go. An internal queue gets populated with received packets during the key exchange process, while waiting for the client to send a SSH_MSG_KEXINIT. An attacker can cause the server to become unresponsive to new connections by delaying or withholding this message, or by causing the queue to consume all available memory.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - -

    Path Traversal

    @@ -1014,76 +701,6 @@

    More about this vulnerability

    - -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-git/go-git/v5/plumbing -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/go-git/go-git/v5/plumbing@v5.11.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - › - github.com/go-git/go-git/v5/plumbing@v5.11.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    github.com/go-git/go-git/v5/plumbing is a highly extensible git implementation library written in pure Go.

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling via specially crafted responses from a Git server, which triggers resource exhaustion in clients.

    -

    Workaround

    -

    In cases where a bump to the latest version of go-git is not possible, we recommend limiting its use to only trustworthy Git servers.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - -

    Out-of-bounds Write

    @@ -2925,131 +2542,6 @@

    More about this vulnerability

    - -
    -

    Cross-site Scripting (XSS)

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - › - github.com/hashicorp/consul/api@v1.13.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Cross-site Scripting (XSS) via requests sent with a Content-Type text value, which is insufficiently validated against the content of the request.

    -

    Note: This vulnerability has also been patched in Enterprise releases 1.15.16, 1.18.6, and 1.19.4.

    -

    Details

    -

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

    -

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

    -

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

    -

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

    -

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

    -

    Types of attacks

    -

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

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

    Affected environments

    -

    The following environments are susceptible to an XSS attack:

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

    How to prevent

    -

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

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

    Remediation

    -

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

    -

    References

    - - -
    - - -

    MPL-2.0 license

    @@ -3299,143 +2791,6 @@

    More about this vulnerability

    - -
    -

    Allocation of Resources Without Limits or Throttling

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - › - github.com/go-jose/go-jose/v3@v3.0.1 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to the use of strings.Split to split JWT tokens. An attacker can cause memory exhaustion and service disruption by sending numerous malformed tokens with a large number of . characters.

    -

    Workaround

    -

    This vulnerability can be mitigated by pre-validating that payloads passed to Go JOSE do not contain an excessive number of . characters.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    Arbitrary Argument Injection

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-git/go-git/v5/plumbing/transport -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/go-git/go-git/v5/plumbing/transport@v5.11.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - › - github.com/go-git/go-git/v5/plumbing/transport@v5.11.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Arbitrary Argument Injection via a malicious URL value, which allows an attacker to set flags on the git-upload-pack command, if the file: protocol is in use.

    -

    Remediation

    -

    Upgrade github.com/go-git/go-git/v5/plumbing/transport to version 5.13.0 or higher.

    -

    References

    - - -
    - - -

    Out-of-bounds Write

    @@ -5014,357 +4369,6 @@
    -
    -

    CVE-2024-13176

    -
    - -
    - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

    -

    Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

    -

    There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

    -

    Remediation

    -

    Upgrade Alpine:3.19 openssl to version 3.1.8-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2025-26519

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - musl/musl -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and musl/musl@1.2.4_git20230717-r4 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - › - musl/musl@1.2.4_git20230717-r4 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - › - apk-tools/apk-tools@2.14.0-r5 - › - musl/musl@1.2.4_git20230717-r4 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - › - busybox/ssl_client@1.36.1-r15 - › - musl/musl@1.2.4_git20230717-r4 - - - -
    • -
    • - 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 - › - musl/musl@1.2.4_git20230717-r4 - - - -
    • -
    • - 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 - › - musl/musl@1.2.4_git20230717-r4 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - › - apk-tools/apk-tools@2.14.0-r5 - › - zlib/zlib@1.3-r2 - › - musl/musl@1.2.4_git20230717-r4 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - › - libc-dev/libc-utils@0.7.2-r5 - › - musl/musl-utils@1.2.4_git20230717-r4 - › - musl/musl@1.2.4_git20230717-r4 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - › - alpine-baselayout/alpine-baselayout@3.4.3-r2 - › - busybox/busybox-binsh@1.36.1-r15 - › - busybox/busybox@1.36.1-r15 - › - musl/musl@1.2.4_git20230717-r4 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - › - libc-dev/libc-utils@0.7.2-r5 - › - musl/musl-utils@1.2.4_git20230717-r4 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.4_git20230717-r4 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - › - musl/musl-utils@1.2.4_git20230717-r4 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - › - libc-dev/libc-utils@0.7.2-r5 - › - musl/musl-utils@1.2.4_git20230717-r4 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

    -

    Remediation

    -

    Upgrade Alpine:3.19 musl to version 1.2.4_git20230717-r5 or higher.

    -

    References

    - - -
    - - - -
    diff --git a/docs/snyk/v2.11.12/haproxy_2.6.14-alpine.html b/docs/snyk/v2.11.12/haproxy_2.6.14-alpine.html new file mode 100644 index 0000000000..3e1a3e3b56 --- /dev/null +++ b/docs/snyk/v2.11.12/haproxy_2.6.14-alpine.html @@ -0,0 +1,2965 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

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

    +
    +
    + Scanned the following path: +
      +
    • haproxy:2.6.14-alpine (apk)
    • +
    +
    + +
    +
    15 known vulnerabilities
    +
    119 vulnerable dependency paths
    +
    18 dependencies
    +
    +
    +
    +
    +
    + + + + + + + +
    Project docker-image|haproxy
    Path haproxy:2.6.14-alpine
    Package Manager apk
    +
    +
    +
    +
    +

    CVE-2023-5363

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Improper Check for Unusual or Exceptional Conditions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: Generating excessively long X9.42 DH keys or checking + excessively long X9.42 DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_generate_key() to + generate an X9.42 DH key may experience long delays. Likewise, applications + that use DH_check_pub_key(), DH_check_pub_key_ex() or EVP_PKEY_public_check() + to check an X9.42 DH key or X9.42 DH parameters may experience long delays. + Where the key or parameters that are being checked have been obtained from + an untrusted source this may lead to a Denial of Service.

    +

    While DH_check() performs all the necessary checks (as of CVE-2023-3817), + DH_check_pub_key() doesn't make any of these checks, and is therefore + vulnerable for excessively large P and Q parameters.

    +

    Likewise, while DH_generate_key() performs a check for an excessively large + P, it doesn't check for an excessively large Q.

    +

    An application that calls DH_generate_key() or DH_check_pub_key() and + supplies a key or parameters obtained from an untrusted source could be + vulnerable to a Denial of Service attack.

    +

    DH_generate_key() and DH_check_pub_key() are also called by a number of + other OpenSSL functions. An application calling any of those other + functions may similarly be affected. The other functions affected by this + are DH_check_pub_key_ex(), EVP_PKEY_public_check(), and EVP_PKEY_generate().

    +

    Also vulnerable are the OpenSSL pkey command line application when using the + "-pubcheck" option, as well as the OpenSSL genpkey command line application.

    +

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

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Out-of-bounds Write

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-0727

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: Processing a maliciously formatted PKCS12 file may lead OpenSSL + to crash leading to a potential Denial of Service attack

    +

    Impact summary: Applications loading files in the PKCS12 format from untrusted + sources might terminate abruptly.

    +

    A file in PKCS12 format can contain certificates and keys and may come from an + untrusted source. The PKCS12 specification allows certain fields to be NULL, but + OpenSSL does not correctly check for this case. This can lead to a NULL pointer + dereference that results in OpenSSL crashing. If an application processes PKCS12 + files from an untrusted source using the OpenSSL APIs then that application will + be vulnerable to this issue.

    +

    OpenSSL APIs that are vulnerable to this are: PKCS12_parse(), + PKCS12_unpack_p7data(), PKCS12_unpack_p7encdata(), PKCS12_unpack_authsafes() + and PKCS12_newpass().

    +

    We have also fixed a similar issue in SMIME_write_PKCS7(). However since this + function is related to writing data we do not consider it security significant.

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Out-of-bounds Write

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and busybox/busybox@1.36.1-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/busybox@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + alpine-baselayout/alpine-baselayout@3.4.3-r1 + › + busybox/busybox-binsh@1.36.1-r2 + › + busybox/busybox@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/busybox-binsh@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + alpine-baselayout/alpine-baselayout@3.4.3-r1 + › + busybox/busybox-binsh@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    A heap-buffer-overflow was discovered in BusyBox v.1.36.1 in the next_token function at awk.c:1159.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Use After Free

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and busybox/busybox@1.36.1-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/busybox@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + alpine-baselayout/alpine-baselayout@3.4.3-r1 + › + busybox/busybox-binsh@1.36.1-r2 + › + busybox/busybox@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/busybox-binsh@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + alpine-baselayout/alpine-baselayout@3.4.3-r1 + › + busybox/busybox-binsh@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    A use-after-free vulnerability was discovered in xasprintf function in xfuncs_printf.c:344 in BusyBox v.1.36.1.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Use After Free

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and busybox/busybox@1.36.1-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/busybox@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + alpine-baselayout/alpine-baselayout@3.4.3-r1 + › + busybox/busybox-binsh@1.36.1-r2 + › + busybox/busybox@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/busybox-binsh@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + alpine-baselayout/alpine-baselayout@3.4.3-r1 + › + busybox/busybox-binsh@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    A use-after-free vulnerability in BusyBox v.1.36.1 allows attackers to cause a denial of service via a crafted awk pattern in the awk.c evaluate function.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Use After Free

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and busybox/busybox@1.36.1-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/busybox@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + alpine-baselayout/alpine-baselayout@3.4.3-r1 + › + busybox/busybox-binsh@1.36.1-r2 + › + busybox/busybox@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/busybox-binsh@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + alpine-baselayout/alpine-baselayout@3.4.3-r1 + › + busybox/busybox-binsh@1.36.1-r2 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    A use-after-free vulnerability was discovered in BusyBox v.1.36.1 via a crafted awk pattern in the awk.c copyvar function.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-6237

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: Checking excessively long invalid RSA public keys may take + a long time.

    +

    Impact summary: Applications that use the function EVP_PKEY_public_check() + to check RSA public keys may experience long delays. Where the key that + is being checked has been obtained from an untrusted source this may lead + to a Denial of Service.

    +

    When function EVP_PKEY_public_check() is called on RSA public keys, + a computation is done to confirm that the RSA modulus, n, is composite. + For valid RSA keys, n is a product of two or more large primes and this + computation completes quickly. However, if n is an overly large prime, + then this computation would take a long time.

    +

    An application that calls EVP_PKEY_public_check() and supplies an RSA key + obtained from an untrusted source could be vulnerable to a Denial of Service + attack.

    +

    The function EVP_PKEY_public_check() is not called from other OpenSSL + functions however it is called from the OpenSSL pkey command line + application. For that reason that application is also vulnerable if used + with the '-pubin' and '-check' options on untrusted data.

    +

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

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are affected by this issue.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-2511

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: Some non-default TLS server configurations can cause unbounded + memory growth when processing TLSv1.3 sessions

    +

    Impact summary: An attacker may exploit certain server configurations to trigger + unbounded memory growth that would lead to a Denial of Service

    +

    This problem can occur in TLSv1.3 if the non-default SSL_OP_NO_TICKET option is + being used (but not if early_data support is also configured and the default + anti-replay protection is in use). In this case, under certain conditions, the + session cache can get into an incorrect state and it will fail to flush properly + as it fills. The session cache will continue to grow in an unbounded manner. A + malicious client could deliberately create the scenario for this failure to + force a Denial of Service. It may also happen by accident in normal operation.

    +

    This issue only affects TLS servers supporting TLSv1.3. It does not affect TLS + clients.

    +

    The FIPS modules in 3.2, 3.1 and 3.0 are not affected by this issue. OpenSSL + 1.0.2 is also not affected by this issue.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-4603

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: Checking excessively long DSA keys or parameters may be very + slow.

    +

    Impact summary: Applications that use the functions EVP_PKEY_param_check() + or EVP_PKEY_public_check() to check a DSA public key or DSA parameters may + experience long delays. Where the key or parameters that are being checked + have been obtained from an untrusted source this may lead to a Denial of + Service.

    +

    The functions EVP_PKEY_param_check() or EVP_PKEY_public_check() perform + various checks on DSA parameters. Some of those computations take a long time + if the modulus (p parameter) is too large.

    +

    Trying to use a very large modulus is slow and OpenSSL will not allow using + public keys with a modulus which is over 10,000 bits in length for signature + verification. However the key and parameter check functions do not limit + the modulus size when performing the checks.

    +

    An application that calls EVP_PKEY_param_check() or EVP_PKEY_public_check() + and supplies a key or parameters obtained from an untrusted source could be + vulnerable to a Denial of Service attack.

    +

    These functions are not called by OpenSSL itself on untrusted DSA keys so + only applications that directly call these functions may be vulnerable.

    +

    Also vulnerable are the OpenSSL pkey and pkeyparam command line applications + when using the -check option.

    +

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

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are affected by this issue.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-5535

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: Calling the OpenSSL API function SSL_select_next_proto with an + empty supported client protocols buffer may cause a crash or memory contents to + be sent to the peer.

    +

    Impact summary: A buffer overread can have a range of potential consequences + such as unexpected application beahviour or a crash. In particular this issue + could result in up to 255 bytes of arbitrary private data from memory being sent + to the peer leading to a loss of confidentiality. However, only applications + that directly call the SSL_select_next_proto function with a 0 length list of + supported client protocols are affected by this issue. This would normally never + be a valid scenario and is typically not under attacker control but may occur by + accident in the case of a configuration or programming error in the calling + application.

    +

    The OpenSSL API function SSL_select_next_proto is typically used by TLS + applications that support ALPN (Application Layer Protocol Negotiation) or NPN + (Next Protocol Negotiation). NPN is older, was never standardised and + is deprecated in favour of ALPN. We believe that ALPN is significantly more + widely deployed than NPN. The SSL_select_next_proto function accepts a list of + protocols from the server and a list of protocols from the client and returns + the first protocol that appears in the server list that also appears in the + client list. In the case of no overlap between the two lists it returns the + first item in the client list. In either case it will signal whether an overlap + between the two lists was found. In the case where SSL_select_next_proto is + called with a zero length client list it fails to notice this condition and + returns the memory immediately following the client list pointer (and reports + that there was no overlap in the lists).

    +

    This function is typically called from a server side application callback for + ALPN or a client side application callback for NPN. In the case of ALPN the list + of protocols supplied by the client is guaranteed by libssl to never be zero in + length. The list of server protocols comes from the application and should never + normally be expected to be of zero length. In this case if the + SSL_select_next_proto function has been called as expected (with the list + supplied by the client passed in the client/client_len parameters), then the + application will not be vulnerable to this issue. If the application has + accidentally been configured with a zero length server list, and has + accidentally passed that zero length server list in the client/client_len + parameters, and has additionally failed to correctly handle a "no overlap" + response (which would normally result in a handshake failure in ALPN) then it + will be vulnerable to this problem.

    +

    In the case of NPN, the protocol permits the client to opportunistically select + a protocol when there is no overlap. OpenSSL returns the first client protocol + in the no overlap case in support of this. The list of client protocols comes + from the application and should never normally be expected to be of zero length. + However if the SSL_select_next_proto function is accidentally called with a + client_len of 0 then an invalid memory pointer will be returned instead. If the + application uses this output as the opportunistic protocol then the loss of + confidentiality will occur.

    +

    This issue has been assessed as Low severity because applications are most + likely to be vulnerable if they are using NPN instead of ALPN - but NPN is not + widely used. It also requires an application configuration or programming error. + Finally, this issue would not typically be under attacker control making active + exploitation unlikely.

    +

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

    +

    Due to the low severity of this issue we are not issuing new releases of + OpenSSL at this time. The fix will be included in the next releases when they + become available.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-4741

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-6119

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + › + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + .haproxy-rundeps@20230809.001942 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + apk-tools/apk-tools@2.14.0-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + › + busybox/ssl_client@1.36.1-r2 + › + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: Applications performing certificate name checks (e.g., TLS + clients checking server certificates) may attempt to read an invalid memory + address resulting in abnormal termination of the application process.

    +

    Impact summary: Abnormal termination of an application can a cause a denial of + service.

    +

    Applications performing certificate name checks (e.g., TLS clients checking + server certificates) may attempt to read an invalid memory address when + comparing the expected name with an otherName subject alternative name of an + X.509 certificate. This may result in an exception that terminates the + application program.

    +

    Note that basic certificate chain validation (signatures, dates, ...) is not + affected, the denial of service can occur only when the application also + specifies an expected DNS name, Email address or IP address.

    +

    TLS servers rarely solicit client certificates, and even when they do, they + generally don't perform a name check against a reference identifier (expected + identity), but rather extract the presented identity after checking the + certificate chain. So TLS servers are generally not affected and the severity + of the issue is Moderate.

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    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.12.10/quay.io_argoproj_argocd_v2.12.10.html b/docs/snyk/v2.11.12/quay.io_argoproj_argocd_v2.11.12.html similarity index 69% rename from docs/snyk/v2.12.10/quay.io_argoproj_argocd_v2.12.10.html rename to docs/snyk/v2.11.12/quay.io_argoproj_argocd_v2.11.12.html index 14a804c200..30082caf72 100644 --- a/docs/snyk/v2.12.10/quay.io_argoproj_argocd_v2.12.10.html +++ b/docs/snyk/v2.11.12/quay.io_argoproj_argocd_v2.11.12.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,23 +456,23 @@

    Snyk test report

    -

    March 16th 2025, 12:29:34 am (UTC+00:00)

    +

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

    Scanned the following paths:
      -
    • quay.io/argoproj/argocd:v2.12.10/argoproj/argocd/Dockerfile (deb)
    • -
    • quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.12.10//usr/local/bin/kustomize (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.12.10/helm/v3//usr/local/bin/helm (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.12.10/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.12/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.12//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.12/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.12/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    -
    42 known vulnerabilities
    -
    172 vulnerable dependency paths
    -
    2292 dependencies
    +
    38 known vulnerabilities
    +
    210 vulnerable dependency paths
    +
    2280 dependencies
    @@ -480,19 +480,19 @@
    -
    -

    Allocation of Resources Without Limits or Throttling

    +
    +

    Incorrect Implementation of Authentication Algorithm

    -
    - high severity +
    + critical severity

    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • Package Manager: golang @@ -500,12 +500,12 @@
    • Vulnerable module: - golang.org/x/oauth2/jws + golang.org/x/crypto/ssh
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and golang.org/x/oauth2/jws@v0.12.0 + github.com/argoproj/argo-cd/v2@* and golang.org/x/crypto/ssh@v0.19.0
    @@ -520,7 +520,7 @@ Introduced through: github.com/argoproj/argo-cd/v2@* › - golang.org/x/oauth2/jws@v0.12.0 + golang.org/x/crypto/ssh@v0.19.0 @@ -532,93 +532,25 @@

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to improper parsing of malformed tokens which can lead to memory consumption.

    +

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

    +

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

    +

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

    Remediation

    -

    Upgrade golang.org/x/oauth2/jws to version 0.27.0 or higher.

    +

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

    References


    - -
    -
    -

    Server-side Request Forgery (SSRF)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http/httpproxy -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and golang.org/x/net/http/httpproxy@v0.33.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - golang.org/x/net/http/httpproxy@v0.33.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http/httpproxy is a package for HTTP proxy determination based on environment variables, as provided by net/http's ProxyFromEnvironment function

    -

    Affected versions of this package are vulnerable to Server-side Request Forgery (SSRF) in proxy.go, because hostname matching against proxy patterns may treat an IPv6 zone ID as a hostname component. An environment variable value like *.example.com could be matched to a request intended for [::1%25.example.com]:80.

    -

    Remediation

    -

    Upgrade golang.org/x/net/http/httpproxy to version 0.36.0 or higher.

    -

    References

    - - -
    - -
    @@ -634,7 +566,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/helm/v3 › /usr/local/bin/helm + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • Package Manager: golang @@ -642,12 +574,12 @@
    • Vulnerable module: - golang.org/x/net/html + k8s.io/apimachinery/pkg/util/runtime
    • Introduced through: - helm.sh/helm/v3@* and golang.org/x/net/html@v0.23.0 + github.com/argoproj/argo-cd/v2@* and k8s.io/apimachinery/pkg/util/runtime@v0.26.11
    @@ -660,9 +592,9 @@
    • Introduced through: - helm.sh/helm/v3@* + github.com/argoproj/argo-cd/v2@* › - golang.org/x/net/html@v0.23.0 + k8s.io/apimachinery/pkg/util/runtime@v0.26.11 @@ -674,9 +606,7 @@

      Overview

      -

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

      -

      Affected versions of this package are vulnerable to Denial of Service (DoS) through the functions parseDoctype, htmlIntegrationPoint, inBodyIM and inTableIM due to inefficient usage of the method strings.ToLower combining with the == operator to convert strings to lowercase and then comparing them.

      -

      An attacker can cause the application to slow down significantly by crafting inputs that are processed non-linearly.

      +

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

      Details

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

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

      @@ -690,18 +620,31 @@

    Remediation

    -

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

    +

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

    References


    @@ -717,7 +660,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • Package Manager: golang @@ -725,12 +668,12 @@
    • Vulnerable module: - golang.org/x/crypto/ssh + golang.org/x/net/http2
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and golang.org/x/crypto/ssh@v0.31.0 + github.com/argoproj/argo-cd/v2@* and golang.org/x/net/http2@v0.19.0
    @@ -745,7 +688,16 @@ Introduced through: github.com/argoproj/argo-cd/v2@* › - golang.org/x/crypto/ssh@v0.31.0 + golang.org/x/net/http2@v0.19.0 + + + + +
  • + Introduced through: + helm.sh/helm/v3@* + › + golang.org/x/net/http2@v0.17.0 @@ -757,126 +709,23 @@

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling in handshakeTransport in handshake.go. An internal queue gets populated with received packets during the key exchange process, while waiting for the client to send a SSH_MSG_KEXINIT. An attacker can cause the server to become unresponsive to new connections by delaying or withholding this message, or by causing the queue to consume all available memory.

    +

    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/crypto/ssh to version 0.35.0 or higher.

    +

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

    References


    - -
  • -
    -

    CVE-2024-56433

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - shadow/passwd -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.12.10 and shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 - › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - apt@2.7.14build2 - › - adduser@3.137ubuntu1 - › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - shadow/login@1:4.13+dfsg1-4ubuntu3.2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    shadow-utils (aka shadow) 4.4 through 4.17.0 establishes a default /etc/subuid behavior (e.g., uid 100000 through 165535 for the first user account) that can realistically conflict with the uids of users defined on locally administered networks, potentially leading to account takeover, e.g., by leveraging newuidmap for access to an NFS home directory (or same-host resources in the case of remote logins by these local network users). NOTE: it may also be argued that system administrators should not have assigned uids, within local networks, that are within the range that can occur in /etc/subuid.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:24.04 shadow.

    -

    References

    - - -
    - -
    @@ -892,10 +741,10 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: @@ -905,7 +754,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 and pam/libpam0g@1.5.3-5ubuntu5.1 + docker-image|quay.io/argoproj/argocd@v2.11.12 and pam/libpam0g@1.4.0-11ubuntu2.4
    @@ -918,174 +767,164 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - pam/libpam0g@1.5.3-5ubuntu5.1 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - shadow/login@1:4.13+dfsg1-4ubuntu3.2 + shadow/login@1:4.8.1-2ubuntu2.2 › - pam/libpam0g@1.5.3-5ubuntu5.1 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - util-linux@2.39.3-9ubuntu6.2 + util-linux@2.37.2-4ubuntu3.4 › - pam/libpam0g@1.5.3-5ubuntu5.1 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + adduser@3.118ubuntu5 › - adduser@3.137ubuntu1 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - › - pam/libpam0g@1.5.3-5ubuntu5.1 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + adduser@3.118ubuntu5 › - adduser@3.137ubuntu1 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - pam/libpam-modules@1.5.3-5ubuntu5.1 - › - pam/libpam0g@1.5.3-5ubuntu5.1 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + adduser@3.118ubuntu5 › - adduser@3.137ubuntu1 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - pam/libpam-modules@1.5.3-5ubuntu5.1 + pam/libpam-modules-bin@1.4.0-11ubuntu2.4 › - pam/libpam-modules-bin@1.5.3-5ubuntu5.1 - › - pam/libpam0g@1.5.3-5ubuntu5.1 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + pam/libpam-modules-bin@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + adduser@3.118ubuntu5 › - adduser@3.137ubuntu1 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - pam/libpam-modules@1.5.3-5ubuntu5.1 - › - pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + pam/libpam-modules-bin@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - pam/libpam-modules@1.5.3-5ubuntu5.1 + pam/libpam-modules@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - pam/libpam-runtime@1.5.3-5ubuntu5.1 + pam/libpam-runtime@1.4.0-11ubuntu2.4 › - pam/libpam-modules@1.5.3-5ubuntu5.1 + pam/libpam-modules@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - shadow/login@1:4.13+dfsg1-4ubuntu3.2 + shadow/login@1:4.8.1-2ubuntu2.2 › - pam/libpam-modules@1.5.3-5ubuntu5.1 + pam/libpam-modules@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + adduser@3.118ubuntu5 › - adduser@3.137ubuntu1 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - › - pam/libpam-modules@1.5.3-5ubuntu5.1 + pam/libpam-modules@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - pam/libpam-runtime@1.5.3-5ubuntu5.1 + pam/libpam-runtime@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - shadow/login@1:4.13+dfsg1-4ubuntu3.2 + shadow/login@1:4.8.1-2ubuntu2.2 › - pam/libpam-runtime@1.5.3-5ubuntu5.1 + pam/libpam-runtime@1.4.0-11ubuntu2.4 @@ -1098,10 +937,10 @@

      NVD Description

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

      + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

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

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 pam.

      +

      There is no fixed version for Ubuntu:22.04 pam.

      References


    @@ -1131,10 +969,10 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: @@ -1144,7 +982,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 and pam/libpam0g@1.5.3-5ubuntu5.1 + docker-image|quay.io/argoproj/argocd@v2.11.12 and pam/libpam0g@1.4.0-11ubuntu2.4
    @@ -1157,174 +995,164 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - pam/libpam0g@1.5.3-5ubuntu5.1 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - shadow/login@1:4.13+dfsg1-4ubuntu3.2 + shadow/login@1:4.8.1-2ubuntu2.2 › - pam/libpam0g@1.5.3-5ubuntu5.1 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - util-linux@2.39.3-9ubuntu6.2 + util-linux@2.37.2-4ubuntu3.4 › - pam/libpam0g@1.5.3-5ubuntu5.1 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + adduser@3.118ubuntu5 › - adduser@3.137ubuntu1 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - › - pam/libpam0g@1.5.3-5ubuntu5.1 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + adduser@3.118ubuntu5 › - adduser@3.137ubuntu1 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - pam/libpam-modules@1.5.3-5ubuntu5.1 - › - pam/libpam0g@1.5.3-5ubuntu5.1 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + adduser@3.118ubuntu5 › - adduser@3.137ubuntu1 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - pam/libpam-modules@1.5.3-5ubuntu5.1 + pam/libpam-modules-bin@1.4.0-11ubuntu2.4 › - pam/libpam-modules-bin@1.5.3-5ubuntu5.1 - › - pam/libpam0g@1.5.3-5ubuntu5.1 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + pam/libpam-modules-bin@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + adduser@3.118ubuntu5 › - adduser@3.137ubuntu1 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - pam/libpam-modules@1.5.3-5ubuntu5.1 - › - pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + pam/libpam-modules-bin@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - pam/libpam-modules@1.5.3-5ubuntu5.1 + pam/libpam-modules@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - pam/libpam-runtime@1.5.3-5ubuntu5.1 + pam/libpam-runtime@1.4.0-11ubuntu2.4 › - pam/libpam-modules@1.5.3-5ubuntu5.1 + pam/libpam-modules@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - shadow/login@1:4.13+dfsg1-4ubuntu3.2 + shadow/login@1:4.8.1-2ubuntu2.2 › - pam/libpam-modules@1.5.3-5ubuntu5.1 + pam/libpam-modules@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + adduser@3.118ubuntu5 › - adduser@3.137ubuntu1 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - › - pam/libpam-modules@1.5.3-5ubuntu5.1 + pam/libpam-modules@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - pam/libpam-runtime@1.5.3-5ubuntu5.1 + pam/libpam-runtime@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - shadow/login@1:4.13+dfsg1-4ubuntu3.2 + shadow/login@1:4.8.1-2ubuntu2.2 › - pam/libpam-runtime@1.5.3-5ubuntu5.1 + pam/libpam-runtime@1.4.0-11ubuntu2.4 @@ -1337,32 +1165,26 @@

      NVD Description

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

      + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

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

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 pam.

      +

      There is no fixed version for Ubuntu:22.04 pam.

      References


    -

    Resource Exhaustion

    +

    CVE-2024-26462

    @@ -1373,365 +1195,10 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - openssh/openssh-client -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.12.10 and openssh/openssh-client@1:9.6p1-3ubuntu13.5 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    A flaw was found in the OpenSSH package. For each ping packet the SSH server receives, a pong packet is allocated in a memory buffer and stored in a queue of packages. It is only freed when the server/client key exchange has finished. A malicious client may keep sending such packages, leading to an uncontrolled increase in memory consumption on the server side. Consequently, the server may become unavailable, resulting in a denial of service attack.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 openssh to version 1:9.6p1-3ubuntu13.8 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Detection of Error Condition Without Action

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - openssh/openssh-client -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.12.10 and openssh/openssh-client@1:9.6p1-3ubuntu13.5 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    A vulnerability was found in OpenSSH when the VerifyHostKeyDNS option is enabled. A machine-in-the-middle attack can be performed by a malicious machine impersonating a legit server. This issue occurs due to how OpenSSH mishandles error codes in specific conditions when verifying the host key. For an attack to be considered successful, the attacker needs to manage to exhaust the client's memory resource first, turning the attack complexity high.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 openssh to version 1:9.6p1-3ubuntu13.8 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Algorithmic Complexity

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - libtasn1-6 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.12.10 and libtasn1-6@4.19.0-3build1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - libtasn1-6@4.19.0-3build1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - apt@2.7.14build2 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - › - libtasn1-6@4.19.0-3build1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    A flaw in libtasn1 causes inefficient handling of specific certificate data. When processing a large number of elements in a certificate, libtasn1 takes much longer than expected, which can slow down or even crash the system. This flaw allows an attacker to send a specially crafted certificate, causing a denial of service attack.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 libtasn1-6 to version 4.19.0-3ubuntu0.24.04.1 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2025-1390

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - libcap2 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.12.10 and libcap2@1:2.66-5ubuntu2.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - libcap2@1:2.66-5ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - apt@2.7.14build2 - › - apt/libapt-pkg6.0t64@2.7.14build2 - › - systemd/libudev1@255.4-1ubuntu8.5 - › - libcap2@1:2.66-5ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - 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.5 - › - libcap2@1:2.66-5ubuntu2.1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    The PAM module pam_cap.so of libcap configuration supports group names starting with “@”, during actual parsing, configurations not starting with “@” are incorrectly recognized as group names. This may result in nonintended users being granted an inherited capability set, potentially leading to security risks. Attackers can exploit this vulnerability to achieve local privilege escalation on systems where /etc/security/capability.conf is used to configure user inherited privileges by constructing specific usernames.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 libcap2 to version 1:2.66-5ubuntu2.2 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Memory Leak

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: @@ -1741,8 +1208,8 @@
    • Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 and krb5/libk5crypto3@1.19.2-2ubuntu0.4 - docker-image|quay.io/argoproj/argocd@v2.12.10, git@1:2.43.0-1ubuntu7.2 and others
    @@ -1754,146 +1221,159 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + adduser@3.118ubuntu5 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 + libnsl/libnsl2@1.3.0-2build2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + › + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + › + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + adduser@3.118ubuntu5 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 + libnsl/libnsl2@1.3.0-2build2 + › + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + › + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + › + krb5/libkrb5-3@1.19.2-2ubuntu0.4 + › + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + adduser@3.118ubuntu5 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 + libnsl/libnsl2@1.3.0-2build2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 + 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.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.34.1-1ubuntu1.11 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.34.1-1ubuntu1.11 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 › - libssh/libssh-4@0.10.6-2build2 + libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - krb5/krb5-locales@1.20.1-6ubuntu2.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 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -1906,10 +1386,10 @@

      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.

      + 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

      -

      Upgrade Ubuntu:24.04 krb5 to version 1.20.1-6ubuntu2.5 or higher.

      +

      There is no fixed version for Ubuntu:22.04 krb5.

      References

    -
    -

    Improper Validation of Integrity Check Value

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - krb5/libk5crypto3 -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.12.10, git@1:2.43.0-1ubuntu7.2 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 - › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - libssh/libssh-4@0.10.6-2build2 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - krb5/krb5-locales@1.20.1-6ubuntu2.2 - - - -
    • -
    - -
    - -
    - -

    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.

    -

    RADIUS Protocol under RFC 2865 is susceptible to forgery attacks by a local attacker who can modify any valid Response (Access-Accept, Access-Reject, or Access-Challenge) to any other response using a chosen-prefix collision attack against MD5 Response Authenticator signature.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 krb5 to version 1.20.1-6ubuntu2.3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2025-24528

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - krb5/libk5crypto3 -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.12.10, git@1:2.43.0-1ubuntu7.2 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 - › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - libssh/libssh-4@0.10.6-2build2 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - krb5/krb5-locales@1.20.1-6ubuntu2.2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 krb5 to version 1.20.1-6ubuntu2.5 or higher.

    -

    References

    - - -
    - -
    @@ -2355,7 +1416,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • Package Manager: golang @@ -2402,229 +1463,6 @@

      More about this vulnerability

    -
    -
    -

    Algorithmic Complexity

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - gnutls28/libgnutls30t64 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.12.10 and gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - apt@2.7.14build2 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - gnupg2/dirmngr@2.4.4-2ubuntu17 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - rtmpdump/librtmp1@2.4+20151223.gitfa8646d.1-2build7 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    A flaw was found in GnuTLS, which relies on libtasn1 for ASN.1 data processing. Due to an inefficient algorithm in libtasn1, decoding certain DER-encoded certificate data can take excessive time, leading to increased resource consumption. This flaw allows a remote attacker to send a specially crafted certificate, causing GnuTLS to become unresponsive or slow, resulting in a denial-of-service condition.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 gnutls28 to version 3.8.3-1.1ubuntu3.3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2025-0395

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - glibc/libc-bin -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.12.10 and glibc/libc-bin@2.39-0ubuntu8.3 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - glibc/libc-bin@2.39-0ubuntu8.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - 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.

    -

    When the assert() function in the GNU C Library versions 2.13 to 2.40 fails, it does not allocate enough space for the assertion failure message string and size information, which may lead to a buffer overflow if the message string size aligns to page size.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 glibc to version 2.39-0ubuntu8.4 or higher.

    -

    References

    - - -
    - - -

    Denial of Service (DoS)

    @@ -2638,7 +1476,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • Package Manager: golang @@ -2748,7 +1586,7 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 › /usr/local/bin/argocd
      • Package Manager: golang @@ -2808,7 +1646,7 @@
        • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 › /usr/local/bin/argocd
        • Package Manager: golang @@ -2821,7 +1659,7 @@
        • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-version@v1.6.0 + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-version@v1.2.1
        @@ -2836,7 +1674,7 @@ Introduced through: github.com/argoproj/argo-cd/v2@* › - github.com/hashicorp/go-version@v1.6.0 + github.com/hashicorp/go-version@v1.2.1 @@ -2857,7 +1695,7 @@
    -

    MPL-2.0 license

    +

    Insertion of Sensitive Information into Log File

    @@ -2868,20 +1706,20 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • Package Manager: golang
    • - Module: + Vulnerable module: github.com/hashicorp/go-retryablehttp
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.7 + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.4
    @@ -2896,7 +1734,75 @@ Introduced through: github.com/argoproj/argo-cd/v2@* › - github.com/hashicorp/go-retryablehttp@v0.7.7 + 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

    + + +
    + + + +
    +
    +

    MPL-2.0 license

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

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + › + github.com/hashicorp/go-retryablehttp@v0.7.4 @@ -2928,7 +1834,7 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.12.10/helm/v3 › /usr/local/bin/helm + Manifest file: quay.io/argoproj/argocd:v2.11.12/helm/v3 › /usr/local/bin/helm
      • Package Manager: golang @@ -2988,7 +1894,7 @@
        • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 › /usr/local/bin/argocd
        • Package Manager: golang @@ -3048,7 +1954,7 @@
          • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 › /usr/local/bin/argocd
          • Package Manager: golang @@ -3097,7 +2003,7 @@
    -

    Allocation of Resources Without Limits or Throttling

    +

    CVE-2023-4039

    @@ -3108,20 +2014,20 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: golang + Package Manager: ubuntu:22.04
    • Vulnerable module: - github.com/go-jose/go-jose/v3 + gcc-12/libstdc++6
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/go-jose/go-jose/v3@v3.0.3 + docker-image|quay.io/argoproj/argocd@v2.11.12 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04
    @@ -3134,239 +2040,51 @@
    • Introduced through: - github.com/argoproj/argo-cd/v2@* + docker-image|quay.io/argoproj/argocd@v2.11.12 › - github.com/go-jose/go-jose/v3@v3.0.3 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to the use of strings.Split to split JWT tokens. An attacker can cause memory exhaustion and service disruption by sending numerous malformed tokens with a large number of . characters.

    -

    Workaround

    -

    This vulnerability can be mitigated by pre-validating that payloads passed to Go JOSE do not contain an excessive number of . characters.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    Generation of Error Message Containing Sensitive Information

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/argoproj/gitops-engine/pkg/utils/kube -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/argoproj/gitops-engine/pkg/utils/kube@v0.7.1-0.20250129155113-faf5a4e5c37d - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - github.com/argoproj/gitops-engine/pkg/utils/kube@v0.7.1-0.20250129155113-faf5a4e5c37d - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Generation of Error Message Containing Sensitive Information when syncing invalid Kubernetes Secret resources. An attacker with write access to the repository can expose secret values by committing an invalid Secret to repository and triggering a Sync, which then become visible to any user with read access to Argo CD.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    Generation of Error Message Containing Sensitive Information

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/argoproj/gitops-engine/pkg/diff -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/argoproj/gitops-engine/pkg/diff@v0.7.1-0.20250129155113-faf5a4e5c37d - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - github.com/argoproj/gitops-engine/pkg/diff@v0.7.1-0.20250129155113-faf5a4e5c37d - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Generation of Error Message Containing Sensitive Information when syncing invalid Kubernetes Secret resources. An attacker with write access to the repository can expose secret values by committing an invalid Secret to repository and triggering a Sync, which then become visible to any user with read access to Argo CD.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    Improper Encoding or Escaping of Output

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - git/git-man -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.12.10, git@1:2.43.0-1ubuntu7.2 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - git@1:2.43.0-1ubuntu7.2 - › - git/git-man@1:2.43.0-1ubuntu7.2 + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + apt@2.4.13 + › + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git-lfs@3.4.1-1ubuntu0.2 + apt@2.4.13 › - git@1:2.43.0-1ubuntu7.2 + apt/libapt-pkg6.0@2.4.13 + › + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 @@ -3378,22 +2096,476 @@

      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 is a source code management tool. When cloning from a server (or fetching, or pushing), informational or error messages are transported from the remote Git process to the client via the so-called "sideband channel". These messages will be prefixed with "remote:" and printed directly to the standard error output. Typically, this standard error output is connected to a terminal that understands ANSI escape sequences, which Git did not protect against. Most modern terminals support control sequences that can be used by a malicious actor to hide and misrepresent information, or to mislead the user into executing untrusted scripts. As requested on the git-security mailing list, the patches are under discussion on the public mailing list. Users are advised to update as soon as possible. Users unable to upgrade should avoid recursive clones unless they are from trusted sources.

      +

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

      +

      DISPUTEDA failure in the -fstack-protector feature in GCC-based toolchains + that target AArch64 allows an attacker to exploit an existing buffer + overflow in dynamically-sized local variables in your application + without this being detected. This stack-protector failure only applies + to C99-style dynamically-sized local variables or those created using + alloca(). The stack-protector operates as intended for statically-sized + local variables.

      +

      The default behavior when the stack-protector + detects an overflow is to terminate your application, resulting in + controlled loss of availability. An attacker who can exploit a buffer + overflow without triggering the stack-protector might be able to change + program flow control to cause an uncontrolled loss of availability or to + go further and affect confidentiality or integrity. NOTE: The GCC project argues that this is a missed hardening bug and not a vulnerability by itself.

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 git.

      +

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

      References


      + +
    +
    +

    CVE-2023-7008

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + systemd/libsystemd0 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.11.12 and systemd/libsystemd0@249.11-0ubuntu3.12 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + systemd/libsystemd0@249.11-0ubuntu3.12 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + apt@2.4.13 + › + systemd/libsystemd0@249.11-0ubuntu3.12 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + procps/libprocps8@2:3.3.17-6ubuntu2.1 + › + systemd/libsystemd0@249.11-0ubuntu3.12 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + util-linux@2.37.2-4ubuntu3.4 + › + systemd/libsystemd0@249.11-0ubuntu3.12 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + util-linux/bsdutils@1:2.37.2-4ubuntu3.4 + › + systemd/libsystemd0@249.11-0ubuntu3.12 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + apt@2.4.13 + › + apt/libapt-pkg6.0@2.4.13 + › + systemd/libsystemd0@249.11-0ubuntu3.12 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + systemd/libudev1@249.11-0ubuntu3.12 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + libfido2/libfido2-1@1.10.0-1 + › + systemd/libudev1@249.11-0ubuntu3.12 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + util-linux@2.37.2-4ubuntu3.4 + › + systemd/libudev1@249.11-0ubuntu3.12 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + apt@2.4.13 + › + apt/libapt-pkg6.0@2.4.13 + › + systemd/libudev1@249.11-0ubuntu3.12 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    A vulnerability was found in systemd-resolved. This issue may allow systemd-resolved to accept records of DNSSEC-signed domains even when they have no signature, allowing man-in-the-middles (or the upstream DNS resolver) to manipulate records.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 systemd.

    +

    References

    + + +
    + + + +
    +
    +

    Arbitrary Code Injection

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + shadow/passwd +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.11.12 and shadow/passwd@1:4.8.1-2ubuntu2.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + shadow/passwd@1:4.8.1-2ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + adduser@3.118ubuntu5 + › + shadow/passwd@1:4.8.1-2ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + openssh/openssh-client@1:8.9p1-3ubuntu0.10 + › + shadow/passwd@1:4.8.1-2ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + shadow/login@1:4.8.1-2ubuntu2.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    In Shadow 4.13, it is possible to inject control characters into fields provided to the SUID program chfn (change finger). Although it is not possible to exploit this directly (e.g., adding a new user fails because \n is in the block list), it is possible to misrepresent the /etc/passwd file when viewed. Use of \r manipulations and Unicode characters to work around blocking of the : character make it possible to give the impression that a new user has been added. In other words, an adversary may be able to convince a system administrator to take the system offline (an indirect, social-engineered denial of service) by demonstrating that "cat /etc/passwd" shows a rogue user account.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 shadow.

    +

    References

    + + +
    + + + +
    +
    +

    Uncontrolled Recursion

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + pcre3/libpcre3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.11.12 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + grep@3.7-1build1 + › + pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    In PCRE 8.41, the OP_KETRMAX feature in the match function in pcre_exec.c allows stack exhaustion (uncontrolled recursion) when processing a crafted regular expression.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 pcre3.

    +

    References

    + + +
    + + + +
    +
    +

    Integer Overflow or Wraparound

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

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + 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

    + + +
    + +
    @@ -3409,10 +2581,10 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: @@ -3422,7 +2594,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 and patch@2.7.6-7build3 + docker-image|quay.io/argoproj/argocd@v2.11.12 and patch@2.7.6-7build2
    @@ -3435,9 +2607,9 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - patch@2.7.6-7build3 + patch@2.7.6-7build2 @@ -3450,10 +2622,10 @@

      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.

      + 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:24.04 patch.

      +

      There is no fixed version for Ubuntu:22.04 patch.

      References

    @@ -3479,10 +2651,10 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: @@ -3492,7 +2664,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 and patch@2.7.6-7build3 + docker-image|quay.io/argoproj/argocd@v2.11.12 and patch@2.7.6-7build2
    @@ -3505,9 +2677,9 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - patch@2.7.6-7build3 + patch@2.7.6-7build2 @@ -3520,10 +2692,10 @@

      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.

      + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

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

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 patch.

      +

      There is no fixed version for Ubuntu:22.04 patch.

      References

    @@ -3554,20 +2726,20 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: - openssl/libssl3t64 + openssl/libssl3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 and openssl/libssl3t64@3.0.13-0ubuntu3.4 + docker-image|quay.io/argoproj/argocd@v2.11.12 and openssl/libssl3@3.0.2-0ubuntu1.18
    @@ -3580,135 +2752,113 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + openssl/libssl3@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - coreutils@9.4-3ubuntu6 + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + openssl/libssl3@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 + libfido2/libfido2-1@1.10.0-1 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + openssl/libssl3@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - libfido2/libfido2-1@1.14.0-1build3 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + openssl/libssl3@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 + ca-certificates@20240203~22.04.1 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + openssl@3.0.2-0ubuntu1.18 + › + openssl/libssl3@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - ca-certificates@20240203 + git@1:2.34.1-1ubuntu1.11 › - openssl@3.0.13-0ubuntu3.4 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + 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.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + adduser@3.118ubuntu5 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - libssh/libssh-4@0.10.6-2build2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - openssl/libssl3t64@3.0.13-0ubuntu3.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.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + openssl@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + ca-certificates@20240203~22.04.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 - › - cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - openssl@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 - › - ca-certificates@20240203 - › - openssl@3.0.13-0ubuntu3.4 + openssl@3.0.2-0ubuntu1.18 @@ -3721,10 +2871,10 @@

      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.

      + 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:24.04 openssl.

      +

      There is no fixed version for Ubuntu:22.04 openssl.

      References

    -

    CVE-2024-9143

    +

    CVE-2023-50495

    @@ -3752,20 +2902,20 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: - openssl/libssl3t64 + ncurses/libtinfo6
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 and openssl/libssl3t64@3.0.13-0ubuntu3.4 + docker-image|quay.io/argoproj/argocd@v2.11.12 and ncurses/libtinfo6@6.3-2ubuntu0.1
    @@ -3778,135 +2928,200 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - coreutils@9.4-3ubuntu6 + bash@5.1-6ubuntu1.1 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 + ncurses/libncursesw6@6.3-2ubuntu0.1 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - libfido2/libfido2-1@1.14.0-1build3 + less@590-1ubuntu0.22.04.3 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 + libedit/libedit2@3.1-20210910-1build1 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - ca-certificates@20240203 + ncurses/libncurses6@6.3-2ubuntu0.1 › - openssl@3.0.13-0ubuntu3.4 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + ncurses/ncurses-bin@6.3-2ubuntu0.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - libssh/libssh-4@0.10.6-2build2 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + procps@2:3.3.17-6ubuntu2.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + util-linux@2.37.2-4ubuntu3.4 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 - › - cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - openssl@3.0.13-0ubuntu3.4 + gnupg2/gpg@2.2.27-3ubuntu2.1 + › + gnupg2/gpgconf@2.2.27-3ubuntu2.1 + › + readline/libreadline8@8.1.2-1 + › + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - ca-certificates@20240203 + gnupg2/gnupg@2.2.27-3ubuntu2.1 › - openssl@3.0.13-0ubuntu3.4 + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + › + pinentry/pinentry-curses@1.1.1-1build2 + › + ncurses/libtinfo6@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + ncurses/libncursesw6@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + procps@2:3.3.17-6ubuntu2.1 + › + ncurses/libncursesw6@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + › + pinentry/pinentry-curses@1.1.1-1build2 + › + ncurses/libncursesw6@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + ncurses/libncurses6@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + procps@2:3.3.17-6ubuntu2.1 + › + ncurses/libncurses6@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + ncurses/ncurses-base@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -3918,57 +3133,29 @@

      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.

      -

      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.

      +

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

      +

      NCurse v6.4-20230418 was discovered to contain a segmentation fault via the component _nc_wrap_entry().

      Remediation

      -

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

      +

      There is no fixed version for Ubuntu:22.04 ncurses.

      References


    -

    CVE-2024-13176

    +

    CVE-2023-45918

    @@ -3979,20 +3166,20 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: - openssl/libssl3t64 + ncurses/libtinfo6
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 and openssl/libssl3t64@3.0.13-0ubuntu3.4 + docker-image|quay.io/argoproj/argocd@v2.11.12 and ncurses/libtinfo6@6.3-2ubuntu0.1
    @@ -4005,135 +3192,200 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - coreutils@9.4-3ubuntu6 + bash@5.1-6ubuntu1.1 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 + ncurses/libncursesw6@6.3-2ubuntu0.1 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - libfido2/libfido2-1@1.14.0-1build3 + less@590-1ubuntu0.22.04.3 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 + libedit/libedit2@3.1-20210910-1build1 › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - ca-certificates@20240203 + ncurses/libncurses6@6.3-2ubuntu0.1 › - openssl@3.0.13-0ubuntu3.4 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + ncurses/ncurses-bin@6.3-2ubuntu0.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - libssh/libssh-4@0.10.6-2build2 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + procps@2:3.3.17-6ubuntu2.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + util-linux@2.37.2-4ubuntu3.4 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 - › - cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - openssl@3.0.13-0ubuntu3.4 + gnupg2/gpg@2.2.27-3ubuntu2.1 + › + gnupg2/gpgconf@2.2.27-3ubuntu2.1 + › + readline/libreadline8@8.1.2-1 + › + ncurses/libtinfo6@6.3-2ubuntu0.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - ca-certificates@20240203 + gnupg2/gnupg@2.2.27-3ubuntu2.1 › - openssl@3.0.13-0ubuntu3.4 + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + › + pinentry/pinentry-curses@1.1.1-1build2 + › + ncurses/libtinfo6@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + ncurses/libncursesw6@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + procps@2:3.3.17-6ubuntu2.1 + › + ncurses/libncursesw6@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + › + pinentry/pinentry-curses@1.1.1-1build2 + › + ncurses/libncursesw6@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + ncurses/libncurses6@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + procps@2:3.3.17-6ubuntu2.1 + › + ncurses/libncurses6@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + ncurses/ncurses-base@6.3-2ubuntu0.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -4145,42 +3397,100 @@

      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.

      -

      Issue summary: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

      -

      Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

      -

      There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

      +

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

      +

      Rejected reason: DO NOT USE THIS CANDIDATE NUMBER. ConsultIDs: none. Reason: This candidate was withdrawn by its CNA. Further investigation showed that it was not a security issue. Notes: none.

      Remediation

      -

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

      +

      There is no fixed version for Ubuntu:22.04 ncurses.

      References


      + +
    +
    +

    Resource Exhaustion

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libzstd/libzstd1 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.11.12 and libzstd/libzstd1@1.4.8+dfsg-3build1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + libzstd/libzstd1@1.4.8+dfsg-3build1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    A vulnerability was found in zstd v1.4.10, where an attacker can supply empty string as an argument to the command line tool to cause buffer overrun.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 libzstd.

    +

    References

    + + +
    + +
    @@ -4196,10 +3506,10 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: @@ -4209,7 +3519,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 and libgcrypt20@1.10.3-2build1 + docker-image|quay.io/argoproj/argocd@v2.11.12 and libgcrypt20@1.9.4-3ubuntu3
    @@ -4222,100 +3532,150 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - libgcrypt20@1.10.3-2build1 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - gnupg2/dirmngr@2.4.4-2ubuntu17 + gnupg2/dirmngr@2.2.27-3ubuntu2.1 › - libgcrypt20@1.10.3-2build1 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - gnupg2/gpg@2.4.4-2ubuntu17 + gnupg2/gpg@2.2.27-3ubuntu2.1 › - libgcrypt20@1.10.3-2build1 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - gnupg2/gpg-agent@2.4.4-2ubuntu17 + apt@2.4.13 › - libgcrypt20@1.10.3-2build1 + apt/libapt-pkg6.0@2.4.13 + › + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + apt@2.4.13 › - apt/libapt-pkg6.0t64@2.7.14build2 + gnupg2/gpgv@2.2.27-3ubuntu2.1 › - libgcrypt20@1.10.3-2build1 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + gnupg2/gpg@2.2.27-3ubuntu2.1 › - gnupg2/gpgv@2.4.4-2ubuntu17 + gnupg2/gpgconf@2.2.27-3ubuntu2.1 › - libgcrypt20@1.10.3-2build1 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - gnupg2/gpg@2.4.4-2ubuntu17 + gnupg2/gnupg@2.2.27-3ubuntu2.1 › - gnupg2/gpgconf@2.4.4-2ubuntu17 + gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 › - libgcrypt20@1.10.3-2build1 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + gnupg2/gnupg@2.2.27-3ubuntu2.1 › - adduser@3.137ubuntu1 + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 › - pam/libpam-modules@1.5.3-5ubuntu5.1 + gnupg2/gnupg@2.2.27-3ubuntu2.1 › - systemd/libsystemd0@255.4-1ubuntu8.5 + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 › - libgcrypt20@1.10.3-2build1 + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + › + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpgsm@2.2.27-3ubuntu2.1 + › + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + apt@2.4.13 + › + apt/libapt-pkg6.0@2.4.13 + › + systemd/libsystemd0@249.11-0ubuntu3.12 + › + libgcrypt20@1.9.4-3ubuntu3 @@ -4328,10 +3688,10 @@

      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.

      + 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:24.04 libgcrypt20.

      +

      There is no fixed version for Ubuntu:22.04 libgcrypt20.

      References

    -

    CVE-2024-26458

    +

    Integer Overflow or Wraparound

    @@ -4360,10 +3720,10 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: @@ -4373,8 +3733,8 @@
    • Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 and krb5/libk5crypto3@1.19.2-2ubuntu0.4 - docker-image|quay.io/argoproj/argocd@v2.12.10, git@1:2.43.0-1ubuntu7.2 and others
    @@ -4386,146 +3746,159 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + adduser@3.118ubuntu5 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 + libnsl/libnsl2@1.3.0-2build2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + › + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + › + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + adduser@3.118ubuntu5 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 + libnsl/libnsl2@1.3.0-2build2 + › + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + › + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + › + krb5/libkrb5-3@1.19.2-2ubuntu0.4 + › + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + adduser@3.118ubuntu5 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 + libnsl/libnsl2@1.3.0-2build2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 + 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.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.34.1-1ubuntu1.11 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.34.1-1ubuntu1.11 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 › - libssh/libssh-4@0.10.6-2build2 + libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - krb5/krb5-locales@1.20.1-6ubuntu2.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 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -4538,21 +3911,24 @@

      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.

      + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      +

      An issue was discovered in MIT Kerberos 5 (aka krb5) through 1.16. There is a variable "dbentry->n_key_data" in kadmin/dbutil/dump.c that can store 16-bit data but unknowingly the developer has assigned a "u4" variable to it, which is for 32-bit data. An attacker can use this vulnerability to affect other artifacts of the database as we know that a Kerberos database dump file contains trusted data.

      Remediation

      -

      Upgrade Ubuntu:24.04 krb5 to version 1.20.1-6ubuntu2.5 or higher.

      +

      There is no fixed version for Ubuntu:22.04 krb5.

      References


    @@ -4568,10 +3944,10 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: @@ -4581,8 +3957,8 @@
    • Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 and krb5/libk5crypto3@1.19.2-2ubuntu0.4 - docker-image|quay.io/argoproj/argocd@v2.12.10, git@1:2.43.0-1ubuntu7.2 and others
    @@ -4594,146 +3970,159 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + adduser@3.118ubuntu5 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 + libnsl/libnsl2@1.3.0-2build2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + › + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + › + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + adduser@3.118ubuntu5 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 + libnsl/libnsl2@1.3.0-2build2 + › + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + › + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + › + krb5/libkrb5-3@1.19.2-2ubuntu0.4 + › + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 - › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + adduser@3.118ubuntu5 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + shadow/passwd@1:4.8.1-2ubuntu2.2 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + pam/libpam-modules@1.4.0-11ubuntu2.4 › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 + libnsl/libnsl2@1.3.0-2build2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.2 + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 › - krb5/libkrb5support0@1.20.1-6ubuntu2.2 + 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.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.34.1-1ubuntu1.11 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.34.1-1ubuntu1.11 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 › - libssh/libssh-4@0.10.6-2build2 + libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - krb5/krb5-locales@1.20.1-6ubuntu2.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 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -4746,10 +4135,10 @@

      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.

      + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      Kerberos 5 (aka krb5) 1.21.2 contains a memory leak vulnerability in /krb5/src/lib/gssapi/krb5/k5sealv3.c.

      Remediation

      -

      Upgrade Ubuntu:24.04 krb5 to version 1.20.1-6ubuntu2.5 or higher.

      +

      There is no fixed version for Ubuntu:22.04 krb5.

      References

    +
    +

    CVE-2024-26458

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

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + krb5/libk5crypto3@1.19.2-2ubuntu0.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + 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/libk5crypto3@1.19.2-2ubuntu0.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + 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.12 + › + krb5/libkrb5-3@1.19.2-2ubuntu0.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + 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 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + openssh/openssh-client@1:8.9p1-3ubuntu0.10 + › + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + git@1:2.34.1-1ubuntu1.11 + › + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 + › + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + git@1:2.34.1-1ubuntu1.11 + › + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 + › + libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 + › + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + 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 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + krb5/libkrb5support0@1.19.2-2ubuntu0.4 + + + +
    • +
    + +
    + +
    + +

    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 in /krb5/src/lib/rpc/pmap_rmt.c.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 krb5.

    +

    References

    + + +
    + +
    @@ -4776,10 +4386,10 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: @@ -4789,7 +4399,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 and gnupg2/gpgv@2.4.4-2ubuntu17 + docker-image|quay.io/argoproj/argocd@v2.11.12 and gnupg2/gpgv@2.2.27-3ubuntu2.1
    @@ -4802,80 +4412,313 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - gnupg2/gpgv@2.4.4-2ubuntu17 + gnupg2/gpgv@2.2.27-3ubuntu2.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - apt@2.7.14build2 + apt@2.4.13 › - gnupg2/gpgv@2.4.4-2ubuntu17 + gnupg2/gpgv@2.2.27-3ubuntu2.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - gnupg2/dirmngr@2.4.4-2ubuntu17 + gnupg2/gnupg@2.2.27-3ubuntu2.1 › - gnupg2/gpgconf@2.4.4-2ubuntu17 + gnupg2/gpgv@2.2.27-3ubuntu2.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - gnupg2/gpg-agent@2.4.4-2ubuntu17 + gnupg2/dirmngr@2.2.27-3ubuntu2.1 › - gnupg2/gpgconf@2.4.4-2ubuntu17 + gnupg2/gpgconf@2.2.27-3ubuntu2.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - gnupg2/gpg@2.4.4-2ubuntu17 + gnupg2/gpg@2.2.27-3ubuntu2.1 › - gnupg2/gpgconf@2.4.4-2ubuntu17 + gnupg2/gpgconf@2.2.27-3ubuntu2.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - gnupg2/dirmngr@2.4.4-2ubuntu17 + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + › + gnupg2/gpgconf@2.2.27-3ubuntu2.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - gnupg2/gpg@2.4.4-2ubuntu17 + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpgsm@2.2.27-3ubuntu2.1 + › + gnupg2/gpgconf@2.2.27-3ubuntu2.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - gnupg2/gpg-agent@2.4.4-2ubuntu17 + gnupg2/dirmngr@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/dirmngr@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + › + gnupg2/dirmngr@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg-l10n@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gnupg-l10n@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gpg@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + › + gnupg2/gpg@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + › + gnupg2/gpg@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gpgsm@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 + › + gnupg2/gpgsm@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -4888,10 +4731,10 @@

      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.

      + See How to fix? for Ubuntu:22.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.

      +

      There is no fixed version for Ubuntu:22.04 gnupg2.

      References

    @@ -4922,10 +4765,10 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: @@ -4935,7 +4778,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 and glibc/libc-bin@2.39-0ubuntu8.3 + docker-image|quay.io/argoproj/argocd@v2.11.12 and glibc/libc-bin@2.35-0ubuntu3.8
    @@ -4948,18 +4791,18 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - glibc/libc-bin@2.39-0ubuntu8.3 + glibc/libc-bin@2.35-0ubuntu3.8
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - glibc/libc6@2.39-0ubuntu8.3 + glibc/libc6@2.35-0ubuntu3.8 @@ -4972,10 +4815,10 @@

      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.

      + See How to fix? for Ubuntu:22.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.

      +

      There is no fixed version for Ubuntu:22.04 glibc.

      References

    @@ -5003,7 +4846,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • Package Manager: golang @@ -5072,7 +4915,7 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 › /usr/local/bin/argocd
      • Package Manager: golang @@ -5130,7 +4973,7 @@
    -

    CVE-2025-0167

    +

    Improper Input Validation

    @@ -5141,21 +4984,21 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: - curl/libcurl3t64-gnutls + git/git-man
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10, git@1:2.43.0-1ubuntu7.2 and others + docker-image|quay.io/argoproj/argocd@v2.11.12, git@1:2.34.1-1ubuntu1.11 and others
    @@ -5167,11 +5010,219 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.34.1-1ubuntu1.11 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + git/git-man@1:2.34.1-1ubuntu1.11 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + git@1:2.34.1-1ubuntu1.11 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + git-lfs@3.0.2-1ubuntu0.2 + › + git@1:2.34.1-1ubuntu1.11 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    GIT version 2.15.1 and earlier contains a Input Validation Error vulnerability in Client that can result in problems including messing up terminal configuration to RCE. This attack appear to be exploitable via The user must interact with a malicious git server, (or have their traffic modified in a MITM attack).

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 git.

    +

    References

    + + +
    + + + +
    +
    +

    Uncontrolled Recursion

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + gcc-12/libstdc++6 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.11.12 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + +
    • +
    + +
    + + +

    Detailed paths

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

    NVD Description

    +

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

    +

    libiberty/rust-demangle.c in GNU GCC 11.2 allows stack consumption in demangle_const, as demonstrated by nm-new.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Insufficient Comparison

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + curl/libcurl3-gnutls +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.11.12, git@1:2.34.1-1ubuntu1.11 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + › + git@1:2.34.1-1ubuntu1.11 + › + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 @@ -5184,27 +5235,43 @@

      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 asked to use a .netrc file for credentials and to follow HTTP - redirects, curl could leak the password used for the first host to the - followed-to host under certain circumstances.

      -

      This flaw only manifests itself if the netrc file has a default entry that - omits both login and password. A rare circumstance.

      + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      +

      When curl is asked to use HSTS, the expiry time for a subdomain might + overwrite a parent domain's cache entry, making it end sooner or later than + otherwise intended.

      +

      This affects curl using applications that enable HSTS and use URLs with the + insecure HTTP:// scheme and perform transfers with hosts like + x.example.com as well as example.com where the first host is a subdomain + of the second host.

      +

      (The HSTS cache either needs to have been populated manually or there needs to + have been previous HTTPS accesses done as the cache needs to have entries for + the domains involved to trigger this problem.)

      +

      When x.example.com responds with Strict-Transport-Security: headers, this + bug can make the subdomain's expiry timeout bleed over and get set for the + parent domain example.com in curl's HSTS cache.

      +

      The result of a triggered bug is that HTTP accesses to example.com get + converted to HTTPS for a different period of time than what was asked for by + the origin server. If example.com for example stops supporting HTTPS at its + expiry time, curl might then fail to access http://example.com until the + (wrongly set) timeout expires. This bug can also expire the parent's entry + earlier, thus making curl inadvertently switch back to insecure HTTP earlier + than otherwise intended.

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 curl.

      +

      Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.19 or higher.

      References


    @@ -5220,10 +5287,10 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.12.10/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd › Dockerfile
    • - Package Manager: ubuntu:24.04 + Package Manager: ubuntu:22.04
    • Vulnerable module: @@ -5233,7 +5300,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 and coreutils@9.4-3ubuntu6 + docker-image|quay.io/argoproj/argocd@v2.11.12 and coreutils@8.32-4.1ubuntu1.2
    @@ -5246,9 +5313,9 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.10 + docker-image|quay.io/argoproj/argocd@v2.11.12 › - coreutils@9.4-3ubuntu6 + coreutils@8.32-4.1ubuntu1.2 @@ -5261,10 +5328,10 @@

      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.

      + See How to fix? for Ubuntu:22.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.

      +

      There is no fixed version for Ubuntu:22.04 coreutils.

      References

    diff --git a/docs/snyk/master/public.ecr.aws_docker_library_redis_7.2.7-alpine.html b/docs/snyk/v2.11.12/redis_7.0.15-alpine.html similarity index 51% rename from docs/snyk/master/public.ecr.aws_docker_library_redis_7.2.7-alpine.html rename to docs/snyk/v2.11.12/redis_7.0.15-alpine.html index 332ea96e33..18fb60b5c1 100644 --- a/docs/snyk/master/public.ecr.aws_docker_library_redis_7.2.7-alpine.html +++ b/docs/snyk/v2.11.12/redis_7.0.15-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,27 +456,213 @@

    Snyk test report

    -

    March 16th 2025, 12:21:15 am (UTC+00:00)

    +

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

    Scanned the following paths:
      -
    • public.ecr.aws/docker/library/redis:7.2.7-alpine/docker/library/redis (apk)
    • -
    • public.ecr.aws/docker/library/redis:7.2.7-alpine/tianon/gosu//usr/local/bin/gosu (gomodules)
    • +
    • redis:7.0.15-alpine (apk)
    • +
    • redis:7.0.15-alpine/tianon/gosu//usr/local/bin/gosu (gomodules)
    -
    0 known vulnerabilities
    -
    0 vulnerable dependency paths
    -
    19 dependencies
    +
    1 known vulnerabilities
    +
    9 vulnerable dependency paths
    +
    18 dependencies
    - 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.10/public.ecr.aws_docker_library_redis_7.0.15-alpine.html b/docs/snyk/v2.12.10/public.ecr.aws_docker_library_redis_7.0.15-alpine.html deleted file mode 100644 index 7196817785..0000000000 --- a/docs/snyk/v2.12.10/public.ecr.aws_docker_library_redis_7.0.15-alpine.html +++ /dev/null @@ -1,1216 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
    -
    -
    -
    - - - Snyk - Open Source Security - - - - - - - -
    -

    Snyk test report

    - -

    March 16th 2025, 12:29:16 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)
    • -
    -
    - -
    -
    4 known vulnerabilities
    -
    38 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-r3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-13176

    -
    - -
    - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

    -

    Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

    -

    There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-12797

    -
    - -
    - 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: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a - server may fail to notice that the server was not authenticated, because - handshakes don't abort as expected when the SSL_VERIFY_PEER verification mode - is set.

    -

    Impact summary: TLS and DTLS connections using raw public keys may be - vulnerable to man-in-middle attacks when server authentication failure is not - detected by clients.

    -

    RPKs are disabled by default in both TLS clients and TLS servers. The issue - only arises when TLS clients explicitly enable RPK use by the server, and the - server, likewise, enables sending of an RPK instead of an X.509 certificate - chain. The affected clients are those that then rely on the handshake to - fail when the server's RPK fails to match one of the expected public keys, - by setting the verification mode to SSL_VERIFY_PEER.

    -

    Clients that enable server-side raw public keys can still find out that raw - public key verification failed by calling SSL_get_verify_result(), and those - that do, and take appropriate action, are not affected. This issue was - introduced in the initial implementation of RPK support in OpenSSL 3.2.

    -

    The FIPS modules in 3.4, 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.3-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2025-26519

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

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - .redis-rundeps@20240906.232324 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - busybox/ssl_client@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - › - musl/musl@1.2.5-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 - › - musl/musl@1.2.5-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 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - zlib/zlib@1.3.1-r1 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - alpine-baselayout/alpine-baselayout@3.6.5-r0 - › - busybox/busybox-binsh@1.36.1-r29 - › - busybox/busybox@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

    -

    Remediation

    -

    Upgrade Alpine:3.20 musl to version 1.2.5-r1 or higher.

    -

    References

    - - -
    - - - -
    -
    -
    -
    - - - diff --git a/docs/snyk/v2.12.10/redis_7.0.15-alpine.html b/docs/snyk/v2.12.10/redis_7.0.15-alpine.html deleted file mode 100644 index 31c069778b..0000000000 --- a/docs/snyk/v2.12.10/redis_7.0.15-alpine.html +++ /dev/null @@ -1,1216 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
    -
    -
    -
    - - - Snyk - Open Source Security - - - - - - - -
    -

    Snyk test report

    - -

    March 16th 2025, 12:29:38 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)
    • -
    -
    - -
    -
    4 known vulnerabilities
    -
    38 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-r3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-13176

    -
    - -
    - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

    -

    Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

    -

    There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-12797

    -
    - -
    - 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: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a - server may fail to notice that the server was not authenticated, because - handshakes don't abort as expected when the SSL_VERIFY_PEER verification mode - is set.

    -

    Impact summary: TLS and DTLS connections using raw public keys may be - vulnerable to man-in-middle attacks when server authentication failure is not - detected by clients.

    -

    RPKs are disabled by default in both TLS clients and TLS servers. The issue - only arises when TLS clients explicitly enable RPK use by the server, and the - server, likewise, enables sending of an RPK instead of an X.509 certificate - chain. The affected clients are those that then rely on the handshake to - fail when the server's RPK fails to match one of the expected public keys, - by setting the verification mode to SSL_VERIFY_PEER.

    -

    Clients that enable server-side raw public keys can still find out that raw - public key verification failed by calling SSL_get_verify_result(), and those - that do, and take appropriate action, are not affected. This issue was - introduced in the initial implementation of RPK support in OpenSSL 3.2.

    -

    The FIPS modules in 3.4, 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.3-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2025-26519

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.20 -
    • -
    • - Vulnerable module: - - musl/musl -
    • - -
    • Introduced through: - - docker-image|redis@7.0.15-alpine and musl/musl@1.2.5-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - › - .redis-rundeps@20240906.232324 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - › - busybox/ssl_client@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - › - .redis-rundeps@20240906.232324 - › - openssl/libcrypto3@3.3.2-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - › - .redis-rundeps@20240906.232324 - › - openssl/libssl3@3.3.2-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - zlib/zlib@1.3.1-r1 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - › - alpine-baselayout/alpine-baselayout@3.6.5-r0 - › - busybox/busybox-binsh@1.36.1-r29 - › - busybox/busybox@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

    -

    Remediation

    -

    Upgrade Alpine:3.20 musl to version 1.2.5-r1 or higher.

    -

    References

    - - -
    - - - -
    -
    -
    -
    - - - diff --git a/docs/snyk/v2.12.10/argocd-iac-install.html b/docs/snyk/v2.12.8/argocd-iac-install.html similarity index 99% rename from docs/snyk/v2.12.10/argocd-iac-install.html rename to docs/snyk/v2.12.8/argocd-iac-install.html index 0bc6859241..2cbc23395c 100644 --- a/docs/snyk/v2.12.10/argocd-iac-install.html +++ b/docs/snyk/v2.12.8/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    March 16th 2025, 12:31:01 am (UTC+00:00)

    +

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

    Scanned the following path: diff --git a/docs/snyk/v2.12.10/argocd-iac-namespace-install.html b/docs/snyk/v2.12.8/argocd-iac-namespace-install.html similarity index 99% rename from docs/snyk/v2.12.10/argocd-iac-namespace-install.html rename to docs/snyk/v2.12.8/argocd-iac-namespace-install.html index 81f25df6e3..0bd319de61 100644 --- a/docs/snyk/v2.12.10/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.12.8/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    March 16th 2025, 12:31:11 am (UTC+00:00)

    +

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

    Scanned the following path: diff --git a/docs/snyk/v2.12.10/argocd-test.html b/docs/snyk/v2.12.8/argocd-test.html similarity index 65% rename from docs/snyk/v2.12.10/argocd-test.html rename to docs/snyk/v2.12.8/argocd-test.html index 1447c36f74..9769ab54cf 100644 --- a/docs/snyk/v2.12.10/argocd-test.html +++ b/docs/snyk/v2.12.8/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    March 16th 2025, 12:29:00 am (UTC+00:00)

    +

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

    Scanned the following paths: @@ -467,9 +467,9 @@
    -
    17 known vulnerabilities
    -
    71 vulnerable dependency paths
    -
    2066 dependencies
    +
    12 known vulnerabilities
    +
    54 vulnerable dependency paths
    +
    2061 dependencies
    @@ -477,508 +477,12 @@
    -
    -

    Prototype Pollution

    +
    +

    Incorrect Implementation of Authentication Algorithm

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

    Detailed paths

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

    Overview

    -

    redoc is an OpenAPI/Swagger-generated API Reference Documentation.

    -

    Affected versions of this package are vulnerable to Prototype Pollution via the mergeObjects() method in utils/helpers.ts due to improper user input sanitization.

    -

    PoC

    -
    (async () => {
    -          const lib = await import('redoc');
    -        
    -        var BAD_JSON = JSON.parse('{"__proto__":{"polluted":true}}');
    -        var victim = {}
    -        console.log("Before Attack: ", JSON.stringify(victim.__proto__));
    -        try {
    -          lib.mergeObjects ({}, BAD_JSON)
    -        } catch (e) { }
    -        console.log("After Attack: ", JSON.stringify(victim.__proto__));
    -        delete Object.prototype.polluted;
    -        })();
    -        
    -

    Details

    -

    Prototype Pollution is a vulnerability affecting JavaScript. Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects. JavaScript allows all Object attributes to be altered, including their magical attributes such as __proto__, constructor and prototype. An attacker manipulates these attributes to overwrite, or pollute, a JavaScript application object prototype of the base object by injecting other values. Properties on the Object.prototype are then inherited by all the JavaScript objects through the prototype chain. When that happens, this leads to either denial of service by triggering JavaScript exceptions, or it tampers with the application source code to force the code path that the attacker injects, thereby leading to remote code execution.

    -

    There are two main ways in which the pollution of prototypes occurs:

    -
      -
    • Unsafe Object recursive merge

      -
    • -
    • Property definition by path

      -
    • -
    -

    Unsafe Object recursive merge

    -

    The logic of a vulnerable recursive merge function follows the following high-level model:

    -
    merge (target, source)
    -        
    -          foreach property of source
    -        
    -            if property exists and is an object on both the target and the source
    -        
    -              merge(target[property], source[property])
    -        
    -            else
    -        
    -              target[property] = source[property]
    -        
    -
    - -

    When the source object contains a property named __proto__ defined with Object.defineProperty() , the condition that checks if the property exists and is an object on both the target and the source passes and the merge recurses with the target, being the prototype of Object and the source of Object as defined by the attacker. Properties are then copied on the Object prototype.

    -

    Clone operations are a special sub-class of unsafe recursive merges, which occur when a recursive merge is conducted on an empty object: merge({},source).

    -

    lodash and Hoek are examples of libraries susceptible to recursive merge attacks.

    -

    Property definition by path

    -

    There are a few JavaScript libraries that use an API to define property values on an object based on a given path. The function that is generally affected contains this signature: theFunction(object, path, value)

    -

    If the attacker can control the value of “path”, they can set this value to __proto__.myValue. myValue is then assigned to the prototype of the class of the object.

    -

    Types of attacks

    -

    There are a few methods by which Prototype Pollution can be manipulated:

    - - - - - - - - - - - - - - - - - - - - - - - -
    TypeOriginShort description
    Denial of service (DoS)ClientThis is the most likely attack.
    DoS occurs when Object holds generic functions that are implicitly called for various operations (for example, toString and valueOf).
    The attacker pollutes Object.prototype.someattr and alters its state to an unexpected value such as Int or Object. In this case, the code fails and is likely to cause a denial of service.
    For example: if an attacker pollutes Object.prototype.toString by defining it as an integer, if the codebase at any point was reliant on someobject.toString() it would fail.
    Remote Code ExecutionClientRemote code execution is generally only possible in cases where the codebase evaluates a specific attribute of an object, and then executes that evaluation.
    For example: eval(someobject.someattr). In this case, if the attacker pollutes Object.prototype.someattr they are likely to be able to leverage this in order to execute code.
    Property InjectionClientThe attacker pollutes properties that the codebase relies on for their informative value, including security properties such as cookies or tokens.
    For example: if a codebase checks privileges for someuser.isAdmin, then when the attacker pollutes Object.prototype.isAdmin and sets it to equal true, they can then achieve admin privileges.
    -

    Affected environments

    -

    The following environments are susceptible to a Prototype Pollution attack:

    -
      -
    • Application server

      -
    • -
    • Web server

      -
    • -
    • Web browser

      -
    • -
    -

    How to prevent

    -
      -
    1. Freeze the prototype— use Object.freeze (Object.prototype).

      -
    2. -
    3. Require schema validation of JSON input.

      -
    4. -
    5. Avoid using unsafe recursive merge functions.

      -
    6. -
    7. Consider using objects without prototypes (for example, Object.create(null)), breaking the prototype chain and preventing pollution.

      -
    8. -
    9. As a best practice use Map instead of Object.

      -
    10. -
    -

    For more information on this vulnerability type:

    -

    Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018

    -

    Remediation

    -

    Upgrade redoc to version 2.4.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/oauth2/jws -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, golang.org/x/oauth2/google@0.12.0 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - golang.org/x/oauth2/google@0.12.0 - › - golang.org/x/oauth2/jws@0.12.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - golang.org/x/oauth2/google@0.12.0 - › - golang.org/x/oauth2/jwt@0.12.0 - › - golang.org/x/oauth2/jws@0.12.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.12.0 - › - golang.org/x/oauth2/jws@0.12.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.12.0 - › - golang.org/x/oauth2/jws@0.12.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.12.0 - › - golang.org/x/oauth2/jws@0.12.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.12.0 - › - golang.org/x/oauth2/jwt@0.12.0 - › - golang.org/x/oauth2/jws@0.12.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.12.0 - › - golang.org/x/oauth2/jws@0.12.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.12.0 - › - golang.org/x/oauth2/jws@0.12.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.12.0 - › - golang.org/x/oauth2/jwt@0.12.0 - › - golang.org/x/oauth2/jws@0.12.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.12.0 - › - golang.org/x/oauth2/jwt@0.12.0 - › - golang.org/x/oauth2/jws@0.12.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.12.0 - › - golang.org/x/oauth2/jwt@0.12.0 - › - golang.org/x/oauth2/jws@0.12.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.12.0 - › - golang.org/x/oauth2/jwt@0.12.0 - › - golang.org/x/oauth2/jws@0.12.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to improper parsing of malformed tokens which can lead to memory consumption.

    -

    Remediation

    -

    Upgrade golang.org/x/oauth2/jws to version 0.27.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity +
    + critical severity

    @@ -998,7 +502,7 @@
  • Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 and golang.org/x/crypto/ssh@0.31.0 + github.com/argoproj/argo-cd/v2@0.0.0 and golang.org/x/crypto/ssh@0.23.0
  • @@ -1013,7 +517,7 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1024,7 +528,7 @@ › code.gitea.io/sdk/gitea@0.18.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1033,9 +537,9 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - golang.org/x/crypto/ssh/knownhosts@0.31.0 + golang.org/x/crypto/ssh/knownhosts@0.23.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1044,9 +548,9 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1059,7 +563,7 @@ › github.com/go-fed/httpsig@1.1.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1068,11 +572,11 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - github.com/skeema/knownhosts@1.3.0 + github.com/skeema/knownhosts@1.2.2 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1083,9 +587,9 @@ › code.gitea.io/sdk/gitea@0.18.0 › - golang.org/x/crypto/ssh/agent@0.31.0 + golang.org/x/crypto/ssh/agent@0.23.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1094,11 +598,11 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1107,13 +611,13 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › github.com/xanzy/ssh-agent@0.3.3 › - golang.org/x/crypto/ssh/agent@0.31.0 + golang.org/x/crypto/ssh/agent@0.23.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1122,13 +626,13 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - github.com/skeema/knownhosts@1.3.0 + github.com/skeema/knownhosts@1.2.2 › - golang.org/x/crypto/ssh/knownhosts@0.31.0 + golang.org/x/crypto/ssh/knownhosts@0.23.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1137,13 +641,13 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - github.com/skeema/knownhosts@1.3.0 + github.com/skeema/knownhosts@1.2.2 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1152,13 +656,13 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5@5.13.1 + github.com/go-git/go-git/v5@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1167,15 +671,15 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › github.com/xanzy/ssh-agent@0.3.3 › - golang.org/x/crypto/ssh/agent@0.31.0 + golang.org/x/crypto/ssh/agent@0.23.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1184,15 +688,15 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - github.com/skeema/knownhosts@1.3.0 + github.com/skeema/knownhosts@1.2.2 › - golang.org/x/crypto/ssh/knownhosts@0.31.0 + golang.org/x/crypto/ssh/knownhosts@0.23.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1201,15 +705,15 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5@5.13.1 + github.com/go-git/go-git/v5@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - github.com/skeema/knownhosts@1.3.0 + github.com/skeema/knownhosts@1.2.2 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1218,17 +722,17 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5@5.13.1 + github.com/go-git/go-git/v5@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › github.com/xanzy/ssh-agent@0.3.3 › - golang.org/x/crypto/ssh/agent@0.31.0 + golang.org/x/crypto/ssh/agent@0.23.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1237,17 +741,17 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5@5.13.1 + github.com/go-git/go-git/v5@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - github.com/skeema/knownhosts@1.3.0 + github.com/skeema/knownhosts@1.2.2 › - golang.org/x/crypto/ssh/knownhosts@0.31.0 + golang.org/x/crypto/ssh/knownhosts@0.23.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.23.0 @@ -1260,20 +764,24 @@

    Overview

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

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling in handshakeTransport in handshake.go. An internal queue gets populated with received packets during the key exchange process, while waiting for the client to send a SSH_MSG_KEXINIT. An attacker can cause the server to become unresponsive to new connections by delaying or withholding this message, or by causing the queue to consume all available memory.

    +

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

    +

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

    Remediation

    -

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

    +

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

    References


    @@ -2020,87 +1528,6 @@

    More about this vulnerability

    -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-jose/go-jose/v3 -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/go-jose/go-jose/v3@3.0.3 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-jose/go-jose/v3@3.0.3 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/coreos/go-oidc/v3/oidc@3.6.0 - › - github.com/go-jose/go-jose/v3@3.0.3 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to the use of strings.Split to split JWT tokens. An attacker can cause memory exhaustion and service disruption by sending numerous malformed tokens with a large number of . characters.

    -

    Workaround

    -

    This vulnerability can be mitigated by pre-validating that payloads passed to Go JOSE do not contain an excessive number of . characters.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - -

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

    @@ -2337,81 +1764,6 @@

    More about this vulnerability

    -
    -
    -

    Arbitrary Code Injection

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd › ui/yarn.lock -
    • -
    • - Package Manager: npm -
    • -
    • - Vulnerable module: - - prismjs -
    • - -
    • 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 - › - prismjs@1.27.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    prismjs is a lightweight, robust, elegant syntax highlighting library.

    -

    Affected versions of this package are vulnerable to Arbitrary Code Injection via the document.currentScript lookup process. An attacker can manipulate the web page content and execute unintended actions by injecting HTML elements that overshadow legitimate DOM elements.

    -

    Note:

    -

    This is only exploitable if the application accepts untrusted input containing HTML but not direct JavaScript.

    -

    Remediation

    -

    Upgrade prismjs to version 1.30.0 or higher.

    -

    References

    - - -
    - - -

    Insufficient Documentation of Error Handling Techniques

    @@ -2662,151 +2014,6 @@
    -
    -

    Cross-site Scripting (XSS)

    -
    - -
    - low 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.5.6 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Cross-site Scripting (XSS) due to incorrect handling of template literals in regular expressions. An attacker can manipulate the output of the script by injecting malicious payloads that bypass the dompurify sanitization.

    -

    PoC

    -
    DOMPurify.sanitize(
    -          `<math><foo-test><mi><li><table><foo-test><li></li></foo-test><a>
    -              <style>
    -                <! \${
    -              </style>
    -              }
    -              <foo-b id="><img src onerror='alert(1)'>">hmm...</foo-b>
    -            </a></table></li></mi></foo-test></math>
    -          `,
    -          {
    -            SAFE_FOR_TEMPLATES: true,
    -            CUSTOM_ELEMENT_HANDLING: {
    -              tagNameCheck: /^foo-/,
    -            },
    -          }
    -        );
    -        
    -

    Details

    -

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

    -

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

    -

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

    -

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

    -

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

    -

    Types of attacks

    -

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

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

    Affected environments

    -

    The following environments are susceptible to an XSS attack:

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

    How to prevent

    -

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

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

    Remediation

    -

    Upgrade dompurify to version 3.2.4 or higher.

    -

    References

    - - -
    - - - -
    diff --git a/docs/snyk/v2.14.5/ghcr.io_dexidp_dex_v2.41.1.html b/docs/snyk/v2.12.8/ghcr.io_dexidp_dex_v2.38.0.html similarity index 53% rename from docs/snyk/v2.14.5/ghcr.io_dexidp_dex_v2.41.1.html rename to docs/snyk/v2.12.8/ghcr.io_dexidp_dex_v2.38.0.html index 2b642171c8..f8bac868b3 100644 --- a/docs/snyk/v2.14.5/ghcr.io_dexidp_dex_v2.41.1.html +++ b/docs/snyk/v2.12.8/ghcr.io_dexidp_dex_v2.38.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,22 +456,22 @@

    Snyk test report

    -

    March 16th 2025, 12:23:53 am (UTC+00:00)

    +

    December 15th 2024, 12:26:55 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)
    • +
    • ghcr.io/dexidp/dex:v2.38.0/dexidp/dex (apk)
    • +
    • ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3//usr/local/bin/gomplate (gomodules)
    • +
    • ghcr.io/dexidp/dex:v2.38.0/dexidp/dex//usr/local/bin/docker-entrypoint (gomodules)
    • +
    • ghcr.io/dexidp/dex:v2.38.0/dexidp/dex//usr/local/bin/dex (gomodules)
    -
    31 known vulnerabilities
    -
    76 vulnerable dependency paths
    -
    969 dependencies
    +
    42 known vulnerabilities
    +
    130 vulnerable dependency paths
    +
    829 dependencies
    @@ -491,7 +491,7 @@
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
    • Package Manager: golang @@ -504,7 +504,7 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and golang.org/x/crypto/ssh@v0.24.0 + github.com/hairyhenderson/gomplate/v3@* and golang.org/x/crypto/ssh@v0.18.0
    @@ -517,9 +517,9 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - golang.org/x/crypto/ssh@v0.24.0 + golang.org/x/crypto/ssh@v0.18.0 @@ -565,7 +565,7 @@
      • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
      • Package Manager: golang @@ -573,12 +573,12 @@
      • Vulnerable module: - golang.org/x/oauth2/jws + golang.org/x/net/http2
      • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and golang.org/x/oauth2/jws@v0.21.0 + github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.19.0
      @@ -591,9 +591,9 @@
      • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - golang.org/x/oauth2/jws@v0.21.0 + golang.org/x/net/http2@v0.19.0 @@ -602,7 +602,7 @@ Introduced through: github.com/dexidp/dex@* › - golang.org/x/oauth2/jws@v0.21.0 + golang.org/x/net/http2@v0.20.0 @@ -614,27 +614,28 @@

        Overview

        -

        Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to improper parsing of malformed tokens which can lead to memory consumption.

        +

        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/oauth2/jws to version 0.27.0 or higher.

        +

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

        References


    -

    Server-side Request Forgery (SSRF)

    +

    Path Traversal

    @@ -645,7 +646,7 @@
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
    • Package Manager: golang @@ -653,12 +654,12 @@
    • Vulnerable module: - golang.org/x/net/http/httpproxy + github.com/hashicorp/consul/api
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and golang.org/x/net/http/httpproxy@v0.26.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0
    @@ -671,18 +672,9 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - golang.org/x/net/http/httpproxy@v0.26.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - › - golang.org/x/net/http/httpproxy@v0.27.0 + github.com/hashicorp/consul/api@v1.13.0 @@ -694,180 +686,24 @@

      Overview

      -

      golang.org/x/net/http/httpproxy is a package for HTTP proxy determination based on environment variables, as provided by net/http's ProxyFromEnvironment function

      -

      Affected versions of this package are vulnerable to Server-side Request Forgery (SSRF) in proxy.go, because hostname matching against proxy patterns may treat an IPv6 zone ID as a hostname component. An environment variable value like *.example.com could be matched to a request intended for [::1%25.example.com]:80.

      +

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

      Remediation

      -

      Upgrade golang.org/x/net/http/httpproxy to version 0.36.0 or higher.

      +

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

      References


      - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/dexidp/dex › /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/html -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and golang.org/x/net/html@v0.27.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - › - golang.org/x/net/html@v0.27.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) through the functions parseDoctype, htmlIntegrationPoint, inBodyIM and inTableIM due to inefficient usage of the method strings.ToLower combining with the == operator to convert strings to lowercase and then comparing them.

    -

    An attacker can cause the application to slow down significantly by crafting inputs that are processed non-linearly.

    -

    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 golang.org/x/net/html to version 0.33.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

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

    Detailed paths

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

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling in handshakeTransport in handshake.go. An internal queue gets populated with received packets during the key exchange process, while waiting for the client to send a SSH_MSG_KEXINIT. An attacker can cause the server to become unresponsive to new connections by delaying or withholding this message, or by causing the queue to consume all available memory.

    -

    Remediation

    -

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

    -

    References

    - - -
    - -
    -

    Insertion of Sensitive Information into Log File

    +

    Out-of-bounds Write

    @@ -878,20 +714,17 @@
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang + Package Manager: alpine:3.19
    • Vulnerable module: - google.golang.org/grpc/metadata + openssl/libcrypto3
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and google.golang.org/grpc/metadata@v1.64.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
    @@ -904,9 +737,342 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - google.golang.org/grpc/metadata@v1.64.0 + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-0727

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.19 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: Processing a maliciously formatted PKCS12 file may lead OpenSSL + to crash leading to a potential Denial of Service attack

    +

    Impact summary: Applications loading files in the PKCS12 format from untrusted + sources might terminate abruptly.

    +

    A file in PKCS12 format can contain certificates and keys and may come from an + untrusted source. The PKCS12 specification allows certain fields to be NULL, but + OpenSSL does not correctly check for this case. This can lead to a NULL pointer + dereference that results in OpenSSL crashing. If an application processes PKCS12 + files from an untrusted source using the OpenSSL APIs then that application will + be vulnerable to this issue.

    +

    OpenSSL APIs that are vulnerable to this are: PKCS12_parse(), + PKCS12_unpack_p7data(), PKCS12_unpack_p7encdata(), PKCS12_unpack_authsafes() + and PKCS12_newpass().

    +

    We have also fixed a similar issue in SMIME_write_PKCS7(). However since this + function is related to writing data we do not consider it security significant.

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Infinite loop

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/protobuf/internal/encoding/json +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/internal/encoding/json@v1.31.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + › + google.golang.org/protobuf/internal/encoding/json@v1.31.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + › + google.golang.org/protobuf/internal/encoding/json@v1.32.0 @@ -918,19 +1084,171 @@

      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.

      +

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

      +

      Note:

      +

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

      Remediation

      -

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

      +

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

      References


      + +
    +
    +

    Stack-based Buffer Overflow

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/protobuf/encoding/protojson +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/encoding/protojson@v1.31.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + › + google.golang.org/protobuf/encoding/protojson@v1.31.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Infinite loop

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/protobuf/encoding/protojson +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/encoding/protojson@v1.31.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + › + google.golang.org/protobuf/encoding/protojson@v1.31.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + › + google.golang.org/protobuf/encoding/protojson@v1.32.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

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

    +

    Note:

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + +
    @@ -946,7 +1264,7 @@
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
    • Package Manager: golang @@ -954,12 +1272,12 @@
    • Module: - github.com/hashicorp/vault/api + github.com/hashicorp/vault/sdk/helper/certutil
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/vault/api@v1.14.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0
    @@ -972,9 +1290,114 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - github.com/hashicorp/vault/api@v1.14.0 + 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 @@ -1006,7 +1429,7 @@
      • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
      • Package Manager: golang @@ -1019,7 +1442,7 @@
      • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/serf/coordinate@v0.10.1 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/serf/coordinate@v0.9.7
      @@ -1032,9 +1455,9 @@
      • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - github.com/hashicorp/serf/coordinate@v0.10.1 + github.com/hashicorp/serf/coordinate@v0.9.7 @@ -1066,7 +1489,7 @@
        • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/dexidp/dex › /usr/local/bin/dex + Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex › /usr/local/bin/dex
        • Package Manager: golang @@ -1189,7 +1612,7 @@
          • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
          • Package Manager: golang @@ -1202,7 +1625,7 @@
          • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/hcl@v1.0.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/hcl@v1.0.0
          @@ -1215,7 +1638,7 @@
          • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › github.com/hashicorp/hcl@v1.0.0 @@ -1224,7 +1647,7 @@
          • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › github.com/hashicorp/hcl/hcl/token@v1.0.0 @@ -1258,7 +1681,7 @@
            • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
            • Package Manager: golang @@ -1271,7 +1694,7 @@
            • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/golang-lru/simplelru@v1.0.2 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/golang-lru/simplelru@v0.5.4
            @@ -1284,9 +1707,9 @@
            • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - github.com/hashicorp/golang-lru/simplelru@v1.0.2 + github.com/hashicorp/golang-lru/simplelru@v0.5.4 @@ -1318,7 +1741,7 @@
              • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
              • Package Manager: golang @@ -1326,12 +1749,12 @@
              • Module: - github.com/hashicorp/go-uuid + github.com/hashicorp/go-version
              • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-uuid@v1.0.3 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-version@v1.5.0
              @@ -1344,9 +1767,9 @@
    @@ -1378,7 +1801,7 @@
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
    • Package Manager: golang @@ -1391,7 +1814,7 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-sockaddr@v1.0.6 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-sockaddr@v1.0.2
    @@ -1404,18 +1827,18 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - github.com/hashicorp/go-sockaddr@v1.0.6 + github.com/hashicorp/go-sockaddr@v1.0.2
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - github.com/hashicorp/go-sockaddr/template@v1.0.6 + github.com/hashicorp/go-sockaddr/template@v1.0.2 @@ -1447,7 +1870,7 @@
      • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
      • Package Manager: golang @@ -1460,7 +1883,7 @@
      • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2
      @@ -1473,7 +1896,7 @@
      • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 @@ -1507,7 +1930,7 @@
        • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
        • Package Manager: golang @@ -1520,7 +1943,7 @@
        • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.8 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5
        @@ -1533,9 +1956,9 @@
        • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.8 + github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5 @@ -1567,7 +1990,7 @@
          • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
          • Package Manager: golang @@ -1575,12 +1998,12 @@
          • Module: - github.com/hashicorp/go-secure-stdlib/awsutil + github.com/hashicorp/go-secure-stdlib/mlock
          • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-secure-stdlib/awsutil@v0.3.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2
          @@ -1593,9 +2016,9 @@
          • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - github.com/hashicorp/go-secure-stdlib/awsutil@v0.3.0 + github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2 @@ -1611,7 +2034,7 @@
    @@ -1627,7 +2050,7 @@
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
    • Package Manager: golang @@ -1640,7 +2063,7 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-rootcerts@v1.0.2 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-rootcerts@v1.0.2
    @@ -1653,7 +2076,7 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › github.com/hashicorp/go-rootcerts@v1.0.2 @@ -1676,7 +2099,7 @@
    -

    MPL-2.0 license

    +

    Insertion of Sensitive Information into Log File

    @@ -1687,20 +2110,20 @@
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
    • Package Manager: golang
    • - Module: + Vulnerable module: github.com/hashicorp/go-retryablehttp
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-retryablehttp@v0.7.7 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1
    @@ -1713,9 +2136,77 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - github.com/hashicorp/go-retryablehttp@v0.7.7 + 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 @@ -1747,7 +2238,7 @@
      • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
      • Package Manager: golang @@ -1755,12 +2246,12 @@
      • Module: - github.com/hashicorp/go-multierror + github.com/hashicorp/go-plugin
      • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-multierror@v1.1.1 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-plugin@v1.4.4
      @@ -1773,9 +2264,18 @@
      • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - github.com/hashicorp/go-multierror@v1.1.1 + 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 @@ -1791,7 +2291,7 @@
    @@ -1807,7 +2307,7 @@
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
    • Package Manager: golang @@ -1820,7 +2320,7 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-immutable-radix@v1.3.1 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-immutable-radix@v1.3.1
    @@ -1833,7 +2333,7 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › github.com/hashicorp/go-immutable-radix@v1.3.1 @@ -1867,7 +2367,7 @@
      • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
      • Package Manager: golang @@ -1880,7 +2380,7 @@
      • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-cleanhttp@v0.5.2 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-cleanhttp@v0.5.2
      @@ -1893,7 +2393,7 @@
      • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › github.com/hashicorp/go-cleanhttp@v0.5.2 @@ -1927,7 +2427,7 @@
        • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
        • Package Manager: golang @@ -1940,7 +2440,7 @@
        • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/errwrap@v1.1.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/errwrap@v1.1.0
        @@ -1953,7 +2453,7 @@
        • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › github.com/hashicorp/errwrap@v1.1.0 @@ -1976,7 +2476,7 @@
    -

    MPL-2.0 license

    +

    Access Control Bypass

    @@ -1987,20 +2487,20 @@
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
    • Package Manager: golang
    • - Module: + Vulnerable module: github.com/hashicorp/consul/api
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/consul/api@v1.29.1 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0
    @@ -2013,9 +2513,77 @@
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - github.com/hashicorp/consul/api@v1.29.1 + github.com/hashicorp/consul/api@v1.13.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

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

    +

    Remediation

    +

    Upgrade github.com/hashicorp/consul/api to version 1.20.1 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/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 @@ -2047,7 +2615,7 @@
      • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 › /usr/local/bin/gomplate
      • Package Manager: golang @@ -2060,7 +2628,7 @@
      • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/gosimple/slug@v1.14.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/gosimple/slug@v1.12.0
      @@ -2073,9 +2641,9 @@
      • Introduced through: - github.com/hairyhenderson/gomplate/v4@* + github.com/hairyhenderson/gomplate/v3@* › - github.com/gosimple/slug@v1.14.0 + github.com/gosimple/slug@v1.12.0 @@ -2107,7 +2675,7 @@
        • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/dexidp/dex › /usr/local/bin/dex + Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex › /usr/local/bin/dex
        • Package Manager: golang @@ -2120,7 +2688,7 @@
        • Introduced through: - github.com/dexidp/dex@* and github.com/go-sql-driver/mysql@v1.8.1 + github.com/dexidp/dex@* and github.com/go-sql-driver/mysql@v1.7.1
        @@ -2135,7 +2703,7 @@ Introduced through: github.com/dexidp/dex@* › - github.com/go-sql-driver/mysql@v1.8.1 + github.com/go-sql-driver/mysql@v1.7.1 @@ -2156,7 +2724,7 @@
    -

    Allocation of Resources Without Limits or Throttling

    +

    Improper Handling of Highly Compressed Data (Data Amplification)

    @@ -2167,7 +2735,7 @@
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex › /usr/local/bin/dex
    • Package Manager: golang @@ -2175,12 +2743,12 @@
    • Vulnerable module: - github.com/go-jose/go-jose/v4 + github.com/go-jose/go-jose/v3
    • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and github.com/go-jose/go-jose/v4@v4.0.2 + github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.1
    @@ -2191,20 +2759,11 @@

    Detailed paths

      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v4@* - › - github.com/go-jose/go-jose/v4@v4.0.2 - - - -
    • Introduced through: github.com/dexidp/dex@* › - github.com/go-jose/go-jose/v4@v4.0.4 + github.com/go-jose/go-jose/v3@v3.0.1 @@ -2216,21 +2775,1277 @@

      Overview

      -

      Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to the use of strings.Split to split JWT tokens. An attacker can cause memory exhaustion and service disruption by sending numerous malformed tokens with a large number of . characters.

      -

      Workaround

      -

      This vulnerability can be mitigated by pre-validating that payloads passed to Go JOSE do not contain an excessive number of . characters.

      +

      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/v4 to version 4.0.5 or higher.

      +

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

      References


      + +
    +
    +

    Out-of-bounds Write

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.19 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/busybox@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + alpine-baselayout/alpine-baselayout@3.4.3-r2 + › + busybox/busybox-binsh@1.36.1-r15 + › + busybox/busybox@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/busybox-binsh@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + alpine-baselayout/alpine-baselayout@3.4.3-r2 + › + busybox/busybox-binsh@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    A heap-buffer-overflow was discovered in BusyBox v.1.36.1 in the next_token function at awk.c:1159.

    +

    Remediation

    +

    Upgrade Alpine:3.19 busybox to version 1.36.1-r16 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Use After Free

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.19 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/busybox@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + alpine-baselayout/alpine-baselayout@3.4.3-r2 + › + busybox/busybox-binsh@1.36.1-r15 + › + busybox/busybox@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/busybox-binsh@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + alpine-baselayout/alpine-baselayout@3.4.3-r2 + › + busybox/busybox-binsh@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    A use-after-free vulnerability was discovered in BusyBox v.1.36.1 via a crafted awk pattern in the awk.c copyvar function.

    +

    Remediation

    +

    Upgrade Alpine:3.19 busybox to version 1.36.1-r19 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Use After Free

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.19 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/busybox@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + alpine-baselayout/alpine-baselayout@3.4.3-r2 + › + busybox/busybox-binsh@1.36.1-r15 + › + busybox/busybox@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/busybox-binsh@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + alpine-baselayout/alpine-baselayout@3.4.3-r2 + › + busybox/busybox-binsh@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    A use-after-free vulnerability in BusyBox v.1.36.1 allows attackers to cause a denial of service via a crafted awk pattern in the awk.c evaluate function.

    +

    Remediation

    +

    Upgrade Alpine:3.19 busybox to version 1.36.1-r19 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Use After Free

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.19 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/busybox@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + alpine-baselayout/alpine-baselayout@3.4.3-r2 + › + busybox/busybox-binsh@1.36.1-r15 + › + busybox/busybox@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/busybox-binsh@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + alpine-baselayout/alpine-baselayout@3.4.3-r2 + › + busybox/busybox-binsh@1.36.1-r15 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    A use-after-free vulnerability was discovered in xasprintf function in xfuncs_printf.c:344 in BusyBox v.1.36.1.

    +

    Remediation

    +

    Upgrade Alpine:3.19 busybox to version 1.36.1-r17 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-6237

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.19 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: Checking excessively long invalid RSA public keys may take + a long time.

    +

    Impact summary: Applications that use the function EVP_PKEY_public_check() + to check RSA public keys may experience long delays. Where the key that + is being checked has been obtained from an untrusted source this may lead + to a Denial of Service.

    +

    When function EVP_PKEY_public_check() is called on RSA public keys, + a computation is done to confirm that the RSA modulus, n, is composite. + For valid RSA keys, n is a product of two or more large primes and this + computation completes quickly. However, if n is an overly large prime, + then this computation would take a long time.

    +

    An application that calls EVP_PKEY_public_check() and supplies an RSA key + obtained from an untrusted source could be vulnerable to a Denial of Service + attack.

    +

    The function EVP_PKEY_public_check() is not called from other OpenSSL + functions however it is called from the OpenSSL pkey command line + application. For that reason that application is also vulnerable if used + with the '-pubin' and '-check' options on untrusted data.

    +

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

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are affected by this issue.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-2511

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.19 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: Some non-default TLS server configurations can cause unbounded + memory growth when processing TLSv1.3 sessions

    +

    Impact summary: An attacker may exploit certain server configurations to trigger + unbounded memory growth that would lead to a Denial of Service

    +

    This problem can occur in TLSv1.3 if the non-default SSL_OP_NO_TICKET option is + being used (but not if early_data support is also configured and the default + anti-replay protection is in use). In this case, under certain conditions, the + session cache can get into an incorrect state and it will fail to flush properly + as it fills. The session cache will continue to grow in an unbounded manner. A + malicious client could deliberately create the scenario for this failure to + force a Denial of Service. It may also happen by accident in normal operation.

    +

    This issue only affects TLS servers supporting TLSv1.3. It does not affect TLS + clients.

    +

    The FIPS modules in 3.2, 3.1 and 3.0 are not affected by this issue. OpenSSL + 1.0.2 is also not affected by this issue.

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-4603

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.19 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: Checking excessively long DSA keys or parameters may be very + slow.

    +

    Impact summary: Applications that use the functions EVP_PKEY_param_check() + or EVP_PKEY_public_check() to check a DSA public key or DSA parameters may + experience long delays. Where the key or parameters that are being checked + have been obtained from an untrusted source this may lead to a Denial of + Service.

    +

    The functions EVP_PKEY_param_check() or EVP_PKEY_public_check() perform + various checks on DSA parameters. Some of those computations take a long time + if the modulus (p parameter) is too large.

    +

    Trying to use a very large modulus is slow and OpenSSL will not allow using + public keys with a modulus which is over 10,000 bits in length for signature + verification. However the key and parameter check functions do not limit + the modulus size when performing the checks.

    +

    An application that calls EVP_PKEY_param_check() or EVP_PKEY_public_check() + and supplies a key or parameters obtained from an untrusted source could be + vulnerable to a Denial of Service attack.

    +

    These functions are not called by OpenSSL itself on untrusted DSA keys so + only applications that directly call these functions may be vulnerable.

    +

    Also vulnerable are the OpenSSL pkey and pkeyparam command line applications + when using the -check option.

    +

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

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.19 openssl to version 3.1.5-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-5535

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.19 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: Calling the OpenSSL API function SSL_select_next_proto with an + empty supported client protocols buffer may cause a crash or memory contents to + be sent to the peer.

    +

    Impact summary: A buffer overread can have a range of potential consequences + such as unexpected application beahviour or a crash. In particular this issue + could result in up to 255 bytes of arbitrary private data from memory being sent + to the peer leading to a loss of confidentiality. However, only applications + that directly call the SSL_select_next_proto function with a 0 length list of + supported client protocols are affected by this issue. This would normally never + be a valid scenario and is typically not under attacker control but may occur by + accident in the case of a configuration or programming error in the calling + application.

    +

    The OpenSSL API function SSL_select_next_proto is typically used by TLS + applications that support ALPN (Application Layer Protocol Negotiation) or NPN + (Next Protocol Negotiation). NPN is older, was never standardised and + is deprecated in favour of ALPN. We believe that ALPN is significantly more + widely deployed than NPN. The SSL_select_next_proto function accepts a list of + protocols from the server and a list of protocols from the client and returns + the first protocol that appears in the server list that also appears in the + client list. In the case of no overlap between the two lists it returns the + first item in the client list. In either case it will signal whether an overlap + between the two lists was found. In the case where SSL_select_next_proto is + called with a zero length client list it fails to notice this condition and + returns the memory immediately following the client list pointer (and reports + that there was no overlap in the lists).

    +

    This function is typically called from a server side application callback for + ALPN or a client side application callback for NPN. In the case of ALPN the list + of protocols supplied by the client is guaranteed by libssl to never be zero in + length. The list of server protocols comes from the application and should never + normally be expected to be of zero length. In this case if the + SSL_select_next_proto function has been called as expected (with the list + supplied by the client passed in the client/client_len parameters), then the + application will not be vulnerable to this issue. If the application has + accidentally been configured with a zero length server list, and has + accidentally passed that zero length server list in the client/client_len + parameters, and has additionally failed to correctly handle a "no overlap" + response (which would normally result in a handshake failure in ALPN) then it + will be vulnerable to this problem.

    +

    In the case of NPN, the protocol permits the client to opportunistically select + a protocol when there is no overlap. OpenSSL returns the first client protocol + in the no overlap case in support of this. The list of client protocols comes + from the application and should never normally be expected to be of zero length. + However if the SSL_select_next_proto function is accidentally called with a + client_len of 0 then an invalid memory pointer will be returned instead. If the + application uses this output as the opportunistic protocol then the loss of + confidentiality will occur.

    +

    This issue has been assessed as Low severity because applications are most + likely to be vulnerable if they are using NPN instead of ALPN - but NPN is not + widely used. It also requires an application configuration or programming error. + Finally, this issue would not typically be under attacker control making active + exploitation unlikely.

    +

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

    +

    Due to the low severity of this issue we are not issuing new releases of + OpenSSL at this time. The fix will be included in the next releases when they + become available.

    +

    Remediation

    +

    Upgrade Alpine:3.19 openssl to version 3.1.6-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-4741

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.19 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + › + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + apk-tools/apk-tools@2.14.0-r5 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + › + busybox/ssl_client@1.36.1-r15 + › + openssl/libssl3@3.1.4-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

    Remediation

    +

    Upgrade Alpine:3.19 openssl to version 3.1.6-r0 or higher.

    +

    References

    + + +
    + +
    @@ -2246,7 +4061,7 @@
    • - Package Manager: alpine:3.20 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -2256,7 +4071,7 @@
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 and openssl/libcrypto3@3.3.1-r3 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
    @@ -2269,75 +4084,75 @@
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - openssl/libcrypto3@3.3.1-r3 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - apk-tools/apk-tools@2.14.4-r0 + apk-tools/apk-tools@2.14.0-r5 › - openssl/libcrypto3@3.3.1-r3 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - busybox/ssl_client@1.36.1-r29 + busybox/ssl_client@1.36.1-r15 › - openssl/libcrypto3@3.3.1-r3 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - apk-tools/apk-tools@2.14.4-r0 + apk-tools/apk-tools@2.14.0-r5 › - openssl/libssl3@3.3.1-r3 + openssl/libssl3@3.1.4-r2 › - openssl/libcrypto3@3.3.1-r3 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - openssl/libssl3@3.3.1-r3 + openssl/libssl3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - apk-tools/apk-tools@2.14.4-r0 + apk-tools/apk-tools@2.14.0-r5 › - openssl/libssl3@3.3.1-r3 + openssl/libssl3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - busybox/ssl_client@1.36.1-r29 + busybox/ssl_client@1.36.1-r15 › - openssl/libssl3@3.3.1-r3 + openssl/libssl3@3.1.4-r2 @@ -2350,7 +4165,7 @@

      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.

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

      Issue summary: Applications performing certificate name checks (e.g., TLS clients checking server certificates) may attempt to read an invalid memory address resulting in abnormal termination of the application process.

      @@ -2371,7 +4186,7 @@ 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.

      +

      Upgrade Alpine:3.19 openssl to version 3.1.7-r0 or higher.

      References

    @@ -2403,7 +4218,7 @@
    • - Package Manager: alpine:3.20 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -2413,7 +4228,7 @@
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 and openssl/libcrypto3@3.3.1-r3 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
    @@ -2426,75 +4241,75 @@
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - openssl/libcrypto3@3.3.1-r3 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - apk-tools/apk-tools@2.14.4-r0 + apk-tools/apk-tools@2.14.0-r5 › - openssl/libcrypto3@3.3.1-r3 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - busybox/ssl_client@1.36.1-r29 + busybox/ssl_client@1.36.1-r15 › - openssl/libcrypto3@3.3.1-r3 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - apk-tools/apk-tools@2.14.4-r0 + apk-tools/apk-tools@2.14.0-r5 › - openssl/libssl3@3.3.1-r3 + openssl/libssl3@3.1.4-r2 › - openssl/libcrypto3@3.3.1-r3 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - openssl/libssl3@3.3.1-r3 + openssl/libssl3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - apk-tools/apk-tools@2.14.4-r0 + apk-tools/apk-tools@2.14.0-r5 › - openssl/libssl3@3.3.1-r3 + openssl/libssl3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 › - busybox/ssl_client@1.36.1-r29 + busybox/ssl_client@1.36.1-r15 › - openssl/libssl3@3.3.1-r3 + openssl/libssl3@3.1.4-r2 @@ -2507,7 +4322,7 @@

      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.

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

      @@ -2531,7 +4346,7 @@ 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-r3 or higher.

      +

      Upgrade Alpine:3.19 openssl to version 3.1.7-r1 or higher.

      References

    -
    -

    CVE-2024-13176

    -
    - -
    - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

    -

    Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

    -

    There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-12797

    -
    - -
    - 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: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a - server may fail to notice that the server was not authenticated, because - handshakes don't abort as expected when the SSL_VERIFY_PEER verification mode - is set.

    -

    Impact summary: TLS and DTLS connections using raw public keys may be - vulnerable to man-in-middle attacks when server authentication failure is not - detected by clients.

    -

    RPKs are disabled by default in both TLS clients and TLS servers. The issue - only arises when TLS clients explicitly enable RPK use by the server, and the - server, likewise, enables sending of an RPK instead of an X.509 certificate - chain. The affected clients are those that then rely on the handshake to - fail when the server's RPK fails to match one of the expected public keys, - by setting the verification mode to SSL_VERIFY_PEER.

    -

    Clients that enable server-side raw public keys can still find out that raw - public key verification failed by calling SSL_get_verify_result(), and those - that do, and take appropriate action, are not affected. This issue was - introduced in the initial implementation of RPK support in OpenSSL 3.2.

    -

    The FIPS modules in 3.4, 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.3-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2025-26519

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.20 -
    • -
    • - Vulnerable module: - - musl/musl -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.41.1 and musl/musl@1.2.5-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - apk-tools/apk-tools@2.14.4-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - busybox/ssl_client@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - musl/musl-utils@1.2.5-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - 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 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - 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 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - apk-tools/apk-tools@2.14.4-r0 - › - zlib/zlib@1.3.1-r1 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - musl/musl-utils@1.2.5-r0 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - alpine-baselayout/alpine-baselayout@3.6.5-r0 - › - busybox/busybox-binsh@1.36.1-r29 - › - busybox/busybox@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - musl/musl-utils@1.2.5-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

    -

    Remediation

    -

    Upgrade Alpine:3.20 musl to version 1.2.5-r1 or higher.

    -

    References

    - - -
    - -
    diff --git a/docs/snyk/v2.14.5/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html b/docs/snyk/v2.12.8/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html similarity index 67% rename from docs/snyk/v2.14.5/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html rename to docs/snyk/v2.12.8/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html index 5d22909945..e024f2d331 100644 --- a/docs/snyk/v2.14.5/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html +++ b/docs/snyk/v2.12.8/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    March 16th 2025, 12:23:57 am (UTC+00:00)

    +

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

    Scanned the following path: @@ -466,8 +466,8 @@
    -
    9 known vulnerabilities
    -
    86 vulnerable dependency paths
    +
    6 known vulnerabilities
    +
    52 vulnerable dependency paths
    18 dependencies
    @@ -1508,7 +1508,7 @@ 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-r3 or higher.

    +

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

    References

    -
    -

    CVE-2024-13176

    -
    - -
    - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

    -

    Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

    -

    There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-12797

    -
    - -
    - 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: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a - server may fail to notice that the server was not authenticated, because - handshakes don't abort as expected when the SSL_VERIFY_PEER verification mode - is set.

    -

    Impact summary: TLS and DTLS connections using raw public keys may be - vulnerable to man-in-middle attacks when server authentication failure is not - detected by clients.

    -

    RPKs are disabled by default in both TLS clients and TLS servers. The issue - only arises when TLS clients explicitly enable RPK use by the server, and the - server, likewise, enables sending of an RPK instead of an X.509 certificate - chain. The affected clients are those that then rely on the handshake to - fail when the server's RPK fails to match one of the expected public keys, - by setting the verification mode to SSL_VERIFY_PEER.

    -

    Clients that enable server-side raw public keys can still find out that raw - public key verification failed by calling SSL_get_verify_result(), and those - that do, and take appropriate action, are not affected. This issue was - introduced in the initial implementation of RPK support in OpenSSL 3.2.

    -

    The FIPS modules in 3.4, 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.3-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2025-26519

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.20 -
    • -
    • - Vulnerable module: - - musl/musl -
    • - -
    • Introduced through: - - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and musl/musl@1.2.5-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - busybox/ssl_client@1.36.1-r28 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - ca-certificates/ca-certificates@20240226-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - musl/musl-utils@1.2.5-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - lua5.3/lua5.3-libs@5.3.6-r6 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - openssl/libcrypto3@3.3.0-r2 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - openssl/libssl3@3.3.0-r2 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - pcre2/pcre2@10.43-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - zlib/zlib@1.3.1-r1 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - musl/musl-utils@1.2.5-r0 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - 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 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - musl/musl-utils@1.2.5-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

    -

    Remediation

    -

    Upgrade Alpine:3.20 musl to version 1.2.5-r1 or higher.

    -

    References

    - - -
    - - - -
    diff --git a/docs/snyk/v2.12.8/public.ecr.aws_docker_library_redis_7.0.15-alpine.html b/docs/snyk/v2.12.8/public.ecr.aws_docker_library_redis_7.0.15-alpine.html new file mode 100644 index 0000000000..46dc068dba --- /dev/null +++ b/docs/snyk/v2.12.8/public.ecr.aws_docker_library_redis_7.0.15-alpine.html @@ -0,0 +1,670 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    December 15th 2024, 12:27:03 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.5/quay.io_argoproj_argocd_v2.13.5.html b/docs/snyk/v2.12.8/quay.io_argoproj_argocd_v2.12.8.html similarity index 56% rename from docs/snyk/v2.13.5/quay.io_argoproj_argocd_v2.13.5.html rename to docs/snyk/v2.12.8/quay.io_argoproj_argocd_v2.12.8.html index 36102099eb..3366948878 100644 --- a/docs/snyk/v2.13.5/quay.io_argoproj_argocd_v2.13.5.html +++ b/docs/snyk/v2.12.8/quay.io_argoproj_argocd_v2.12.8.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,23 +456,23 @@

    Snyk test report

    -

    March 16th 2025, 12:26:59 am (UTC+00:00)

    +

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

    Scanned the following paths:
      -
    • quay.io/argoproj/argocd:v2.13.5/argoproj/argocd/Dockerfile (deb)
    • -
    • quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.13.5//usr/local/bin/kustomize (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.13.5/helm/v3//usr/local/bin/helm (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.13.5/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.8/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.8//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.8/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.8/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    -
    40 known vulnerabilities
    -
    161 vulnerable dependency paths
    -
    2359 dependencies
    +
    24 known vulnerabilities
    +
    104 vulnerable dependency paths
    +
    2292 dependencies
    @@ -480,244 +480,19 @@
    -
    -

    Allocation of Resources Without Limits or Throttling

    +
    +

    Incorrect Implementation of Authentication Algorithm

    -
    - high severity +
    + critical severity

    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/oauth2/jws -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and golang.org/x/oauth2/jws@v0.23.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - golang.org/x/oauth2/jws@v0.23.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to improper parsing of malformed tokens which can lead to memory consumption.

    -

    Remediation

    -

    Upgrade golang.org/x/oauth2/jws to version 0.27.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Server-side Request Forgery (SSRF)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http/httpproxy -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and golang.org/x/net/http/httpproxy@v0.33.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - golang.org/x/net/http/httpproxy@v0.33.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http/httpproxy is a package for HTTP proxy determination based on environment variables, as provided by net/http's ProxyFromEnvironment function

    -

    Affected versions of this package are vulnerable to Server-side Request Forgery (SSRF) in proxy.go, because hostname matching against proxy patterns may treat an IPv6 zone ID as a hostname component. An environment variable value like *.example.com could be matched to a request intended for [::1%25.example.com]:80.

    -

    Remediation

    -

    Upgrade golang.org/x/net/http/httpproxy to version 0.36.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/helm/v3 › /usr/local/bin/helm -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/html -
    • - -
    • Introduced through: - - helm.sh/helm/v3@* and golang.org/x/net/html@v0.23.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - helm.sh/helm/v3@* - › - golang.org/x/net/html@v0.23.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) through the functions parseDoctype, htmlIntegrationPoint, inBodyIM and inTableIM due to inefficient usage of the method strings.ToLower combining with the == operator to convert strings to lowercase and then comparing them.

    -

    An attacker can cause the application to slow down significantly by crafting inputs that are processed non-linearly.

    -

    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 golang.org/x/net/html to version 0.33.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • Package Manager: golang @@ -730,7 +505,7 @@
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and golang.org/x/crypto/ssh@v0.31.0 + github.com/argoproj/argo-cd/v2@* and golang.org/x/crypto/ssh@v0.23.0
    @@ -745,7 +520,7 @@ Introduced through: github.com/argoproj/argo-cd/v2@* › - golang.org/x/crypto/ssh@v0.31.0 + golang.org/x/crypto/ssh@v0.23.0 @@ -758,125 +533,24 @@

    Overview

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

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling in handshakeTransport in handshake.go. An internal queue gets populated with received packets during the key exchange process, while waiting for the client to send a SSH_MSG_KEXINIT. An attacker can cause the server to become unresponsive to new connections by delaying or withholding this message, or by causing the queue to consume all available memory.

    +

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

    +

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

    Remediation

    -

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

    +

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

    References


    - -
    -
    -

    CVE-2024-56433

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - shadow/passwd -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.13.5 and shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 - › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - apt@2.7.14build2 - › - adduser@3.137ubuntu1 - › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - shadow/login@1:4.13+dfsg1-4ubuntu3.2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    shadow-utils (aka shadow) 4.4 through 4.17.0 establishes a default /etc/subuid behavior (e.g., uid 100000 through 165535 for the first user account) that can realistically conflict with the uids of users defined on locally administered networks, potentially leading to account takeover, e.g., by leveraging newuidmap for access to an NFS home directory (or same-host resources in the case of remote logins by these local network users). NOTE: it may also be argued that system administrators should not have assigned uids, within local networks, that are within the range that can occur in /etc/subuid.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:24.04 shadow.

    -

    References

    - - -
    - -
    @@ -892,7 +566,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
    • Package Manager: ubuntu:24.04 @@ -905,7 +579,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 and pam/libpam0g@1.5.3-5ubuntu5.1 + docker-image|quay.io/argoproj/argocd@v2.12.8 and pam/libpam0g@1.5.3-5ubuntu5.1
    @@ -918,7 +592,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › pam/libpam0g@1.5.3-5ubuntu5.1 @@ -927,7 +601,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › shadow/login@1:4.13+dfsg1-4ubuntu3.2 › @@ -938,9 +612,9 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - util-linux@2.39.3-9ubuntu6.2 + util-linux@2.39.3-9ubuntu6.1 › pam/libpam0g@1.5.3-5ubuntu5.1 @@ -949,7 +623,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -964,7 +638,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -981,7 +655,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -1000,7 +674,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › pam/libpam-modules-bin@1.5.3-5ubuntu5.1 @@ -1009,7 +683,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -1026,7 +700,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › pam/libpam-modules@1.5.3-5ubuntu5.1 @@ -1035,7 +709,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › pam/libpam-runtime@1.5.3-5ubuntu5.1 › @@ -1046,7 +720,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › shadow/login@1:4.13+dfsg1-4ubuntu3.2 › @@ -1057,7 +731,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -1072,7 +746,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › pam/libpam-runtime@1.5.3-5ubuntu5.1 @@ -1081,7 +755,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › shadow/login@1:4.13+dfsg1-4ubuntu3.2 › @@ -1109,7 +783,6 @@
    • https://bugzilla.redhat.com/show_bug.cgi?id=2319212
    • https://access.redhat.com/errata/RHSA-2024:9941
    • https://access.redhat.com/errata/RHSA-2024:10379
    • -
    • https://access.redhat.com/errata/RHSA-2024:11250

    @@ -1131,7 +804,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
    • Package Manager: ubuntu:24.04 @@ -1144,7 +817,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 and pam/libpam0g@1.5.3-5ubuntu5.1 + docker-image|quay.io/argoproj/argocd@v2.12.8 and pam/libpam0g@1.5.3-5ubuntu5.1
    @@ -1157,7 +830,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › pam/libpam0g@1.5.3-5ubuntu5.1 @@ -1166,7 +839,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › shadow/login@1:4.13+dfsg1-4ubuntu3.2 › @@ -1177,9 +850,9 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - util-linux@2.39.3-9ubuntu6.2 + util-linux@2.39.3-9ubuntu6.1 › pam/libpam0g@1.5.3-5ubuntu5.1 @@ -1188,7 +861,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -1203,7 +876,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -1220,7 +893,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -1239,7 +912,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › pam/libpam-modules-bin@1.5.3-5ubuntu5.1 @@ -1248,7 +921,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -1265,7 +938,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › pam/libpam-modules@1.5.3-5ubuntu5.1 @@ -1274,7 +947,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › pam/libpam-runtime@1.5.3-5ubuntu5.1 › @@ -1285,7 +958,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › shadow/login@1:4.13+dfsg1-4ubuntu3.2 › @@ -1296,7 +969,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -1311,7 +984,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › pam/libpam-runtime@1.5.3-5ubuntu5.1 @@ -1320,7 +993,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › shadow/login@1:4.13+dfsg1-4ubuntu3.2 › @@ -1346,12 +1019,6 @@
    • http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-10963
    • https://access.redhat.com/security/cve/CVE-2024-10963
    • https://bugzilla.redhat.com/show_bug.cgi?id=2324291
    • -
    • https://access.redhat.com/errata/RHSA-2024:10232
    • -
    • https://access.redhat.com/errata/RHSA-2024:10244
    • -
    • https://access.redhat.com/errata/RHSA-2024:10379
    • -
    • https://access.redhat.com/errata/RHSA-2024:10518
    • -
    • https://access.redhat.com/errata/RHSA-2024:10528
    • -
    • https://access.redhat.com/errata/RHSA-2024:10852

    @@ -1362,7 +1029,7 @@
    -

    Resource Exhaustion

    +

    CVE-2024-26462

    @@ -1373,362 +1040,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - openssh/openssh-client -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.13.5 and openssh/openssh-client@1:9.6p1-3ubuntu13.5 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    A flaw was found in the OpenSSH package. For each ping packet the SSH server receives, a pong packet is allocated in a memory buffer and stored in a queue of packages. It is only freed when the server/client key exchange has finished. A malicious client may keep sending such packages, leading to an uncontrolled increase in memory consumption on the server side. Consequently, the server may become unavailable, resulting in a denial of service attack.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 openssh to version 1:9.6p1-3ubuntu13.8 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Detection of Error Condition Without Action

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - openssh/openssh-client -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.13.5 and openssh/openssh-client@1:9.6p1-3ubuntu13.5 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    A vulnerability was found in OpenSSH when the VerifyHostKeyDNS option is enabled. A machine-in-the-middle attack can be performed by a malicious machine impersonating a legit server. This issue occurs due to how OpenSSH mishandles error codes in specific conditions when verifying the host key. For an attack to be considered successful, the attacker needs to manage to exhaust the client's memory resource first, turning the attack complexity high.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 openssh to version 1:9.6p1-3ubuntu13.8 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Algorithmic Complexity

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - libtasn1-6 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.13.5 and libtasn1-6@4.19.0-3build1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - libtasn1-6@4.19.0-3build1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - apt@2.7.14build2 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - › - libtasn1-6@4.19.0-3build1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    A flaw in libtasn1 causes inefficient handling of specific certificate data. When processing a large number of elements in a certificate, libtasn1 takes much longer than expected, which can slow down or even crash the system. This flaw allows an attacker to send a specially crafted certificate, causing a denial of service attack.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 libtasn1-6 to version 4.19.0-3ubuntu0.24.04.1 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2025-1390

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - libcap2 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.13.5 and libcap2@1:2.66-5ubuntu2.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - libcap2@1:2.66-5ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - apt@2.7.14build2 - › - apt/libapt-pkg6.0t64@2.7.14build2 - › - systemd/libudev1@255.4-1ubuntu8.5 - › - libcap2@1:2.66-5ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - 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.5 - › - libcap2@1:2.66-5ubuntu2.1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    The PAM module pam_cap.so of libcap configuration supports group names starting with “@”, during actual parsing, configurations not starting with “@” are incorrectly recognized as group names. This may result in nonintended users being granted an inherited capability set, potentially leading to security risks. Attackers can exploit this vulnerability to achieve local privilege escalation on systems where /etc/security/capability.conf is used to configure user inherited privileges by constructing specific usernames.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 libcap2 to version 1:2.66-5ubuntu2.2 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Memory Leak

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
    • Package Manager: ubuntu:24.04 @@ -1742,7 +1054,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5, git@1:2.43.0-1ubuntu7.2 and others + docker-image|quay.io/argoproj/argocd@v2.12.8, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1754,146 +1066,146 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.3 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.3 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5support0@1.20.1-6ubuntu2.3 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 › - krb5/libkrb5support0@1.20.1-6ubuntu2.3 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.3 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 › - krb5/libkrb5support0@1.20.1-6ubuntu2.3 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › openssh/openssh-client@1:9.6p1-3ubuntu13.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › libssh/libssh-4@0.10.6-2build2 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - krb5/krb5-locales@1.20.1-6ubuntu2.3 + krb5/krb5-locales@1.20.1-6ubuntu2.2 @@ -1909,7 +1221,7 @@ 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

      -

      Upgrade Ubuntu:24.04 krb5 to version 1.20.1-6ubuntu2.5 or higher.

      +

      There is no fixed version for Ubuntu:24.04 krb5.

      References

    -
    -
    -

    CVE-2025-24528

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - krb5/libk5crypto3 -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.13.5, git@1:2.43.0-1ubuntu7.2 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 - › - krb5/libk5crypto3@1.20.1-6ubuntu2.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 - › - krb5/libk5crypto3@1.20.1-6ubuntu2.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 - › - krb5/libkrb5support0@1.20.1-6ubuntu2.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 - › - krb5/libkrb5support0@1.20.1-6ubuntu2.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 - › - krb5/libk5crypto3@1.20.1-6ubuntu2.3 - › - krb5/libkrb5support0@1.20.1-6ubuntu2.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - openssh/openssh-client@1:9.6p1-3ubuntu13.5 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - libssh/libssh-4@0.10.6-2build2 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - krb5/krb5-locales@1.20.1-6ubuntu2.3 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 krb5 to version 1.20.1-6ubuntu2.5 or higher.

    -

    References

    - - -
    - - -

    LGPL-3.0 license

    @@ -2140,7 +1248,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • Package Manager: golang @@ -2189,7 +1297,7 @@
    -

    Algorithmic Complexity

    +

    Denial of Service (DoS)

    @@ -2200,20 +1308,20 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • - Package Manager: ubuntu:24.04 + Package Manager: golang
    • Vulnerable module: - gnutls28/libgnutls30t64 + github.com/rs/cors
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 and gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 + github.com/argoproj/argo-cd/v2@* and github.com/rs/cors@v1.9.0
    @@ -2226,74 +1334,9 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + github.com/argoproj/argo-cd/v2@* › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - apt@2.7.14build2 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - gnupg2/dirmngr@2.4.4-2ubuntu17 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - rtmpdump/librtmp1@2.4+20151223.gitfa8646d.1-2build7 - › - gnutls28/libgnutls30t64@3.8.3-1.1ubuntu3.2 + github.com/rs/cors@v1.9.0 @@ -2304,110 +1347,62 @@
      -

      NVD Description

      -

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

      -

      A flaw was found in GnuTLS, which relies on libtasn1 for ASN.1 data processing. Due to an inefficient algorithm in libtasn1, decoding certain DER-encoded certificate data can take excessive time, leading to increased resource consumption. This flaw allows a remote attacker to send a specially crafted certificate, causing GnuTLS to become unresponsive or slow, resulting in a denial-of-service condition.

      +

      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 Ubuntu:24.04 gnutls28 to version 3.8.3-1.1ubuntu3.3 or higher.

      +

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

      References


      - -
    -
    -

    CVE-2025-0395

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - glibc/libc-bin -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.13.5 and glibc/libc-bin@2.39-0ubuntu8.3 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - glibc/libc-bin@2.39-0ubuntu8.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - 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.

    -

    When the assert() function in the GNU C Library versions 2.13 to 2.40 fails, it does not allocate enough space for the assertion failure message string and size information, which may lead to a buffer overflow if the message string size aligns to page size.

    -

    Remediation

    -

    Upgrade Ubuntu:24.04 glibc to version 2.39-0ubuntu8.4 or higher.

    -

    References

    - - -
    - -
    @@ -2423,7 +1418,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 › /usr/local/bin/argocd
    • Package Manager: golang @@ -2483,7 +1478,7 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 › /usr/local/bin/argocd
      • Package Manager: golang @@ -2543,7 +1538,7 @@
        • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 › /usr/local/bin/argocd
        • Package Manager: golang @@ -2603,7 +1598,7 @@
          • - Manifest file: quay.io/argoproj/argocd:v2.13.5/helm/v3 › /usr/local/bin/helm + Manifest file: quay.io/argoproj/argocd:v2.12.8/helm/v3 › /usr/local/bin/helm
          • Package Manager: golang @@ -2663,7 +1658,7 @@
            • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 › /usr/local/bin/argocd
            • Package Manager: golang @@ -2723,7 +1718,7 @@
              • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 › /usr/local/bin/argocd
              • Package Manager: golang @@ -2736,7 +1731,7 @@
              • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.14.0 + github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.13.1
              @@ -2751,7 +1746,7 @@ Introduced through: github.com/argoproj/argo-cd/v2@* › - github.com/gosimple/slug@v1.14.0 + github.com/gosimple/slug@v1.13.1 @@ -2770,307 +1765,6 @@

              More about this vulnerability

    -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-jose/go-jose/v4 -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/go-jose/go-jose/v4@v4.0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - github.com/go-jose/go-jose/v4@v4.0.2 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to the use of strings.Split to split JWT tokens. An attacker can cause memory exhaustion and service disruption by sending numerous malformed tokens with a large number of . characters.

    -

    Workaround

    -

    This vulnerability can be mitigated by pre-validating that payloads passed to Go JOSE do not contain an excessive number of . characters.

    -

    Remediation

    -

    Upgrade github.com/go-jose/go-jose/v4 to version 4.0.5 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Generation of Error Message Containing Sensitive Information

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/argoproj/gitops-engine/pkg/utils/kube -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/argoproj/gitops-engine/pkg/utils/kube@v0.7.1-0.20250129155113-4c6e03c46314 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - github.com/argoproj/gitops-engine/pkg/utils/kube@v0.7.1-0.20250129155113-4c6e03c46314 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Generation of Error Message Containing Sensitive Information when syncing invalid Kubernetes Secret resources. An attacker with write access to the repository can expose secret values by committing an invalid Secret to repository and triggering a Sync, which then become visible to any user with read access to Argo CD.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    Generation of Error Message Containing Sensitive Information

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/argoproj/gitops-engine/pkg/diff -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/argoproj/gitops-engine/pkg/diff@v0.7.1-0.20250129155113-4c6e03c46314 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - github.com/argoproj/gitops-engine/pkg/diff@v0.7.1-0.20250129155113-4c6e03c46314 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Generation of Error Message Containing Sensitive Information when syncing invalid Kubernetes Secret resources. An attacker with write access to the repository can expose secret values by committing an invalid Secret to repository and triggering a Sync, which then become visible to any user with read access to Argo CD.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    Improper Encoding or Escaping of Output

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile -
    • -
    • - Package Manager: ubuntu:24.04 -
    • -
    • - Vulnerable module: - - git/git-man -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.13.5, git@1:2.43.0-1ubuntu7.2 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - git/git-man@1:2.43.0-1ubuntu7.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git-lfs@3.4.1-1ubuntu0.2 - › - git@1:2.43.0-1ubuntu7.2 - - - -
    • -
    - -
    - -
    - -

    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 is a source code management tool. When cloning from a server (or fetching, or pushing), informational or error messages are transported from the remote Git process to the client via the so-called "sideband channel". These messages will be prefixed with "remote:" and printed directly to the standard error output. Typically, this standard error output is connected to a terminal that understands ANSI escape sequences, which Git did not protect against. Most modern terminals support control sequences that can be used by a malicious actor to hide and misrepresent information, or to mislead the user into executing untrusted scripts. As requested on the git-security mailing list, the patches are under discussion on the public mailing list. Users are advised to update as soon as possible. Users unable to upgrade should avoid recursive clones unless they are from trusted sources.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:24.04 git.

    -

    References

    - - -
    - - -

    Release of Invalid Pointer or Reference

    @@ -3084,7 +1778,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
    • Package Manager: ubuntu:24.04 @@ -3097,7 +1791,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 and patch@2.7.6-7build3 + docker-image|quay.io/argoproj/argocd@v2.12.8 and patch@2.7.6-7build3
    @@ -3110,7 +1804,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › patch@2.7.6-7build3 @@ -3154,7 +1848,7 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
      • Package Manager: ubuntu:24.04 @@ -3167,7 +1861,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 and patch@2.7.6-7build3 + docker-image|quay.io/argoproj/argocd@v2.12.8 and patch@2.7.6-7build3
      @@ -3180,7 +1874,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › patch@2.7.6-7build3 @@ -3229,7 +1923,7 @@
        • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
        • Package Manager: ubuntu:24.04 @@ -3242,7 +1936,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 and openssl/libssl3t64@3.0.13-0ubuntu3.4 + docker-image|quay.io/argoproj/argocd@v2.12.8 and openssl/libssl3t64@3.0.13-0ubuntu3.4
        @@ -3255,7 +1949,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -3264,7 +1958,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › coreutils@9.4-3ubuntu6 › @@ -3275,7 +1969,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 › @@ -3286,7 +1980,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › libfido2/libfido2-1@1.14.0-1build3 › @@ -3297,7 +1991,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › openssh/openssh-client@1:9.6p1-3ubuntu13.5 › @@ -3308,7 +2002,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › ca-certificates@20240203 › @@ -3321,11 +2015,11 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › libssh/libssh-4@0.10.6-2build2 › @@ -3336,15 +2030,15 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 › openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -3353,11 +2047,11 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 › @@ -3370,7 +2064,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › openssl@3.0.13-0ubuntu3.4 @@ -3379,7 +2073,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › ca-certificates@20240203 › @@ -3414,450 +2108,6 @@

          More about this vulnerability

    -
    -
    -

    CVE-2024-9143

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

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - coreutils@9.4-3ubuntu6 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - 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.5 - › - libfido2/libfido2-1@1.14.0-1build3 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - 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.5 - › - 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.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - libssh/libssh-4@0.10.6-2build2 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 - › - cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - openssl@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - 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.

    -

    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 Ubuntu:24.04 openssl to version 3.0.13-0ubuntu3.5 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-13176

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

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - coreutils@9.4-3ubuntu6 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - 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.5 - › - libfido2/libfido2-1@1.14.0-1build3 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - 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.5 - › - 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.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - libssh/libssh-4@0.10.6-2build2 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 - › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 - › - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 - › - cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 - › - openssl/libssl3t64@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - openssl@3.0.13-0ubuntu3.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 - › - 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.

    -

    Issue summary: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

    -

    Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

    -

    There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - -

    Information Exposure

    @@ -3871,7 +2121,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
    • Package Manager: ubuntu:24.04 @@ -3884,7 +2134,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 and libgcrypt20@1.10.3-2build1 + docker-image|quay.io/argoproj/argocd@v2.12.8 and libgcrypt20@1.10.3-2build1
    @@ -3897,7 +2147,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › libgcrypt20@1.10.3-2build1 @@ -3906,7 +2156,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › gnupg2/dirmngr@2.4.4-2ubuntu17 › @@ -3917,7 +2167,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › gnupg2/gpg@2.4.4-2ubuntu17 › @@ -3928,7 +2178,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › gnupg2/gpg-agent@2.4.4-2ubuntu17 › @@ -3939,7 +2189,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -3952,7 +2202,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -3965,7 +2215,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › gnupg2/gpg@2.4.4-2ubuntu17 › @@ -3978,7 +2228,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -3988,7 +2238,7 @@ › pam/libpam-modules@1.5.3-5ubuntu5.1 › - systemd/libsystemd0@255.4-1ubuntu8.5 + systemd/libsystemd0@255.4-1ubuntu8.4 › libgcrypt20@1.10.3-2build1 @@ -4035,7 +2285,7 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
      • Package Manager: ubuntu:24.04 @@ -4049,7 +2299,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5, git@1:2.43.0-1ubuntu7.2 and others + docker-image|quay.io/argoproj/argocd@v2.12.8, git@1:2.43.0-1ubuntu7.1 and others
      @@ -4061,146 +2311,146 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.3 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.3 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5support0@1.20.1-6ubuntu2.3 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 › - krb5/libkrb5support0@1.20.1-6ubuntu2.3 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.3 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 › - krb5/libkrb5support0@1.20.1-6ubuntu2.3 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › openssh/openssh-client@1:9.6p1-3ubuntu13.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › libssh/libssh-4@0.10.6-2build2 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - krb5/krb5-locales@1.20.1-6ubuntu2.3 + krb5/krb5-locales@1.20.1-6ubuntu2.2 @@ -4216,7 +2466,7 @@ 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

        -

        Upgrade Ubuntu:24.04 krb5 to version 1.20.1-6ubuntu2.5 or higher.

        +

        There is no fixed version for Ubuntu:24.04 krb5.

        References

        • http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-26458
        • @@ -4243,7 +2493,7 @@
          • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
          • Package Manager: ubuntu:24.04 @@ -4257,7 +2507,7 @@
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5, git@1:2.43.0-1ubuntu7.2 and others + docker-image|quay.io/argoproj/argocd@v2.12.8, git@1:2.43.0-1ubuntu7.1 and others
          @@ -4269,146 +2519,146 @@
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.3 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.3 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5support0@1.20.1-6ubuntu2.3 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 › - krb5/libkrb5support0@1.20.1-6ubuntu2.3 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 › - krb5/libk5crypto3@1.20.1-6ubuntu2.3 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 › - krb5/libkrb5support0@1.20.1-6ubuntu2.3 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.2
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › openssh/openssh-client@1:9.6p1-3ubuntu13.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › libssh/libssh-4@0.10.6-2build2 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › - krb5/krb5-locales@1.20.1-6ubuntu2.3 + krb5/krb5-locales@1.20.1-6ubuntu2.2 @@ -4424,7 +2674,7 @@ 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

            -

            Upgrade Ubuntu:24.04 krb5 to version 1.20.1-6ubuntu2.5 or higher.

            +

            There is no fixed version for Ubuntu:24.04 krb5.

            References

            • http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-26461
            • @@ -4451,7 +2701,7 @@
              • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
              • Package Manager: ubuntu:24.04 @@ -4464,7 +2714,7 @@
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 and gnupg2/gpgv@2.4.4-2ubuntu17 + docker-image|quay.io/argoproj/argocd@v2.12.8 and gnupg2/gpgv@2.4.4-2ubuntu17
              @@ -4477,7 +2727,7 @@
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › gnupg2/gpgv@2.4.4-2ubuntu17 @@ -4486,7 +2736,7 @@
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › apt@2.7.14build2 › @@ -4497,7 +2747,7 @@
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › gnupg2/dirmngr@2.4.4-2ubuntu17 › @@ -4508,7 +2758,7 @@
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › gnupg2/gpg-agent@2.4.4-2ubuntu17 › @@ -4519,7 +2769,7 @@
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › gnupg2/gpg@2.4.4-2ubuntu17 › @@ -4530,7 +2780,7 @@
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › gnupg2/dirmngr@2.4.4-2ubuntu17 @@ -4539,7 +2789,7 @@
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › gnupg2/gpg@2.4.4-2ubuntu17 @@ -4548,7 +2798,7 @@
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › gnupg2/gpg-agent@2.4.4-2ubuntu17 @@ -4597,7 +2847,7 @@
                • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
                • Package Manager: ubuntu:24.04 @@ -4610,7 +2860,7 @@
                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 and glibc/libc-bin@2.39-0ubuntu8.3 + docker-image|quay.io/argoproj/argocd@v2.12.8 and glibc/libc-bin@2.39-0ubuntu8.3
                @@ -4623,7 +2873,7 @@
                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › glibc/libc-bin@2.39-0ubuntu8.3 @@ -4632,7 +2882,7 @@
                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › glibc/libc6@2.39-0ubuntu8.3 @@ -4678,7 +2928,7 @@
                  • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 › /usr/local/bin/argocd
                  • Package Manager: golang @@ -4747,7 +2997,7 @@
                    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 › /usr/local/bin/argocd
                    • Package Manager: golang @@ -4805,7 +3055,7 @@
    -

    CVE-2025-0167

    +

    Improper Input Validation

    @@ -4816,7 +3066,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
    • Package Manager: ubuntu:24.04 @@ -4824,13 +3074,13 @@
    • Vulnerable module: - curl/libcurl3t64-gnutls + git/git-man
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5, git@1:2.43.0-1ubuntu7.2 and others + docker-image|quay.io/argoproj/argocd@v2.12.8, git@1:2.43.0-1ubuntu7.1 and others
    @@ -4842,11 +3092,31 @@
    @@ -4895,7 +3159,7 @@
    • - Manifest file: quay.io/argoproj/argocd:v2.13.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd › Dockerfile
    • Package Manager: ubuntu:24.04 @@ -4908,7 +3172,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 and coreutils@9.4-3ubuntu6 + docker-image|quay.io/argoproj/argocd@v2.12.8 and coreutils@9.4-3ubuntu6
    @@ -4921,7 +3185,7 @@
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.13.5 + docker-image|quay.io/argoproj/argocd@v2.12.8 › coreutils@9.4-3ubuntu6 diff --git a/docs/snyk/master/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html b/docs/snyk/v2.12.8/redis_7.0.15-alpine.html similarity index 51% rename from docs/snyk/master/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html rename to docs/snyk/v2.12.8/redis_7.0.15-alpine.html index 6a7b46ebce..c7a1a3757c 100644 --- a/docs/snyk/master/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html +++ b/docs/snyk/v2.12.8/redis_7.0.15-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,35 +456,213 @@

      Snyk test report

      -

      March 16th 2025, 12:21:11 am (UTC+00:00)

      +

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

      - Scanned the following path: + Scanned the following paths:
        -
      • public.ecr.aws/docker/library/haproxy:3.0.8-alpine/docker/library/haproxy (apk)
      • +
      • redis:7.0.15-alpine (apk)
      • +
      • redis:7.0.15-alpine/tianon/gosu//usr/local/bin/gosu (gomodules)
      -
      0 known vulnerabilities
      -
      0 vulnerable dependency paths
      -
      19 dependencies
      +
      1 known vulnerabilities
      +
      9 vulnerable dependency paths
      +
      18 dependencies
    -
    - - - - - - - -
    Project docker-image|public.ecr.aws/docker/library/haproxy
    Path public.ecr.aws/docker/library/haproxy:3.0.8-alpine/docker/library/haproxy
    Package Manager apk
    -
    +
    - 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.5/argocd-iac-install.html b/docs/snyk/v2.13.2/argocd-iac-install.html similarity index 99% rename from docs/snyk/v2.13.5/argocd-iac-install.html rename to docs/snyk/v2.13.2/argocd-iac-install.html index 0410544cbe..ab0d42998e 100644 --- a/docs/snyk/v2.13.5/argocd-iac-install.html +++ b/docs/snyk/v2.13.2/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    March 16th 2025, 12:28:32 am (UTC+00:00)

    +

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

    Scanned the following path: diff --git a/docs/snyk/v2.13.5/argocd-iac-namespace-install.html b/docs/snyk/v2.13.2/argocd-iac-namespace-install.html similarity index 99% rename from docs/snyk/v2.13.5/argocd-iac-namespace-install.html rename to docs/snyk/v2.13.2/argocd-iac-namespace-install.html index 4edaf57143..e9e1a24ff1 100644 --- a/docs/snyk/v2.13.5/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.13.2/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    March 16th 2025, 12:28:42 am (UTC+00:00)

    +

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

    Scanned the following path: diff --git a/docs/snyk/v2.13.5/argocd-test.html b/docs/snyk/v2.13.2/argocd-test.html similarity index 61% rename from docs/snyk/v2.13.5/argocd-test.html rename to docs/snyk/v2.13.2/argocd-test.html index ed75b43cb0..c25d755fd4 100644 --- a/docs/snyk/v2.13.5/argocd-test.html +++ b/docs/snyk/v2.13.2/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    March 16th 2025, 12:26:23 am (UTC+00:00)

    +

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

    Scanned the following paths: @@ -467,9 +467,9 @@
    -
    18 known vulnerabilities
    -
    71 vulnerable dependency paths
    -
    2141 dependencies
    +
    11 known vulnerabilities
    +
    53 vulnerable dependency paths
    +
    2131 dependencies
    @@ -477,579 +477,12 @@
    -
    -

    Prototype Pollution

    +
    +

    Incorrect Implementation of Authentication Algorithm

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

    Detailed paths

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

    Overview

    -

    redoc is an OpenAPI/Swagger-generated API Reference Documentation.

    -

    Affected versions of this package are vulnerable to Prototype Pollution via the mergeObjects() method in utils/helpers.ts due to improper user input sanitization.

    -

    PoC

    -
    (async () => {
    -          const lib = await import('redoc');
    -        
    -        var BAD_JSON = JSON.parse('{"__proto__":{"polluted":true}}');
    -        var victim = {}
    -        console.log("Before Attack: ", JSON.stringify(victim.__proto__));
    -        try {
    -          lib.mergeObjects ({}, BAD_JSON)
    -        } catch (e) { }
    -        console.log("After Attack: ", JSON.stringify(victim.__proto__));
    -        delete Object.prototype.polluted;
    -        })();
    -        
    -

    Details

    -

    Prototype Pollution is a vulnerability affecting JavaScript. Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects. JavaScript allows all Object attributes to be altered, including their magical attributes such as __proto__, constructor and prototype. An attacker manipulates these attributes to overwrite, or pollute, a JavaScript application object prototype of the base object by injecting other values. Properties on the Object.prototype are then inherited by all the JavaScript objects through the prototype chain. When that happens, this leads to either denial of service by triggering JavaScript exceptions, or it tampers with the application source code to force the code path that the attacker injects, thereby leading to remote code execution.

    -

    There are two main ways in which the pollution of prototypes occurs:

    -
      -
    • Unsafe Object recursive merge

      -
    • -
    • Property definition by path

      -
    • -
    -

    Unsafe Object recursive merge

    -

    The logic of a vulnerable recursive merge function follows the following high-level model:

    -
    merge (target, source)
    -        
    -          foreach property of source
    -        
    -            if property exists and is an object on both the target and the source
    -        
    -              merge(target[property], source[property])
    -        
    -            else
    -        
    -              target[property] = source[property]
    -        
    -
    - -

    When the source object contains a property named __proto__ defined with Object.defineProperty() , the condition that checks if the property exists and is an object on both the target and the source passes and the merge recurses with the target, being the prototype of Object and the source of Object as defined by the attacker. Properties are then copied on the Object prototype.

    -

    Clone operations are a special sub-class of unsafe recursive merges, which occur when a recursive merge is conducted on an empty object: merge({},source).

    -

    lodash and Hoek are examples of libraries susceptible to recursive merge attacks.

    -

    Property definition by path

    -

    There are a few JavaScript libraries that use an API to define property values on an object based on a given path. The function that is generally affected contains this signature: theFunction(object, path, value)

    -

    If the attacker can control the value of “path”, they can set this value to __proto__.myValue. myValue is then assigned to the prototype of the class of the object.

    -

    Types of attacks

    -

    There are a few methods by which Prototype Pollution can be manipulated:

    - - - - - - - - - - - - - - - - - - - - - - - -
    TypeOriginShort description
    Denial of service (DoS)ClientThis is the most likely attack.
    DoS occurs when Object holds generic functions that are implicitly called for various operations (for example, toString and valueOf).
    The attacker pollutes Object.prototype.someattr and alters its state to an unexpected value such as Int or Object. In this case, the code fails and is likely to cause a denial of service.
    For example: if an attacker pollutes Object.prototype.toString by defining it as an integer, if the codebase at any point was reliant on someobject.toString() it would fail.
    Remote Code ExecutionClientRemote code execution is generally only possible in cases where the codebase evaluates a specific attribute of an object, and then executes that evaluation.
    For example: eval(someobject.someattr). In this case, if the attacker pollutes Object.prototype.someattr they are likely to be able to leverage this in order to execute code.
    Property InjectionClientThe attacker pollutes properties that the codebase relies on for their informative value, including security properties such as cookies or tokens.
    For example: if a codebase checks privileges for someuser.isAdmin, then when the attacker pollutes Object.prototype.isAdmin and sets it to equal true, they can then achieve admin privileges.
    -

    Affected environments

    -

    The following environments are susceptible to a Prototype Pollution attack:

    -
      -
    • Application server

      -
    • -
    • Web server

      -
    • -
    • Web browser

      -
    • -
    -

    How to prevent

    -
      -
    1. Freeze the prototype— use Object.freeze (Object.prototype).

      -
    2. -
    3. Require schema validation of JSON input.

      -
    4. -
    5. Avoid using unsafe recursive merge functions.

      -
    6. -
    7. Consider using objects without prototypes (for example, Object.create(null)), breaking the prototype chain and preventing pollution.

      -
    8. -
    9. As a best practice use Map instead of Object.

      -
    10. -
    -

    For more information on this vulnerability type:

    -

    Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018

    -

    Remediation

    -

    Upgrade redoc to version 2.4.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/oauth2/jws -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, golang.org/x/oauth2/google@0.23.0 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - golang.org/x/oauth2/google@0.23.0 - › - golang.org/x/oauth2/jws@0.23.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - golang.org/x/oauth2/google@0.23.0 - › - golang.org/x/oauth2/jwt@0.23.0 - › - golang.org/x/oauth2/jws@0.23.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.23.0 - › - golang.org/x/oauth2/jws@0.23.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.23.0 - › - golang.org/x/oauth2/jws@0.23.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.23.0 - › - golang.org/x/oauth2/jws@0.23.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.23.0 - › - golang.org/x/oauth2/jwt@0.23.0 - › - golang.org/x/oauth2/jws@0.23.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.23.0 - › - golang.org/x/oauth2/jws@0.23.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.23.0 - › - golang.org/x/oauth2/jws@0.23.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.23.0 - › - golang.org/x/oauth2/jwt@0.23.0 - › - golang.org/x/oauth2/jws@0.23.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.23.0 - › - golang.org/x/oauth2/jwt@0.23.0 - › - golang.org/x/oauth2/jws@0.23.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.23.0 - › - golang.org/x/oauth2/jwt@0.23.0 - › - golang.org/x/oauth2/jws@0.23.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - › - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - › - google.golang.org/api/chat/v1@0.132.0 - › - google.golang.org/api/transport/http@0.132.0 - › - google.golang.org/api/option@0.132.0 - › - google.golang.org/api/internal@0.132.0 - › - golang.org/x/oauth2/google@0.23.0 - › - golang.org/x/oauth2/jwt@0.23.0 - › - golang.org/x/oauth2/jws@0.23.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to improper parsing of malformed tokens which can lead to memory consumption.

    -

    Remediation

    -

    Upgrade golang.org/x/oauth2/jws to version 0.27.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Server-side Request Forgery (SSRF)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http/httpproxy -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and golang.org/x/net/http/httpproxy@0.33.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - golang.org/x/net/http/httpproxy@0.33.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http/httpproxy is a package for HTTP proxy determination based on environment variables, as provided by net/http's ProxyFromEnvironment function

    -

    Affected versions of this package are vulnerable to Server-side Request Forgery (SSRF) in proxy.go, because hostname matching against proxy patterns may treat an IPv6 zone ID as a hostname component. An environment variable value like *.example.com could be matched to a request intended for [::1%25.example.com]:80.

    -

    Remediation

    -

    Upgrade golang.org/x/net/http/httpproxy to version 0.36.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity +
    + critical severity

    @@ -1069,7 +502,7 @@
  • Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 and golang.org/x/crypto/ssh@0.31.0 + github.com/argoproj/argo-cd/v2@0.0.0 and golang.org/x/crypto/ssh@0.27.0
  • @@ -1084,7 +517,7 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1095,7 +528,7 @@ › code.gitea.io/sdk/gitea@0.19.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1104,9 +537,9 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - golang.org/x/crypto/ssh/knownhosts@0.31.0 + golang.org/x/crypto/ssh/knownhosts@0.27.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1115,9 +548,9 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1130,7 +563,7 @@ › github.com/go-fed/httpsig@1.1.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1139,11 +572,11 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - github.com/skeema/knownhosts@1.3.0 + github.com/skeema/knownhosts@1.2.2 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1154,9 +587,9 @@ › code.gitea.io/sdk/gitea@0.19.0 › - golang.org/x/crypto/ssh/agent@0.31.0 + golang.org/x/crypto/ssh/agent@0.27.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1165,11 +598,11 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1178,13 +611,13 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › github.com/xanzy/ssh-agent@0.3.3 › - golang.org/x/crypto/ssh/agent@0.31.0 + golang.org/x/crypto/ssh/agent@0.27.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1193,13 +626,13 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - github.com/skeema/knownhosts@1.3.0 + github.com/skeema/knownhosts@1.2.2 › - golang.org/x/crypto/ssh/knownhosts@0.31.0 + golang.org/x/crypto/ssh/knownhosts@0.27.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1208,13 +641,13 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - github.com/skeema/knownhosts@1.3.0 + github.com/skeema/knownhosts@1.2.2 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1223,13 +656,13 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5@5.13.1 + github.com/go-git/go-git/v5@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1238,15 +671,15 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › github.com/xanzy/ssh-agent@0.3.3 › - golang.org/x/crypto/ssh/agent@0.31.0 + golang.org/x/crypto/ssh/agent@0.27.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1255,15 +688,15 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - github.com/skeema/knownhosts@1.3.0 + github.com/skeema/knownhosts@1.2.2 › - golang.org/x/crypto/ssh/knownhosts@0.31.0 + golang.org/x/crypto/ssh/knownhosts@0.27.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1272,15 +705,15 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5@5.13.1 + github.com/go-git/go-git/v5@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - github.com/skeema/knownhosts@1.3.0 + github.com/skeema/knownhosts@1.2.2 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1289,17 +722,17 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5@5.13.1 + github.com/go-git/go-git/v5@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › github.com/xanzy/ssh-agent@0.3.3 › - golang.org/x/crypto/ssh/agent@0.31.0 + golang.org/x/crypto/ssh/agent@0.27.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1308,17 +741,17 @@ Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 › - github.com/go-git/go-git/v5@5.13.1 + github.com/go-git/go-git/v5@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/client@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.13.1 + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 › - github.com/skeema/knownhosts@1.3.0 + github.com/skeema/knownhosts@1.2.2 › - golang.org/x/crypto/ssh/knownhosts@0.31.0 + golang.org/x/crypto/ssh/knownhosts@0.27.0 › - golang.org/x/crypto/ssh@0.31.0 + golang.org/x/crypto/ssh@0.27.0 @@ -1331,20 +764,24 @@

    Overview

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

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling in handshakeTransport in handshake.go. An internal queue gets populated with received packets during the key exchange process, while waiting for the client to send a SSH_MSG_KEXINIT. An attacker can cause the server to become unresponsive to new connections by delaying or withholding this message, or by causing the queue to consume all available memory.

    +

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

    +

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

    Remediation

    -

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

    +

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

    References


    @@ -1979,148 +1416,6 @@

    More about this vulnerability

    -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-jose/go-jose/v4 -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, github.com/coreos/go-oidc/v3/oidc@3.11.0 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/coreos/go-oidc/v3/oidc@3.11.0 - › - github.com/go-jose/go-jose/v4@4.0.2 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to the use of strings.Split to split JWT tokens. An attacker can cause memory exhaustion and service disruption by sending numerous malformed tokens with a large number of . characters.

    -

    Workaround

    -

    This vulnerability can be mitigated by pre-validating that payloads passed to Go JOSE do not contain an excessive number of . characters.

    -

    Remediation

    -

    Upgrade github.com/go-jose/go-jose/v4 to version 4.0.5 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-jose/go-jose/v3 -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/go-jose/go-jose/v3@3.0.3 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-jose/go-jose/v3@3.0.3 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to the use of strings.Split to split JWT tokens. An attacker can cause memory exhaustion and service disruption by sending numerous malformed tokens with a large number of . characters.

    -

    Workaround

    -

    This vulnerability can be mitigated by pre-validating that payloads passed to Go JOSE do not contain an excessive number of . characters.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - -

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

    @@ -2357,81 +1652,6 @@

    More about this vulnerability

    -
    -
    -

    Arbitrary Code Injection

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd › ui/yarn.lock -
    • -
    • - Package Manager: npm -
    • -
    • - Vulnerable module: - - prismjs -
    • - -
    • 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 - › - prismjs@1.27.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    prismjs is a lightweight, robust, elegant syntax highlighting library.

    -

    Affected versions of this package are vulnerable to Arbitrary Code Injection via the document.currentScript lookup process. An attacker can manipulate the web page content and execute unintended actions by injecting HTML elements that overshadow legitimate DOM elements.

    -

    Note:

    -

    This is only exploitable if the application accepts untrusted input containing HTML but not direct JavaScript.

    -

    Remediation

    -

    Upgrade prismjs to version 1.30.0 or higher.

    -

    References

    - - -
    - - -

    Insufficient Documentation of Error Handling Techniques

    @@ -2682,151 +1902,6 @@
    -
    -

    Cross-site Scripting (XSS)

    -
    - -
    - low 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.5.6 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Cross-site Scripting (XSS) due to incorrect handling of template literals in regular expressions. An attacker can manipulate the output of the script by injecting malicious payloads that bypass the dompurify sanitization.

    -

    PoC

    -
    DOMPurify.sanitize(
    -          `<math><foo-test><mi><li><table><foo-test><li></li></foo-test><a>
    -              <style>
    -                <! \${
    -              </style>
    -              }
    -              <foo-b id="><img src onerror='alert(1)'>">hmm...</foo-b>
    -            </a></table></li></mi></foo-test></math>
    -          `,
    -          {
    -            SAFE_FOR_TEMPLATES: true,
    -            CUSTOM_ELEMENT_HANDLING: {
    -              tagNameCheck: /^foo-/,
    -            },
    -          }
    -        );
    -        
    -

    Details

    -

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

    -

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

    -

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

    -

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

    -

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

    -

    Types of attacks

    -

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

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

    Affected environments

    -

    The following environments are susceptible to an XSS attack:

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

    How to prevent

    -

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

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

    Remediation

    -

    Upgrade dompurify to version 3.2.4 or higher.

    -

    References

    - - -
    - - - -
    diff --git a/docs/snyk/v2.13.5/ghcr.io_dexidp_dex_v2.41.1.html b/docs/snyk/v2.13.2/ghcr.io_dexidp_dex_v2.41.1.html similarity index 64% rename from docs/snyk/v2.13.5/ghcr.io_dexidp_dex_v2.41.1.html rename to docs/snyk/v2.13.2/ghcr.io_dexidp_dex_v2.41.1.html index 50a3936423..0c92c0b620 100644 --- a/docs/snyk/v2.13.5/ghcr.io_dexidp_dex_v2.41.1.html +++ b/docs/snyk/v2.13.2/ghcr.io_dexidp_dex_v2.41.1.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    March 16th 2025, 12:26:30 am (UTC+00:00)

    +

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

    Scanned the following paths: @@ -469,8 +469,8 @@
    -
    31 known vulnerabilities
    -
    76 vulnerable dependency paths
    +
    23 known vulnerabilities
    +
    44 vulnerable dependency paths
    969 dependencies
    @@ -552,319 +552,6 @@

    More about this vulnerability

    -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/oauth2/jws -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v4@* and golang.org/x/oauth2/jws@v0.21.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v4@* - › - golang.org/x/oauth2/jws@v0.21.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - › - golang.org/x/oauth2/jws@v0.21.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to improper parsing of malformed tokens which can lead to memory consumption.

    -

    Remediation

    -

    Upgrade golang.org/x/oauth2/jws to version 0.27.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Server-side Request Forgery (SSRF)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http/httpproxy -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v4@* and golang.org/x/net/http/httpproxy@v0.26.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v4@* - › - golang.org/x/net/http/httpproxy@v0.26.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - › - golang.org/x/net/http/httpproxy@v0.27.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http/httpproxy is a package for HTTP proxy determination based on environment variables, as provided by net/http's ProxyFromEnvironment function

    -

    Affected versions of this package are vulnerable to Server-side Request Forgery (SSRF) in proxy.go, because hostname matching against proxy patterns may treat an IPv6 zone ID as a hostname component. An environment variable value like *.example.com could be matched to a request intended for [::1%25.example.com]:80.

    -

    Remediation

    -

    Upgrade golang.org/x/net/http/httpproxy to version 0.36.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/dexidp/dex › /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/html -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and golang.org/x/net/html@v0.27.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - › - golang.org/x/net/html@v0.27.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) through the functions parseDoctype, htmlIntegrationPoint, inBodyIM and inTableIM due to inefficient usage of the method strings.ToLower combining with the == operator to convert strings to lowercase and then comparing them.

    -

    An attacker can cause the application to slow down significantly by crafting inputs that are processed non-linearly.

    -

    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 golang.org/x/net/html to version 0.33.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

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

    Detailed paths

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

    Overview

    -

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

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling in handshakeTransport in handshake.go. An internal queue gets populated with received packets during the key exchange process, while waiting for the client to send a SSH_MSG_KEXINIT. An attacker can cause the server to become unresponsive to new connections by delaying or withholding this message, or by causing the queue to consume all available memory.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - -

    Insertion of Sensitive Information into Log File

    @@ -2154,85 +1841,6 @@

    More about this vulnerability

    -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 › /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-jose/go-jose/v4 -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v4@* and github.com/go-jose/go-jose/v4@v4.0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v4@* - › - github.com/go-jose/go-jose/v4@v4.0.2 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - › - github.com/go-jose/go-jose/v4@v4.0.4 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to the use of strings.Split to split JWT tokens. An attacker can cause memory exhaustion and service disruption by sending numerous malformed tokens with a large number of . characters.

    -

    Workaround

    -

    This vulnerability can be mitigated by pre-validating that payloads passed to Go JOSE do not contain an excessive number of . characters.

    -

    Remediation

    -

    Upgrade github.com/go-jose/go-jose/v4 to version 4.0.5 or higher.

    -

    References

    - - -
    - - -

    CVE-2024-6119

    @@ -2531,7 +2139,7 @@ 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-r3 or higher.

    +

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

    References

    -
    -

    CVE-2024-13176

    -
    - -
    - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

    -

    Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

    -

    There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-12797

    -
    - -
    - 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: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a - server may fail to notice that the server was not authenticated, because - handshakes don't abort as expected when the SSL_VERIFY_PEER verification mode - is set.

    -

    Impact summary: TLS and DTLS connections using raw public keys may be - vulnerable to man-in-middle attacks when server authentication failure is not - detected by clients.

    -

    RPKs are disabled by default in both TLS clients and TLS servers. The issue - only arises when TLS clients explicitly enable RPK use by the server, and the - server, likewise, enables sending of an RPK instead of an X.509 certificate - chain. The affected clients are those that then rely on the handshake to - fail when the server's RPK fails to match one of the expected public keys, - by setting the verification mode to SSL_VERIFY_PEER.

    -

    Clients that enable server-side raw public keys can still find out that raw - public key verification failed by calling SSL_get_verify_result(), and those - that do, and take appropriate action, are not affected. This issue was - introduced in the initial implementation of RPK support in OpenSSL 3.2.

    -

    The FIPS modules in 3.4, 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.3-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2025-26519

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.20 -
    • -
    • - Vulnerable module: - - musl/musl -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.41.1 and musl/musl@1.2.5-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - apk-tools/apk-tools@2.14.4-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - busybox/ssl_client@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - musl/musl-utils@1.2.5-r0 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - 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 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - 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 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - apk-tools/apk-tools@2.14.4-r0 - › - zlib/zlib@1.3.1-r1 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - musl/musl-utils@1.2.5-r0 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - alpine-baselayout/alpine-baselayout@3.6.5-r0 - › - busybox/busybox-binsh@1.36.1-r29 - › - busybox/busybox@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.41.1 - › - musl/musl-utils@1.2.5-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

    -

    Remediation

    -

    Upgrade Alpine:3.20 musl to version 1.2.5-r1 or higher.

    -

    References

    - - -
    - - - -
    diff --git a/docs/snyk/v2.12.10/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html b/docs/snyk/v2.13.2/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html similarity index 67% rename from docs/snyk/v2.12.10/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html rename to docs/snyk/v2.13.2/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html index 3508732d30..b539d1cc9f 100644 --- a/docs/snyk/v2.12.10/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html +++ b/docs/snyk/v2.13.2/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    March 16th 2025, 12:29:12 am (UTC+00:00)

    +

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

    Scanned the following path: @@ -466,8 +466,8 @@
    -
    9 known vulnerabilities
    -
    86 vulnerable dependency paths
    +
    6 known vulnerabilities
    +
    52 vulnerable dependency paths
    18 dependencies
    @@ -1508,7 +1508,7 @@ 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-r3 or higher.

    +

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

    References

    • https://github.com/openssl/openssl/commit/72ae83ad214d2eef262461365a1975707f862712
    • @@ -1531,611 +1531,6 @@ -
      -

      CVE-2024-13176

      -
      - -
      - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

      -

      Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

      -

      There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

      -

      Remediation

      -

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

      -

      References

      - - -
      - - - -
      -
      -

      CVE-2024-12797

      -
      - -
      - 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: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a - server may fail to notice that the server was not authenticated, because - handshakes don't abort as expected when the SSL_VERIFY_PEER verification mode - is set.

      -

      Impact summary: TLS and DTLS connections using raw public keys may be - vulnerable to man-in-middle attacks when server authentication failure is not - detected by clients.

      -

      RPKs are disabled by default in both TLS clients and TLS servers. The issue - only arises when TLS clients explicitly enable RPK use by the server, and the - server, likewise, enables sending of an RPK instead of an X.509 certificate - chain. The affected clients are those that then rely on the handshake to - fail when the server's RPK fails to match one of the expected public keys, - by setting the verification mode to SSL_VERIFY_PEER.

      -

      Clients that enable server-side raw public keys can still find out that raw - public key verification failed by calling SSL_get_verify_result(), and those - that do, and take appropriate action, are not affected. This issue was - introduced in the initial implementation of RPK support in OpenSSL 3.2.

      -

      The FIPS modules in 3.4, 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.3-r0 or higher.

      -

      References

      - - -
      - - - -
      -
      -

      CVE-2025-26519

      -
      - -
      - low severity -
      - -
      - -
        -
      • - Package Manager: alpine:3.20 -
      • -
      • - Vulnerable module: - - musl/musl -
      • - -
      • Introduced through: - - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and musl/musl@1.2.5-r0 - -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - busybox/ssl_client@1.36.1-r28 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - ca-certificates/ca-certificates@20240226-r0 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - musl/musl-utils@1.2.5-r0 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - lua5.3/lua5.3-libs@5.3.6-r6 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - openssl/libcrypto3@3.3.0-r2 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - openssl/libssl3@3.3.0-r2 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - .haproxy-rundeps@20240524.005458 - › - pcre2/pcre2@10.43-r0 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - zlib/zlib@1.3.1-r1 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - musl/musl-utils@1.2.5-r0 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - 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 - › - musl/musl@1.2.5-r0 - - - -
      • -
      • - Introduced through: - docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine - › - musl/musl-utils@1.2.5-r0 - - - -
      • -
      - -
      - -
      - -

      NVD Description

      -

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

      -

      musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

      -

      Remediation

      -

      Upgrade Alpine:3.20 musl to version 1.2.5-r1 or higher.

      -

      References

      - - -
      - - - -
      diff --git a/docs/snyk/v2.13.2/public.ecr.aws_docker_library_redis_7.0.15-alpine.html b/docs/snyk/v2.13.2/public.ecr.aws_docker_library_redis_7.0.15-alpine.html new file mode 100644 index 0000000000..9ad65012ff --- /dev/null +++ b/docs/snyk/v2.13.2/public.ecr.aws_docker_library_redis_7.0.15-alpine.html @@ -0,0 +1,670 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
      +
      +
      +
      + + + Snyk - Open Source Security + + + + + + + +
      +

      Snyk test report

      + +

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

      +
      +
      + Scanned the following paths: +
        +
      • public.ecr.aws/docker/library/redis:7.0.15-alpine/docker/library/redis (apk)
      • +
      • public.ecr.aws/docker/library/redis:7.0.15-alpine/tianon/gosu//usr/local/bin/gosu (gomodules)
      • +
      +
      + +
      +
      1 known vulnerabilities
      +
      9 vulnerable dependency paths
      +
      18 dependencies
      +
      +
      +
      +
      + +
      +
      +
      +

      CVE-2024-9143

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

      Detailed paths

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

      NVD Description

      +

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

      +

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

      +

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

      +

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

      +

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

      +

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

      +

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

      +

      Remediation

      +

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

      +

      References

      + + +
      + + + +
      +
      +
      +
      + + + diff --git a/docs/snyk/v2.14.5/quay.io_argoproj_argocd_v2.14.5.html b/docs/snyk/v2.13.2/quay.io_argoproj_argocd_v2.13.2.html similarity index 76% rename from docs/snyk/v2.14.5/quay.io_argoproj_argocd_v2.14.5.html rename to docs/snyk/v2.13.2/quay.io_argoproj_argocd_v2.13.2.html index 608c0c2400..a5b6935254 100644 --- a/docs/snyk/v2.14.5/quay.io_argoproj_argocd_v2.14.5.html +++ b/docs/snyk/v2.13.2/quay.io_argoproj_argocd_v2.13.2.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,23 +456,23 @@

      Snyk test report

      -

      March 16th 2025, 12:24:21 am (UTC+00:00)

      +

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

      Scanned the following paths:
        -
      • quay.io/argoproj/argocd:v2.14.5/argoproj/argocd/Dockerfile (deb)
      • -
      • quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
      • -
      • quay.io/argoproj/argocd:v2.14.5//usr/local/bin/kustomize (gomodules)
      • -
      • quay.io/argoproj/argocd:v2.14.5/helm/v3//usr/local/bin/helm (gomodules)
      • -
      • quay.io/argoproj/argocd:v2.14.5/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
      • +
      • quay.io/argoproj/argocd:v2.13.2/argoproj/argocd/Dockerfile (deb)
      • +
      • quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
      • +
      • quay.io/argoproj/argocd:v2.13.2//usr/local/bin/kustomize (gomodules)
      • +
      • quay.io/argoproj/argocd:v2.13.2/helm/v3//usr/local/bin/helm (gomodules)
      • +
      • quay.io/argoproj/argocd:v2.13.2/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
      -
      28 known vulnerabilities
      -
      84 vulnerable dependency paths
      -
      2381 dependencies
      +
      23 known vulnerabilities
      +
      103 vulnerable dependency paths
      +
      2354 dependencies
      @@ -480,244 +480,19 @@
      -
      -

      Allocation of Resources Without Limits or Throttling

      +
      +

      Incorrect Implementation of Authentication Algorithm

      -
      - high severity +
      + critical severity

      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
      • -
      • - Package Manager: golang -
      • -
      • - Vulnerable module: - - golang.org/x/oauth2/jws -
      • - -
      • Introduced through: - - github.com/argoproj/argo-cd/v2@* and golang.org/x/oauth2/jws@v0.24.0 - -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - golang.org/x/oauth2/jws@v0.24.0 - - - -
      • -
      - -
      - -
      - -

      Overview

      -

      Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to improper parsing of malformed tokens which can lead to memory consumption.

      -

      Remediation

      -

      Upgrade golang.org/x/oauth2/jws to version 0.27.0 or higher.

      -

      References

      - - -
      - - - -
      -
      -

      Server-side Request Forgery (SSRF)

      -
      - -
      - high severity -
      - -
      - -
        -
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
      • -
      • - Package Manager: golang -
      • -
      • - Vulnerable module: - - golang.org/x/net/http/httpproxy -
      • - -
      • Introduced through: - - github.com/argoproj/argo-cd/v2@* and golang.org/x/net/http/httpproxy@v0.34.0 - -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - golang.org/x/net/http/httpproxy@v0.34.0 - - - -
      • -
      - -
      - -
      - -

      Overview

      -

      golang.org/x/net/http/httpproxy is a package for HTTP proxy determination based on environment variables, as provided by net/http's ProxyFromEnvironment function

      -

      Affected versions of this package are vulnerable to Server-side Request Forgery (SSRF) in proxy.go, because hostname matching against proxy patterns may treat an IPv6 zone ID as a hostname component. An environment variable value like *.example.com could be matched to a request intended for [::1%25.example.com]:80.

      -

      Remediation

      -

      Upgrade golang.org/x/net/http/httpproxy to version 0.36.0 or higher.

      -

      References

      - - -
      - - - -
      -
      -

      Denial of Service (DoS)

      -
      - -
      - high severity -
      - -
      - -
        -
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/helm/v3 › /usr/local/bin/helm -
      • -
      • - Package Manager: golang -
      • -
      • - Vulnerable module: - - golang.org/x/net/html -
      • - -
      • Introduced through: - - helm.sh/helm/v3@* and golang.org/x/net/html@v0.26.0 - -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - helm.sh/helm/v3@* - › - golang.org/x/net/html@v0.26.0 - - - -
      • -
      - -
      - -
      - -

      Overview

      -

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

      -

      Affected versions of this package are vulnerable to Denial of Service (DoS) through the functions parseDoctype, htmlIntegrationPoint, inBodyIM and inTableIM due to inefficient usage of the method strings.ToLower combining with the == operator to convert strings to lowercase and then comparing them.

      -

      An attacker can cause the application to slow down significantly by crafting inputs that are processed non-linearly.

      -

      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 golang.org/x/net/html to version 0.33.0 or higher.

      -

      References

      - - -
      - - - -
      -
      -

      Allocation of Resources Without Limits or Throttling

      -
      - -
      - high severity -
      - -
      - -
        -
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 › /usr/local/bin/argocd
      • Package Manager: golang @@ -730,7 +505,7 @@
      • Introduced through: - github.com/argoproj/argo-cd/v2@* and golang.org/x/crypto/ssh@v0.32.0 + github.com/argoproj/argo-cd/v2@* and golang.org/x/crypto/ssh@v0.27.0
      @@ -745,7 +520,7 @@ Introduced through: github.com/argoproj/argo-cd/v2@* › - golang.org/x/crypto/ssh@v0.32.0 + golang.org/x/crypto/ssh@v0.27.0 @@ -758,195 +533,24 @@

      Overview

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

      -

      Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling in handshakeTransport in handshake.go. An internal queue gets populated with received packets during the key exchange process, while waiting for the client to send a SSH_MSG_KEXINIT. An attacker can cause the server to become unresponsive to new connections by delaying or withholding this message, or by causing the queue to consume all available memory.

      +

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

      +

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

      Remediation

      -

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

      +

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

      References


      - -
      -
      -

      Allocation of Resources Without Limits or Throttling

      -
      - -
      - high severity -
      - -
      - -
        -
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
      • -
      • - Package Manager: golang -
      • -
      • - Vulnerable module: - - github.com/go-git/go-git/v5/plumbing -
      • - -
      • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/go-git/go-git/v5/plumbing@v5.12.0 - -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - github.com/go-git/go-git/v5/plumbing@v5.12.0 - - - -
      • -
      - -
      - -
      - -

      Overview

      -

      github.com/go-git/go-git/v5/plumbing is a highly extensible git implementation library written in pure Go.

      -

      Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling via specially crafted responses from a Git server, which triggers resource exhaustion in clients.

      -

      Workaround

      -

      In cases where a bump to the latest version of go-git is not possible, we recommend limiting its use to only trustworthy Git servers.

      -

      Remediation

      -

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

      -

      References

      - - -
      - - - -
      -
      -

      CVE-2024-56433

      -
      - -
      - medium severity -
      - -
      - -
        -
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argocd › Dockerfile -
      • -
      • - Package Manager: ubuntu:24.04 -
      • -
      • - Vulnerable module: - - shadow/passwd -
      • - -
      • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.14.5 and shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 - › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - - - -
      • -
      • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 - › - openssh/openssh-client@1:9.6p1-3ubuntu13.8 - › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - - - -
      • -
      • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 - › - apt@2.7.14build2 - › - adduser@3.137ubuntu1 - › - shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - - - -
      • -
      • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 - › - shadow/login@1:4.13+dfsg1-4ubuntu3.2 - - - -
      • -
      - -
      - -
      - -

      NVD Description

      -

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

      -

      shadow-utils (aka shadow) 4.4 through 4.17.0 establishes a default /etc/subuid behavior (e.g., uid 100000 through 165535 for the first user account) that can realistically conflict with the uids of users defined on locally administered networks, potentially leading to account takeover, e.g., by leveraging newuidmap for access to an NFS home directory (or same-host resources in the case of remote logins by these local network users). NOTE: it may also be argued that system administrators should not have assigned uids, within local networks, that are within the range that can occur in /etc/subuid.

      -

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 shadow.

      -

      References

      - - -
      - -
      @@ -962,7 +566,7 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd › Dockerfile
      • Package Manager: ubuntu:24.04 @@ -975,7 +579,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 and pam/libpam0g@1.5.3-5ubuntu5.1 + docker-image|quay.io/argoproj/argocd@v2.13.2 and pam/libpam0g@1.5.3-5ubuntu5.1
      @@ -988,7 +592,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › pam/libpam0g@1.5.3-5ubuntu5.1 @@ -997,7 +601,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › shadow/login@1:4.13+dfsg1-4ubuntu3.2 › @@ -1008,9 +612,9 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › - util-linux@2.39.3-9ubuntu6.2 + util-linux@2.39.3-9ubuntu6.1 › pam/libpam0g@1.5.3-5ubuntu5.1 @@ -1019,7 +623,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -1034,7 +638,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -1051,7 +655,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -1070,7 +674,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › pam/libpam-modules-bin@1.5.3-5ubuntu5.1 @@ -1079,7 +683,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -1096,7 +700,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › pam/libpam-modules@1.5.3-5ubuntu5.1 @@ -1105,7 +709,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › pam/libpam-runtime@1.5.3-5ubuntu5.1 › @@ -1116,7 +720,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › shadow/login@1:4.13+dfsg1-4ubuntu3.2 › @@ -1127,7 +731,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -1142,7 +746,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › pam/libpam-runtime@1.5.3-5ubuntu5.1 @@ -1151,7 +755,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › shadow/login@1:4.13+dfsg1-4ubuntu3.2 › @@ -1179,7 +783,6 @@
      • https://bugzilla.redhat.com/show_bug.cgi?id=2319212
      • https://access.redhat.com/errata/RHSA-2024:9941
      • https://access.redhat.com/errata/RHSA-2024:10379
      • -
      • https://access.redhat.com/errata/RHSA-2024:11250

      @@ -1201,7 +804,7 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd › Dockerfile
      • Package Manager: ubuntu:24.04 @@ -1214,7 +817,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 and pam/libpam0g@1.5.3-5ubuntu5.1 + docker-image|quay.io/argoproj/argocd@v2.13.2 and pam/libpam0g@1.5.3-5ubuntu5.1
      @@ -1227,7 +830,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › pam/libpam0g@1.5.3-5ubuntu5.1 @@ -1236,7 +839,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › shadow/login@1:4.13+dfsg1-4ubuntu3.2 › @@ -1247,9 +850,9 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › - util-linux@2.39.3-9ubuntu6.2 + util-linux@2.39.3-9ubuntu6.1 › pam/libpam0g@1.5.3-5ubuntu5.1 @@ -1258,7 +861,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -1273,7 +876,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -1290,7 +893,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -1309,7 +912,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › pam/libpam-modules-bin@1.5.3-5ubuntu5.1 @@ -1318,7 +921,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -1335,7 +938,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › pam/libpam-modules@1.5.3-5ubuntu5.1 @@ -1344,7 +947,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › pam/libpam-runtime@1.5.3-5ubuntu5.1 › @@ -1355,7 +958,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › shadow/login@1:4.13+dfsg1-4ubuntu3.2 › @@ -1366,7 +969,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -1381,7 +984,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › pam/libpam-runtime@1.5.3-5ubuntu5.1 @@ -1390,7 +993,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › shadow/login@1:4.13+dfsg1-4ubuntu3.2 › @@ -1416,12 +1019,6 @@
      • http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-10963
      • https://access.redhat.com/security/cve/CVE-2024-10963
      • https://bugzilla.redhat.com/show_bug.cgi?id=2324291
      • -
      • https://access.redhat.com/errata/RHSA-2024:10232
      • -
      • https://access.redhat.com/errata/RHSA-2024:10244
      • -
      • https://access.redhat.com/errata/RHSA-2024:10379
      • -
      • https://access.redhat.com/errata/RHSA-2024:10518
      • -
      • https://access.redhat.com/errata/RHSA-2024:10528
      • -
      • https://access.redhat.com/errata/RHSA-2024:10852

      @@ -1430,6 +1027,214 @@

      More about this vulnerability

      +
      +
      +

      CVE-2024-26462

      +
      + +
      + medium severity +
      + +
      + +
        +
      • + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd › Dockerfile +
      • +
      • + Package Manager: ubuntu:24.04 +
      • +
      • + Vulnerable module: + + krb5/libk5crypto3 +
      • + +
      • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.13.2, git@1:2.43.0-1ubuntu7.1 and others +
      • +
      + +
      + + +

      Detailed paths

      + +
        +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + libssh/libssh-4@0.10.6-2build2 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + krb5/krb5-locales@1.20.1-6ubuntu2.2 + + + +
      • +
      + +
      + +
      + +

      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

      @@ -1443,7 +1248,7 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 › /usr/local/bin/argocd
      • Package Manager: golang @@ -1503,7 +1308,7 @@
        • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 › /usr/local/bin/argocd
        • Package Manager: golang @@ -1563,7 +1368,7 @@
          • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 › /usr/local/bin/argocd
          • Package Manager: golang @@ -1623,7 +1428,7 @@
            • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 › /usr/local/bin/argocd
            • Package Manager: golang @@ -1683,7 +1488,7 @@
              • - Manifest file: quay.io/argoproj/argocd:v2.14.5/helm/v3 › /usr/local/bin/helm + Manifest file: quay.io/argoproj/argocd:v2.13.2/helm/v3 › /usr/local/bin/helm
              • Package Manager: golang @@ -1743,7 +1548,7 @@
                • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 › /usr/local/bin/argocd
                • Package Manager: golang @@ -1803,7 +1608,7 @@
                  • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 › /usr/local/bin/argocd
                  • Package Manager: golang @@ -1850,374 +1655,6 @@

                    More about this vulnerability

      -
      -
      -

      Allocation of Resources Without Limits or Throttling

      -
      - -
      - medium severity -
      - -
      - -
        -
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
      • -
      • - Package Manager: golang -
      • -
      • - Vulnerable module: - - github.com/go-jose/go-jose/v4 -
      • - -
      • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/go-jose/go-jose/v4@v4.0.2 - -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - github.com/go-jose/go-jose/v4@v4.0.2 - - - -
      • -
      - -
      - -
      - -

      Overview

      -

      Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to the use of strings.Split to split JWT tokens. An attacker can cause memory exhaustion and service disruption by sending numerous malformed tokens with a large number of . characters.

      -

      Workaround

      -

      This vulnerability can be mitigated by pre-validating that payloads passed to Go JOSE do not contain an excessive number of . characters.

      -

      Remediation

      -

      Upgrade github.com/go-jose/go-jose/v4 to version 4.0.5 or higher.

      -

      References

      - - -
      - - - -
      -
      -

      Arbitrary Argument Injection

      -
      - -
      - medium severity -
      - -
      - -
        -
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
      • -
      • - Package Manager: golang -
      • -
      • - Vulnerable module: - - github.com/go-git/go-git/v5/plumbing/transport -
      • - -
      • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/go-git/go-git/v5/plumbing/transport@v5.12.0 - -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - github.com/go-git/go-git/v5/plumbing/transport@v5.12.0 - - - -
      • -
      - -
      - -
      - -

      Overview

      -

      Affected versions of this package are vulnerable to Arbitrary Argument Injection via a malicious URL value, which allows an attacker to set flags on the git-upload-pack command, if the file: protocol is in use.

      -

      Remediation

      -

      Upgrade github.com/go-git/go-git/v5/plumbing/transport to version 5.13.0 or higher.

      -

      References

      - - -
      - - - -
      -
      -

      Generation of Error Message Containing Sensitive Information

      -
      - -
      - medium severity -
      - -
      - -
        -
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
      • -
      • - Package Manager: golang -
      • -
      • - Vulnerable module: - - github.com/argoproj/gitops-engine/pkg/utils/kube -
      • - -
      • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/argoproj/gitops-engine/pkg/utils/kube@v0.7.1-0.20250304190342-43fce7ce19f1 - -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - github.com/argoproj/gitops-engine/pkg/utils/kube@v0.7.1-0.20250304190342-43fce7ce19f1 - - - -
      • -
      - -
      - -
      - -

      Overview

      -

      Affected versions of this package are vulnerable to Generation of Error Message Containing Sensitive Information when syncing invalid Kubernetes Secret resources. An attacker with write access to the repository can expose secret values by committing an invalid Secret to repository and triggering a Sync, which then become visible to any user with read access to Argo CD.

      -

      Remediation

      -

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

      -

      References

      - - -
      - - - -
      -
      -

      Generation of Error Message Containing Sensitive Information

      -
      - -
      - medium severity -
      - -
      - -
        -
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argo-cd/v2 › /usr/local/bin/argocd -
      • -
      • - Package Manager: golang -
      • -
      • - Vulnerable module: - - github.com/argoproj/gitops-engine/pkg/diff -
      • - -
      • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/argoproj/gitops-engine/pkg/diff@v0.7.1-0.20250304190342-43fce7ce19f1 - -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - github.com/argoproj/argo-cd/v2@* - › - github.com/argoproj/gitops-engine/pkg/diff@v0.7.1-0.20250304190342-43fce7ce19f1 - - - -
      • -
      - -
      - -
      - -

      Overview

      -

      Affected versions of this package are vulnerable to Generation of Error Message Containing Sensitive Information when syncing invalid Kubernetes Secret resources. An attacker with write access to the repository can expose secret values by committing an invalid Secret to repository and triggering a Sync, which then become visible to any user with read access to Argo CD.

      -

      Remediation

      -

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

      -

      References

      - - -
      - - - -
      -
      -

      Improper Encoding or Escaping of Output

      -
      - -
      - medium severity -
      - -
      - -
        -
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argocd › Dockerfile -
      • -
      • - Package Manager: ubuntu:24.04 -
      • -
      • - Vulnerable module: - - git/git-man -
      • - -
      • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.14.5, git@1:2.43.0-1ubuntu7.2 and others -
      • -
      - -
      - - -

      Detailed paths

      - -
        -
      • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 - › - git@1:2.43.0-1ubuntu7.2 - › - git/git-man@1:2.43.0-1ubuntu7.2 - - - -
      • -
      • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 - › - git@1:2.43.0-1ubuntu7.2 - - - -
      • -
      • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 - › - git-lfs@3.4.1-1ubuntu0.2 - › - git@1:2.43.0-1ubuntu7.2 - - - -
      • -
      - -
      - -
      - -

      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 is a source code management tool. When cloning from a server (or fetching, or pushing), informational or error messages are transported from the remote Git process to the client via the so-called "sideband channel". These messages will be prefixed with "remote:" and printed directly to the standard error output. Typically, this standard error output is connected to a terminal that understands ANSI escape sequences, which Git did not protect against. Most modern terminals support control sequences that can be used by a malicious actor to hide and misrepresent information, or to mislead the user into executing untrusted scripts. As requested on the git-security mailing list, the patches are under discussion on the public mailing list. Users are advised to update as soon as possible. Users unable to upgrade should avoid recursive clones unless they are from trusted sources.

      -

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 git.

      -

      References

      - - -
      - - -

      Release of Invalid Pointer or Reference

      @@ -2231,7 +1668,7 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd › Dockerfile
      • Package Manager: ubuntu:24.04 @@ -2244,7 +1681,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 and patch@2.7.6-7build3 + docker-image|quay.io/argoproj/argocd@v2.13.2 and patch@2.7.6-7build3
      @@ -2257,7 +1694,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › patch@2.7.6-7build3 @@ -2301,7 +1738,7 @@
        • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd › Dockerfile
        • Package Manager: ubuntu:24.04 @@ -2314,7 +1751,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 and patch@2.7.6-7build3 + docker-image|quay.io/argoproj/argocd@v2.13.2 and patch@2.7.6-7build3
        @@ -2327,7 +1764,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › patch@2.7.6-7build3 @@ -2376,7 +1813,7 @@
          • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd › Dockerfile
          • Package Manager: ubuntu:24.04 @@ -2389,7 +1826,7 @@
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 and openssl/libssl3t64@3.0.13-0ubuntu3.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 and openssl/libssl3t64@3.0.13-0ubuntu3.4
          @@ -2402,135 +1839,135 @@
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › coreutils@9.4-3ubuntu6 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › libfido2/libfido2-1@1.14.0-1build3 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › - openssh/openssh-client@1:9.6p1-3ubuntu13.8 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › ca-certificates@20240203 › - openssl@3.0.13-0ubuntu3.5 + openssl@3.0.13-0ubuntu3.4 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › libssh/libssh-4@0.10.6-2build2 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.5 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 › - krb5/libkrb5-3@1.20.1-6ubuntu2.5 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › - git@1:2.43.0-1ubuntu7.2 + git@1:2.43.0-1ubuntu7.1 › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 › - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.2 + openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 › cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 › - openssl/libssl3t64@3.0.13-0ubuntu3.5 + openssl/libssl3t64@3.0.13-0ubuntu3.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › - openssl@3.0.13-0ubuntu3.5 + openssl@3.0.13-0ubuntu3.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › ca-certificates@20240203 › - openssl@3.0.13-0ubuntu3.5 + openssl@3.0.13-0ubuntu3.4 @@ -2574,7 +2011,7 @@
            • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd › Dockerfile
            • Package Manager: ubuntu:24.04 @@ -2587,7 +2024,7 @@
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 and libgcrypt20@1.10.3-2build1 + docker-image|quay.io/argoproj/argocd@v2.13.2 and libgcrypt20@1.10.3-2build1
            @@ -2600,7 +2037,7 @@
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › libgcrypt20@1.10.3-2build1 @@ -2609,7 +2046,7 @@
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › gnupg2/dirmngr@2.4.4-2ubuntu17 › @@ -2620,7 +2057,7 @@
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › gnupg2/gpg@2.4.4-2ubuntu17 › @@ -2631,7 +2068,7 @@
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › gnupg2/gpg-agent@2.4.4-2ubuntu17 › @@ -2642,7 +2079,7 @@
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -2655,7 +2092,7 @@
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -2668,7 +2105,7 @@
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › gnupg2/gpg@2.4.4-2ubuntu17 › @@ -2681,7 +2118,7 @@
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -2691,7 +2128,7 @@ › pam/libpam-modules@1.5.3-5ubuntu5.1 › - systemd/libsystemd0@255.4-1ubuntu8.5 + systemd/libsystemd0@255.4-1ubuntu8.4 › libgcrypt20@1.10.3-2build1 @@ -2725,6 +2162,422 @@

              More about this vulnerability

      +
      +
      +

      CVE-2024-26458

      +
      + +
      + low severity +
      + +
      + +
        +
      • + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd › Dockerfile +
      • +
      • + Package Manager: ubuntu:24.04 +
      • +
      • + Vulnerable module: + + krb5/libk5crypto3 +
      • + +
      • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.13.2, git@1:2.43.0-1ubuntu7.1 and others +
      • +
      + +
      + + +

      Detailed paths

      + +
        +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + libssh/libssh-4@0.10.6-2build2 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + krb5/krb5-locales@1.20.1-6ubuntu2.2 + + + +
      • +
      + +
      + +
      + +

      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.2/argoproj/argocd › Dockerfile +
      • +
      • + Package Manager: ubuntu:24.04 +
      • +
      • + Vulnerable module: + + krb5/libk5crypto3 +
      • + +
      • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.13.2, git@1:2.43.0-1ubuntu7.1 and others +
      • +
      + +
      + + +

      Detailed paths

      + +
        +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + › + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + › + krb5/libkrb5support0@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + › + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git@1:2.43.0-1ubuntu7.1 + › + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + › + libssh/libssh-4@0.10.6-2build2 + › + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + krb5/krb5-locales@1.20.1-6ubuntu2.2 + + + +
      • +
      + +
      + +
      + +

      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

      @@ -2738,7 +2591,7 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd › Dockerfile
      • Package Manager: ubuntu:24.04 @@ -2751,7 +2604,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 and gnupg2/gpgv@2.4.4-2ubuntu17 + docker-image|quay.io/argoproj/argocd@v2.13.2 and gnupg2/gpgv@2.4.4-2ubuntu17
      @@ -2764,7 +2617,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › gnupg2/gpgv@2.4.4-2ubuntu17 @@ -2773,7 +2626,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › apt@2.7.14build2 › @@ -2784,7 +2637,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › gnupg2/dirmngr@2.4.4-2ubuntu17 › @@ -2795,7 +2648,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › gnupg2/gpg-agent@2.4.4-2ubuntu17 › @@ -2806,7 +2659,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › gnupg2/gpg@2.4.4-2ubuntu17 › @@ -2817,7 +2670,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › gnupg2/dirmngr@2.4.4-2ubuntu17 @@ -2826,7 +2679,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › gnupg2/gpg@2.4.4-2ubuntu17 @@ -2835,7 +2688,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › gnupg2/gpg-agent@2.4.4-2ubuntu17 @@ -2884,7 +2737,7 @@
        • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd › Dockerfile
        • Package Manager: ubuntu:24.04 @@ -2897,7 +2750,7 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 and glibc/libc-bin@2.39-0ubuntu8.4 + docker-image|quay.io/argoproj/argocd@v2.13.2 and glibc/libc-bin@2.39-0ubuntu8.3
        @@ -2910,18 +2763,18 @@
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › - glibc/libc-bin@2.39-0ubuntu8.4 + glibc/libc-bin@2.39-0ubuntu8.3
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › - glibc/libc6@2.39-0ubuntu8.4 + glibc/libc6@2.39-0ubuntu8.3 @@ -2954,7 +2807,7 @@
      -

      CVE-2025-0167

      +

      Insufficient Documentation of Error Handling Techniques

      @@ -2965,21 +2818,21 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 › /usr/local/bin/argocd
      • - Package Manager: ubuntu:24.04 + Package Manager: golang
      • Vulnerable module: - curl/libcurl3t64-gnutls + github.com/golang-jwt/jwt/v4
      • Introduced through: + github.com/argoproj/argo-cd/v2@* and github.com/golang-jwt/jwt/v4@v4.5.0 - docker-image|quay.io/argoproj/argocd@v2.14.5, git@1:2.43.0-1ubuntu7.2 and others
      @@ -2991,11 +2844,9 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + github.com/argoproj/argo-cd/v2@* › - git@1:2.43.0-1ubuntu7.2 - › - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.6 + github.com/golang-jwt/jwt/v4@v4.5.0 @@ -3006,29 +2857,90 @@
        -

        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 asked to use a .netrc file for credentials and to follow HTTP - redirects, curl could leak the password used for the first host to the - followed-to host under certain circumstances.

        -

        This flaw only manifests itself if the netrc file has a default entry that - omits both login and password. A rare circumstance.

        +

        Overview

        +

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

        +

        Workaround

        +

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

        Remediation

        -

        There is no fixed version for Ubuntu:24.04 curl.

        +

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

        References


        + +
      +
      +

      Insufficient Documentation of Error Handling Techniques

      +
      + +
      + low severity +
      + +
      + +
        +
      • + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 › /usr/local/bin/argocd +
      • +
      • + Package Manager: golang +
      • +
      • + Vulnerable module: + + github.com/golang-jwt/jwt +
      • + +
      • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/golang-jwt/jwt@v3.2.2+incompatible + +
      • +
      + +
      + + +

      Detailed paths

      + +
        +
      • + Introduced through: + github.com/argoproj/argo-cd/v2@* + › + github.com/golang-jwt/jwt@v3.2.2+incompatible + + + +
      • +
      + +
      + +
      + +

      Overview

      +

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

      +

      Workaround

      +

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

      +

      Remediation

      +

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

      +

      References

      + + +
      + +
      @@ -3044,7 +2956,100 @@
      • - Manifest file: quay.io/argoproj/argocd:v2.14.5/argoproj/argocd › Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd › Dockerfile +
      • +
      • + Package Manager: ubuntu:24.04 +
      • +
      • + Vulnerable module: + + git/git-man +
      • + +
      • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.13.2, git@1:2.43.0-1ubuntu7.1 and others +
      • +
      + +
      + + +

      Detailed paths

      + +
        +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + 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.2 + › + git@1:2.43.0-1ubuntu7.1 + + + +
      • +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + › + git-lfs@3.4.1-1ubuntu0.2 + › + 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.2/argoproj/argocd › Dockerfile
      • Package Manager: ubuntu:24.04 @@ -3057,7 +3062,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 and coreutils@9.4-3ubuntu6 + docker-image|quay.io/argoproj/argocd@v2.13.2 and coreutils@9.4-3ubuntu6
      @@ -3070,7 +3075,7 @@
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.14.5 + docker-image|quay.io/argoproj/argocd@v2.13.2 › coreutils@9.4-3ubuntu6 diff --git a/docs/snyk/v2.13.2/redis_7.0.15-alpine.html b/docs/snyk/v2.13.2/redis_7.0.15-alpine.html new file mode 100644 index 0000000000..1d00ef99b8 --- /dev/null +++ b/docs/snyk/v2.13.2/redis_7.0.15-alpine.html @@ -0,0 +1,670 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
        +
        +
        +
        + + + Snyk - Open Source Security + + + + + + + +
        +

        Snyk test report

        + +

        December 15th 2024, 12:24:54 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/snyk/v2.13.5/public.ecr.aws_docker_library_redis_7.0.15-alpine.html b/docs/snyk/v2.13.5/public.ecr.aws_docker_library_redis_7.0.15-alpine.html deleted file mode 100644 index 7aaf7ac94f..0000000000 --- a/docs/snyk/v2.13.5/public.ecr.aws_docker_library_redis_7.0.15-alpine.html +++ /dev/null @@ -1,1216 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
        -
        -
        -
        - - - Snyk - Open Source Security - - - - - - - -
        -

        Snyk test report

        - -

        March 16th 2025, 12:26:38 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)
        • -
        -
        - -
        -
        4 known vulnerabilities
        -
        38 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-r3 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        CVE-2024-13176

        -
        - -
        - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

        -

        Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

        -

        There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

        -

        Remediation

        -

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

        -

        References

        - - -
        - - - -
        -
        -

        CVE-2024-12797

        -
        - -
        - 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: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a - server may fail to notice that the server was not authenticated, because - handshakes don't abort as expected when the SSL_VERIFY_PEER verification mode - is set.

        -

        Impact summary: TLS and DTLS connections using raw public keys may be - vulnerable to man-in-middle attacks when server authentication failure is not - detected by clients.

        -

        RPKs are disabled by default in both TLS clients and TLS servers. The issue - only arises when TLS clients explicitly enable RPK use by the server, and the - server, likewise, enables sending of an RPK instead of an X.509 certificate - chain. The affected clients are those that then rely on the handshake to - fail when the server's RPK fails to match one of the expected public keys, - by setting the verification mode to SSL_VERIFY_PEER.

        -

        Clients that enable server-side raw public keys can still find out that raw - public key verification failed by calling SSL_get_verify_result(), and those - that do, and take appropriate action, are not affected. This issue was - introduced in the initial implementation of RPK support in OpenSSL 3.2.

        -

        The FIPS modules in 3.4, 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.3-r0 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        CVE-2025-26519

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

        Detailed paths

        - -
          -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - .redis-rundeps@20240906.232324 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - busybox/ssl_client@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - › - musl/musl@1.2.5-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 - › - musl/musl@1.2.5-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 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - zlib/zlib@1.3.1-r1 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - alpine-baselayout/alpine-baselayout@3.6.5-r0 - › - busybox/busybox-binsh@1.36.1-r29 - › - busybox/busybox@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - - - -
        • -
        - -
        - -
        - -

        NVD Description

        -

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

        -

        musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

        -

        Remediation

        -

        Upgrade Alpine:3.20 musl to version 1.2.5-r1 or higher.

        -

        References

        - - -
        - - - -
        -
        -
        -
        - - - diff --git a/docs/snyk/v2.13.5/redis_7.0.15-alpine.html b/docs/snyk/v2.13.5/redis_7.0.15-alpine.html deleted file mode 100644 index 2be1cf3303..0000000000 --- a/docs/snyk/v2.13.5/redis_7.0.15-alpine.html +++ /dev/null @@ -1,1216 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
        -
        -
        -
        - - - Snyk - Open Source Security - - - - - - - -
        -

        Snyk test report

        - -

        March 16th 2025, 12:27:03 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)
        • -
        -
        - -
        -
        4 known vulnerabilities
        -
        38 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-r3 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        CVE-2024-13176

        -
        - -
        - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

        -

        Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

        -

        There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

        -

        Remediation

        -

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

        -

        References

        - - -
        - - - -
        -
        -

        CVE-2024-12797

        -
        - -
        - 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: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a - server may fail to notice that the server was not authenticated, because - handshakes don't abort as expected when the SSL_VERIFY_PEER verification mode - is set.

        -

        Impact summary: TLS and DTLS connections using raw public keys may be - vulnerable to man-in-middle attacks when server authentication failure is not - detected by clients.

        -

        RPKs are disabled by default in both TLS clients and TLS servers. The issue - only arises when TLS clients explicitly enable RPK use by the server, and the - server, likewise, enables sending of an RPK instead of an X.509 certificate - chain. The affected clients are those that then rely on the handshake to - fail when the server's RPK fails to match one of the expected public keys, - by setting the verification mode to SSL_VERIFY_PEER.

        -

        Clients that enable server-side raw public keys can still find out that raw - public key verification failed by calling SSL_get_verify_result(), and those - that do, and take appropriate action, are not affected. This issue was - introduced in the initial implementation of RPK support in OpenSSL 3.2.

        -

        The FIPS modules in 3.4, 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.3-r0 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        CVE-2025-26519

        -
        - -
        - low severity -
        - -
        - -
          -
        • - Package Manager: alpine:3.20 -
        • -
        • - Vulnerable module: - - musl/musl -
        • - -
        • Introduced through: - - docker-image|redis@7.0.15-alpine and musl/musl@1.2.5-r0 - -
        • -
        - -
        - - -

        Detailed paths

        - -
          -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - .redis-rundeps@20240906.232324 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - busybox/ssl_client@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - .redis-rundeps@20240906.232324 - › - openssl/libcrypto3@3.3.2-r0 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - .redis-rundeps@20240906.232324 - › - openssl/libssl3@3.3.2-r0 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - zlib/zlib@1.3.1-r1 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - alpine-baselayout/alpine-baselayout@3.6.5-r0 - › - busybox/busybox-binsh@1.36.1-r29 - › - busybox/busybox@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - - - -
        • -
        - -
        - -
        - -

        NVD Description

        -

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

        -

        musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

        -

        Remediation

        -

        Upgrade Alpine:3.20 musl to version 1.2.5-r1 or higher.

        -

        References

        - - -
        - - - -
        -
        -
        -
        - - - diff --git a/docs/snyk/v2.14.5/argocd-test.html b/docs/snyk/v2.14.5/argocd-test.html deleted file mode 100644 index 9adcf0d8e4..0000000000 --- a/docs/snyk/v2.14.5/argocd-test.html +++ /dev/null @@ -1,4112 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
        -
        -
        -
        - - - Snyk - Open Source Security - - - - - - - -
        -

        Snyk test report

        - -

        March 16th 2025, 12:23:47 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)
        • -
        -
        - -
        -
        17 known vulnerabilities
        -
        148 vulnerable dependency paths
        -
        2159 dependencies
        -
        -
        -
        -
        - -
        -
        -
        -

        Prototype Pollution

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

        Detailed paths

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

        Overview

        -

        redoc is an OpenAPI/Swagger-generated API Reference Documentation.

        -

        Affected versions of this package are vulnerable to Prototype Pollution via the mergeObjects() method in utils/helpers.ts due to improper user input sanitization.

        -

        PoC

        -
        (async () => {
        -          const lib = await import('redoc');
        -        
        -        var BAD_JSON = JSON.parse('{"__proto__":{"polluted":true}}');
        -        var victim = {}
        -        console.log("Before Attack: ", JSON.stringify(victim.__proto__));
        -        try {
        -          lib.mergeObjects ({}, BAD_JSON)
        -        } catch (e) { }
        -        console.log("After Attack: ", JSON.stringify(victim.__proto__));
        -        delete Object.prototype.polluted;
        -        })();
        -        
        -

        Details

        -

        Prototype Pollution is a vulnerability affecting JavaScript. Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects. JavaScript allows all Object attributes to be altered, including their magical attributes such as __proto__, constructor and prototype. An attacker manipulates these attributes to overwrite, or pollute, a JavaScript application object prototype of the base object by injecting other values. Properties on the Object.prototype are then inherited by all the JavaScript objects through the prototype chain. When that happens, this leads to either denial of service by triggering JavaScript exceptions, or it tampers with the application source code to force the code path that the attacker injects, thereby leading to remote code execution.

        -

        There are two main ways in which the pollution of prototypes occurs:

        -
          -
        • Unsafe Object recursive merge

          -
        • -
        • Property definition by path

          -
        • -
        -

        Unsafe Object recursive merge

        -

        The logic of a vulnerable recursive merge function follows the following high-level model:

        -
        merge (target, source)
        -        
        -          foreach property of source
        -        
        -            if property exists and is an object on both the target and the source
        -        
        -              merge(target[property], source[property])
        -        
        -            else
        -        
        -              target[property] = source[property]
        -        
        -
        - -

        When the source object contains a property named __proto__ defined with Object.defineProperty() , the condition that checks if the property exists and is an object on both the target and the source passes and the merge recurses with the target, being the prototype of Object and the source of Object as defined by the attacker. Properties are then copied on the Object prototype.

        -

        Clone operations are a special sub-class of unsafe recursive merges, which occur when a recursive merge is conducted on an empty object: merge({},source).

        -

        lodash and Hoek are examples of libraries susceptible to recursive merge attacks.

        -

        Property definition by path

        -

        There are a few JavaScript libraries that use an API to define property values on an object based on a given path. The function that is generally affected contains this signature: theFunction(object, path, value)

        -

        If the attacker can control the value of “path”, they can set this value to __proto__.myValue. myValue is then assigned to the prototype of the class of the object.

        -

        Types of attacks

        -

        There are a few methods by which Prototype Pollution can be manipulated:

        - - - - - - - - - - - - - - - - - - - - - - - -
        TypeOriginShort description
        Denial of service (DoS)ClientThis is the most likely attack.
        DoS occurs when Object holds generic functions that are implicitly called for various operations (for example, toString and valueOf).
        The attacker pollutes Object.prototype.someattr and alters its state to an unexpected value such as Int or Object. In this case, the code fails and is likely to cause a denial of service.
        For example: if an attacker pollutes Object.prototype.toString by defining it as an integer, if the codebase at any point was reliant on someobject.toString() it would fail.
        Remote Code ExecutionClientRemote code execution is generally only possible in cases where the codebase evaluates a specific attribute of an object, and then executes that evaluation.
        For example: eval(someobject.someattr). In this case, if the attacker pollutes Object.prototype.someattr they are likely to be able to leverage this in order to execute code.
        Property InjectionClientThe attacker pollutes properties that the codebase relies on for their informative value, including security properties such as cookies or tokens.
        For example: if a codebase checks privileges for someuser.isAdmin, then when the attacker pollutes Object.prototype.isAdmin and sets it to equal true, they can then achieve admin privileges.
        -

        Affected environments

        -

        The following environments are susceptible to a Prototype Pollution attack:

        -
          -
        • Application server

          -
        • -
        • Web server

          -
        • -
        • Web browser

          -
        • -
        -

        How to prevent

        -
          -
        1. Freeze the prototype— use Object.freeze (Object.prototype).

          -
        2. -
        3. Require schema validation of JSON input.

          -
        4. -
        5. Avoid using unsafe recursive merge functions.

          -
        6. -
        7. Consider using objects without prototypes (for example, Object.create(null)), breaking the prototype chain and preventing pollution.

          -
        8. -
        9. As a best practice use Map instead of Object.

          -
        10. -
        -

        For more information on this vulnerability type:

        -

        Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018

        -

        Remediation

        -

        Upgrade redoc to version 2.4.0 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        Allocation of Resources Without Limits or Throttling

        -
        - -
        - high severity -
        - -
        - -
          -
        • - Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod -
        • -
        • - Package Manager: golang -
        • -
        • - Vulnerable module: - - golang.org/x/oauth2/jws -
        • - -
        • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, golang.org/x/oauth2/google@0.24.0 and others -
        • -
        - -
        - - -

        Detailed paths

        - -
          -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - golang.org/x/oauth2/google@0.24.0 - › - golang.org/x/oauth2/jws@0.24.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - golang.org/x/oauth2/google@0.24.0 - › - golang.org/x/oauth2/jwt@0.24.0 - › - golang.org/x/oauth2/jws@0.24.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd - › - google.golang.org/api/chat/v1@0.171.0 - › - google.golang.org/api/transport/http@0.171.0 - › - google.golang.org/api/option@0.171.0 - › - google.golang.org/api/internal@0.171.0 - › - golang.org/x/oauth2/google@0.24.0 - › - golang.org/x/oauth2/jws@0.24.0 - - - -
        • -
        • - 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 - › - google.golang.org/api/chat/v1@0.171.0 - › - google.golang.org/api/transport/http@0.171.0 - › - google.golang.org/api/option@0.171.0 - › - google.golang.org/api/internal@0.171.0 - › - golang.org/x/oauth2/google@0.24.0 - › - golang.org/x/oauth2/jws@0.24.0 - - - -
        • -
        • - 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 - › - google.golang.org/api/chat/v1@0.171.0 - › - google.golang.org/api/transport/http@0.171.0 - › - google.golang.org/api/option@0.171.0 - › - google.golang.org/api/internal@0.171.0 - › - golang.org/x/oauth2/google@0.24.0 - › - golang.org/x/oauth2/jws@0.24.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd - › - google.golang.org/api/chat/v1@0.171.0 - › - google.golang.org/api/transport/http@0.171.0 - › - google.golang.org/api/option@0.171.0 - › - google.golang.org/api/internal@0.171.0 - › - golang.org/x/oauth2/google@0.24.0 - › - golang.org/x/oauth2/jwt@0.24.0 - › - golang.org/x/oauth2/jws@0.24.0 - - - -
        • -
        • - 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 - › - google.golang.org/api/chat/v1@0.171.0 - › - google.golang.org/api/transport/http@0.171.0 - › - google.golang.org/api/option@0.171.0 - › - google.golang.org/api/internal@0.171.0 - › - golang.org/x/oauth2/google@0.24.0 - › - golang.org/x/oauth2/jws@0.24.0 - - - -
        • -
        • - 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 - › - google.golang.org/api/chat/v1@0.171.0 - › - google.golang.org/api/transport/http@0.171.0 - › - google.golang.org/api/option@0.171.0 - › - google.golang.org/api/internal@0.171.0 - › - golang.org/x/oauth2/google@0.24.0 - › - golang.org/x/oauth2/jws@0.24.0 - - - -
        • -
        • - 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 - › - google.golang.org/api/chat/v1@0.171.0 - › - google.golang.org/api/transport/http@0.171.0 - › - google.golang.org/api/option@0.171.0 - › - google.golang.org/api/internal@0.171.0 - › - golang.org/x/oauth2/google@0.24.0 - › - golang.org/x/oauth2/jwt@0.24.0 - › - golang.org/x/oauth2/jws@0.24.0 - - - -
        • -
        • - 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 - › - google.golang.org/api/chat/v1@0.171.0 - › - google.golang.org/api/transport/http@0.171.0 - › - google.golang.org/api/option@0.171.0 - › - google.golang.org/api/internal@0.171.0 - › - golang.org/x/oauth2/google@0.24.0 - › - golang.org/x/oauth2/jwt@0.24.0 - › - golang.org/x/oauth2/jws@0.24.0 - - - -
        • -
        • - 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 - › - google.golang.org/api/chat/v1@0.171.0 - › - google.golang.org/api/transport/http@0.171.0 - › - google.golang.org/api/option@0.171.0 - › - google.golang.org/api/internal@0.171.0 - › - golang.org/x/oauth2/google@0.24.0 - › - golang.org/x/oauth2/jwt@0.24.0 - › - golang.org/x/oauth2/jws@0.24.0 - - - -
        • -
        • - 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 - › - google.golang.org/api/chat/v1@0.171.0 - › - google.golang.org/api/transport/http@0.171.0 - › - google.golang.org/api/option@0.171.0 - › - google.golang.org/api/internal@0.171.0 - › - golang.org/x/oauth2/google@0.24.0 - › - golang.org/x/oauth2/jwt@0.24.0 - › - golang.org/x/oauth2/jws@0.24.0 - - - -
        • -
        - -
        - -
        - -

        Overview

        -

        Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to improper parsing of malformed tokens which can lead to memory consumption.

        -

        Remediation

        -

        Upgrade golang.org/x/oauth2/jws to version 0.27.0 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        Server-side Request Forgery (SSRF)

        -
        - -
        - high severity -
        - -
        - -
          -
        • - Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod -
        • -
        • - Package Manager: golang -
        • -
        • - Vulnerable module: - - golang.org/x/net/http/httpproxy -
        • - -
        • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and golang.org/x/net/http/httpproxy@0.34.0 - -
        • -
        - -
        - - -

        Detailed paths

        - -
          -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - golang.org/x/net/http/httpproxy@0.34.0 - - - -
        • -
        - -
        - -
        - -

        Overview

        -

        golang.org/x/net/http/httpproxy is a package for HTTP proxy determination based on environment variables, as provided by net/http's ProxyFromEnvironment function

        -

        Affected versions of this package are vulnerable to Server-side Request Forgery (SSRF) in proxy.go, because hostname matching against proxy patterns may treat an IPv6 zone ID as a hostname component. An environment variable value like *.example.com could be matched to a request intended for [::1%25.example.com]:80.

        -

        Remediation

        -

        Upgrade golang.org/x/net/http/httpproxy to version 0.36.0 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        Allocation of Resources Without Limits or Throttling

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

        Detailed paths

        - -
          -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - code.gitea.io/sdk/gitea@0.19.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - golang.org/x/crypto/ssh/knownhosts@0.32.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - code.gitea.io/sdk/gitea@0.19.0 - › - github.com/go-fed/httpsig@1.1.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/skeema/knownhosts@1.2.2 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - code.gitea.io/sdk/gitea@0.19.0 - › - golang.org/x/crypto/ssh/agent@0.32.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/xanzy/ssh-agent@0.3.3 - › - golang.org/x/crypto/ssh/agent@0.32.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/skeema/knownhosts@1.2.2 - › - golang.org/x/crypto/ssh/knownhosts@0.32.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/skeema/knownhosts@1.2.2 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/xanzy/ssh-agent@0.3.3 - › - golang.org/x/crypto/ssh/agent@0.32.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/skeema/knownhosts@1.2.2 - › - golang.org/x/crypto/ssh/knownhosts@0.32.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/skeema/knownhosts@1.2.2 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/xanzy/ssh-agent@0.3.3 - › - golang.org/x/crypto/ssh/agent@0.32.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/skeema/knownhosts@1.2.2 - › - golang.org/x/crypto/ssh/knownhosts@0.32.0 - › - golang.org/x/crypto/ssh@0.32.0 - - - -
        • -
        - -
        - -
        - -

        Overview

        -

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

        -

        Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling in handshakeTransport in handshake.go. An internal queue gets populated with received packets during the key exchange process, while waiting for the client to send a SSH_MSG_KEXINIT. An attacker can cause the server to become unresponsive to new connections by delaying or withholding this message, or by causing the queue to consume all available memory.

        -

        Remediation

        -

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

        -

        References

        - - -
        - - - -
        -
        -

        Allocation of Resources Without Limits or Throttling

        -
        - -
        - high severity -
        - -
        - -
          -
        • - Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod -
        • -
        • - Package Manager: golang -
        • -
        • - Vulnerable module: - - github.com/go-git/go-git/v5/plumbing -
        • - -
        • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/go-git/go-git/v5/plumbing@5.12.0 - -
        • -
        - -
        - - -

        Detailed paths

        - -
          -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/config@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem/dotgit@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/utils/merkletrie/filesystem@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/config@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/utils/merkletrie/index@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/index@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem/dotgit@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/packfile@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem/dotgit@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/objfile@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/config@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem/dotgit@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/packfile@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/cache@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/index@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/revlist@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem/dotgit@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/packfile@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/idxfile@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/utils/merkletrie/index@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/index@5.12.0 - › - github.com/go-git/go-git/v5/utils/binary@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/config@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/revlist@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/object@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/revlist@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem/dotgit@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/index@5.12.0 - › - github.com/go-git/go-git/v5/utils/binary@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/index@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem/dotgit@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/packfile@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/revlist@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/object@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/revlist@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/object@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/diff@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem/dotgit@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/objfile@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/config@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/config@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem/dotgit@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/packfile@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/cache@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/revlist@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/object@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/diff@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem@5.12.0 - › - github.com/go-git/go-git/v5/storage/filesystem/dotgit@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/packfile@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/idxfile@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/index@5.12.0 - › - github.com/go-git/go-git/v5/utils/binary@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/config@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/index@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/index@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/index@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/index@5.12.0 - › - github.com/go-git/go-git/v5/utils/binary@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/index@5.12.0 - › - github.com/go-git/go-git/v5/utils/binary@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/protocol/packp@5.12.0 - › - github.com/go-git/go-git/v5/storage/memory@5.12.0 - › - github.com/go-git/go-git/v5/storage@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/storer@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/format/index@5.12.0 - › - github.com/go-git/go-git/v5/utils/binary@5.12.0 - › - github.com/go-git/go-git/v5/plumbing@5.12.0 - - - -
        • -
        - -
        - -
        - -

        Overview

        -

        github.com/go-git/go-git/v5/plumbing is a highly extensible git implementation library written in pure Go.

        -

        Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling via specially crafted responses from a Git server, which triggers resource exhaustion in clients.

        -

        Workaround

        -

        In cases where a bump to the latest version of go-git is not possible, we recommend limiting its use to only trustworthy Git servers.

        -

        Remediation

        -

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

        -

        References

        - - -
        - - - -
        -
        -

        LGPL-3.0 license

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

        Detailed paths

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

        LGPL-3.0 license

        - -
        - - - -
        -
        -

        MPL-2.0 license

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

        Detailed paths

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

        MPL-2.0 license

        - -
        - - - -
        -
        -

        MPL-2.0 license

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

        Detailed paths

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

        MPL-2.0 license

        - -
        - - - -
        -
        -

        MPL-2.0 license

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

        Detailed paths

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

        MPL-2.0 license

        - -
        - - - -
        -
        -

        MPL-2.0 license

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

        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

        - -
        - - - -
        -
        -

        Allocation of Resources Without Limits or Throttling

        -
        - -
        - medium severity -
        - -
        - -
          -
        • - Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod -
        • -
        • - Package Manager: golang -
        • -
        • - Vulnerable module: - - github.com/go-jose/go-jose/v4 -
        • - -
        • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, github.com/coreos/go-oidc/v3/oidc@3.11.0 and others -
        • -
        - -
        - - -

        Detailed paths

        - -
          -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/coreos/go-oidc/v3/oidc@3.11.0 - › - github.com/go-jose/go-jose/v4@4.0.2 - - - -
        • -
        - -
        - -
        - -

        Overview

        -

        Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to the use of strings.Split to split JWT tokens. An attacker can cause memory exhaustion and service disruption by sending numerous malformed tokens with a large number of . characters.

        -

        Workaround

        -

        This vulnerability can be mitigated by pre-validating that payloads passed to Go JOSE do not contain an excessive number of . characters.

        -

        Remediation

        -

        Upgrade github.com/go-jose/go-jose/v4 to version 4.0.5 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        Allocation of Resources Without Limits or Throttling

        -
        - -
        - medium severity -
        - -
        - -
          -
        • - Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod -
        • -
        • - Package Manager: golang -
        • -
        • - Vulnerable module: - - github.com/go-jose/go-jose/v3 -
        • - -
        • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/go-jose/go-jose/v3@3.0.3 - -
        • -
        - -
        - - -

        Detailed paths

        - -
          -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-jose/go-jose/v3@3.0.3 - - - -
        • -
        - -
        - -
        - -

        Overview

        -

        Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling due to the use of strings.Split to split JWT tokens. An attacker can cause memory exhaustion and service disruption by sending numerous malformed tokens with a large number of . characters.

        -

        Workaround

        -

        This vulnerability can be mitigated by pre-validating that payloads passed to Go JOSE do not contain an excessive number of . characters.

        -

        Remediation

        -

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

        -

        References

        - - -
        - - - -
        -
        -

        Arbitrary Argument Injection

        -
        - -
        - medium severity -
        - -
        - -
          -
        • - Manifest file: /argo-cd/argoproj/argo-cd/v2 › go.mod -
        • -
        • - Package Manager: golang -
        • -
        • - Vulnerable module: - - github.com/go-git/go-git/v5/plumbing/transport -
        • - -
        • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - -
        • -
        - -
        - - -

        Detailed paths

        - -
          -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/git@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/git@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/http@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/file@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/server@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - › - github.com/go-git/go-git/v5@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport/internal/common@5.12.0 - › - github.com/go-git/go-git/v5/plumbing/transport@5.12.0 - - - -
        • -
        - -
        - -
        - -

        Overview

        -

        Affected versions of this package are vulnerable to Arbitrary Argument Injection via a malicious URL value, which allows an attacker to set flags on the git-upload-pack command, if the file: protocol is in use.

        -

        Remediation

        -

        Upgrade github.com/go-git/go-git/v5/plumbing/transport to version 5.13.0 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        Regular Expression Denial of Service (ReDoS)

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

        Detailed paths

        - -
          -
        • - Introduced through: - argo-cd-ui@1.0.0 - › - foundation-sites@6.8.1 - - - -
        • -
        • - Introduced through: - argo-cd-ui@1.0.0 - › - argo-ui@1.0.0 - › - foundation-sites@6.8.1 - - - -
        • -
        - -
        - -
        - -

        Overview

        -

        foundation-sites is a responsive front-end framework

        -

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

        -

        PoC

        -
        https://www.''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        -        
        -

        Details

        -

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

        -

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

        -

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

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

        This regular expression accomplishes the following:

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

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

        -

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

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

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

        -

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

        -

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

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

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

        -

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

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

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

        -

        Remediation

        -

        There is no fixed version for foundation-sites.

        -

        References

        - - -
        - - - -
        -
        -

        Arbitrary Code Injection

        -
        - -
        - low severity -
        - -
        - -
          -
        • - Manifest file: /argo-cd › ui/yarn.lock -
        • -
        • - Package Manager: npm -
        • -
        • - Vulnerable module: - - prismjs -
        • - -
        • 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 - › - prismjs@1.27.0 - - - -
        • -
        - -
        - -
        - -

        Overview

        -

        prismjs is a lightweight, robust, elegant syntax highlighting library.

        -

        Affected versions of this package are vulnerable to Arbitrary Code Injection via the document.currentScript lookup process. An attacker can manipulate the web page content and execute unintended actions by injecting HTML elements that overshadow legitimate DOM elements.

        -

        Note:

        -

        This is only exploitable if the application accepts untrusted input containing HTML but not direct JavaScript.

        -

        Remediation

        -

        Upgrade prismjs to version 1.30.0 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        Cross-site Scripting (XSS)

        -
        - -
        - low 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.5.6 - - - -
        • -
        - -
        - -
        - -

        Overview

        -

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

        -

        Affected versions of this package are vulnerable to Cross-site Scripting (XSS) due to incorrect handling of template literals in regular expressions. An attacker can manipulate the output of the script by injecting malicious payloads that bypass the dompurify sanitization.

        -

        PoC

        -
        DOMPurify.sanitize(
        -          `<math><foo-test><mi><li><table><foo-test><li></li></foo-test><a>
        -              <style>
        -                <! \${
        -              </style>
        -              }
        -              <foo-b id="><img src onerror='alert(1)'>">hmm...</foo-b>
        -            </a></table></li></mi></foo-test></math>
        -          `,
        -          {
        -            SAFE_FOR_TEMPLATES: true,
        -            CUSTOM_ELEMENT_HANDLING: {
        -              tagNameCheck: /^foo-/,
        -            },
        -          }
        -        );
        -        
        -

        Details

        -

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

        -

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

        -

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

        -

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

        -

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

        -

        Types of attacks

        -

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

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

        Affected environments

        -

        The following environments are susceptible to an XSS attack:

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

        How to prevent

        -

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

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

        Remediation

        -

        Upgrade dompurify to version 3.2.4 or higher.

        -

        References

        - - -
        - - - -
        -
        -
        -
        - - - diff --git a/docs/snyk/v2.14.5/public.ecr.aws_docker_library_redis_7.0.15-alpine.html b/docs/snyk/v2.14.5/public.ecr.aws_docker_library_redis_7.0.15-alpine.html deleted file mode 100644 index cf42c3d6f1..0000000000 --- a/docs/snyk/v2.14.5/public.ecr.aws_docker_library_redis_7.0.15-alpine.html +++ /dev/null @@ -1,1216 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
        -
        -
        -
        - - - Snyk - Open Source Security - - - - - - - -
        -

        Snyk test report

        - -

        March 16th 2025, 12:24:03 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)
        • -
        -
        - -
        -
        4 known vulnerabilities
        -
        38 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-r3 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        CVE-2024-13176

        -
        - -
        - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

        -

        Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

        -

        There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

        -

        Remediation

        -

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

        -

        References

        - - -
        - - - -
        -
        -

        CVE-2024-12797

        -
        - -
        - 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: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a - server may fail to notice that the server was not authenticated, because - handshakes don't abort as expected when the SSL_VERIFY_PEER verification mode - is set.

        -

        Impact summary: TLS and DTLS connections using raw public keys may be - vulnerable to man-in-middle attacks when server authentication failure is not - detected by clients.

        -

        RPKs are disabled by default in both TLS clients and TLS servers. The issue - only arises when TLS clients explicitly enable RPK use by the server, and the - server, likewise, enables sending of an RPK instead of an X.509 certificate - chain. The affected clients are those that then rely on the handshake to - fail when the server's RPK fails to match one of the expected public keys, - by setting the verification mode to SSL_VERIFY_PEER.

        -

        Clients that enable server-side raw public keys can still find out that raw - public key verification failed by calling SSL_get_verify_result(), and those - that do, and take appropriate action, are not affected. This issue was - introduced in the initial implementation of RPK support in OpenSSL 3.2.

        -

        The FIPS modules in 3.4, 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.3-r0 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        CVE-2025-26519

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

        Detailed paths

        - -
          -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - .redis-rundeps@20240906.232324 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - busybox/ssl_client@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - › - musl/musl@1.2.5-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 - › - musl/musl@1.2.5-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 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - zlib/zlib@1.3.1-r1 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - alpine-baselayout/alpine-baselayout@3.6.5-r0 - › - busybox/busybox-binsh@1.36.1-r29 - › - busybox/busybox@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - - - -
        • -
        - -
        - -
        - -

        NVD Description

        -

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

        -

        musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

        -

        Remediation

        -

        Upgrade Alpine:3.20 musl to version 1.2.5-r1 or higher.

        -

        References

        - - -
        - - - -
        -
        -
        -
        - - - diff --git a/docs/snyk/v2.14.5/redis_7.0.15-alpine.html b/docs/snyk/v2.14.5/redis_7.0.15-alpine.html deleted file mode 100644 index f321179a61..0000000000 --- a/docs/snyk/v2.14.5/redis_7.0.15-alpine.html +++ /dev/null @@ -1,1216 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
        -
        -
        -
        - - - Snyk - Open Source Security - - - - - - - -
        -

        Snyk test report

        - -

        March 16th 2025, 12:24:26 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)
        • -
        -
        - -
        -
        4 known vulnerabilities
        -
        38 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-r3 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        CVE-2024-13176

        -
        - -
        - 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: A timing side-channel which could potentially allow recovering - the private key exists in the ECDSA signature computation.

        -

        Impact summary: A timing side-channel in ECDSA signature computations - could allow recovering the private key by an attacker. However, measuring - the timing would require either local access to the signing application or - a very fast network connection with low latency.

        -

        There is a timing signal of around 300 nanoseconds when the top word of - the inverted ECDSA nonce value is zero. This can happen with significant - probability only for some of the supported elliptic curves. In particular - the NIST P-521 curve is affected. To be able to measure this leak, the attacker - process must either be located in the same physical computer or must - have a very fast network connection with low latency. For that reason - the severity of this vulnerability is Low.

        -

        Remediation

        -

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

        -

        References

        - - -
        - - - -
        -
        -

        CVE-2024-12797

        -
        - -
        - 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: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a - server may fail to notice that the server was not authenticated, because - handshakes don't abort as expected when the SSL_VERIFY_PEER verification mode - is set.

        -

        Impact summary: TLS and DTLS connections using raw public keys may be - vulnerable to man-in-middle attacks when server authentication failure is not - detected by clients.

        -

        RPKs are disabled by default in both TLS clients and TLS servers. The issue - only arises when TLS clients explicitly enable RPK use by the server, and the - server, likewise, enables sending of an RPK instead of an X.509 certificate - chain. The affected clients are those that then rely on the handshake to - fail when the server's RPK fails to match one of the expected public keys, - by setting the verification mode to SSL_VERIFY_PEER.

        -

        Clients that enable server-side raw public keys can still find out that raw - public key verification failed by calling SSL_get_verify_result(), and those - that do, and take appropriate action, are not affected. This issue was - introduced in the initial implementation of RPK support in OpenSSL 3.2.

        -

        The FIPS modules in 3.4, 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.3-r0 or higher.

        -

        References

        - - -
        - - - -
        -
        -

        CVE-2025-26519

        -
        - -
        - low severity -
        - -
        - -
          -
        • - Package Manager: alpine:3.20 -
        • -
        • - Vulnerable module: - - musl/musl -
        • - -
        • Introduced through: - - docker-image|redis@7.0.15-alpine and musl/musl@1.2.5-r0 - -
        • -
        - -
        - - -

        Detailed paths

        - -
          -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - .redis-rundeps@20240906.232324 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - busybox/ssl_client@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - .redis-rundeps@20240906.232324 - › - openssl/libcrypto3@3.3.2-r0 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - .redis-rundeps@20240906.232324 - › - openssl/libssl3@3.3.2-r0 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - apk-tools/apk-tools@2.14.4-r0 - › - zlib/zlib@1.3.1-r1 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - › - pax-utils/scanelf@1.3.7-r2 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - alpine-baselayout/alpine-baselayout@3.6.5-r0 - › - busybox/busybox-binsh@1.36.1-r29 - › - busybox/busybox@1.36.1-r29 - › - musl/musl@1.2.5-r0 - - - -
        • -
        • - Introduced through: - docker-image|redis@7.0.15-alpine - › - musl/musl-utils@1.2.5-r0 - - - -
        • -
        - -
        - -
        - -

        NVD Description

        -

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

        -

        musl libc 0.9.13 through 1.2.5 before 1.2.6 has an out-of-bounds write vulnerability when an attacker can trigger iconv conversion of untrusted EUC-KR text to UTF-8.

        -

        Remediation

        -

        Upgrade Alpine:3.20 musl to version 1.2.5-r1 or higher.

        -

        References

        - - -
        - - - -
        -
        -
        -
        - - - diff --git a/docs/try_argo_cd_locally.md b/docs/try_argo_cd_locally.md index 72bd69be5c..2d08105875 100644 --- a/docs/try_argo_cd_locally.md +++ b/docs/try_argo_cd_locally.md @@ -6,7 +6,7 @@ Follow these steps to install `Kind` for local development and set it up with Argo CD. -To run an Argo CD development environment review the [developer guide for running locally](./developer-guide/running-locally.md). +To run an Argo CD development environment [review the developer guide for running locally](../developer-guide/running-locally). ## Install Kind @@ -50,4 +50,4 @@ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath='{.data.pas ``` Use the admin username and the retrieved password to log in. -You can now move on to step #2 in the [Getting Started Guide](getting_started.md). +You can now move on to step #2 in the [Getting Started Guide](getting_started.md]. diff --git a/docs/user-guide/application_sources.md b/docs/user-guide/application_sources.md index 31d88545d2..332136d618 100644 --- a/docs/user-guide/application_sources.md +++ b/docs/user-guide/application_sources.md @@ -6,7 +6,7 @@ Argo CD supports several different ways in which Kubernetes manifests can be def * [Kustomize](kustomize.md) applications * [Helm](helm.md) charts -* A directory of YAML, JSON, or [Jsonnet](jsonnet.md) manifests. +* A directory of YAML/JSON/Jsonnet manifests, including [Jsonnet](jsonnet.md). * Any [custom config management tool](../operator-manual/config-management-plugins.md) configured as a config management plugin ## Development diff --git a/docs/user-guide/auto_sync.md b/docs/user-guide/auto_sync.md index 7da2cc5be4..66e20c9fc0 100644 --- a/docs/user-guide/auto_sync.md +++ b/docs/user-guide/auto_sync.md @@ -18,22 +18,6 @@ spec: syncPolicy: automated: {} ``` -Application CRD now also support explicitly setting automated sync to be turned on or off by using `spec.syncPolicy.automated.enabled` flag to true or false. When `enable` field is set to true, Automated Sync is active and when set to false controller will skip automated sync even if `prune`, `self-heal` and `allowEmpty` are set. -```yaml -spec: - syncPolicy: - automated: - enabled: true -``` - -!!!note - Setting the `spec.syncPolicy.automated.enabled` flag to null will be treated as if automated sync is enabled. When the `enabled` field is set to false, fields like `prune`, `selfHeal` and `allowEmpty` can be set without enabling them. - -## Temporarily toggling auto-sync for applications managed by ApplicationSets - -For a standalone application, toggling auto-sync is performed by changing the application's `spec.syncPolicy.automated` field. For an ApplicationSet managed application, changing the application's `spec.syncPolicy.automated` field will, however, have no effect. -Read more details about how to perform the toggling for applications managed by ApplicationSets [here](../operator-manual/applicationset/Controlling-Resource-Modification.md). - ## Automatic Pruning @@ -82,7 +66,7 @@ when the live cluster's state deviates from the state defined in Git, run: argocd app set --self-heal ``` -Or by setting the self-heal option to true in the automated sync policy: +Or by setting the self heal option to true in the automated sync policy: ```yaml spec: @@ -100,10 +84,10 @@ Disabling self-heal does not guarantee that live cluster changes won't be revert * Automated sync will only attempt one synchronization per unique combination of commit SHA1 and application parameters. If the most recent successful sync in the history was already performed against the same commit-SHA and parameters, a second sync will not be attempted, unless `selfHeal` flag is set to true. -* If the `selfHeal` flag is set to true, then the sync will be attempted again after self-heal timeout (5 seconds by default) +* If `selfHeal` flag is set to true then sync will be attempted again after self heal timeout (5 seconds by default) which is controlled by `--self-heal-timeout-seconds` flag of `argocd-application-controller` deployment. * Automatic sync will not reattempt a sync if the previous sync attempt against the same commit-SHA and parameters had failed. * Rollback cannot be performed against an application with automated sync enabled. -* The automatic sync interval is determined by [the `timeout.reconciliation` value in the `argocd-cm` ConfigMap](../faq.md#how-often-does-argo-cd-check-for-changes-to-my-git-or-helm-repository), which defaults to `120s` with added jitter of `60s` for a maximum period of 3 minutes. +* The automatic sync interval is determined by [the `timeout.reconciliation` value in the `argocd-cm` ConfigMap](../faq.md#how-often-does-argo-cd-check-for-changes-to-my-git-or-helm-repository), which defaults to `180s` (3 minutes). diff --git a/docs/user-guide/build-environment.md b/docs/user-guide/build-environment.md index 7bd7b4ca46..52fc8b1d03 100644 --- a/docs/user-guide/build-environment.md +++ b/docs/user-guide/build-environment.md @@ -6,7 +6,6 @@ |-------------------------------------|-------------------------------------------------------------------------| | `ARGOCD_APP_NAME` | The name of the application. | | `ARGOCD_APP_NAMESPACE` | The destination namespace of the application. | -| `ARGOCD_APP_PROJECT_NAME` | The name of the project the application belongs to. | | `ARGOCD_APP_REVISION` | The resolved revision, e.g. `f913b6cbf58aa5ae5ca1f8a2b149477aebcbd9d8`. | | `ARGOCD_APP_REVISION_SHORT` | The resolved short revision, e.g. `f913b6c`. | | `ARGOCD_APP_REVISION_SHORT_8` | The resolved short revision with length 8, e.g. `f913b6cb`. | diff --git a/docs/user-guide/ci_automation.md b/docs/user-guide/ci_automation.md index 38aa3d5e51..433483eba7 100644 --- a/docs/user-guide/ci_automation.md +++ b/docs/user-guide/ci_automation.md @@ -52,4 +52,4 @@ argocd app wait guestbook If [automated synchronization](auto_sync.md) is configured for the application, this step is unnecessary. The controller will automatically detect the new config (fast tracked using a -[webhook](../operator-manual/webhook.md), or polled at least every 3 minutes by default), and automatically sync the new manifests. +[webhook](../operator-manual/webhook.md), or polled every 3 minutes), and automatically sync the new manifests. diff --git a/docs/user-guide/commands/argocd.md b/docs/user-guide/commands/argocd.md index 19b0f4afe2..50dd2ffcaa 100644 --- a/docs/user-guide/commands/argocd.md +++ b/docs/user-guide/commands/argocd.md @@ -25,7 +25,7 @@ argocd [flags] --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: json|text (default "json") + --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 @@ -57,6 +57,6 @@ argocd [flags] * [argocd proj](argocd_proj.md) - Manage projects * [argocd relogin](argocd_relogin.md) - Refresh an expired authenticate token * [argocd repo](argocd_repo.md) - Manage repository connection parameters -* [argocd repocreds](argocd_repocreds.md) - Manage credential templates for repositories +* [argocd repocreds](argocd_repocreds.md) - Manage repository connection parameters * [argocd version](argocd_version.md) - Print version information diff --git a/docs/user-guide/commands/argocd_account.md b/docs/user-guide/commands/argocd_account.md index a50a00526a..082c305a0d 100644 --- a/docs/user-guide/commands/argocd_account.md +++ b/docs/user-guide/commands/argocd_account.md @@ -65,7 +65,7 @@ argocd account [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_account_bcrypt.md b/docs/user-guide/commands/argocd_account_bcrypt.md index 301abaac1c..94186dafcb 100644 --- a/docs/user-guide/commands/argocd_account_bcrypt.md +++ b/docs/user-guide/commands/argocd_account_bcrypt.md @@ -38,7 +38,7 @@ argocd account bcrypt --password YOUR_PASSWORD --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_account_can-i.md b/docs/user-guide/commands/argocd_account_can-i.md index 05e335bdf1..b229a1e577 100644 --- a/docs/user-guide/commands/argocd_account_can-i.md +++ b/docs/user-guide/commands/argocd_account_can-i.md @@ -48,7 +48,7 @@ Resources: [clusters projects applications applicationsets repositories write-re --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_account_delete-token.md b/docs/user-guide/commands/argocd_account_delete-token.md index 2f26a8146c..7571ec5aee 100644 --- a/docs/user-guide/commands/argocd_account_delete-token.md +++ b/docs/user-guide/commands/argocd_account_delete-token.md @@ -41,7 +41,7 @@ argocd account delete-token --account ID --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_account_generate-token.md b/docs/user-guide/commands/argocd_account_generate-token.md index 6541306e8a..fde85cf5f2 100644 --- a/docs/user-guide/commands/argocd_account_generate-token.md +++ b/docs/user-guide/commands/argocd_account_generate-token.md @@ -43,7 +43,7 @@ argocd account generate-token --account --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: json|text (default "json") + --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 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 106e8ef533..2ff293ddba 100644 --- a/docs/user-guide/commands/argocd_account_get-user-info.md +++ b/docs/user-guide/commands/argocd_account_get-user-info.md @@ -41,7 +41,7 @@ argocd account get-user-info [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_account_get.md b/docs/user-guide/commands/argocd_account_get.md index 20024f019a..21595a1009 100644 --- a/docs/user-guide/commands/argocd_account_get.md +++ b/docs/user-guide/commands/argocd_account_get.md @@ -42,7 +42,7 @@ argocd account get --account --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_account_list.md b/docs/user-guide/commands/argocd_account_list.md index 59f66b654f..17575ecfc6 100644 --- a/docs/user-guide/commands/argocd_account_list.md +++ b/docs/user-guide/commands/argocd_account_list.md @@ -37,7 +37,7 @@ argocd account list --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_account_update-password.md b/docs/user-guide/commands/argocd_account_update-password.md index 42ef6b77d7..6b45f4f9da 100644 --- a/docs/user-guide/commands/argocd_account_update-password.md +++ b/docs/user-guide/commands/argocd_account_update-password.md @@ -53,7 +53,7 @@ argocd account update-password [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin.md b/docs/user-guide/commands/argocd_admin.md index 8b2f629b80..6f12fb5fcc 100644 --- a/docs/user-guide/commands/argocd_admin.md +++ b/docs/user-guide/commands/argocd_admin.md @@ -23,7 +23,7 @@ $ argocd admin initial-password reset ``` -h, --help help for admin - --logformat string Set the logging format. One of: json|text (default "json") + --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") ``` diff --git a/docs/user-guide/commands/argocd_admin_app.md b/docs/user-guide/commands/argocd_admin_app.md index 630ced4b7d..fcad283b49 100644 --- a/docs/user-guide/commands/argocd_admin_app.md +++ b/docs/user-guide/commands/argocd_admin_app.md @@ -45,7 +45,7 @@ argocd admin app get-reconcile-results APPNAME --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: json|text (default "json") + --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 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 849983ba9d..8f85ab8837 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 @@ -30,7 +30,7 @@ argocd admin app diff-reconcile-results PATH1 PATH2 [flags] --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: json|text (default "json") + --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 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 7d8cc7e32f..ea663ecb04 100644 --- a/docs/user-guide/commands/argocd_admin_app_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_app_generate-spec.md @@ -25,7 +25,7 @@ argocd admin app generate-spec APPNAME [flags] argocd admin app generate-spec nginx-ingress --repo https://charts.helm.sh/stable --helm-chart nginx-ingress --revision 1.24.3 --dest-namespace default --dest-server https://kubernetes.default.svc # Generate declarative config for a Kustomize app - argocd admin app generate-spec kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image quay.io/argoprojlabs/argocd-e2e-container:0.1 + argocd admin app generate-spec kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1 # Generate declarative config for a app using a custom tool: argocd admin app generate-spec kasane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane @@ -64,7 +64,6 @@ argocd admin app generate-spec APPNAME [flags] --helm-version string Helm version -h, --help help for generate-spec --hydrate-to-branch string The branch to hydrate the app to - --ignore-missing-components Ignore locally missing component directories when setting Kustomize components --ignore-missing-value-files Ignore locally missing valueFiles when setting helm template --values -i, --inline If set then generated resource is written back to the file specified in --file flag --jsonnet-ext-var-code stringArray Jsonnet ext var @@ -79,8 +78,7 @@ argocd admin app generate-spec APPNAME [flags] --kustomize-force-common-label Force common labels in Kustomize --kustomize-image stringArray Kustomize images (e.g. --kustomize-image node:8.15.0 --kustomize-image mysql=mariadb,alpine@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d) --kustomize-kube-version string kube-version to use when running helm template. If not set, use the kube version from the destination cluster. Only applicable when Helm is enabled for Kustomize builds - --kustomize-label-include-templates Apply common label to resource templates - --kustomize-label-without-selector Do not apply common label to selectors. Also do not apply label to templates unless --kustomize-label-include-templates is set + --kustomize-label-without-selector Do not apply common label to selectors or templates --kustomize-namespace string Kustomize namespace --kustomize-replica stringArray Kustomize replicas (e.g. --kustomize-replica my-development=2 --kustomize-replica my-statefulset=4) --kustomize-version string Kustomize version @@ -130,7 +128,7 @@ argocd admin app generate-spec APPNAME [flags] --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: json|text (default "json") + --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 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 2a6a5a1843..f4c187be18 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 @@ -56,7 +56,7 @@ argocd admin app get-reconcile-results PATH [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_cluster.md b/docs/user-guide/commands/argocd_admin_cluster.md index de1bad2a8d..99e730b238 100644 --- a/docs/user-guide/commands/argocd_admin_cluster.md +++ b/docs/user-guide/commands/argocd_admin_cluster.md @@ -44,7 +44,7 @@ argocd admin cluster namespaces my-cluster --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: json|text (default "json") + --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 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 e3b0d2a3bd..92cd331eac 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_cluster_generate-spec.md @@ -54,7 +54,7 @@ argocd admin cluster generate-spec CONTEXT [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md index 0f3f0ab259..e261efc9e1 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md +++ b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md @@ -67,7 +67,7 @@ argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kub --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_cluster_namespaces.md b/docs/user-guide/commands/argocd_admin_cluster_namespaces.md index 492fc1e1ec..7047a4e5d8 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_namespaces.md +++ b/docs/user-guide/commands/argocd_admin_cluster_namespaces.md @@ -50,7 +50,7 @@ argocd admin cluster namespaces [flags] --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: json|text (default "json") + --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 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 dd3d9c86d1..0d538f4123 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 @@ -51,7 +51,7 @@ argocd admin cluster namespaces disable-namespaced-mode PATTERN [flags] --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: json|text (default "json") + --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 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 e14adf103e..b01d26a106 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 @@ -53,7 +53,7 @@ argocd admin cluster namespaces enable-namespaced-mode PATTERN [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_cluster_shards.md b/docs/user-guide/commands/argocd_admin_cluster_shards.md index be0eec3c1c..5d0c528fcc 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_shards.md +++ b/docs/user-guide/commands/argocd_admin_cluster_shards.md @@ -66,7 +66,7 @@ argocd admin cluster shards [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_cluster_stats.md b/docs/user-guide/commands/argocd_admin_cluster_stats.md index b0a9da7616..298b756055 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_stats.md +++ b/docs/user-guide/commands/argocd_admin_cluster_stats.md @@ -80,7 +80,7 @@ argocd admin cluster stats target-cluster --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_dashboard.md b/docs/user-guide/commands/argocd_admin_dashboard.md index d9f4affd2f..a8ac84acbd 100644 --- a/docs/user-guide/commands/argocd_admin_dashboard.md +++ b/docs/user-guide/commands/argocd_admin_dashboard.md @@ -66,7 +66,7 @@ $ argocd admin dashboard --redis-compress gzip --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_export.md b/docs/user-guide/commands/argocd_admin_export.md index e3bc3a4079..90e842e117 100644 --- a/docs/user-guide/commands/argocd_admin_export.md +++ b/docs/user-guide/commands/argocd_admin_export.md @@ -11,8 +11,8 @@ argocd admin export [flags] ### Options ``` - --application-namespaces strings Comma-separated list of namespace globs to export applications from, in addition to the control plane namespace (Argo CD namespace). By default, all applications from the control plane namespace are always exported. If this flag is provided, applications from the specified namespaces are exported along with the control plane namespace. If not specified, the value from 'application.namespaces' in argocd-cmd-params-cm is used (if defined in the ConfigMap). If the ConfigMap value is not set, only applications from the control plane namespace are exported. - --applicationset-namespaces strings Comma-separated list of namespace globs to export ApplicationSets from, in addition to the control plane namespace (Argo CD namespace). By default, all ApplicationSets from the control plane namespace are always exported. If this flag is provided, ApplicationSets from the specified namespaces are exported along with the control plane namespace. If not specified, the value from 'applicationsetcontroller.namespaces' in argocd-cmd-params-cm is used (if defined in the ConfigMap). If the ConfigMap value is not set, only ApplicationSets from the control plane namespace are exported. + --application-namespaces strings Comma separated list of namespace globs to export applications from. If not provided value from 'application.namespaces' in argocd-cmd-params-cm will be used,if it's not defined only applications from Argo CD namespace will be exported + --applicationset-namespaces strings Comma separated list of namespace globs to export applicationsets from. If not provided value from 'applicationsetcontroller.namespaces' in argocd-cmd-params-cm will be used,if it's not defined only applicationsets from Argo CD namespace will be exported --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 @@ -53,7 +53,7 @@ argocd admin export [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_import.md b/docs/user-guide/commands/argocd_admin_import.md index 6fadc82e5e..fc812f3bb7 100644 --- a/docs/user-guide/commands/argocd_admin_import.md +++ b/docs/user-guide/commands/argocd_admin_import.md @@ -11,8 +11,8 @@ argocd admin import SOURCE [flags] ### Options ``` - --application-namespaces strings Comma separated list of namespace globs to which import of applications is allowed. If not provided, value from 'application.namespaces' in argocd-cmd-params-cm will be used. If it's not defined, only applications without an explicit namespace will be imported to the Argo CD namespace - --applicationset-namespaces strings Comma separated list of namespace globs which import of applicationsets is allowed. If not provided, value from 'applicationsetcontroller.namespaces' in argocd-cmd-params-cm will be used. If it's not defined, only applicationsets without an explicit namespace will be imported to the Argo CD namespace + --application-namespaces strings Comma separated list of namespace globs to which import of applications is allowed. If not provided value from 'application.namespaces' in argocd-cmd-params-cm will be used,if it's not defined only applications without an explicit namespace will be imported to the Argo CD namespace + --applicationset-namespaces strings Comma separated list of namespace globs which import of applicationsets is allowed. If not provided value from 'applicationsetcontroller.namespaces' in argocd-cmd-params-cm will be used,if it's not defined only applicationsets without an explicit namespace will be imported to the Argo CD namespace --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 @@ -28,14 +28,12 @@ argocd admin import SOURCE [flags] --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 - --override-on-conflict Override the resource on conflict when updating resources --password string Password for basic authentication to the API server --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --prune Prune secrets, applications and projects which do not appear in the backup --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") --server string The address and port of the Kubernetes API server - --skip-resources-with-label string Skip importing resources based on the label e.g. '--skip-resources-with-label my-label/example.io=true' --stop-operation Stop any existing operations --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 @@ -60,7 +58,7 @@ argocd admin import SOURCE [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_initial-password.md b/docs/user-guide/commands/argocd_admin_initial-password.md index e6011be2f7..3a67365c96 100644 --- a/docs/user-guide/commands/argocd_admin_initial-password.md +++ b/docs/user-guide/commands/argocd_admin_initial-password.md @@ -50,7 +50,7 @@ argocd admin initial-password [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_notifications.md b/docs/user-guide/commands/argocd_admin_notifications.md index fcd5d96bfb..233037fab0 100644 --- a/docs/user-guide/commands/argocd_admin_notifications.md +++ b/docs/user-guide/commands/argocd_admin_notifications.md @@ -55,7 +55,7 @@ argocd admin notifications [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_notifications_template.md b/docs/user-guide/commands/argocd_admin_notifications_template.md index 36e1de4f77..a4b35d0fa1 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template.md @@ -45,7 +45,7 @@ argocd admin notifications template [flags] --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server 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 ff3bdc9cb4..cdf1b9089c 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template_get.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template_get.md @@ -57,7 +57,7 @@ argocd admin notifications template get app-sync-succeeded -o=yaml --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server 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 04f36e4938..7c1cbe71a8 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template_notify.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template_notify.md @@ -58,7 +58,7 @@ argocd admin notifications template notify app-sync-succeeded guestbook --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server diff --git a/docs/user-guide/commands/argocd_admin_notifications_trigger.md b/docs/user-guide/commands/argocd_admin_notifications_trigger.md index 470f7e6e20..064932d45d 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger.md @@ -45,7 +45,7 @@ argocd admin notifications trigger [flags] --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server 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 cf4a4f0b5c..5082d33a9c 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md @@ -57,7 +57,7 @@ argocd admin notifications trigger get on-sync-failed -o=yaml --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server 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 c6b79f8167..00d4c5f0bd 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md @@ -57,7 +57,7 @@ argocd admin notifications trigger run on-sync-status-unknown ./sample-app.yaml --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server diff --git a/docs/user-guide/commands/argocd_admin_proj.md b/docs/user-guide/commands/argocd_admin_proj.md index 261a07d6e3..1e09f34211 100644 --- a/docs/user-guide/commands/argocd_admin_proj.md +++ b/docs/user-guide/commands/argocd_admin_proj.md @@ -30,7 +30,7 @@ argocd admin proj [flags] --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: json|text (default "json") + --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 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 2454cbea49..4f865b6399 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 @@ -58,7 +58,7 @@ argocd admin proj generate-allow-list /path/to/clusterrole.yaml my-project --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: json|text (default "json") + --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 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 7fb58fbf7a..c89baf994d 100644 --- a/docs/user-guide/commands/argocd_admin_proj_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_proj_generate-spec.md @@ -58,7 +58,7 @@ argocd admin proj generate-spec PROJECT [flags] --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: json|text (default "json") + --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 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 8fba15d6d2..72bf923704 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 @@ -66,7 +66,7 @@ argocd admin proj update-role-policy PROJECT_GLOB MODIFICATION ACTION [flags] --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: json|text (default "json") + --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 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 37a687c41e..95ce81309b 100644 --- a/docs/user-guide/commands/argocd_admin_redis-initial-password.md +++ b/docs/user-guide/commands/argocd_admin_redis-initial-password.md @@ -50,7 +50,7 @@ argocd admin redis-initial-password [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_repo.md b/docs/user-guide/commands/argocd_admin_repo.md index d845b99f63..e609511c27 100644 --- a/docs/user-guide/commands/argocd_admin_repo.md +++ b/docs/user-guide/commands/argocd_admin_repo.md @@ -30,7 +30,7 @@ argocd admin repo [flags] --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: json|text (default "json") + --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 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 ae48af702a..5be56946c2 100644 --- a/docs/user-guide/commands/argocd_admin_repo_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_repo_generate-spec.md @@ -21,9 +21,6 @@ argocd admin repo generate-spec REPOURL [flags] # Add a private Git repository via HTTPS using username/password and TLS client certificates: argocd admin repo generate-spec https://git.example.com/repos/repo --username git --password secret --tls-client-cert-path ~/mycert.crt --tls-client-cert-key-path ~/mycert.key - # Add a private Git BitBucket Data Center repository via HTTPS using bearer token: - argocd admin repo generate-spec https://bitbucket.example.com/scm/proj/repo --bearer-token secret-token - # Add a private Git repository via HTTPS using username/password without verifying the server's TLS certificate argocd admin repo generate-spec https://git.example.com/repos/repo --username git --password secret --insecure-skip-server-verification @@ -41,7 +38,6 @@ argocd admin repo generate-spec REPOURL [flags] ### Options ``` - --bearer-token string bearer token to the Git BitBucket Data Center repository --enable-lfs enable git-lfs (Large File Support) on this repository --enable-oci enable helm-oci (Helm OCI-Based Repository) --force-http-basic-auth whether to force use of basic auth when connecting repository via HTTP @@ -63,7 +59,6 @@ argocd admin repo generate-spec REPOURL [flags] --tls-client-cert-key-path string path to the TLS client cert's key path (must be PEM format) --tls-client-cert-path string path to the TLS client cert (must be PEM format) --type string type of the repository, "git" or "helm" (default "git") - --use-azure-workload-identity whether to use azure workload identity for authentication --username string username to the repository ``` @@ -83,7 +78,7 @@ argocd admin repo generate-spec REPOURL [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_settings.md b/docs/user-guide/commands/argocd_admin_settings.md index bdb59b3ce6..f1ebac6ba3 100644 --- a/docs/user-guide/commands/argocd_admin_settings.md +++ b/docs/user-guide/commands/argocd_admin_settings.md @@ -53,7 +53,7 @@ argocd admin settings [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_admin_settings_rbac.md b/docs/user-guide/commands/argocd_admin_settings_rbac.md index fd0467922d..cf1039f1fb 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac.md @@ -44,7 +44,7 @@ argocd admin settings rbac [flags] --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster --load-cluster-settings Indicates that config map and secret should be loaded from cluster unless local file path is provided - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server 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 d609d2ac1e..79ac464abc 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac_can.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac_can.md @@ -88,7 +88,7 @@ argocd admin settings rbac can someuser create application 'default/app' --defau --insecure Skip server certificate and domain verification --kube-context string Directs the command to the given kube-context --load-cluster-settings Indicates that config map and secret should be loaded from cluster unless local file path is provided - --logformat string Set the logging format. One of: json|text (default "json") + --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 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 565ca27e9e..2507c1788a 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md @@ -80,7 +80,7 @@ argocd admin settings rbac validate --namespace argocd --insecure Skip server certificate and domain verification --kube-context string Directs the command to the given kube-context --load-cluster-settings Indicates that config map and secret should be loaded from cluster unless local file path is provided - --logformat string Set the logging format. One of: json|text (default "json") + --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 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 77f67869d3..8e03c64b27 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md @@ -44,7 +44,7 @@ argocd admin settings resource-overrides [flags] --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster --load-cluster-settings Indicates that config map and secret should be loaded from cluster unless local file path is provided - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server 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 f11a96ad51..f3774610c5 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 @@ -55,7 +55,7 @@ argocd admin settings resource-overrides health ./deploy.yaml --argocd-cm-path . --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster --load-cluster-settings Indicates that config map and secret should be loaded from cluster unless local file path is provided - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server 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 74e061d5fc..9cffffeccf 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 @@ -55,7 +55,7 @@ argocd admin settings resource-overrides ignore-differences ./deploy.yaml --argo --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster --load-cluster-settings Indicates that config map and secret should be loaded from cluster unless local file path is provided - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server 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 f401321f75..cca38fbdd6 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 @@ -56,7 +56,7 @@ argocd admin settings resource-overrides ignore-resource-updates ./deploy.yaml - --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster --load-cluster-settings Indicates that config map and secret should be loaded from cluster unless local file path is provided - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server 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 7e74b6ae12..c7f838062b 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 @@ -55,7 +55,7 @@ argocd admin settings resource-overrides action list /tmp/deploy.yaml --argocd-c --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster --load-cluster-settings Indicates that config map and secret should be loaded from cluster unless local file path is provided - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server 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 e10d6ece07..280e4a4ffb 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 @@ -22,8 +22,7 @@ argocd admin settings resource-overrides action /tmp/deploy.yaml restart --argoc ### Options ``` - -h, --help help for run-action - --param stringArray Action parameters (e.g. --param key1=value1) + -h, --help help for run-action ``` ### Options inherited from parent commands @@ -56,7 +55,7 @@ argocd admin settings resource-overrides action /tmp/deploy.yaml restart --argoc --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster --load-cluster-settings Indicates that config map and secret should be loaded from cluster unless local file path is provided - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server diff --git a/docs/user-guide/commands/argocd_admin_settings_validate.md b/docs/user-guide/commands/argocd_admin_settings_validate.md index 303276e367..c4d03ffe5e 100644 --- a/docs/user-guide/commands/argocd_admin_settings_validate.md +++ b/docs/user-guide/commands/argocd_admin_settings_validate.md @@ -26,7 +26,7 @@ argocd admin settings validate --group accounts --group plugins --load-cluster-s ### Options ``` - --group stringArray Optional list of setting groups that have to be validated ( one of: accounts, general, kustomize, resource-overrides) + --group stringArray Optional list of setting groups that have to be validated ( one of: accounts, general, kustomize, repositories, resource-overrides) -h, --help help for validate ``` @@ -60,7 +60,7 @@ argocd admin settings validate --group accounts --group plugins --load-cluster-s --kube-context string Directs the command to the given kube-context --kubeconfig string Path to a kube config. Only required if out-of-cluster --load-cluster-settings Indicates that config map and secret should be loaded from cluster unless local file path is provided - --logformat string Set the logging format. One of: json|text (default "json") + --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") -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server diff --git a/docs/user-guide/commands/argocd_app.md b/docs/user-guide/commands/argocd_app.md index 6497de402c..b1e8461662 100644 --- a/docs/user-guide/commands/argocd_app.md +++ b/docs/user-guide/commands/argocd_app.md @@ -62,7 +62,7 @@ argocd app [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_actions.md b/docs/user-guide/commands/argocd_app_actions.md index af0aab4075..a59a5afcbb 100644 --- a/docs/user-guide/commands/argocd_app_actions.md +++ b/docs/user-guide/commands/argocd_app_actions.md @@ -40,7 +40,7 @@ argocd app actions [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_actions_list.md b/docs/user-guide/commands/argocd_app_actions_list.md index da4b9b24b4..b1a2394f11 100644 --- a/docs/user-guide/commands/argocd_app_actions_list.md +++ b/docs/user-guide/commands/argocd_app_actions_list.md @@ -42,7 +42,7 @@ argocd app actions list APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_actions_run.md b/docs/user-guide/commands/argocd_app_actions_run.md index 4e9fcf9aac..61eae0fd96 100644 --- a/docs/user-guide/commands/argocd_app_actions_run.md +++ b/docs/user-guide/commands/argocd_app_actions_run.md @@ -42,7 +42,7 @@ argocd app actions run APPNAME ACTION [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_add-source.md b/docs/user-guide/commands/argocd_app_add-source.md index fe869c1f62..6f699f2845 100644 --- a/docs/user-guide/commands/argocd_app_add-source.md +++ b/docs/user-guide/commands/argocd_app_add-source.md @@ -46,7 +46,6 @@ argocd app add-source APPNAME [flags] --helm-version string Helm version -h, --help help for add-source --hydrate-to-branch string The branch to hydrate the app to - --ignore-missing-components Ignore locally missing component directories when setting Kustomize components --ignore-missing-value-files Ignore locally missing valueFiles when setting helm template --values --jsonnet-ext-var-code stringArray Jsonnet ext var --jsonnet-ext-var-str stringArray Jsonnet string ext var @@ -60,8 +59,7 @@ argocd app add-source APPNAME [flags] --kustomize-force-common-label Force common labels in Kustomize --kustomize-image stringArray Kustomize images (e.g. --kustomize-image node:8.15.0 --kustomize-image mysql=mariadb,alpine@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d) --kustomize-kube-version string kube-version to use when running helm template. If not set, use the kube version from the destination cluster. Only applicable when Helm is enabled for Kustomize builds - --kustomize-label-include-templates Apply common label to resource templates - --kustomize-label-without-selector Do not apply common label to selectors. Also do not apply label to templates unless --kustomize-label-include-templates is set + --kustomize-label-without-selector Do not apply common label to selectors or templates --kustomize-namespace string Kustomize namespace --kustomize-replica stringArray Kustomize replicas (e.g. --kustomize-replica my-development=2 --kustomize-replica my-statefulset=4) --kustomize-version string Kustomize version @@ -107,7 +105,7 @@ argocd app add-source APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_confirm-deletion.md b/docs/user-guide/commands/argocd_app_confirm-deletion.md index a0f80f5618..6c7bae4ddd 100644 --- a/docs/user-guide/commands/argocd_app_confirm-deletion.md +++ b/docs/user-guide/commands/argocd_app_confirm-deletion.md @@ -31,7 +31,7 @@ argocd app confirm-deletion APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_create.md b/docs/user-guide/commands/argocd_app_create.md index 5529650f86..a76895aafd 100644 --- a/docs/user-guide/commands/argocd_app_create.md +++ b/docs/user-guide/commands/argocd_app_create.md @@ -24,7 +24,7 @@ argocd app create APPNAME [flags] argocd app create nginx-ingress --repo https://charts.helm.sh/stable --helm-chart nginx-ingress --revision 1.24.3 --dest-namespace default --dest-server https://kubernetes.default.svc # Create a Kustomize app - argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image quay.io/argoprojlabs/argocd-e2e-container:0.1 + argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1 # Create a MultiSource app while yaml file contains an application with multiple sources argocd app create guestbook --file @@ -66,7 +66,6 @@ argocd app create APPNAME [flags] --helm-version string Helm version -h, --help help for create --hydrate-to-branch string The branch to hydrate the app to - --ignore-missing-components Ignore locally missing component directories when setting Kustomize components --ignore-missing-value-files Ignore locally missing valueFiles when setting helm template --values --jsonnet-ext-var-code stringArray Jsonnet ext var --jsonnet-ext-var-str stringArray Jsonnet string ext var @@ -80,8 +79,7 @@ argocd app create APPNAME [flags] --kustomize-force-common-label Force common labels in Kustomize --kustomize-image stringArray Kustomize images (e.g. --kustomize-image node:8.15.0 --kustomize-image mysql=mariadb,alpine@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d) --kustomize-kube-version string kube-version to use when running helm template. If not set, use the kube version from the destination cluster. Only applicable when Helm is enabled for Kustomize builds - --kustomize-label-include-templates Apply common label to resource templates - --kustomize-label-without-selector Do not apply common label to selectors. Also do not apply label to templates unless --kustomize-label-include-templates is set + --kustomize-label-without-selector Do not apply common label to selectors or templates --kustomize-namespace string Kustomize namespace --kustomize-replica stringArray Kustomize replicas (e.g. --kustomize-replica my-development=2 --kustomize-replica my-statefulset=4) --kustomize-version string Kustomize version @@ -131,7 +129,7 @@ argocd app create APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_delete-resource.md b/docs/user-guide/commands/argocd_app_delete-resource.md index 91930ebc15..0b0429ca89 100644 --- a/docs/user-guide/commands/argocd_app_delete-resource.md +++ b/docs/user-guide/commands/argocd_app_delete-resource.md @@ -38,7 +38,7 @@ argocd app delete-resource APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_delete.md b/docs/user-guide/commands/argocd_app_delete.md index d448fc112f..a425ce5a5c 100644 --- a/docs/user-guide/commands/argocd_app_delete.md +++ b/docs/user-guide/commands/argocd_app_delete.md @@ -53,7 +53,7 @@ argocd app delete APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_diff.md b/docs/user-guide/commands/argocd_app_diff.md index cbbf77203c..a77247ebab 100644 --- a/docs/user-guide/commands/argocd_app_diff.md +++ b/docs/user-guide/commands/argocd_app_diff.md @@ -51,7 +51,7 @@ argocd app diff APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_edit.md b/docs/user-guide/commands/argocd_app_edit.md index 9253b93440..b5330ac010 100644 --- a/docs/user-guide/commands/argocd_app_edit.md +++ b/docs/user-guide/commands/argocd_app_edit.md @@ -31,7 +31,7 @@ argocd app edit APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_get.md b/docs/user-guide/commands/argocd_app_get.md index 1786e0535a..fd3d148eec 100644 --- a/docs/user-guide/commands/argocd_app_get.md +++ b/docs/user-guide/commands/argocd_app_get.md @@ -57,7 +57,6 @@ argocd app get APPNAME [flags] --show-params Show application parameters and overrides --source-name string Name of the source from the list of sources of the app. --source-position int Position of the source from the list of sources of the app. Counting starts at 1. (default -1) - --timeout uint Time out after this many seconds ``` ### Options inherited from parent commands @@ -76,7 +75,7 @@ argocd app get APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_history.md b/docs/user-guide/commands/argocd_app_history.md index 6ee739b514..e5adf74548 100644 --- a/docs/user-guide/commands/argocd_app_history.md +++ b/docs/user-guide/commands/argocd_app_history.md @@ -32,7 +32,7 @@ argocd app history APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_list.md b/docs/user-guide/commands/argocd_app_list.md index 057a0f2339..cd1146b4d7 100644 --- a/docs/user-guide/commands/argocd_app_list.md +++ b/docs/user-guide/commands/argocd_app_list.md @@ -50,7 +50,7 @@ argocd app list [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_logs.md b/docs/user-guide/commands/argocd_app_logs.md index 731e517612..8ea312a4b5 100644 --- a/docs/user-guide/commands/argocd_app_logs.md +++ b/docs/user-guide/commands/argocd_app_logs.md @@ -41,9 +41,6 @@ argocd app logs APPNAME [flags] # Filter logs to show only those containing a specific string argocd app logs my-app --filter "error" - # Filter logs to show only those containing a specific string and match case - argocd app logs my-app --filter "error" --match-case - # Get logs for a specific container within the pods argocd app logs my-app -c my-container @@ -60,7 +57,6 @@ argocd app logs APPNAME [flags] --group string Resource group -h, --help help for logs --kind string Resource kind - -m, --match-case Specify if the filter should be case-sensitive --name string Resource name --namespace string Resource namespace -p, --previous Specify if the previously terminated container logs should be returned @@ -85,7 +81,7 @@ argocd app logs APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_manifests.md b/docs/user-guide/commands/argocd_app_manifests.md index c3283cc70f..6c866429c4 100644 --- a/docs/user-guide/commands/argocd_app_manifests.md +++ b/docs/user-guide/commands/argocd_app_manifests.md @@ -53,7 +53,7 @@ argocd app manifests APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_patch-resource.md b/docs/user-guide/commands/argocd_app_patch-resource.md index b7da6c7090..c9b607b4af 100644 --- a/docs/user-guide/commands/argocd_app_patch-resource.md +++ b/docs/user-guide/commands/argocd_app_patch-resource.md @@ -38,7 +38,7 @@ argocd app patch-resource APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_patch.md b/docs/user-guide/commands/argocd_app_patch.md index b7df4a4faa..6c119a1cbe 100644 --- a/docs/user-guide/commands/argocd_app_patch.md +++ b/docs/user-guide/commands/argocd_app_patch.md @@ -43,7 +43,7 @@ argocd app patch APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_remove-source.md b/docs/user-guide/commands/argocd_app_remove-source.md index c04950b550..39c47cead9 100644 --- a/docs/user-guide/commands/argocd_app_remove-source.md +++ b/docs/user-guide/commands/argocd_app_remove-source.md @@ -43,7 +43,7 @@ argocd app remove-source APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_resources.md b/docs/user-guide/commands/argocd_app_resources.md index e4d0548d88..516ad4a798 100644 --- a/docs/user-guide/commands/argocd_app_resources.md +++ b/docs/user-guide/commands/argocd_app_resources.md @@ -33,7 +33,7 @@ argocd app resources APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_rollback.md b/docs/user-guide/commands/argocd_app_rollback.md index d85b87e377..c53aed713c 100644 --- a/docs/user-guide/commands/argocd_app_rollback.md +++ b/docs/user-guide/commands/argocd_app_rollback.md @@ -34,7 +34,7 @@ argocd app rollback APPNAME [ID] [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_set.md b/docs/user-guide/commands/argocd_app_set.md index 9a38336762..a62e27fc5e 100644 --- a/docs/user-guide/commands/argocd_app_set.md +++ b/docs/user-guide/commands/argocd_app_set.md @@ -58,7 +58,6 @@ argocd app set APPNAME [flags] --helm-version string Helm version -h, --help help for set --hydrate-to-branch string The branch to hydrate the app to - --ignore-missing-components Ignore locally missing component directories when setting Kustomize components --ignore-missing-value-files Ignore locally missing valueFiles when setting helm template --values --jsonnet-ext-var-code stringArray Jsonnet ext var --jsonnet-ext-var-str stringArray Jsonnet string ext var @@ -72,8 +71,7 @@ argocd app set APPNAME [flags] --kustomize-force-common-label Force common labels in Kustomize --kustomize-image stringArray Kustomize images (e.g. --kustomize-image node:8.15.0 --kustomize-image mysql=mariadb,alpine@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d) --kustomize-kube-version string kube-version to use when running helm template. If not set, use the kube version from the destination cluster. Only applicable when Helm is enabled for Kustomize builds - --kustomize-label-include-templates Apply common label to resource templates - --kustomize-label-without-selector Do not apply common label to selectors. Also do not apply label to templates unless --kustomize-label-include-templates is set + --kustomize-label-without-selector Do not apply common label to selectors or templates --kustomize-namespace string Kustomize namespace --kustomize-replica stringArray Kustomize replicas (e.g. --kustomize-replica my-development=2 --kustomize-replica my-statefulset=4) --kustomize-version string Kustomize version @@ -120,7 +118,7 @@ argocd app set APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_sync.md b/docs/user-guide/commands/argocd_app_sync.md index e9f09603e0..f300e9fd19 100644 --- a/docs/user-guide/commands/argocd_app_sync.md +++ b/docs/user-guide/commands/argocd_app_sync.md @@ -90,7 +90,7 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_terminate-op.md b/docs/user-guide/commands/argocd_app_terminate-op.md index 411198fc11..e73f5c9e9d 100644 --- a/docs/user-guide/commands/argocd_app_terminate-op.md +++ b/docs/user-guide/commands/argocd_app_terminate-op.md @@ -30,7 +30,7 @@ argocd app terminate-op APPNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_unset.md b/docs/user-guide/commands/argocd_app_unset.md index 65f6b293bf..89463bf691 100644 --- a/docs/user-guide/commands/argocd_app_unset.md +++ b/docs/user-guide/commands/argocd_app_unset.md @@ -32,7 +32,6 @@ argocd app unset APPNAME parameters [flags] ``` -N, --app-namespace string Unset application parameters in namespace -h, --help help for unset - --ignore-missing-components Unset the kustomize ignore-missing-components option (revert to false) --ignore-missing-value-files Unset the helm ignore-missing-value-files option (revert to false) --kustomize-image stringArray Kustomize images name (e.g. --kustomize-image node --kustomize-image mysql) --kustomize-namespace Kustomize namespace @@ -65,7 +64,7 @@ argocd app unset APPNAME parameters [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_app_wait.md b/docs/user-guide/commands/argocd_app_wait.md index 12ba15262d..5c2b3b5f8a 100644 --- a/docs/user-guide/commands/argocd_app_wait.md +++ b/docs/user-guide/commands/argocd_app_wait.md @@ -69,7 +69,7 @@ argocd app wait [APPNAME.. | -l selector] [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_appset.md b/docs/user-guide/commands/argocd_appset.md index ad19bfb8cc..5aa7905437 100644 --- a/docs/user-guide/commands/argocd_appset.md +++ b/docs/user-guide/commands/argocd_appset.md @@ -65,7 +65,7 @@ argocd appset [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_appset_create.md b/docs/user-guide/commands/argocd_appset_create.md index df0a41cca0..84dc245434 100644 --- a/docs/user-guide/commands/argocd_appset_create.md +++ b/docs/user-guide/commands/argocd_appset_create.md @@ -43,7 +43,7 @@ argocd appset create [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_appset_delete.md b/docs/user-guide/commands/argocd_appset_delete.md index 9339337d30..e2ce9650a4 100644 --- a/docs/user-guide/commands/argocd_appset_delete.md +++ b/docs/user-guide/commands/argocd_appset_delete.md @@ -38,7 +38,7 @@ argocd appset delete [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_appset_generate.md b/docs/user-guide/commands/argocd_appset_generate.md index a270058d7b..475a857a20 100644 --- a/docs/user-guide/commands/argocd_appset_generate.md +++ b/docs/user-guide/commands/argocd_appset_generate.md @@ -38,7 +38,7 @@ argocd appset generate [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_appset_get.md b/docs/user-guide/commands/argocd_appset_get.md index 6f6913cb09..b8b0138f01 100644 --- a/docs/user-guide/commands/argocd_appset_get.md +++ b/docs/user-guide/commands/argocd_appset_get.md @@ -39,7 +39,7 @@ argocd appset get APPSETNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_appset_list.md b/docs/user-guide/commands/argocd_appset_list.md index 6c5a30f1c3..3ec08080ef 100644 --- a/docs/user-guide/commands/argocd_appset_list.md +++ b/docs/user-guide/commands/argocd_appset_list.md @@ -41,7 +41,7 @@ argocd appset list [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_appset_update.md b/docs/user-guide/commands/argocd_appset_update.md new file mode 100644 index 0000000000..37a7e5dbe2 --- /dev/null +++ b/docs/user-guide/commands/argocd_appset_update.md @@ -0,0 +1,50 @@ +## argocd appset update + +Updates the given ApplicationSet(s) + +``` +argocd appset update [flags] +``` + +### Examples + +``` + + # Update ApplicationSet + argocd appset update (...) + +``` + +### Options + +``` + -h, --help help for update +``` + +### Options inherited from parent commands + +``` + --auth-token string Authentication token + --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") + --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. + --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. + -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) + --http-retry-max int Maximum number of retries to establish http connection to Argo CD server + --insecure Skip server certificate and domain verification + --kube-context string Directs the command to the given kube-context + --logformat string Set the logging format. One of: text|json (default "text") + --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") + --plaintext Disable TLS + --port-forward Connect to a random argocd-server port using port forwarding + --port-forward-namespace string Namespace name which should be used for port forwarding + --server string Argo CD server address + --server-crt string Server certificate file +``` + +### SEE ALSO + +* [argocd appset](argocd_appset.md) - Manage ApplicationSets + diff --git a/docs/user-guide/commands/argocd_cert.md b/docs/user-guide/commands/argocd_cert.md index 7b14744912..71e0517b5a 100644 --- a/docs/user-guide/commands/argocd_cert.md +++ b/docs/user-guide/commands/argocd_cert.md @@ -72,7 +72,7 @@ argocd cert [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_cert_add-ssh.md b/docs/user-guide/commands/argocd_cert_add-ssh.md index abfb6831e5..cb56846f3d 100644 --- a/docs/user-guide/commands/argocd_cert_add-ssh.md +++ b/docs/user-guide/commands/argocd_cert_add-ssh.md @@ -33,7 +33,7 @@ argocd cert add-ssh --batch [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_cert_add-tls.md b/docs/user-guide/commands/argocd_cert_add-tls.md index dcbd360d4d..90dd17e68e 100644 --- a/docs/user-guide/commands/argocd_cert_add-tls.md +++ b/docs/user-guide/commands/argocd_cert_add-tls.md @@ -32,7 +32,7 @@ argocd cert add-tls SERVERNAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_cert_list.md b/docs/user-guide/commands/argocd_cert_list.md index 2473f639b8..50691c78ff 100644 --- a/docs/user-guide/commands/argocd_cert_list.md +++ b/docs/user-guide/commands/argocd_cert_list.md @@ -34,7 +34,7 @@ argocd cert list [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_cert_rm.md b/docs/user-guide/commands/argocd_cert_rm.md index b4d71ff5fd..2f0a0c5e1c 100644 --- a/docs/user-guide/commands/argocd_cert_rm.md +++ b/docs/user-guide/commands/argocd_cert_rm.md @@ -32,7 +32,7 @@ argocd cert rm REPOSERVER [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_cli.md b/docs/user-guide/commands/argocd_cli.md new file mode 100644 index 0000000000..52f96a1ffd --- /dev/null +++ b/docs/user-guide/commands/argocd_cli.md @@ -0,0 +1,3 @@ +# ArgoCD Command Reference + +Argo CD command reference can be found [here](./argocd.md). \ No newline at end of file diff --git a/docs/user-guide/commands/argocd_cluster.md b/docs/user-guide/commands/argocd_cluster.md index 1563cc18a3..3fb60daa2c 100644 --- a/docs/user-guide/commands/argocd_cluster.md +++ b/docs/user-guide/commands/argocd_cluster.md @@ -69,7 +69,7 @@ argocd cluster [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_cluster_add.md b/docs/user-guide/commands/argocd_cluster_add.md index 5487fc870c..aac7ba7517 100644 --- a/docs/user-guide/commands/argocd_cluster_add.md +++ b/docs/user-guide/commands/argocd_cluster_add.md @@ -54,7 +54,7 @@ argocd cluster add CONTEXT [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_cluster_get.md b/docs/user-guide/commands/argocd_cluster_get.md index 23de30e5ce..171b250349 100644 --- a/docs/user-guide/commands/argocd_cluster_get.md +++ b/docs/user-guide/commands/argocd_cluster_get.md @@ -38,7 +38,7 @@ argocd cluster get in-cluster --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_cluster_list.md b/docs/user-guide/commands/argocd_cluster_list.md index 0e66b18548..7f19b0ec09 100644 --- a/docs/user-guide/commands/argocd_cluster_list.md +++ b/docs/user-guide/commands/argocd_cluster_list.md @@ -53,7 +53,7 @@ argocd cluster list -o server --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_cluster_rm.md b/docs/user-guide/commands/argocd_cluster_rm.md index b9281ab7f8..bfc10677e6 100644 --- a/docs/user-guide/commands/argocd_cluster_rm.md +++ b/docs/user-guide/commands/argocd_cluster_rm.md @@ -38,7 +38,7 @@ argocd cluster rm cluster-name --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_cluster_rotate-auth.md b/docs/user-guide/commands/argocd_cluster_rotate-auth.md index 26a6c1805b..d22a2092cf 100644 --- a/docs/user-guide/commands/argocd_cluster_rotate-auth.md +++ b/docs/user-guide/commands/argocd_cluster_rotate-auth.md @@ -37,7 +37,7 @@ argocd cluster rotate-auth cluster-name --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_cluster_set.md b/docs/user-guide/commands/argocd_cluster_set.md index 0a5429d4dd..2fb7a5b4f4 100644 --- a/docs/user-guide/commands/argocd_cluster_set.md +++ b/docs/user-guide/commands/argocd_cluster_set.md @@ -42,7 +42,7 @@ argocd cluster set NAME [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_completion.md b/docs/user-guide/commands/argocd_completion.md index a83ef02d9b..3ad61ff76c 100644 --- a/docs/user-guide/commands/argocd_completion.md +++ b/docs/user-guide/commands/argocd_completion.md @@ -65,7 +65,7 @@ $ source ~/.config/fish/completions/argocd.fish --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_configure.md b/docs/user-guide/commands/argocd_configure.md index d83e030595..41d778db90 100644 --- a/docs/user-guide/commands/argocd_configure.md +++ b/docs/user-guide/commands/argocd_configure.md @@ -61,7 +61,7 @@ argocd configure --prompts-enabled=false --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_context.md b/docs/user-guide/commands/argocd_context.md index e75620e337..44427d8844 100644 --- a/docs/user-guide/commands/argocd_context.md +++ b/docs/user-guide/commands/argocd_context.md @@ -44,7 +44,7 @@ argocd context cd.argoproj.io --delete --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_gpg.md b/docs/user-guide/commands/argocd_gpg.md index ddd8c0f48f..5f6edc1a53 100644 --- a/docs/user-guide/commands/argocd_gpg.md +++ b/docs/user-guide/commands/argocd_gpg.md @@ -49,7 +49,7 @@ argocd gpg [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_gpg_add.md b/docs/user-guide/commands/argocd_gpg_add.md index 3a504d067b..f7d3664a6e 100644 --- a/docs/user-guide/commands/argocd_gpg_add.md +++ b/docs/user-guide/commands/argocd_gpg_add.md @@ -38,7 +38,7 @@ argocd gpg add [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_gpg_get.md b/docs/user-guide/commands/argocd_gpg_get.md index d7089d32bc..c0b027f69f 100644 --- a/docs/user-guide/commands/argocd_gpg_get.md +++ b/docs/user-guide/commands/argocd_gpg_get.md @@ -44,7 +44,7 @@ argocd gpg get KEYID [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_gpg_list.md b/docs/user-guide/commands/argocd_gpg_list.md index e008b595e9..afbc750944 100644 --- a/docs/user-guide/commands/argocd_gpg_list.md +++ b/docs/user-guide/commands/argocd_gpg_list.md @@ -44,7 +44,7 @@ argocd gpg list [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_gpg_rm.md b/docs/user-guide/commands/argocd_gpg_rm.md index 43a1c221cc..3ac5793ed5 100644 --- a/docs/user-guide/commands/argocd_gpg_rm.md +++ b/docs/user-guide/commands/argocd_gpg_rm.md @@ -30,7 +30,7 @@ argocd gpg rm KEYID [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_login.md b/docs/user-guide/commands/argocd_login.md index 70c491a079..e189f47429 100644 --- a/docs/user-guide/commands/argocd_login.md +++ b/docs/user-guide/commands/argocd_login.md @@ -54,7 +54,7 @@ argocd login cd.argoproj.io --core --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_logout.md b/docs/user-guide/commands/argocd_logout.md index 6eab9e7f5e..18f9df7b74 100644 --- a/docs/user-guide/commands/argocd_logout.md +++ b/docs/user-guide/commands/argocd_logout.md @@ -43,7 +43,7 @@ $ argocd logout --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj.md b/docs/user-guide/commands/argocd_proj.md index 65d581e70d..2a751f2e04 100644 --- a/docs/user-guide/commands/argocd_proj.md +++ b/docs/user-guide/commands/argocd_proj.md @@ -65,7 +65,7 @@ argocd proj [flags] --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: json|text (default "json") + --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 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 8eb2f5d043..d966ab8201 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 @@ -41,7 +41,7 @@ argocd proj add-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ACC --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_add-destination.md b/docs/user-guide/commands/argocd_proj_add-destination.md index 3b28f7a095..9ffd63fca9 100644 --- a/docs/user-guide/commands/argocd_proj_add-destination.md +++ b/docs/user-guide/commands/argocd_proj_add-destination.md @@ -41,7 +41,7 @@ argocd proj add-destination PROJECT SERVER/NAME NAMESPACE [flags] --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: json|text (default "json") + --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 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 5ffaf8c25b..c0c2907dc9 100644 --- a/docs/user-guide/commands/argocd_proj_add-orphaned-ignore.md +++ b/docs/user-guide/commands/argocd_proj_add-orphaned-ignore.md @@ -41,7 +41,7 @@ argocd proj add-orphaned-ignore PROJECT GROUP KIND [flags] --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: json|text (default "json") + --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 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 1062264045..a6672e58c6 100644 --- a/docs/user-guide/commands/argocd_proj_add-signature-key.md +++ b/docs/user-guide/commands/argocd_proj_add-signature-key.md @@ -37,7 +37,7 @@ argocd proj add-signature-key PROJECT KEY-ID [flags] --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: json|text (default "json") + --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 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 5110e45617..a4dc0703e3 100644 --- a/docs/user-guide/commands/argocd_proj_add-source-namespace.md +++ b/docs/user-guide/commands/argocd_proj_add-source-namespace.md @@ -37,7 +37,7 @@ argocd proj add-source-namespace PROJECT NAMESPACE [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_add-source.md b/docs/user-guide/commands/argocd_proj_add-source.md index c4a39191fb..11bc2fbefd 100644 --- a/docs/user-guide/commands/argocd_proj_add-source.md +++ b/docs/user-guide/commands/argocd_proj_add-source.md @@ -37,7 +37,7 @@ argocd proj add-source PROJECT URL [flags] --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: json|text (default "json") + --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 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 c6b0f4b6c5..5e8d394b25 100644 --- a/docs/user-guide/commands/argocd_proj_allow-cluster-resource.md +++ b/docs/user-guide/commands/argocd_proj_allow-cluster-resource.md @@ -38,7 +38,7 @@ argocd proj allow-cluster-resource PROJECT GROUP KIND [flags] --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: json|text (default "json") + --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 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 4308db6a6d..36144a50a2 100644 --- a/docs/user-guide/commands/argocd_proj_allow-namespace-resource.md +++ b/docs/user-guide/commands/argocd_proj_allow-namespace-resource.md @@ -38,7 +38,7 @@ argocd proj allow-namespace-resource PROJECT GROUP KIND [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_create.md b/docs/user-guide/commands/argocd_proj_create.md index 4bb0eb1127..cb8a7fea23 100644 --- a/docs/user-guide/commands/argocd_proj_create.md +++ b/docs/user-guide/commands/argocd_proj_create.md @@ -54,7 +54,7 @@ argocd proj create PROJECT [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_delete.md b/docs/user-guide/commands/argocd_proj_delete.md index 1a244318fc..960316745e 100644 --- a/docs/user-guide/commands/argocd_proj_delete.md +++ b/docs/user-guide/commands/argocd_proj_delete.md @@ -37,7 +37,7 @@ argocd proj delete PROJECT [flags] --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: json|text (default "json") + --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 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 291fd6fd52..bc7e5d8d06 100644 --- a/docs/user-guide/commands/argocd_proj_deny-cluster-resource.md +++ b/docs/user-guide/commands/argocd_proj_deny-cluster-resource.md @@ -38,7 +38,7 @@ argocd proj deny-cluster-resource PROJECT GROUP KIND [flags] --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: json|text (default "json") + --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 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 6f4a7772b9..53d2a5c7cc 100644 --- a/docs/user-guide/commands/argocd_proj_deny-namespace-resource.md +++ b/docs/user-guide/commands/argocd_proj_deny-namespace-resource.md @@ -38,7 +38,7 @@ argocd proj deny-namespace-resource PROJECT GROUP KIND [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_edit.md b/docs/user-guide/commands/argocd_proj_edit.md index 7c9e744c08..f4a2705566 100644 --- a/docs/user-guide/commands/argocd_proj_edit.md +++ b/docs/user-guide/commands/argocd_proj_edit.md @@ -37,7 +37,7 @@ argocd proj edit PROJECT [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_get.md b/docs/user-guide/commands/argocd_proj_get.md index e1beec34af..0c24d16df9 100644 --- a/docs/user-guide/commands/argocd_proj_get.md +++ b/docs/user-guide/commands/argocd_proj_get.md @@ -41,7 +41,7 @@ argocd proj get PROJECT [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_list.md b/docs/user-guide/commands/argocd_proj_list.md index e8049d3c16..464ed3590e 100644 --- a/docs/user-guide/commands/argocd_proj_list.md +++ b/docs/user-guide/commands/argocd_proj_list.md @@ -41,7 +41,7 @@ argocd proj list [flags] --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: json|text (default "json") + --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 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 360404aa00..e4b0bd3aca 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 @@ -37,7 +37,7 @@ argocd proj remove-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_remove-destination.md b/docs/user-guide/commands/argocd_proj_remove-destination.md index ae548194fa..5824123472 100644 --- a/docs/user-guide/commands/argocd_proj_remove-destination.md +++ b/docs/user-guide/commands/argocd_proj_remove-destination.md @@ -37,7 +37,7 @@ argocd proj remove-destination PROJECT SERVER NAMESPACE [flags] --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: json|text (default "json") + --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 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 8aa431ccd4..e247b88aae 100644 --- a/docs/user-guide/commands/argocd_proj_remove-orphaned-ignore.md +++ b/docs/user-guide/commands/argocd_proj_remove-orphaned-ignore.md @@ -41,7 +41,7 @@ argocd proj remove-orphaned-ignore PROJECT GROUP KIND [flags] --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: json|text (default "json") + --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 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 cdc7ff68d8..cf538001cc 100644 --- a/docs/user-guide/commands/argocd_proj_remove-signature-key.md +++ b/docs/user-guide/commands/argocd_proj_remove-signature-key.md @@ -37,7 +37,7 @@ argocd proj remove-signature-key PROJECT KEY-ID [flags] --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: json|text (default "json") + --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 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 730b971f21..6c2b225fc6 100644 --- a/docs/user-guide/commands/argocd_proj_remove-source-namespace.md +++ b/docs/user-guide/commands/argocd_proj_remove-source-namespace.md @@ -37,7 +37,7 @@ argocd proj remove-source-namespace PROJECT NAMESPACE [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_remove-source.md b/docs/user-guide/commands/argocd_proj_remove-source.md index 4fa51746b1..aa3456fc40 100644 --- a/docs/user-guide/commands/argocd_proj_remove-source.md +++ b/docs/user-guide/commands/argocd_proj_remove-source.md @@ -37,7 +37,7 @@ argocd proj remove-source PROJECT URL [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_role.md b/docs/user-guide/commands/argocd_proj_role.md index 094d7025b5..b34583a380 100644 --- a/docs/user-guide/commands/argocd_proj_role.md +++ b/docs/user-guide/commands/argocd_proj_role.md @@ -30,7 +30,7 @@ argocd proj role [flags] --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: json|text (default "json") + --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 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 4fdc6d9d8a..4b52bba019 100644 --- a/docs/user-guide/commands/argocd_proj_role_add-group.md +++ b/docs/user-guide/commands/argocd_proj_role_add-group.md @@ -30,7 +30,7 @@ argocd proj role add-group PROJECT ROLE-NAME GROUP-CLAIM [flags] --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: json|text (default "json") + --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 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 36d2b4f07c..9cd2d25da0 100644 --- a/docs/user-guide/commands/argocd_proj_role_add-policy.md +++ b/docs/user-guide/commands/argocd_proj_role_add-policy.md @@ -62,7 +62,7 @@ ID ISSUED-AT EXPIRES-AT --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: json|text (default "json") + --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 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 b274ef6291..849e0e4cb7 100644 --- a/docs/user-guide/commands/argocd_proj_role_create-token.md +++ b/docs/user-guide/commands/argocd_proj_role_create-token.md @@ -45,7 +45,7 @@ Create token succeeded for proj:test-project:test-role. --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_role_create.md b/docs/user-guide/commands/argocd_proj_role_create.md index 32bd25d43c..268461007b 100644 --- a/docs/user-guide/commands/argocd_proj_role_create.md +++ b/docs/user-guide/commands/argocd_proj_role_create.md @@ -38,7 +38,7 @@ argocd proj role create PROJECT ROLE-NAME [flags] --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: json|text (default "json") + --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 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 38f31b5779..abb930a858 100644 --- a/docs/user-guide/commands/argocd_proj_role_delete-token.md +++ b/docs/user-guide/commands/argocd_proj_role_delete-token.md @@ -62,7 +62,7 @@ $ argocd proj role delete-token test-project test-role 1696769937 --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_role_delete.md b/docs/user-guide/commands/argocd_proj_role_delete.md index 572c0e4fb7..2915b02698 100644 --- a/docs/user-guide/commands/argocd_proj_role_delete.md +++ b/docs/user-guide/commands/argocd_proj_role_delete.md @@ -36,7 +36,7 @@ $ argocd proj role delete test-project test-role --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_role_get.md b/docs/user-guide/commands/argocd_proj_role_get.md index 6d65276044..9345df8bc1 100644 --- a/docs/user-guide/commands/argocd_proj_role_get.md +++ b/docs/user-guide/commands/argocd_proj_role_get.md @@ -45,7 +45,7 @@ ID ISSUED-AT EXPIRES-AT --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: json|text (default "json") + --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 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 1ce7bf3aff..a9fd374a1d 100644 --- a/docs/user-guide/commands/argocd_proj_role_list-tokens.md +++ b/docs/user-guide/commands/argocd_proj_role_list-tokens.md @@ -41,7 +41,7 @@ fa9d3517-c52d-434c-9bff-215b38508842 2023-10-08T11:08:18+01:00 Never --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_role_list.md b/docs/user-guide/commands/argocd_proj_role_list.md index e99d61d0be..b1e7870d5f 100644 --- a/docs/user-guide/commands/argocd_proj_role_list.md +++ b/docs/user-guide/commands/argocd_proj_role_list.md @@ -41,7 +41,7 @@ argocd proj role list PROJECT [flags] --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: json|text (default "json") + --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 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 daf888b42c..7383f884bc 100644 --- a/docs/user-guide/commands/argocd_proj_role_remove-group.md +++ b/docs/user-guide/commands/argocd_proj_role_remove-group.md @@ -30,7 +30,7 @@ argocd proj role remove-group PROJECT ROLE-NAME GROUP-CLAIM [flags] --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: json|text (default "json") + --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 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 9de0fc478d..912857a11c 100644 --- a/docs/user-guide/commands/argocd_proj_role_remove-policy.md +++ b/docs/user-guide/commands/argocd_proj_role_remove-policy.md @@ -62,7 +62,7 @@ ID ISSUED-AT EXPIRES-AT --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_set.md b/docs/user-guide/commands/argocd_proj_set.md index ee8854a407..00673df4d0 100644 --- a/docs/user-guide/commands/argocd_proj_set.md +++ b/docs/user-guide/commands/argocd_proj_set.md @@ -52,7 +52,7 @@ argocd proj set PROJECT [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_windows.md b/docs/user-guide/commands/argocd_proj_windows.md index dcc1dcbf36..098e89e0d7 100644 --- a/docs/user-guide/commands/argocd_proj_windows.md +++ b/docs/user-guide/commands/argocd_proj_windows.md @@ -18,7 +18,7 @@ argocd proj windows add my-project \ --duration 3600 \ --prune -#Delete a sync window from a project +#Delete a sync window from a project argocd proj windows delete #List project sync windows @@ -47,7 +47,7 @@ argocd proj windows list --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_windows_add.md b/docs/user-guide/commands/argocd_proj_windows_add.md index abf2f0b28e..e730bdada6 100644 --- a/docs/user-guide/commands/argocd_proj_windows_add.md +++ b/docs/user-guide/commands/argocd_proj_windows_add.md @@ -17,8 +17,7 @@ argocd proj windows add PROJECT \ --kind allow \ --schedule "0 22 * * *" \ --duration 1h \ - --applications "*" \ - --description "Ticket 123" + --applications "*" #Add a deny sync window with the ability to manually sync. argocd proj windows add PROJECT \ @@ -28,8 +27,7 @@ argocd proj windows add PROJECT \ --applications "prod-\\*,website" \ --namespaces "default,\\*-prod" \ --clusters "prod,staging" \ - --manual-sync \ - --description "Ticket 123" + --manual-sync ``` @@ -38,7 +36,6 @@ argocd proj windows add PROJECT \ ``` --applications strings Applications that the schedule will be applied to. Comma separated, wildcards supported (e.g. --applications prod-\*,website) --clusters strings Clusters that the schedule will be applied to. Comma separated, wildcards supported (e.g. --clusters prod,staging) - --description string Sync window description --duration string Sync window duration. (e.g. --duration 1h) -h, --help help for add -k, --kind string Sync window kind, either allow or deny @@ -46,7 +43,6 @@ argocd proj windows add PROJECT \ --namespaces strings Namespaces that the schedule will be applied to. Comma separated, wildcards supported (e.g. --namespaces default,\*-prod) --schedule string Sync window schedule in cron format. (e.g. --schedule "0 22 * * *") --time-zone string Time zone of the sync window (default "UTC") - --use-and-operator Use AND operator for matching applications, namespaces and clusters instead of the default OR operator ``` ### Options inherited from parent commands @@ -65,7 +61,7 @@ argocd proj windows add PROJECT \ --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_windows_delete.md b/docs/user-guide/commands/argocd_proj_windows_delete.md index 0275c23dbd..fe1f95834d 100644 --- a/docs/user-guide/commands/argocd_proj_windows_delete.md +++ b/docs/user-guide/commands/argocd_proj_windows_delete.md @@ -12,7 +12,7 @@ argocd proj windows delete PROJECT ID [flags] ``` -#Delete a sync window from a project (default) with ID 0 +#Delete a sync window from a project (default) with ID 0 argocd proj windows delete default 0 #Delete a sync window from a project (new-project) with ID 1 @@ -41,7 +41,7 @@ argocd proj windows delete new-project 1 --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: json|text (default "json") + --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 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 0616bd991c..27f95265de 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 @@ -16,8 +16,8 @@ argocd proj windows disable-manual-sync PROJECT ID [flags] ``` -#Disable manual sync for a sync window for the Project -argocd proj windows disable-manual-sync PROJECT ID +#Disable manual sync for a sync window for the Project +argocd proj windows disable-manual-sync PROJECT ID #Disabling manual sync for a windows set on the default project with Id 0 argocd proj windows disable-manual-sync default 0 @@ -45,7 +45,7 @@ argocd proj windows disable-manual-sync default 0 --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: json|text (default "json") + --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 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 18cb5fc26c..ba89c3d907 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 @@ -17,7 +17,7 @@ argocd proj windows enable-manual-sync PROJECT ID [flags] ``` #Enabling manual sync for a general case -argocd proj windows enable-manual-sync PROJECT ID +argocd proj windows enable-manual-sync PROJECT ID #Enabling manual sync for a windows set on the default project with Id 2 argocd proj windows enable-manual-sync default 2 @@ -48,7 +48,7 @@ argocd proj windows enable-manual-sync my-app-project --message "Manual sync ini --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_windows_list.md b/docs/user-guide/commands/argocd_proj_windows_list.md index ce454b05b4..9e2b1fab82 100644 --- a/docs/user-guide/commands/argocd_proj_windows_list.md +++ b/docs/user-guide/commands/argocd_proj_windows_list.md @@ -45,7 +45,7 @@ argocd proj windows list test-project --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_proj_windows_update.md b/docs/user-guide/commands/argocd_proj_windows_update.md index bfffcd30b7..63d5842ff2 100644 --- a/docs/user-guide/commands/argocd_proj_windows_update.md +++ b/docs/user-guide/commands/argocd_proj_windows_update.md @@ -26,7 +26,6 @@ argocd proj windows update PROJECT ID \ ``` --applications strings Applications that the schedule will be applied to. Comma separated, wildcards supported (e.g. --applications prod-\*,website) --clusters strings Clusters that the schedule will be applied to. Comma separated, wildcards supported (e.g. --clusters prod,staging) - --description string Sync window description --duration string Sync window duration. (e.g. --duration 1h) -h, --help help for update --namespaces strings Namespaces that the schedule will be applied to. Comma separated, wildcards supported (e.g. --namespaces default,\*-prod) @@ -50,7 +49,7 @@ argocd proj windows update PROJECT ID \ --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_relogin.md b/docs/user-guide/commands/argocd_relogin.md index 6efedd3406..0cf78260a6 100644 --- a/docs/user-guide/commands/argocd_relogin.md +++ b/docs/user-guide/commands/argocd_relogin.md @@ -54,7 +54,7 @@ argocd login cd.argoproj.io --core --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_repo.md b/docs/user-guide/commands/argocd_repo.md index 58367f8241..d211c4ccd1 100644 --- a/docs/user-guide/commands/argocd_repo.md +++ b/docs/user-guide/commands/argocd_repo.md @@ -67,7 +67,7 @@ argocd repo rm https://github.com/yourusername/your-repo.git --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_repo_add.md b/docs/user-guide/commands/argocd_repo_add.md index d0a885720d..ea93d6f87e 100644 --- a/docs/user-guide/commands/argocd_repo_add.md +++ b/docs/user-guide/commands/argocd_repo_add.md @@ -52,7 +52,6 @@ argocd repo add REPOURL [flags] ### Options ``` - --bearer-token string bearer token to the Git BitBucket Data Center repository --enable-lfs enable git-lfs (Large File Support) on this repository --enable-oci enable helm-oci (Helm OCI-Based Repository) --force-http-basic-auth whether to force use of basic auth when connecting repository via HTTP @@ -74,7 +73,6 @@ argocd repo add REPOURL [flags] --tls-client-cert-path string path to the TLS client cert (must be PEM format) --type string type of the repository, "git" or "helm" (default "git") --upsert Override an existing repository with the same name even if the spec differs - --use-azure-workload-identity whether to use azure workload identity for authentication --username string username to the repository ``` @@ -94,7 +92,7 @@ argocd repo add REPOURL [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_repo_get.md b/docs/user-guide/commands/argocd_repo_get.md index 2f5191f8ee..2efac6344d 100644 --- a/docs/user-guide/commands/argocd_repo_get.md +++ b/docs/user-guide/commands/argocd_repo_get.md @@ -33,7 +33,7 @@ argocd repo get [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_repo_list.md b/docs/user-guide/commands/argocd_repo_list.md index b2d620ec28..60346b7623 100644 --- a/docs/user-guide/commands/argocd_repo_list.md +++ b/docs/user-guide/commands/argocd_repo_list.md @@ -32,7 +32,7 @@ argocd repo list [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_repo_rm.md b/docs/user-guide/commands/argocd_repo_rm.md index d55bdca01f..d475e3e02a 100644 --- a/docs/user-guide/commands/argocd_repo_rm.md +++ b/docs/user-guide/commands/argocd_repo_rm.md @@ -31,7 +31,7 @@ argocd repo rm REPO [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_repocreds.md b/docs/user-guide/commands/argocd_repocreds.md index 7eb62f9319..6bd8842700 100644 --- a/docs/user-guide/commands/argocd_repocreds.md +++ b/docs/user-guide/commands/argocd_repocreds.md @@ -2,7 +2,7 @@ ## argocd repocreds -Manage credential templates for repositories +Manage repository connection parameters ``` argocd repocreds [flags] @@ -62,7 +62,7 @@ argocd repocreds [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/commands/argocd_repocreds_add.md b/docs/user-guide/commands/argocd_repocreds_add.md index 033f6de091..290351132a 100644 --- a/docs/user-guide/commands/argocd_repocreds_add.md +++ b/docs/user-guide/commands/argocd_repocreds_add.md @@ -14,9 +14,6 @@ argocd repocreds add REPOURL [flags] # Add credentials with user/pass authentication to use for all repositories under https://git.example.com/repos argocd repocreds add https://git.example.com/repos/ --username git --password secret - # Add credentials with bearer token authentication to use for all BitBucket Data Center repositories under https://bitbucket.example.com/scm - argocd repocreds add https://bitbucket.example.com/scm/ --bearer-token secret-token - # Add credentials with SSH private key authentication to use for all repositories under ssh://git@git.example.com/repos argocd repocreds add ssh://git@git.example.com/repos/ --ssh-private-key-path ~/.ssh/id_rsa @@ -37,7 +34,6 @@ argocd repocreds add REPOURL [flags] ### Options ``` - --bearer-token string bearer token to the Git repository --enable-oci Specifies whether helm-oci support should be enabled for this repo --force-http-basic-auth whether to force basic auth when connecting via HTTP --gcp-service-account-key-path string service account key for the Google Cloud Platform @@ -53,7 +49,6 @@ argocd repocreds add REPOURL [flags] --tls-client-cert-path string path to the TLS client cert (must be PEM format) --type string type of the repository, "git" or "helm" (default "git") --upsert Override an existing repository with the same name even if the spec differs - --use-azure-workload-identity whether to use azure workload identity for authentication --username string username to the repository ``` @@ -73,7 +68,7 @@ argocd repocreds add REPOURL [flags] --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: json|text (default "json") + --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 @@ -90,5 +85,5 @@ argocd repocreds add REPOURL [flags] ### SEE ALSO -* [argocd repocreds](argocd_repocreds.md) - Manage credential templates for repositories +* [argocd repocreds](argocd_repocreds.md) - Manage repository connection parameters diff --git a/docs/user-guide/commands/argocd_repocreds_list.md b/docs/user-guide/commands/argocd_repocreds_list.md index ef4fe2469d..f860c410cd 100644 --- a/docs/user-guide/commands/argocd_repocreds_list.md +++ b/docs/user-guide/commands/argocd_repocreds_list.md @@ -47,7 +47,7 @@ argocd repocreds list [flags] --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: json|text (default "json") + --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 @@ -64,5 +64,5 @@ argocd repocreds list [flags] ### SEE ALSO -* [argocd repocreds](argocd_repocreds.md) - Manage credential templates for repositories +* [argocd repocreds](argocd_repocreds.md) - Manage repository connection parameters diff --git a/docs/user-guide/commands/argocd_repocreds_rm.md b/docs/user-guide/commands/argocd_repocreds_rm.md index e2610cd48d..a27d7371f2 100644 --- a/docs/user-guide/commands/argocd_repocreds_rm.md +++ b/docs/user-guide/commands/argocd_repocreds_rm.md @@ -37,7 +37,7 @@ argocd repocreds rm CREDSURL [flags] --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: json|text (default "json") + --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 @@ -54,5 +54,5 @@ argocd repocreds rm CREDSURL [flags] ### SEE ALSO -* [argocd repocreds](argocd_repocreds.md) - Manage credential templates for repositories +* [argocd repocreds](argocd_repocreds.md) - Manage repository connection parameters diff --git a/docs/user-guide/commands/argocd_version.md b/docs/user-guide/commands/argocd_version.md index 5a248d1416..9a26aa051f 100644 --- a/docs/user-guide/commands/argocd_version.md +++ b/docs/user-guide/commands/argocd_version.md @@ -69,7 +69,7 @@ argocd version [flags] --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: json|text (default "json") + --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 diff --git a/docs/user-guide/diff-strategies.md b/docs/user-guide/diff-strategies.md index 79711c6f20..48cd4893d3 100644 --- a/docs/user-guide/diff-strategies.md +++ b/docs/user-guide/diff-strategies.md @@ -17,14 +17,16 @@ Argo CD currently has 3 different strategies to calculate diffs: ## Structured-Merge Diff -!!! warning "Feature Discontinued" - After different issues were identified by the community, this strategy is being discontinued in favour of Server-Side Diff. +!!! 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 -that define default values. +that define default values. After different issues were identified by +the community, this strategy is being discontinued in favour of +Server-Side Diff. ## Server-Side Diff @@ -48,12 +50,6 @@ a validation webhook identifies a resource to be invalid, that will be informed to Argo CD during the diff stage rather than during the sync stage. -Note that Server-Side Diff will not be performed during the creation of new resources. -This is to save an additional call to KubeAPI and provide a much lighter and faster diff calculation -(Non-Server-Side Apply) when resources don't exist to compare against. During resource creation performing a -Server-Side Diff won't have the benefit of the Kubernetes Admission Controller in the diff stage as validation webhooks -won't be executed when calculating diffs if the resource is not applied in the cluster yet. - ### Enabling it Server-Side Diff can be enabled at the Argo CD Controller level or per @@ -63,7 +59,7 @@ Application. Add the following entry in the argocd-cmd-params-cm configmap: -```yaml +``` apiVersion: v1 kind: ConfigMap metadata: @@ -80,7 +76,7 @@ after applying this configuration. Add the following annotation in the Argo CD Application resource: -```yaml +``` apiVersion: argoproj.io/v1alpha1 kind: Application metadata: @@ -95,7 +91,7 @@ If Server-Side Diff is enabled globally in your Argo CD instance, it is possible to disable it at the application level. In order to do so, add the following annotation in the Application resource: -```yaml +``` apiVersion: argoproj.io/v1alpha1 kind: Application metadata: @@ -113,7 +109,7 @@ Server-Side Diff does not include changes made by mutation webhooks by default. If you want to include mutation webhooks in Argo CD diffs add the following annotation in the Argo CD Application resource: -```yaml +``` apiVersion: argoproj.io/v1alpha1 kind: Application metadata: @@ -126,7 +122,7 @@ Note: This annotation is only effective when Server-Side Diff is enabled. To enable both options for a given application add the following annotation in the Argo CD Application resource: -```yaml +``` apiVersion: argoproj.io/v1alpha1 kind: Application metadata: diff --git a/docs/user-guide/diffing.md b/docs/user-guide/diffing.md index f9c0c45f74..895f330dfc 100644 --- a/docs/user-guide/diffing.md +++ b/docs/user-guide/diffing.md @@ -2,14 +2,14 @@ It is possible for an application to be `OutOfSync` even immediately after a successful Sync operation. Some reasons for this might be: -- There is a bug in the manifest, where it contains extra/unknown fields from the actual K8s spec. These extra fields would get dropped when querying Kubernetes for the live state, - resulting in an `OutOfSync` status indicating a missing field was detected. -- The sync was performed (with pruning disabled), and there are resources which need to be deleted. -- A controller or [mutating webhook](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook) is altering the object after it was - submitted to Kubernetes so it differs from the one in Git. -- A Helm chart is using a template function such as [`randAlphaNum`](https://github.com/helm/charts/blob/master/stable/redis/templates/secret.yaml#L16), - which generates different data every time `helm template` is invoked. -- For Horizontal Pod Autoscaling (HPA) objects, the HPA controller is known to reorder `spec.metrics` +* There is a bug in the manifest, where it contains extra/unknown fields from the actual K8s spec. These extra fields would get dropped when querying Kubernetes for the live state, +resulting in an `OutOfSync` status indicating a missing field was detected. +* The sync was performed (with pruning disabled), and there are resources which need to be deleted. +* A controller or [mutating webhook](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook) is altering the object after it was +submitted to Kubernetes in a manner which contradicts Git. +* A Helm chart is using a template function such as [`randAlphaNum`](https://github.com/helm/charts/blob/master/stable/redis/templates/secret.yaml#L16), +which generates different data every time `helm template` is invoked. +* For Horizontal Pod Autoscaling (HPA) objects, the HPA controller is known to reorder `spec.metrics` in a specific order. See [kubernetes issue #74099](https://github.com/kubernetes/kubernetes/issues/74099). To work around this, you can order `spec.metrics` in Git in the same order that the controller prefers. @@ -19,17 +19,17 @@ The diffing customization can be configured for single or multiple application r ## Application Level Configuration -Argo CD allows ignoring differences at a specific JSON path, using [RFC6902 JSON patches](https://tools.ietf.org/html/rfc6902) and [JQ path expressions](). It is also possible to ignore differences from fields owned by specific managers defined in `metadata.managedFields` in live resources. +Argo CD allows ignoring differences 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 is also possible to ignore differences from fields owned by specific managers defined in `metadata.managedFields` in live resources. The following sample application is configured to ignore differences in `spec.replicas` for all deployments: ```yaml spec: ignoreDifferences: - - group: apps - kind: Deployment - jsonPointers: - - /spec/replicas + - group: apps + kind: Deployment + jsonPointers: + - /spec/replicas ``` Note that the `group` field relates to the [Kubernetes API group](https://kubernetes.io/docs/reference/using-api/#api-groups) without the version. @@ -38,34 +38,32 @@ The above customization could be narrowed to a resource with the specified name ```yaml spec: ignoreDifferences: - - group: apps - kind: Deployment - name: guestbook - namespace: default - jsonPointers: - - /spec/replicas + - group: apps + kind: Deployment + name: guestbook + namespace: default + jsonPointers: + - /spec/replicas ``` To ignore elements of a list, you can use JQ path expressions to identify list items based on item content: - ```yaml spec: ignoreDifferences: - - group: apps - kind: Deployment - jqPathExpressions: - - .spec.template.spec.initContainers[] | select(.name == "injected-init-container") + - group: apps + kind: Deployment + jqPathExpressions: + - .spec.template.spec.initContainers[] | select(.name == "injected-init-container") ``` To ignore fields owned by specific managers defined in your live resources: - ```yaml spec: ignoreDifferences: - - group: '*' - kind: '*' - managedFieldsManagers: - - kube-controller-manager + - group: "*" + kind: "*" + managedFieldsManagers: + - kube-controller-manager ``` The above configuration will ignore differences from all fields owned by `kube-controller-manager` for all resources belonging to this application. @@ -75,9 +73,9 @@ If you have a slash `/` in your pointer path, you need to replace it with the `~ ```yaml spec: ignoreDifferences: - - kind: Node - jsonPointers: - - /metadata/labels/node-role.kubernetes.io~1worker + - kind: Node + jsonPointers: + - /metadata/labels/node-role.kubernetes.io~1worker ``` ## System-Level Configuration @@ -88,13 +86,12 @@ of a `MutatingWebhookConfiguration` webhooks: ```yaml data: - resource.customizations.ignoreDifferences.admissionregistration.k8s.io_MutatingWebhookConfiguration: - | + resource.customizations.ignoreDifferences.admissionregistration.k8s.io_MutatingWebhookConfiguration: | jqPathExpressions: - '.webhooks[]?.clientConfig.caBundle' ``` -Resource customization can also be configured to ignore all differences made by a `managedField.manager` at the system level. The example below shows how to configure Argo CD to ignore changes made by `kube-controller-manager` in `Deployment` resources. +Resource customization can also be configured to ignore all differences made by a managedField.manager at the system level. The example below shows how to configure Argo CD to ignore changes made by `kube-controller-manager` in `Deployment` resources. ```yaml data: @@ -103,7 +100,7 @@ data: - kube-controller-manager ``` -It is possible to configure `ignoreDifferences` to be applied to all resources in every Application managed by an Argo CD instance. In order to do so, resource customizations can be configured like in the example below: +It is possible to configure ignoreDifferences to be applied to all resources in every Application managed by an Argo CD instance. In order to do so, resource customizations can be configured like in the example below: ```yaml data: @@ -114,23 +111,20 @@ data: - /spec/replicas ``` -The `status` field of many resources is often stored in Git/Helm manifest and should be ignored during diffing. The `status` field is used by -Kubernetes controller to persist the current state of the resource and therefore cannot be applied as a desired configuration. +The `status` field of `CustomResourceDefinitions` is often stored in Git/Helm manifest and should be ignored during diffing. The `ignoreResourceStatusField` setting simplifies +handling that edge case: ```yaml data: resource.compareoptions: | # disables status field diffing in specified resource types - # 'crd' - CustomResourceDefinitions - # 'all' - all resources (default) + # 'crd' - CustomResourceDefinitions (default) + # 'all' - all resources # 'none' - disabled - ignoreResourceStatusField: all + ignoreResourceStatusField: crd ``` -If you rely on the status field being part of your desired state, although this is not recommended, the `ignoreResourceStatusField` setting can be used to configure this behavior. - -!!! note - Since it is common for `CustomResourceDefinitions` to have their `status` commited to Git, consider using `crd` over `none`. +By default `status` field is ignored during diffing for `CustomResourceDefinition` resource. The behavior can be extended to all resources using `all` value or disabled using `none`. ### Ignoring RBAC changes made by AggregateRoles @@ -157,7 +151,6 @@ A typical example is the `argoproj.io/Rollout` CRD that re-using `core/v1/PodSpe might be reformatted by the custom marshaller of `IntOrString` data type: from: - ```yaml resources: requests: @@ -165,7 +158,6 @@ resources: ``` to: - ```yaml resources: requests: @@ -192,8 +184,9 @@ data: The list of supported Kubernetes types is available in [diffing_known_types.txt](https://raw.githubusercontent.com/argoproj/argo-cd/master/util/argo/normalizers/diffing_known_types.txt) and additionally: -- `core/Quantity` -- `meta/v1/duration` +* `core/Quantity` +* `meta/v1/duration` + ### JQ Path expression timeout @@ -205,5 +198,5 @@ kind: ConfigMap metadata: name: argocd-cmd-params-cm data: - ignore.normalizer.jq.timeout: '5s' + ignore.normalizer.jq.timeout: "5s" ``` diff --git a/docs/user-guide/gpg-verification.md b/docs/user-guide/gpg-verification.md index 892b92059a..f0881df0f0 100644 --- a/docs/user-guide/gpg-verification.md +++ b/docs/user-guide/gpg-verification.md @@ -211,7 +211,7 @@ argocd proj remove-signature-key myproj 4AEE18F83AFDEB23 #### Showing allowed key IDs for a project To see which key IDs are allowed for a given project, you can inspect the -output of the `argocd proj get` command, i.e. for a project named `gpg`: +output of the `argocd proj get` command, i.e for a project named `gpg`: ```bash $ argocd proj get gpg diff --git a/docs/user-guide/helm.md b/docs/user-guide/helm.md index 57db713dbd..938a1d318c 100644 --- a/docs/user-guide/helm.md +++ b/docs/user-guide/helm.md @@ -1,4 +1,4 @@ - # Helm +# Helm ## Declarative @@ -42,7 +42,7 @@ spec: namespace: nginx ``` -!!! note "When using Helm there are multiple ways to provide values" +!!! note "When using multiple ways to provide values" Order of precedence is `parameters > valuesObject > values > valueFiles > helm repository values.yaml` (see [Here](./helm.md#helm-value-precedence) for a more detailed example) See [here](../operator-manual/declarative-setup.md#helm-chart-repositories) for more info about how to configure private Helm repositories. @@ -170,18 +170,18 @@ Values injections have the following order of precedence highest -> parameters ``` -So valuesObject trumps values - therefore values will be ignored, and both valuesObject and values trump valueFiles. -Parameters trump all of them. +so values/valuesObject trumps valueFiles, and parameters trump both. -Precedence of multiple valueFiles: -When multiple valueFiles are specified, the last file listed has the highest precedence: +Precedence of valueFiles themselves is the order they are defined in ``` +if we have + valueFiles: - values-file-2.yaml - values-file-1.yaml -In this case, values-file-1.yaml will override values from values-file-2.yaml. +the last values-file i.e. values-file-1.yaml will trump the first ``` When multiple of the same key are found the last one wins i.e @@ -390,9 +390,9 @@ RUN helm plugin install ${GCS_PLUGIN_REPO} --version ${GCS_PLUGIN_VERSION} ENV HELM_PLUGINS="/home/argocd/.local/share/helm/plugins/" ``` -The `HELM_PLUGINS` environment property required for ArgoCD to locale plugins correctly. +You have to remember about `HELM_PLUGINS` environment property - this is required for plugins to work correctly. -Once built, use the custom image for ArgoCD installation. +After that you have to use your custom image for ArgoCD installation. ### Using `initContainers` Another option is to install Helm plugins via Kubernetes `initContainers`. @@ -519,6 +519,7 @@ spec: ``` + ## 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. @@ -536,4 +537,4 @@ spec: source: helm: skipTests: true # or false -``` +``` \ No newline at end of file diff --git a/docs/user-guide/how_phases_work.png b/docs/user-guide/how_phases_work.png deleted file mode 100644 index 26e0608f6d..0000000000 Binary files a/docs/user-guide/how_phases_work.png and /dev/null differ diff --git a/docs/user-guide/how_waves_work.png b/docs/user-guide/how_waves_work.png deleted file mode 100644 index ffc898d61f..0000000000 Binary files a/docs/user-guide/how_waves_work.png and /dev/null differ diff --git a/docs/user-guide/kustomize.md b/docs/user-guide/kustomize.md index d515dab519..100622cf03 100644 --- a/docs/user-guide/kustomize.md +++ b/docs/user-guide/kustomize.md @@ -29,8 +29,7 @@ The following configuration options are available for Kustomize: * `images` is a list of Kustomize image overrides * `replicas` is a list of Kustomize replica overrides * `commonLabels` is a string map of additional labels -* `labelWithoutSelector` is a boolean value which defines if the common label(s) should be applied to resource selectors. It also excludes common labels from templates unless `labelIncludeTemplates` is set to true. -* `labelIncludeTemplates` is a boolean value which defines if the common label(s) should be applied to resource templates. +* `labelWithoutSelector` is a boolean value which defines if the common label(s) should be applied to resource selectors and templates. * `forceCommonLabels` is a boolean value which defines if it's allowed to override existing labels * `commonAnnotations` is a string map of additional annotations * `namespace` is a Kubernetes resources namespace @@ -38,7 +37,6 @@ The following configuration options are available for Kustomize: * `commonAnnotationsEnvsubst` is a boolean value which enables env variables substition in annotation values * `patches` is a list of Kustomize patches that supports inline updates * `components` is a list of Kustomize components -* `ignoreMissingComponents` prevents kustomize from failing when components do not exist locally by not appending them to kustomization file To use Kustomize with an overlay, point your path to the overlay. @@ -132,8 +130,7 @@ spec: ``` ## Components -Kustomize [components](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/components.md) encapsulate both resources and patches together. They provide a powerful way to modularize and reuse configuration in Kubernetes applications. -If Kustomize is passed a non-existing component directory, it will error out. Missing component directories can be ignored (meaning, not passed to Kustomize) using `ignoreMissingComponents`. This can be particularly helpful to implement a [default/override pattern]. +Kustomize [components](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/components.md) encapsulate both resources and patches together. They provide a powerful way to modularize and reuse configuration in Kubernetes applications. Outside of Argo CD, to utilize components, you must add the following to the `kustomization.yaml` that the Application references. For example: ```yaml @@ -161,7 +158,6 @@ spec: kustomize: components: - ../component # relative to the kustomization.yaml (`source.path`). - ignoreMissingComponents: true ``` ## Private Remote Bases diff --git a/docs/user-guide/multiple_sources.md b/docs/user-guide/multiple_sources.md index 5be7cb5136..4d7f1f7ea4 100644 --- a/docs/user-guide/multiple_sources.md +++ b/docs/user-guide/multiple_sources.md @@ -74,13 +74,14 @@ In the above example, the `prometheus` chart will use the value file from `git.e For Argo to reference the external Git repository containing the value files, you must set the `ref` parameter on the repository. In the above example, the parameter `ref: values` maps to the variable `$values`, which resolves to the root of the `value-files` repository. -Note that the `$values` variable can only be used at the beginning of the value file path and that its path is always relative to the root of the referenced source. +Note that the `$values` variable can only be used at the beginning of the value file path. If the `path` field is set in the `$values` source, Argo CD will attempt to generate resources from the git repository at that URL. If the `path` field is not set, Argo CD will use the repository solely as a source of value files. !!! note - Sources with the `ref` field set cannot include the `chart` field. Currently, Argo CD does not support using another Helm chart as a source for value files. + Sources with the `ref` field set must not also specify the `chart` field. Argo CD does not currently support using + another Helm chart as a source for value files. !!! note Even when the `ref` field is configured with the `path` field, `$value` still represents the root of sources with the `ref` field. Consequently, `valueFiles` must be specified as relative paths from the root of sources. diff --git a/docs/user-guide/parameters.md b/docs/user-guide/parameters.md index 54ff471bea..3b892782b8 100644 --- a/docs/user-guide/parameters.md +++ b/docs/user-guide/parameters.md @@ -26,8 +26,8 @@ argocd app set guestbook -p ingress.enabled=true argocd app set guestbook -p ingress.hosts[0]=guestbook.myclusterurl ``` -The `argocd app set` [command](./commands/argocd_app_set.md) supports more tool-specific flags such as `--kustomize-image`, `--jsonnet-ext-var-str`, etc. -You can also specify overrides directly in the source field on the application spec. Read more about supported options in the corresponding tool [documentation](./application_sources.md). +The `argocd app set` [command](./commands/argocd_app_set.md) supports more tool-specific flags such as `--kustomize-image`, `--jsonnet-ext-var-str` etc +flags. You can also specify overrides directly in the source field on application spec. Read more about supported options in corresponded tool [documentation](./application_sources.md). ## When To Use Overrides? @@ -65,7 +65,7 @@ Example: ```yaml kustomize: images: - - quay.io/argoprojlabs/argocd-e2e-container:0.2 + - gcr.io/heptio-images/ks-guestbook-demo:0.2 ``` The `.argocd-source` is trying to solve two following main use cases: @@ -81,7 +81,7 @@ are sourcing multiple applications from a single path in your repository. The application specific file must be named `.argocd-source-.yaml`, where `` is the name of the application the overrides are valid for. -If there exists a non-application specific `.argocd-source.yaml`, parameters +If there exists an non-application specific `.argocd-source.yaml`, parameters included in that file will be merged first, and then the application specific parameters are merged, which can also contain overrides to the parameters stored in the non-application specific file. diff --git a/docs/user-guide/plugins.md b/docs/user-guide/plugins.md deleted file mode 100644 index 74db1b6c97..0000000000 --- a/docs/user-guide/plugins.md +++ /dev/null @@ -1,201 +0,0 @@ -# Plugins - -## Overview - -This guide demonstrates how to write plugins for the -`argocd` CLI tool. Plugins are a way to extend `argocd` CLI with new sub-commands, -allowing for custom features which are not part of the default distribution -of the `argocd` CLI.. - -If you would like to take a look at the original proposal, head over to this [enhancement proposal](../proposals/argocd-cli-pluin.md). -It covers how the plugin mechanism works, its benefits, motivations, and the goals it aims to achieve. - -## Prerequisites - -You need to have a working `argocd` binary installed locally. You can follow -the [cli installation documentation](https://argo-cd.readthedocs.io/en/stable/cli_installation/) to install the binary. - -## Create `argocd` plugins - -A plugin is a standalone executable file whose name begins with argocd-. -To install a plugin, move its executable file to any directory included in your PATH. -Ensure that the PATH configuration specifies the full absolute path to the executable, -not a relative path. `argocd` allows plugins to add custom commands such as -`argocd my-plugin arg1 arg2 --flag1` by executing a `argocd-my-plugin` binary in the PATH. - -## Limitations - -1. It is currently not possible to create plugins that overwrite existing -`argocd` commands. For example, creating a plugin such as `argocd-version` -will cause the plugin to never get executed, as the existing `argocd version` -command will always take precedence over it. Due to this limitation, it is -also not possible to use plugins to add new subcommands to existing `argocd` commands. -For example, adding a subcommand `argocd cluster upgrade` by naming your plugin -`argocd-cluster` will cause the plugin to be ignored. - -2. It is currently not possible to parse the global flags set by `argocd` CLI. For example, -if you have set any global flag value such as `--logformat` value to `text`, the plugin will -not parse the global flags and pass the default value to the `--logformat` flag which is `json`. -The flag parsing will work exactly the same way for existing `argocd` commands which means executing a -existing argocd command such as `argocd cluster list` will correctly parse the flag value as `text`. - -## Conditions for an `argocd` plugin - -Any binary that you would want to execute as an `argocd` plugin need to satisfy the following three conditions: - -1. The binary should start with `argocd-` as the prefix name. For example, - `argocd-demo-plugin` or `argocd-demo_plugin` is a valid binary name but not - `argocd_demo-plugin` or `argocd_demo_plugin`. -2. The binary should have executable permissions otherwise it will be ignored. -3. The binary should reside anywhere in the system's absolute PATH. - -## Writing `argocd` plugins - -### Naming a plugin - -An Argo CD plugin’s filename must start with `argocd-`. The subcommands implemented -by the plugin are determined by the portion of the filename after the `argocd-` prefix. -Anything after `argocd-` will become a subcommand for `argocd`. - -For example, A plugin named `argocd-demo-plugin` is invoked when the user types: -```bash -argocd demo-plugin [args] [flags] -``` - -The `argocd` CLI determines which plugin to invoke based on the subcommands provided. - -For example, executing the following command: -```bash -argocd my-custom-command [args] [flags] -``` -will lead to the execution of plugin named `argocd-my-custom-command` if it is present in the PATH. - -### Writing a plugin - -A plugin can be written in any programming language or script that allows you to write command-line commands. - -A plugin determines which command path it wishes to implement based on its name. - -For example, If a binary named `argocd-demo-plugin` is available in your system's absolute PATH, and the user runs the following command: - -```bash -argocd demo-plugin subcommand1 --flag=true -``` - -Argo CD will translate and execute the corresponding plugin with the following command: - -```bash -argocd-demo-plugin subcommand1 --flag=true -``` - -Similarly, if a plugin named `argocd-demo-demo-plugin` is found in the absolute PATH, and the user invokes: - -```bash -argocd demo-demo-plugin subcommand2 subcommand3 --flag=true -``` - -Argo CD will execute the plugin as: - -```bash -argocd-demo-demo-plugin subcommand2 subcommand3 --flag=true -``` - -### Example plugin -```bash -#!/bin/bash - -# Check if the argocd CLI is installed -if ! command -v argocd &> /dev/null; then - echo "Error: Argo CD CLI (argocd) is not installed. Please install it first." - exit 1 -fi - -if [[ "$1" == "version" ]] -then - echo "displaying argocd version..." - argocd version - exit 0 -fi - - -echo "I am a plugin named argocd-foo" -``` - -### Using a plugin - -To use a plugin, make the plugin executable: -```bash -sudo chmod +x ./argocd-foo -``` - -and place it anywhere in your `PATH`: -```bash -sudo mv ./argocd-foo /usr/local/bin -``` - -You may now invoke your plugin as a argocd command: -```bash -argocd foo -``` - -This would give the following output -```bash -I am a plugin named argocd-foo -``` - -All args and flags are passed as-is to the executable: -```bash -argocd foo version -``` - -This would give the following output -```bash -DEBU[0000] command does not exist, looking for a plugin... -displaying argocd version... -2025/01/16 13:24:36 maxprocs: Leaving GOMAXPROCS=16: CPU quota undefined -argocd: v2.13.0-rc2+0f083c9 - BuildDate: 2024-09-20T11:59:25Z - GitCommit: 0f083c9e58638fc292cf064e294a1aa53caa5630 - GitTreeState: clean - GoVersion: go1.22.7 - Compiler: gc - Platform: linux/amd64 -argocd-server: v2.13.0-rc2+0f083c9 - BuildDate: 2024-09-20T11:59:25Z - GitCommit: 0f083c9e58638fc292cf064e294a1aa53caa5630 - GitTreeState: clean - GoVersion: go1.22.7 - Compiler: gc - Platform: linux/amd64 - Kustomize Version: v5.4.3 2024-07-19T16:40:33Z - Helm Version: v3.15.2+g1a500d5 - Kubectl Version: v0.31.0 - Jsonnet Version: v0.20.0 -``` - -## Distributing `argocd` plugins - -If you’ve developed an Argo CD plugin for others to use, -you should carefully consider how to package, distribute, and -deliver updates to ensure a smooth installation and upgrade process -for your users. - -### Native / platform specific package management - -You can distribute your plugin using traditional package managers, -such as `apt` or `yum` for Linux, `Chocolatey` for Windows, and `Homebrew` for macOS. -These package managers are well-suited for distributing plugins as they can -place executables directly into the user's PATH, making them easily accessible. - -However, as a plugin author, choosing this approach comes with the responsibility of -maintaining and updating the plugin's distribution packages across multiple platforms -for every release. This includes testing for compatibility, ensuring timely updates, -and managing versioning to provide a seamless experience for your users. - -### Source code - -You can publish the source code of your plugin, for example, -in a Git repository. This allows users to access and inspect -the code directly. Users who want to install the plugin will need -to fetch the code, set up a suitable build environment (if the plugin requires compiling), -and manually deploy it. diff --git a/docs/user-guide/private-repositories.md b/docs/user-guide/private-repositories.md index 44514faf5f..074e5caad9 100644 --- a/docs/user-guide/private-repositories.md +++ b/docs/user-guide/private-repositories.md @@ -63,7 +63,7 @@ Of course, you can also use this in combination with the `--username` and `--pas Your TLS client certificate and corresponding key can also be configured using the UI, see instructions for adding Git repos using HTTPS. !!! note - Your client certificate and key data must be in PEM format, other formats (such as PKCS12) are not supported. Also make sure that your certificate's key is not password protected, otherwise it cannot be used by Argo CD. + Your client certificate and key data must be in PEM format, other formats (such as PKCS12) are not understood. Also make sure that your certificate's key is not password protected, otherwise it cannot be used by Argo CD. !!! note When pasting TLS client certificate and key in the text areas in the web UI, make sure they contain no unintended line breaks or additional characters. @@ -119,19 +119,14 @@ Using the CLI: argocd repo add https://github.com/argoproj/argocd-example-apps.git --github-app-id 1 --github-app-installation-id 2 --github-app-private-key-path test.private-key.pem ``` -!!!note - To add a private Git repository on GitHub Enterprise using the CLI add `--github-app-enterprise-base-url https://ghe.example.com/api/v3` flag. - Using the UI: 1. Navigate to `Settings/Repositories` ![connect repo overview](../assets/repo-add-overview.png) -2. Click `Connect Repo using GitHub App` button, choose type: `GitHub` or `GitHub Enterprise`, enter the URL, App Id, Installation Id, and the app's private key. +2. Click `Connect Repo using GitHub App` button, enter the URL, App Id, Installation Id, and the app's private key. -!!!note - Enter the GitHub Enterprise Base URL for type `GitHub Enterprise`. ![connect repo](../assets/repo-add-github-app.png) 3. Click `Connect` to test the connection and have the repository added @@ -166,75 +161,6 @@ Using the UI: 3. Click `Connect` to test the connection and have the repository added - -### Azure Container Registry/Azure Repos using Azure Workload Identity - -Before using this feature, you must perform the following steps to enable workload identity configuration in Argo CD: - -- **Label the Pods:** Add the `azure.workload.identity/use: "true"` label to the repo-server pods. -- **Create Federated Identity Credential:** Generate an Azure federated identity credential for the repo-server service account. Refer to the [Federated Identity Credential](https://azure.github.io/azure-workload-identity/docs/topics/federated-identity-credential.html) documentation for detailed instructions. -- **Add Annotation to Service Account:** Add `azure.workload.identity/client-id: "$CLIENT_ID"` annotation to the repo-server service account, using the `CLIENT_ID` from the workload identity. -- Setup the permissions for Azure Container Registry/Azure Repos for the workload identity. - -Using CLI for Helm OCI with Azure workload identity: - -``` -argocd repo add contoso.azurecr.io/charts --type helm --enable-oci --use-azure-workload-identity -``` - -Using CLI for Azure Repos with Azure workload identity: - -``` -argocd repo add https://contoso@dev.azure.com/my-projectcollection/my-project/_git/my-repo --use-azure-workload-identity -``` - -Using the UI: - -- Navigate to `Settings/Repositories` - - ![connect repo overview](../assets/repo-add-overview.png) -- Click on `+ Connect Repo` -- On the connection page: - - Choose Connection Method as `VIA HTTPS` - - Select the type as `git` or `helm` - - Enter the Repository URL - - Enter name, if the repo type is helm - - Select `Enable OCI`, if repo type is helm - - Select `Use Azure Workload Identity` - - ![connect repo](../assets/repo-add-azure-workload-identity.png) -- Click `Connect` - -Using secret definition: - -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: helm-private-repo - namespace: argocd - labels: - argocd.argoproj.io/secret-type: repository -stringData: - type: helm - url: contoso.azurecr.io/charts - name: contosocharts - enableOCI: "true" - useAzureWorkloadIdentity: "true" ---- -apiVersion: v1 -kind: Secret -metadata: - name: git-private-repo - namespace: argocd - labels: - argocd.argoproj.io/secret-type: repository -stringData: - type: git - url: https://contoso@dev.azure.com/my-projectcollection/my-project/_git/my-repo - useAzureWorkloadIdentity: "true" -``` - ## Credential templates You can also set up credentials to serve as templates for connecting repositories, without having to repeat credential configuration. For example, if you setup credential templates for the URL prefix `https://github.com/argoproj`, these credentials will be used for all repositories with this URL as prefix (e.g. `https://github.com/argoproj/argocd-example-apps`) that do not have their own credentials configured. diff --git a/docs/user-guide/projects.md b/docs/user-guide/projects.md index 8ca1e63af2..d027193421 100644 --- a/docs/user-guide/projects.md +++ b/docs/user-guide/projects.md @@ -9,7 +9,7 @@ Projects provide a logical grouping of applications, which is useful when Argo C ### The Default Project -Every application belongs to a single project. If unspecified, an application belongs to the `default` project, which is created automatically and by default, permits deployments from any source repo, to any cluster, and all resource Kinds. When initially created, it's specification is configured to be the most permissive: +Every application belongs to a single project. If unspecified, an application belongs to the `default` project, which is created automatically and by default, permits deployments from any source repo, to any cluster, and all resource Kinds. The default project can be modified, but not deleted. When initially created, it's specification is configured to be the most permissive: ```yaml spec: @@ -23,26 +23,6 @@ spec: kind: '*' ``` -The `default` project can be modified, but not deleted. The project is useful for initial testing, but it is recommended to create dedicated projects with explicit source, destination, and resource permissions. - -To remove all permissions from the `default` project, apply the following manifest to the namespace where Argo CD is installed: - -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: AppProject -metadata: - name: default -spec: - sourceRepos: [] - sourceNamespaces: [] - destinations: [] - namespaceResourceBlacklist: - - group: '*' - kind: '*' -``` - -After you modify the `default` project, any application that attempts to use it will be denied until you explicitly move the application to a more permissive project. - ### Creating Projects Additional projects can be created to give separate teams different levels of access to namespaces. The following command creates a new project `myproject` which can deploy applications to namespace `mynamespace` of cluster `https://kubernetes.default.svc`. The permitted Git source repository is set to `https://github.com/argoproj/argocd-example-apps.git` repository. @@ -143,7 +123,7 @@ argocd app set guestbook-default --project myproject ## Project Roles -Projects include a feature called roles that can be used to determine who and what can be done to the applications associated with the project. As an example, it can be used to give a CI pipeline a restricted set of permissions allowing sync operations on a single app (but not change its source or destination). +Projects include a feature called roles that can be used to determine who and what can be done applications associated with the project. As an example, it can be used to give a CI pipeline a restricted set of permissions allowing sync operations on a single app (but not change its source or destination). Projects can have multiple roles, and those roles can have different access granted to them. These permissions are called policies which follows the same [RBAC pattern used in Argo CD configuration](../operator-manual/rbac.md). They are stored within the role as a list of policy strings. A role's policy can only grant access to that role. Users are associated with roles based on the groups list. Consider the hypothetical AppProject definition below: @@ -155,25 +135,25 @@ metadata: spec: ... roles: - - name: custom-project-role - description: The "custom-project-role" will be applied to the `some-user` group. + - description: some-role groups: - some-user + name: admin policies: - - p, proj:sample-test-project:custom-project-role, applications, *, *, allow + - p, proj:sample-test-project:some-role, applications, *, *, allow ... ``` Argo CD will use the policies defined in the AppProject roles while authorizing users actions. To determine which role a given users is associated with, it will dynamically create groups based on the role name in runtime. The project definition above will generate the following Casbin RBAC rules: ``` - p, proj:sample-test-project:custom-project-role, applications, *, *, allow - g, some-user, proj:sample-test-project:custom-project-role + p, proj:sample-test-project:some-role, applications, *, *, allow + g, some-user, proj:sample-test-project:some-role ``` _Note 1_: It is very important that policy roles follow the pattern `proj::` or they won't be effective during the Argo CD authorization process. -_Note 2_: The example above used `applications` as the resource for the policy definition. However other types of resources can also be used: `repositories`, `clusters`, `logs` and `exec`. See the [RBAC documentation](../operator-manual/rbac.md) for more details about those resources. +_Note 2_: The example above used `applications` as the resource for the policy definition. However other types of resources can also be used: `repositories`, `clusters`, `logs`, `exec` and `projects`. See the [RBAC documentation](../operator-manual/rbac.md) for more details about those resources. In order to create roles in a project and add policies to a role, a user will need permission to update a project. The following commands can be used to manage a role. @@ -195,7 +175,7 @@ argocd proj role create-token PROJECT ROLE-NAME argocd proj role delete-token PROJECT ROLE-NAME ISSUED-AT ``` -Since the JWT tokens aren't stored in Argo CD, they can only be retrieved when they are created. A user can leverage them in the cli by either passing them in using the `--auth-token` flag or setting the ARGOCD_AUTH_TOKEN environment variable. The JWT tokens can be used until they expire or are revoked. The JWT tokens can be created with or without an expiration. By default, the cli creates them without an expirations date. Even if a token has not expired, it cannot be used if the token has been revoked. +Since the JWT tokens aren't stored in Argo CD, they can only be retrieved when they are created. A user can leverage them in the cli by either passing them in using the `--auth-token` flag or setting the ARGOCD_AUTH_TOKEN environment variable. The JWT tokens can be used until they expire or are revoked. The JWT tokens can created with or without an expiration, but the default on the cli is creates them without an expirations date. Even if a token has not expired, it cannot be used if the token has been revoked. Below is an example of leveraging a JWT token to access a guestbook application. It makes the assumption that the user already has a project named myproject and an application called guestbook-default. @@ -232,7 +212,7 @@ argocd app get $APP --auth-token $JWT ## Configuring RBAC With Projects -Project roles allow configuring RBAC rules scoped to the project. The following sample project provides read-only permissions on project applications to any member of `my-oidc-group` group. +The project Roles allows configuring RBAC rules scoped to the project. The following sample project provides read-only permissions on project applications to any member of `my-oidc-group` group. *AppProject example:* @@ -297,7 +277,7 @@ It is possible to offer a self-service process for developers so that they can a For this purpose Argo CD supports project-scoped repositories and clusters. To begin the process, Argo CD admins must configure RBAC security to allow this self-service behavior. -For example, to allow users to add project scoped repositories an admin would have to add the following RBAC rules: +For example, to allow users to add project scoped repositories and admin would have to add the following RBAC rules: ``` p, proj:my-project:admin, repositories, create, my-project/*, allow @@ -335,12 +315,11 @@ stringData: ``` !!! warning - Please keep in mind when using a project-scoped repository, only applications or applicationsets with a matching project - name can make use of it. When using an applicationset with a Git generator that also makes use of a templated `project` - (i.e. it contains ``{{ ... }}``) only non-scoped repositories can be used with the applicationset (i.e. repositories - that do _not_ have a `project` set). +Please keep in mind when using a project-scoped repository, only applications from the same project can make use of +it. When using applicationsets with the Git generator, only non-scoped repositories can be used (i.e. repositories that +do _not_ have a `project` set). -All the examples above concern Git repositories, but the same principles apply to clusters as well. +All the examples above talk about Git repositories, but the same principles apply to clusters as well. ```yaml apiVersion: v1 diff --git a/docs/user-guide/resource_hooks.md b/docs/user-guide/resource_hooks.md index 8d6d70e366..6e15a55bb2 100644 --- a/docs/user-guide/resource_hooks.md +++ b/docs/user-guide/resource_hooks.md @@ -1 +1,143 @@ -> ⚠️ This page has moved. See [New Page](sync-waves.md) +# Resource Hooks +## Overview + +Synchronization can be configured using resource hooks. Hooks are ways to run scripts before, during, +and after a Sync operation. Hooks can also be run if a Sync operation fails at any point. Some use cases for hooks are: + +* Using a `PreSync` hook to perform a database schema migration before deploying a new version of the app. +* Using a `Sync` hook to orchestrate a complex deployment requiring more sophistication than the +Kubernetes rolling update strategy. +* Using a `PostSync` hook to run integration and health checks after a deployment. +* Using a `SyncFail` hook to run clean-up or finalizer logic if a Sync operation fails. +* Using a `PostDelete` hook to run clean-up or finalizer logic after all Application resources are deleted. Please note that + `PostDelete` hooks are only deleted if the delete policy matches the aggregated deletion hooks status and not garbage collected after the application is deleted. + +## Usage + +Hooks are simply Kubernetes manifests tracked in the source repository of your Argo CD Application annotated with `argocd.argoproj.io/hook`, e.g.: + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + generateName: schema-migrate- + annotations: + argocd.argoproj.io/hook: PreSync +``` + +During a Sync operation, Argo CD will apply the resource during the appropriate phase of the +deployment. Hooks can be any type of Kubernetes resource kind, but tend to be Pod, +[Job](https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/) +or [Argo Workflows](https://github.com/argoproj/argo). Multiple hooks can be specified as a comma +separated list. + +The following hooks are defined: + +| Hook | Description | +|------|-------------| +| `PreSync` | Executes prior to the application of the manifests. | +| `Sync` | Executes after all `PreSync` hooks completed and were successful, at the same time as the application of the manifests. | +| `Skip` | Indicates to Argo CD to skip the application of the manifest. | +| `PostSync` | Executes after all `Sync` hooks completed and were successful, a successful application, and all resources in a `Healthy` state. | +| `SyncFail` | Executes when the sync operation fails. | +| `PostDelete` | Executes after all Application resources are deleted. _Available starting in v2.10._ | + +### Generate Name + +Named hooks (i.e. ones with `/metadata/name`) will only be created once. If you want a hook to be re-created each time either use `BeforeHookCreation` policy (see below) or `/metadata/generateName`. + +## Selective Sync + +Hooks are not run during [selective sync](selective_sync.md). + +## Hook Deletion Policies + +Hooks can be deleted in an automatic fashion using the annotation: `argocd.argoproj.io/hook-delete-policy`. + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + generateName: integration-test- + annotations: + argocd.argoproj.io/hook: PostSync + argocd.argoproj.io/hook-delete-policy: HookSucceeded +``` +Multiple hook delete policies can be specified as a comma separated list. + +The following policies define when the hook will be deleted. + +| Policy | Description | +|--------|-------------| +| `HookSucceeded` | The hook resource is deleted after the hook succeeded (e.g. Job/Workflow completed successfully). | +| `HookFailed` | The hook resource is deleted after the hook failed. | +| `BeforeHookCreation` | Any existing hook resource is deleted before the new one is created (since v1.3). It is meant to be used with `/metadata/name`. | + +Note that if no deletion policy is specified, Argo CD will automatically assume `BeforeHookCreation` rules. + +### Sync Status with Jobs/Workflows with Time to Live (ttl) + +Jobs support the [`ttlSecondsAfterFinished`](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/) +field in the spec, which let their respective controllers delete the Job after it completes. Argo Workflows support a +[`ttlStrategy`](https://argoproj.github.io/argo-workflows/fields/#ttlstrategy) property that also allow a Workflow to be +cleaned up depending on the ttl strategy chosen. + +Using either of the properties above can lead to Applications being OutOfSync. This is because Argo CD will detect a difference +between the Job or Workflow defined in the git repository and what's on the cluster since the ttl properties cause deletion of the resource after completion. + +However, using deletion hooks instead of the ttl approaches mentioned above will prevent Applications from having a status of +OutOfSync even though the Job or Workflow was deleted after completion. + +## Using A Hook To Send A Slack Message + +The following example uses the Slack API to send a Slack message when sync completes or fails: + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + generateName: app-slack-notification- + annotations: + argocd.argoproj.io/hook: PostSync + argocd.argoproj.io/hook-delete-policy: HookSucceeded +spec: + template: + spec: + containers: + - name: slack-notification + image: curlimages/curl + command: + - "curl" + - "-X" + - "POST" + - "--data-urlencode" + - "payload={\"channel\": \"#somechannel\", \"username\": \"hello\", \"text\": \"App Sync succeeded\", \"icon_emoji\": \":ghost:\"}" + - "https://hooks.slack.com/services/..." + restartPolicy: Never + backoffLimit: 2 +``` + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + generateName: app-slack-notification-fail- + annotations: + argocd.argoproj.io/hook: SyncFail + argocd.argoproj.io/hook-delete-policy: HookSucceeded +spec: + template: + spec: + containers: + - name: slack-notification + image: curlimages/curl + command: + - "curl" + - "-X" + - "POST" + - "--data-urlencode" + - "payload={\"channel\": \"#somechannel\", \"username\": \"hello\", \"text\": \"App Sync failed\", \"icon_emoji\": \":ghost:\"}" + - "https://hooks.slack.com/services/..." + restartPolicy: Never + backoffLimit: 2 +``` diff --git a/docs/user-guide/resource_tracking.md b/docs/user-guide/resource_tracking.md index 38499f56ee..ff43d6d739 100644 --- a/docs/user-guide/resource_tracking.md +++ b/docs/user-guide/resource_tracking.md @@ -1,46 +1,8 @@ # Resource Tracking -## Tracking Kubernetes resources by annotation - -Argo CD can be instructed to use the following methods for tracking: - -1. `annotation` (default) - Argo CD uses the `argocd.argoproj.io/tracking-id` annotation to track application resources. Use this when you don't need to maintain both the label and the annotation. -1. `annotation+label` - Argo CD uses the `app.kubernetes.io/instance` label but only for informational purposes. The label is not used for tracking purposes, and the value is still truncated if longer than 63 characters. The annotation `argocd.argoproj.io/tracking-id` is used instead to track application resources. Use this for resources that you manage with Argo CD, but still need compatibility with other tools that require the instance label. -1. `label` - Argo CD uses the `app.kubernetes.io/instance` label - - -Here is an example of using the annotation method for tracking resources: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: my-deployment - namespace: default - annotations: - argocd.argoproj.io/tracking-id: my-app:apps/Deployment:default/my-deployment -``` - -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/installation-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. - -This allows other kubernetes tools (e.g. [HNC](https://github.com/kubernetes-sigs/hierarchical-namespaces)) to copy a resource to a different namespace without impacting the Argo CD application's sync status. Copied resources will be visible on the UI at top level. They will have no sync status and won't impact the application's sync status. - - ## Tracking Kubernetes resources by label -In this mode, Argo CD identifies resources it manages by setting the application instance label to the name of the managing Application on all resources that are managed (i.e. reconciled from Git). The default label used is the well-known label `app.kubernetes.io/instance`. +Argo CD identifies resources it manages by setting the application instance label to the name of the managing Application on all resources that are managed (i.e. reconciled from Git). The default label used is the well-known label `app.kubernetes.io/instance`. Example: @@ -78,6 +40,44 @@ data: application.instanceLabelKey: argocd.argoproj.io/instance ``` +## Additional tracking methods via an annotation + +>v2.2 + +To offer more flexible options for tracking resources and solve some of the issues outlined in the previous section Argo CD can be instructed to use the following methods for tracking: + +1. `label` (default) - Argo CD uses the `app.kubernetes.io/instance` label +1. `annotation+label` - Argo CD uses the `app.kubernetes.io/instance` label but only for informational purposes. The label is not used for tracking purposes, and the value is still truncated if longer than 63 characters. The annotation `argocd.argoproj.io/tracking-id` is used instead to track application resources. Use this for resources that you manage with Argo CD, but still need compatibility with other tools that require the instance label. +1. `annotation` - Argo CD uses the `argocd.argoproj.io/tracking-id` annotation to track application resources. Use this when you don't need to maintain both the label and the annotation. + +Here is an example of using the annotation method for tracking resources: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment + namespace: default + annotations: + argocd.argoproj.io/tracking-id: my-app:apps/Deployment:default/nginx-deployment +``` + +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. + +This allows other kubernetes tools (e.g. [HNC](https://github.com/kubernetes-sigs/hierarchical-namespaces)) to copy a resource to a different namespace without impacting the Argo CD application's sync status. Copied resources will be visible on the UI at top level. They will have no sync status and won't impact the application's sync status. + ## Choosing a tracking method To actually select your preferred tracking method edit the `resourceTrackingMethod` value contained inside the `argocd-cm` configmap. @@ -93,8 +93,8 @@ metadata: data: application.resourceTrackingMethod: annotation ``` -Possible values are `label`, `annotation+label` and `annotation` as described above. +Possible values are `label`, `annotation+label` and `annotation` as described in the previous section. Note that once you change the value you need to sync your applications again (or wait for the sync mechanism to kick-in) in order to apply your changes. -You can revert to a previous choice, by changing the configmap again. +You can revert to a previous choice, by changing again the configmap. diff --git a/docs/user-guide/scale_application_resources.md b/docs/user-guide/scale_application_resources.md deleted file mode 100644 index 53858983a6..0000000000 --- a/docs/user-guide/scale_application_resources.md +++ /dev/null @@ -1,22 +0,0 @@ -# Scale Resources in ArgoCD UI - -This enables users to scale resources directly from the ArgoCD UI. Users will be able to increase or decrease the number of replicas (Pods) for Deployments and StatefulSets by using an input field. The feature aims to enhance user experience, especially for non-technical users, by eliminating the need to modify configuration files or use kubectl commands for scaling. - - -## Example Usage -1. User navigates to a Deployment or StatefulSet in any ArgoCD application. -2. User clicks on the Actions dropdown and selects "Scale". - ![action button for scaling](../assets/scale_resources_1.png) -3. A modal pops up showing an input field `Enter input parameters for action: scale` with the current number of Pods. -4. User adjusts the number of Pods by entering a number. - ![input field for scaling](../assets/scale_resources_2.png) -5. User presses OK, and the resource is scaled accordingly. - ![result for scaling](../assets/scale_resources_3.png) - - -!!! note - This feature will only apply to `Deployments`, and `StatefulSets`. - -!!! note - If you use HPA (Horizontal Pod Autoscaling) or enabled ArgoCD auto-sync, changing the replica count in scale actions would be overwritten. - Ensure that invalid values (e.g., `non-numeric` characters, `negative` numbers, or values beyond the `max integer limit`) cannot be entered. diff --git a/docs/user-guide/selective_sync.md b/docs/user-guide/selective_sync.md index 8719a01f06..d607cc636b 100644 --- a/docs/user-guide/selective_sync.md +++ b/docs/user-guide/selective_sync.md @@ -4,10 +4,10 @@ A *selective sync* is one where only some resources are sync'd. You can choose w ![selective sync](../assets/selective-sync.png) -When doing so, bear in mind that: +When doing so, bear in mind: * Your sync is not recorded in the history, and so rollback is not possible. -* [Hooks](resource_hooks.md) are not run. +* Hooks are not run. ## Selective Sync Option diff --git a/docs/user-guide/source-hydrator.md b/docs/user-guide/source-hydrator.md index 2fe4f51169..936880902a 100644 --- a/docs/user-guide/source-hydrator.md +++ b/docs/user-guide/source-hydrator.md @@ -205,5 +205,5 @@ Examples of non-deterministic hydration: Argo CD should be the only thing pushing hydrated manifests to the hydrated branches. To prevent other tools or users from pushing to the hydrated branches, enable branch protection in your SCM. -It is best practice to prefix the hydrated branches with a common prefix, such as `environments/`. This makes it easier +It is best practice to prefix the hydrated branches with a common prefix, such as `environment/`. This makes it easier to configure branch protection rules on the destination repository. diff --git a/docs/user-guide/status-badge.md b/docs/user-guide/status-badge.md index e6aedf0f28..a933a751d2 100644 --- a/docs/user-guide/status-badge.md +++ b/docs/user-guide/status-badge.md @@ -1,28 +1,22 @@ # Status Badge Argo CD can display a badge with health and sync status for any application. The feature is disabled by default because badge image is available to any user without authentication. -The feature can be enabled using `statusbadge.enabled` key of `argocd-cm` ConfigMap (see [argocd-cm.yaml](../operator-manual/argocd-cm-yaml/)). - +The feature can be enabled using `statusbadge.enabled` key of `argocd-cm` ConfigMap (see [argocd-cm.yaml](../operator-manual/argocd-cm.yaml)). ![healthy and synced](../assets/status-badge-healthy-synced.png) To show this badge, use the following URL format `${argoCdBaseUrl}/api/badge?name=${appName}`, e.g. http://localhost:8080/api/badge?name=guestbook. - -To override the `${argoCdBaseUrl}` value, you can use the `statusbadge.url` key of `argocd-cm` ConfigMap. - The URLs for status image are available on application details page: 1. Navigate to application details page and click on 'Details' button. 2. Scroll down to 'Status Badge' section. 3. Select required template such as URL, Markdown etc. - for the status image URL in markdown, html, etc are available . +for the status image URL in markdown, html, etc are available . 4. Copy the text and paste it into your README or website. ## Additional query parameters options - ### showAppName - -Display the application name in the status badge. +Display the application name in the status badge. Available values: `true/false` @@ -31,7 +25,6 @@ Default value: `false` Example: `&showAppName=true` ### revision - Display revision targeted by the application. It will also extend the badge width to 192px. @@ -41,10 +34,8 @@ Available values: `true/false` Default value: `false` Example: `&revision=true` - ### keepFullRevision - -By default, displayed revision is truncated to 7 characters. +By default, displayed revision is truncated to 7 characters. This parameter allows to display it fully if it exceeds that length. @@ -55,9 +46,7 @@ Available values: `true/false` Default value: `false` Example: `&keepFullRevision=true` - ### width - Change width of the badge. Completely replace current calculated width. @@ -66,4 +55,4 @@ Available values: `integer` Default value: `nil` -Example: `&width=500` +Example: `&width=500` \ No newline at end of file diff --git a/docs/user-guide/sync-kubectl.md b/docs/user-guide/sync-kubectl.md index 7cbcaa0b65..53700afed4 100644 --- a/docs/user-guide/sync-kubectl.md +++ b/docs/user-guide/sync-kubectl.md @@ -51,7 +51,7 @@ In these cases, "kubectl apply" gives better results. Either with a "kubectl patch" or "kubectl apply", the state of the synchronization is reported in the "operationState" field in the application object. ```bash -$ kubectl get -n app -o yaml +$ kubectl get -n get app -o yaml ... status: operationState: diff --git a/docs/user-guide/sync-options.md b/docs/user-guide/sync-options.md index 96b78da061..206b0b690b 100644 --- a/docs/user-guide/sync-options.md +++ b/docs/user-guide/sync-options.md @@ -1,6 +1,6 @@ # Sync Options -Argo CD allows users to customize some aspects of how it syncs the desired state in the target cluster. Some Sync Options can be defined as annotations in a specific resource. Most of the Sync Options are configured in the Application resource `spec.syncPolicy.syncOptions` attribute. Multiple Sync Options which are configured with the `argocd.argoproj.io/sync-options` annotation can be concatenated with a `,` in the annotation value; white-space will be trimmed. +Argo CD allows users to customize some aspects of how it syncs the desired state in the target cluster. Some Sync Options can be defined as annotations in a specific resource. Most of the Sync Options are configured in the Application resource `spec.syncPolicy.syncOptions` attribute. Multiple Sync Options which are configured with the `argocd.argoproj.io/sync-options` annotation can be concatenated with a `,` in the annotation value; white spaces will be trimmed. Below you can find details about each available Sync Option: @@ -16,6 +16,11 @@ metadata: argocd.argoproj.io/sync-options: Prune=false ``` +In the UI, the pod will simply appear as out-of-sync: + +![sync option no prune](../assets/sync-option-no-prune.png) + + The sync-status panel shows that pruning was skipped, and why: ![sync option no prune](../assets/sync-option-no-prune-sync-status.png) @@ -38,7 +43,7 @@ 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 annotation: +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: ```yaml @@ -53,8 +58,8 @@ If you want to exclude a whole class of objects globally, consider setting `reso When syncing a custom resource which is not yet known to the cluster, there are generally two options: -1. The CRD manifest is part of the same sync. Then Argo CD will automatically skip the dry run, the CRD will be applied and the resource can be created. -2. In some cases the CRD is not part of the sync, but it could be created in another way, e.g. by a controller in the cluster. An example is [gatekeeper](https://github.com/open-policy-agent/gatekeeper), +1) The CRD manifest is part of the same sync. Then Argo CD will automatically skip the dry run, the CRD will be applied and the resource can be created. +2) In some cases the CRD is not part of the sync, but it could be created in another way, e.g. by a controller in the cluster. An example is [gatekeeper](https://github.com/open-policy-agent/gatekeeper), which creates CRDs in response to user defined `ConstraintTemplates`. Argo CD cannot find the CRD in the sync and will fail with the error `the server could not find the requested resource`. To skip the dry run for missing resource types, use the following annotation: @@ -67,18 +72,6 @@ metadata: The dry run will still be executed if the CRD is already present in the cluster. -It is also possible to skip dry run on missing resource for all application resources. You can set the `SkipDryRunOnMissingResource=true` -sync option to skip dry run on missing resource - -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Application -spec: - syncPolicy: - syncOptions: - - SkipDryRunOnMissingResource=true -``` - ## No Resource Deletion For certain resources you might want to retain them even after your application is deleted, for eg. Persistent Volume Claims. @@ -107,7 +100,7 @@ annotation to the application. ## Selective Sync -Currently, when syncing using auto sync Argo CD applies every object in the application. +Currently when syncing using auto sync Argo CD applies every object in the application. For applications containing thousands of objects this takes quite a long time and puts undue pressure on the api server. Turning on selective sync option which will sync only out-of-sync resources. diff --git a/docs/user-guide/sync-waves.md b/docs/user-guide/sync-waves.md index 2347902587..73ee08221a 100644 --- a/docs/user-guide/sync-waves.md +++ b/docs/user-guide/sync-waves.md @@ -1,84 +1,12 @@ # Sync Phases and Waves -Sync phases and hooks define when resources are applied such as before or after the main sync operation. This makes it possible to define jobs, or any other resource to run or be applied in any specific order. +>v1.1 -Argo CD has the following hook types: + -| Hook | Description | -|------|-------------| -| `PreSync` | Executes prior to the application of the manifests. | -| `Sync` | Executes after all `PreSync` hooks completed and were successful, at the same time as the application of the manifests. | -| `Skip` | Indicates to Argo CD to skip the application of the manifest. | -| `PostSync` | Executes after all `Sync` hooks completed and were successful, a successful application, and all resources in a `Healthy` state. | -| `SyncFail` | Executes when the sync operation fails. | -| `PostDelete` | Executes after all Application resources are deleted. _Available starting in v2.10._ | +Argo CD executes a sync operation in a number of steps. At a high-level, there are three phases *pre-sync*, *sync* and *post-sync*. -Adding the argocd.argoproj.io/hook annotation to a resource will assign it to a specific phase. During a Sync operation, Argo CD will apply the resource during the appropriate phase of the deployment. Hooks can be any type of Kubernetes resource kind, but tend to be Pod, Job or Argo Workflows. Multiple hooks can be specified as a comma separated list. - -## How phases work? - -Argo CD will respect resources assigned to different phases, during a sync operation Argo CD will do the following. - -Apply all the resources marked as PreSync hooks. If any of them fails the whole sync process will stop and will be marked as failed -Apply all the resources marked as Sync hooks. If any of them fails the whole sync process will be marked as failed. Hooks marked with SyncFail will also run -Apply all the resources marked as PostSync hooks. If any of them fails the whole sync process will be marked as failed. -Hooks marked with Skip will not be applied. - -Here is a graphical overview of the sync process: - -![phases](how_phases_work.png) - -You can use this simple lifecycle method in various scenarios. For example you can run an essential check as a PreSync hook. If it fails then the whole sync operation will stop preventing the deployment from taking place. In a similar manner you can run smoke tests as PostSync hooks. If they succeed you know that your application has passed the validation. If they fail then the whole deployment will be marked as failed and Argo CD can then notify you in order to take further actions. - -Hooks at the SyncFail phase can be used for cleanup actions and other housekeeping tasks. Note that if they themselves fail, Argo CD will not do anything special (other than marking the whole operation as failed). - -Note that hooks do not run during a selective sync operation. - -## Hook lifecycle and cleanup - -Argo CD offers several methods to clean up hooks and decide how much history will be kept for previous runs. -In the most basic case you can use the argocd.argoproj.io/hook-delete-policy to decide when a hook will be deleted. -This can take the following values: - -| Policy | Description | -|--------|-------------| -| `HookSucceeded` | The hook resource is deleted after the hook succeeded (e.g. Job/Workflow completed successfully). | -| `HookFailed` | The hook resource is deleted after the hook failed. | -| `BeforeHookCreation` | Any existing hook resource is deleted before the new one is created (since v1.3). It is meant to be used with `/metadata/name`. | - - -## How sync waves work? - -Argo CD also offers an alternative method of changing the sync order of resources. These are sync waves. They are defined by the argocd.argoproj.io/sync-wave annotation. The value is an integer that defines the ordering (ArgoCD will start deploying from the lowest number and finish with the highest number). - -Hooks and resources are assigned to wave 0 by default. The wave can be negative, so you can create a wave that runs before all other resources. - -When a sync operation takes place, Argo CD will: -Order all resources according to their wave (lowest to highest) -Apply the resources according to the resulting sequence - -There is currently a delay between each sync wave in order to give other controllers a chance to react to the spec change that was just applied. This also prevents Argo CD from assessing resource health too quickly (against the stale object), causing hooks to fire prematurely. The current delay between each sync wave is 2 seconds and can be configured via the environment variable ARGOCD_SYNC_WAVE_DELAY. - -## Combining Sync waves and hooks - -While you can use sync waves on their own, for maximum flexibility you can combine them with hooks. This way you can use sync phases for coarse grained ordering and sync waves for defining the exact order of a resource within an individual phase. - -![waves](how_waves_work.png) - -When Argo CD starts a sync, it orders the resources in the following precedence: - -The phase -The wave they are in (lower values first) -By kind (e.g. namespaces first and then other Kubernetes resources, followed by custom resources) -By name - -Once the order is defined: - -First Argo CD determines the number of the first wave to apply. This is the first number where any resource is out-of-sync or unhealthy. -It applies resources in that wave. -It repeats this process until all phases and waves are in-sync and healthy. - -Because an application can have resources that are unhealthy in the first wave, it may be that the app can never get to healthy. +Within each phase you can have one or more waves, that allows you to ensure certain resources are healthy before subsequent resources are synced. ## How Do I Configure Phases? @@ -104,65 +32,30 @@ metadata: Hooks and resources are assigned to wave zero by default. The wave can be negative, so you can create a wave that runs before all other resources. -## Examples +### Can Multiple Resources Share the Same Wave? -The following example uses the Slack API to send a a Slack message when sync completes: +Yes, multiple resources can share the same sync-wave value. Resources with the same sync-wave are processed together. -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - generateName: app-slack-notification- - annotations: - argocd.argoproj.io/hook: PostSync - argocd.argoproj.io/hook-delete-policy: HookSucceeded -spec: - template: - spec: - containers: - - name: slack-notification - image: curlimages/curl - command: - - curl - - '-X' - - POST - - '--data-urlencode' - - >- - payload={"channel": "#somechannel", "username": "hello", "text": - "App Sync succeeded", "icon_emoji": ":ghost:"} - - 'https://hooks.slack.com/services/...' - restartPolicy: Never - backoffLimit: 2 -``` +Within a wave, resources are ordered by their kind (e.g. namespaces first) and then by their name. -The following example runs a db migration command before the main sync operation (also in wave -1): -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: db-migrate - annotations: - argocd.argoproj.io/hook: PreSync - argocd.argoproj.io/hook-delete-policy: HookSucceeded - argocd.argoproj.io/sync-wave: '-1' -spec: - ttlSecondsAfterFinished: 360 - template: - spec: - containers: - - name: postgresql-client - image: 'my-postgres-data:11.5' - imagePullPolicy: Always - env: - - name: PGPASSWORD - value: admin - - name: POSTGRES_HOST - value: my_postgresql_db - command: - - psql - - '-h=my_postgresql_db' - - '-U postgres' - - '-f preload.sql' - restartPolicy: Never - backoffLimit: 1 -``` +## How Does It Work? + +When Argo CD starts a sync, it orders the resources in the following precedence: + +* The phase +* The wave they are in (lower values first for creation & updation and higher values first for deletion) +* By kind (e.g. [namespaces first and then other Kubernetes resources, followed by custom resources](https://github.com/argoproj/gitops-engine/blob/bc9ce5764fa306f58cf59199a94f6c968c775a2d/pkg/sync/sync_tasks.go#L27-L66)) +* By name + +It then determines the number of the next wave to apply. This is the first number where any resource is out-of-sync or unhealthy. + +It applies resources in that wave. + +It repeats this process until all phases and waves are in-sync and healthy. + +Because an application can have resources that are unhealthy in the first wave, it may be that the app can never get to healthy. + +During pruning of resources, resources from higher waves are processed first before moving to lower waves. If, for any reason, a resource isn't removed/pruned in a wave, the resources in next waves won't be processed. This is to ensure proper resource cleanup between waves. + +Note: there is a delay between each sync wave to give other controllers a chance to react to the applied spec change. This prevents Argo CD from assessing resource health too quickly (against a stale object), and firing +hooks prematurely. The default delay between each sync wave is 2 seconds. This can be adjusted by setting the `ARGOCD_SYNC_WAVE_DELAY` environment variable in the argocd-application-controller deployment. diff --git a/docs/user-guide/sync_windows.md b/docs/user-guide/sync_windows.md index 1c91d73cbe..a786d158ff 100644 --- a/docs/user-guide/sync_windows.md +++ b/docs/user-guide/sync_windows.md @@ -2,9 +2,7 @@ Sync windows are configurable windows of time where syncs will either be blocked or allowed. These are defined by a kind, which can be either `allow` or `deny`, a `schedule` in cron format and a duration along with one or -more of either `applications`, `namespaces` and `clusters`. If more than one option is specified, by default, the enabled options will -be OR-ed. If you want to AND the options, you can tick the `Use AND operator` option. -Wildcards are supported. +more of either `applications`, `namespaces` and `clusters`. Wildcards are supported. ## Relationship between Sync Windows and Applications @@ -28,18 +26,15 @@ then the Application is affected by the Sync Window. ## Effect of Sync Windows -These windows affect the running of both manual and automated syncs but allow an override -for manual syncs which is useful if you are only interested in preventing automated syncs or if you need to temporarily -override a window to perform a sync. +These windows affect the running +of both manual and automated syncs but allow an override for manual syncs which is useful if you are only interested +in preventing automated syncs or if you need to temporarily override a window to perform a sync. -The windows work in the following way: - -- If there are no windows matching an application then all syncs are allowed. -- If there are any `allow` windows matching an application then syncs will only be allowed when there is an active `allow` window. -- If there are any `deny` windows matching an application then all syncs will be denied when the `deny` windows are active. -- If there is an active matching `allow` and an active matching `deny` then syncs will be denied as `deny` windows override `allow` windows. - -The UI and the CLI will both display the state of the sync windows. The UI has a panel which will display different colours depending +The windows work in the following way. If there are no windows matching an application then all syncs are allowed. If there +are any `allow` windows matching an application then syncs will only be allowed when there is an active `allow` window. If there +are any `deny` windows matching an application then all syncs will be denied when the `deny` windows are active. If there is an +active matching `allow` and an active matching `deny` then syncs will be denied as `deny` windows override `allow` windows. The +UI and the CLI will both display the state of the sync windows. The UI has a panel which will display different colours depending on the state. The colours are as follows. `Red: sync denied`, `Orange: manual allowed` and `Green: sync allowed`. To display the sync state using the CLI: diff --git a/docs/user-guide/tool_detection.md b/docs/user-guide/tool_detection.md index ec0a9e36b9..06648df3e2 100644 --- a/docs/user-guide/tool_detection.md +++ b/docs/user-guide/tool_detection.md @@ -5,7 +5,7 @@ The tool used to build an application is detected as follows: If a specific tool is explicitly configured, then that tool is selected to create your application's manifests. The tool can be explicitly specified in the Application custom resource like this: -```yaml +``` apiVersion: argoproj.io/v1alpha1 kind: Application metadata: @@ -38,3 +38,8 @@ keys, in the `argocd-cm` ConfigMap, to `false`: `kustomize.enable`, `helm.enable tool is disabled, Argo CD will assume the application target directory contains plain Kubernetes YAML manifests. Disabling unused config management tools can be a helpful security enhancement. Vulnerabilities are sometimes limited to certain config management tools. Even if there is no vulnerability, an attacker may use a certain tool to take advantage of a misconfiguration in an Argo CD instance. Disabling unused config management tools limits the tools available to malicious actors. + +## References + +* [reposerver/repository/repository.go/GetAppSourceType](https://github.com/argoproj/argo-cd/blob/master/reposerver/repository/repository.go#L286) +* [server/repository/repository.go/listAppTypes](https://github.com/argoproj/argo-cd/blob/master/server/repository/repository.go#L97) diff --git a/docs/user-guide/tracking_strategies.md b/docs/user-guide/tracking_strategies.md index 17c38294d1..9cfc63811b 100644 --- a/docs/user-guide/tracking_strategies.md +++ b/docs/user-guide/tracking_strategies.md @@ -23,11 +23,6 @@ Helm chart versions are [Semantic Versions](https://semver.org/). As a result, y [Read about version ranges](https://www.telerik.com/blogs/the-mystical-magical-semver-ranges-used-by-npm-bower) -!!! note - If you want Argo CD to include all existing prerelease version tags of a repository in the comparison logic, you explicitly have to add a prerelease `-0` suffix to the version constraint. As mentioned `*-0` will compare against prerelease versions in a repository, `*` will not. The same applies for other constraints e.g. `>=1.2.2` will **not** compare prerelease versions vs. `>=1.2.2-0` which will include prerelease versions in the comparison. - -[Read about prerelease version comparison](https://github.com/Masterminds/semver?tab=readme-ov-file#working-with-prerelease-versions) - ## Git For Git, all versions are Git references but tags [Semantic Versions](https://semver.org/) can also be used: diff --git a/examples/dashboard.json b/examples/dashboard.json index b56f8a18c8..2e460c8e10 100644 --- a/examples/dashboard.json +++ b/examples/dashboard.json @@ -1508,8 +1508,7 @@ "fieldConfig": { "defaults": { "links": [], - "unitScale": true, - "unit": "bytes" + "unitScale": true }, "overrides": [] }, @@ -1806,6 +1805,7 @@ "title": "Controller Telemetry", "type": "row" }, + { "collapsed": true, "datasource": { @@ -1830,8 +1830,7 @@ "fieldConfig": { "defaults": { "links": [], - "unitScale": true, - "unit": "bytes" + "unitScale": true }, "overrides": [] }, @@ -2844,14 +2843,6 @@ "datasource": { "uid": "$datasource" }, - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true, - "unit": "bytes" - }, - "overrides": [] - }, "fill": 1, "fillGradient": 0, "gridPos": { @@ -3049,8 +3040,7 @@ }, "fieldConfig": { "defaults": { - "unitScale": true, - "unit": "bytes" + "unitScale": true }, "overrides": [] }, diff --git a/generate-snyk-report.sh b/generate-snyk-report.sh new file mode 100644 index 0000000000..e69de29bb2 diff --git a/go.mod b/go.mod index f0b5c9b7c1..05c8c56540 100644 --- a/go.mod +++ b/go.mod @@ -1,181 +1,202 @@ -module github.com/argoproj/argo-cd/v3 +module github.com/argoproj/argo-cd/v2 -go 1.24.3 +go 1.24.4 require ( - code.gitea.io/sdk/gitea v0.21.0 - dario.cat/mergo v1.0.2 - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0 - github.com/Azure/kubelogin v0.2.8 + code.gitea.io/sdk/gitea v0.19.0 + github.com/Azure/kubelogin v0.1.6 github.com/Masterminds/semver/v3 v3.3.1 github.com/Masterminds/sprig/v3 v3.3.0 - github.com/TomOnTime/utfutil v1.0.0 - github.com/alicebob/miniredis/v2 v2.34.0 - github.com/argoproj/gitops-engine v0.7.1-0.20250520182409-89c110b5952e - github.com/argoproj/notifications-engine v0.4.1-0.20250309174002-87bf0576a872 - github.com/argoproj/pkg/v2 v2.0.1 - github.com/aws/aws-sdk-go v1.55.7 - github.com/bmatcuk/doublestar/v4 v4.8.1 - github.com/bombsimon/logrusr/v4 v4.1.0 - github.com/bradleyfalzon/ghinstallation/v2 v2.15.0 - github.com/casbin/casbin/v2 v2.105.0 - github.com/casbin/govaluate v1.7.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.20250521000818-c08b0a72c1f1 + 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.7.1 + github.com/bombsimon/logrusr/v2 v2.0.1 + github.com/bradleyfalzon/ghinstallation/v2 v2.12.0 + github.com/casbin/casbin/v2 v2.102.0 + github.com/casbin/govaluate v1.2.0 github.com/cespare/xxhash/v2 v2.3.0 github.com/chainguard-dev/git-urls v1.0.2 - github.com/coreos/go-oidc/v3 v3.14.1 - github.com/cyphar/filepath-securejoin v0.4.1 - github.com/dlclark/regexp2 v1.11.5 + github.com/coreos/go-oidc/v3 v3.11.0 + github.com/cyphar/filepath-securejoin v0.3.6 github.com/dustin/go-humanize v1.0.1 - github.com/evanphx/json-patch v5.9.11+incompatible - github.com/expr-lang/expr v1.17.3 + github.com/evanphx/json-patch v5.9.0+incompatible + github.com/expr-lang/expr v1.17.0 github.com/felixge/httpsnoop v1.0.4 - github.com/fsnotify/fsnotify v1.9.0 - github.com/gfleury/go-bitbucket-v1 v0.0.0-20240917142304-df385efaac68 - github.com/go-git/go-git/v5 v5.16.0 - github.com/go-jose/go-jose/v4 v4.1.0 + github.com/fsnotify/fsnotify v1.8.0 + github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e + github.com/go-git/go-git/v5 v5.13.2 + github.com/go-jose/go-jose/v3 v3.0.3 github.com/go-logr/logr v1.4.2 github.com/go-openapi/loads v0.22.0 github.com/go-openapi/runtime v0.28.0 github.com/go-playground/webhooks/v6 v6.4.0 github.com/go-redis/cache/v9 v9.0.0 github.com/gobwas/glob v0.2.3 - github.com/gogits/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 + github.com/gogits/go-gogs-client v0.0.0-20200905025246-8bb8a50cb355 github.com/gogo/protobuf v1.3.2 - github.com/golang-jwt/jwt/v5 v5.2.2 + github.com/golang-jwt/jwt/v4 v4.5.2 github.com/golang/protobuf v1.5.4 github.com/google/btree v1.1.3 - github.com/google/go-cmp v0.7.0 - github.com/google/go-github/v69 v69.2.0 - github.com/google/go-jsonnet v0.21.0 + github.com/google/go-cmp v0.6.0 + github.com/google/go-github/v66 v66.0.0 + github.com/google/go-jsonnet v0.20.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 - github.com/google/uuid v1.6.1-0.20241114170450-2d3c2a9cc518 + github.com/google/uuid v1.6.0 github.com/gorilla/handlers v1.5.2 github.com/gorilla/websocket v1.5.3 - github.com/gosimple/slug v1.15.0 - github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 - github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 + github.com/gosimple/slug v1.14.0 + github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/hashicorp/go-retryablehttp v0.7.7 - github.com/improbable-eng/grpc-web v0.15.1-0.20230209220825-1d9bbb09a099 + github.com/imdario/mergo v0.3.16 + github.com/improbable-eng/grpc-web v0.15.0 github.com/itchyny/gojq v0.12.17 - github.com/jarcoal/httpmock v1.4.0 - github.com/jeremywohl/flatten v1.0.2-0.20211013061545-07e4a09fb8e4 + github.com/jeremywohl/flatten v1.0.1 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 - github.com/ktrysmt/go-bitbucket v0.9.85 + 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/v7 v7.1.1-0.20241014080628-3045bdf43455 + 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 v1.0.6 - github.com/patrickmn/go-cache v2.1.1-0.20191004192108-46f407853014+incompatible - github.com/prometheus/client_golang v1.22.0 - github.com/prometheus/client_model v0.6.2 - github.com/r3labs/diff/v3 v3.0.1 - github.com/redis/go-redis/v9 v9.8.0 - github.com/robfig/cron/v3 v3.0.2-0.20210106135023-bc59245fe10e + github.com/olekukonko/tablewriter v0.0.5 + github.com/patrickmn/go-cache v2.1.0+incompatible + github.com/prometheus/client_golang v1.20.5 + github.com/r3labs/diff v1.1.0 + github.com/redis/go-redis/v9 v9.7.3 + github.com/robfig/cron/v3 v3.0.1 github.com/sirupsen/logrus v1.9.3 - github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 + github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c github.com/soheilhy/cmux v0.1.5 - github.com/spf13/cobra v1.9.1 - github.com/spf13/pflag v1.0.6 + github.com/spf13/cobra v1.8.1 + github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.10.0 github.com/valyala/fasttemplate v1.2.2 + github.com/xanzy/go-gitlab v0.114.0 github.com/yuin/gopher-lua v1.1.1 - gitlab.com/gitlab-org/api/client-go v0.116.0 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 - go.opentelemetry.io/otel v1.35.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 - go.opentelemetry.io/otel/sdk v1.35.0 - go.uber.org/automaxprocs v1.6.0 - golang.org/x/crypto v0.38.0 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 + go.opentelemetry.io/otel v1.33.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 + go.opentelemetry.io/otel/sdk v1.33.0 + golang.org/x/crypto v0.37.0 golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f - golang.org/x/net v0.40.0 - golang.org/x/oauth2 v0.30.0 - golang.org/x/sync v0.14.0 - golang.org/x/term v0.32.0 - golang.org/x/time v0.11.0 - google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a - google.golang.org/grpc v1.72.1 - google.golang.org/protobuf v1.36.6 + golang.org/x/net v0.39.0 + golang.org/x/oauth2 v0.24.0 + golang.org/x/sync v0.13.0 + golang.org/x/term v0.31.0 + golang.org/x/time v0.8.0 + google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 + google.golang.org/grpc v1.68.1 + google.golang.org/protobuf v1.35.2 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.32.2 - k8s.io/apiextensions-apiserver v0.32.2 - k8s.io/apimachinery v0.32.2 - k8s.io/client-go v0.32.2 - k8s.io/code-generator v0.32.2 + k8s.io/api v0.31.0 + k8s.io/apiextensions-apiserver v0.31.2 + k8s.io/apimachinery v0.31.0 + k8s.io/apiserver v0.31.0 + k8s.io/client-go v0.31.0 + k8s.io/code-generator v0.31.0 k8s.io/klog/v2 v2.130.1 - k8s.io/kube-openapi v0.0.0-20250304201544-e5f78fe3ede9 - k8s.io/kubectl v0.32.2 - k8s.io/utils v0.0.0-20241210054802-24370beab758 + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 + k8s.io/kubectl v0.31.2 + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 layeh.com/gopher-json v0.0.0-20190114024228-97fed8db8427 - oras.land/oras-go/v2 v2.6.0 - sigs.k8s.io/controller-runtime v0.20.4 - sigs.k8s.io/structured-merge-diff/v4 v4.7.0 + oras.land/oras-go/v2 v2.5.0 + sigs.k8s.io/controller-runtime v0.19.3 + sigs.k8s.io/structured-merge-diff/v4 v4.4.4-0.20241211184406-7bf59b3d70ee sigs.k8s.io/yaml v1.4.0 ) require ( - cloud.google.com/go/auth v0.15.0 // indirect - cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect - cloud.google.com/go/compute/metadata v0.6.0 // indirect - github.com/42wim/httpsig v1.2.2 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + dario.cat/mergo v1.0.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect + github.com/aws/aws-sdk-go-v2 v1.24.1 // indirect + github.com/aws/aws-sdk-go-v2/config v1.25.12 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect + github.com/aws/aws-sdk-go-v2/service/sqs v1.29.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect + github.com/aws/smithy-go v1.19.0 // indirect + github.com/davidmz/go-pageant v1.0.2 // indirect + github.com/distribution/reference v0.5.0 // indirect + 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/v5 v5.2.2 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/googleapis/gax-go/v2 v2.12.3 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/x448/float16 v0.8.4 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect + go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + golang.org/x/tools v0.27.0 // indirect + google.golang.org/api v0.171.0 // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/retry.v1 v1.0.3 // indirect + k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect + nhooyr.io/websocket v1.8.7 // indirect +) + +require ( + 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 github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect - github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/OvyFlash/telegram-bot-api v0.0.0-20241219171906-3f2ca0c14ada // indirect - github.com/PagerDuty/go-pagerduty v1.8.0 // indirect - github.com/ProtonMail/go-crypto v1.1.6 // indirect - github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20240116134246-a8cbe886bab0 // indirect - github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/PagerDuty/go-pagerduty v1.7.0 // indirect + github.com/ProtonMail/go-crypto v1.1.5 // indirect + github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20210112200207-10ab4d695d60 // indirect + github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect - github.com/aws/aws-sdk-go-v2/config v1.29.9 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.62 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect - github.com/aws/aws-sdk-go-v2/service/sqs v1.38.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.25.1 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 // indirect - github.com/aws/smithy-go v1.22.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/cloudflare/circl v1.6.1 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/davidmz/go-pageant v1.0.2 // indirect - github.com/desertbit/timer v1.0.1 // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/distribution/reference v0.6.0 // indirect + github.com/dlclark/regexp2 v1.11.4 github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/evanphx/json-patch/v5 v5.9.11 // indirect - github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect + github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/fatih/camelcase v1.0.0 // indirect - github.com/fatih/color v1.18.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.4.2 // indirect - github.com/go-fed/httpsig v1.1.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -187,117 +208,94 @@ require ( github.com/go-openapi/strfmt v0.23.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-openapi/validate v0.24.0 // indirect - github.com/gobwas/ws v1.2.1 // indirect - github.com/golang-jwt/jwt/v4 v4.5.2 // indirect - github.com/golang/glog v1.2.4 // indirect - github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect - github.com/google/gnostic-models v0.6.9 // indirect - github.com/google/go-github/v71 v71.0.0 // indirect + github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.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 github.com/google/gofuzz v1.2.0 // indirect - github.com/google/s2a-go v0.1.9 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect - github.com/googleapis/gax-go/v2 v2.14.1 // indirect github.com/gosimple/unidecode v1.0.1 // indirect - github.com/gregdel/pushover v1.3.1 // indirect + github.com/gregdel/pushover v1.2.1 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/itchyny/timefmt-go v0.1.6 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/jonboulle/clockwork v0.4.0 // indirect + github.com/jonboulle/clockwork v0.2.2 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/keybase/go-keychain v0.0.1 // indirect - github.com/klauspost/compress v1.18.0 // indirect - github.com/kylelemons/godebug v1.1.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/malexdev/utfutil v0.0.0-20180510171754-00c8d4a8e7a8 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/moby/spdystream v0.5.0 // indirect + github.com/moby/spdystream v0.4.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/oklog/ulid v1.3.1 // indirect - github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 // indirect - github.com/olekukonko/ll v0.0.8-0.20250516010636-22ea57d81985 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.1 // indirect - github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.23 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/opsgenie/opsgenie-go-sdk-v2 v1.0.5 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pjbgf/sha1cd v0.3.2 // indirect - github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect - github.com/pkg/errors v0.9.1 // indirect + github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/common v0.62.0 // indirect + github.com/prometheus/client_model v0.6.1 + github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect - github.com/rs/cors v1.11.1 // indirect + github.com/rs/cors v1.11.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/shopspring/decimal v1.4.0 // indirect - github.com/skeema/knownhosts v1.3.1 // indirect - github.com/slack-go/slack v0.16.0 // indirect - github.com/spf13/cast v1.7.1 // indirect + github.com/skeema/knownhosts v1.3.0 // indirect + github.com/slack-go/slack v0.12.2 // indirect + github.com/spf13/cast v1.7.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/vmihailenco/go-tinylfu v0.2.2 // indirect - github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect + github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/x448/float16 v0.8.4 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xlab/treeprint v1.2.0 // indirect go.mongodb.org/mongo-driver v1.17.1 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect - go.opentelemetry.io/otel/metric v1.35.0 // indirect - go.opentelemetry.io/otel/trace v1.35.0 // indirect - go.opentelemetry.io/proto/otlp v1.5.0 // indirect - golang.org/x/mod v0.22.0 // indirect - golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.25.0 // indirect - golang.org/x/tools v0.27.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 // indirect + go.opentelemetry.io/otel/metric v1.33.0 // indirect + go.opentelemetry.io/otel/trace v1.33.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect + go.uber.org/automaxprocs v1.6.0 gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gomodules.xyz/notify v0.1.1 // indirect - google.golang.org/api v0.223.0 // indirect - google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - k8s.io/apiserver v0.32.2 // indirect - k8s.io/cli-runtime v0.32.2 // indirect - k8s.io/component-base v0.32.2 // indirect - k8s.io/component-helpers v0.32.2 // indirect - k8s.io/controller-manager v0.0.0 // indirect - k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 // indirect - k8s.io/kube-aggregator v0.32.2 // indirect - k8s.io/kubernetes v1.32.2 // indirect - nhooyr.io/websocket v1.8.7 // indirect - sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect - sigs.k8s.io/kustomize/api v0.18.0 // indirect - sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect - sigs.k8s.io/randfill v1.0.0 // indirect + k8s.io/cli-runtime v0.31.0 // indirect + k8s.io/component-base v0.31.0 // indirect + k8s.io/component-helpers v0.31.0 // indirect + k8s.io/kube-aggregator v0.31.2 // indirect + k8s.io/kubernetes v1.31.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.17.2 // indirect + sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect ) replace ( + github.com/go-telegram-bot-api/telegram-bot-api/v5 => github.com/OvyFlash/telegram-bot-api/v5 v5.0.0-20240108230938-63e5c59035bf + github.com/golang/protobuf => github.com/golang/protobuf v1.5.4 github.com/grpc-ecosystem/grpc-gateway => github.com/grpc-ecosystem/grpc-gateway v1.16.0 @@ -307,36 +305,35 @@ replace ( // Avoid CVE-2022-28948 gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 - k8s.io/api => k8s.io/api v0.32.2 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.32.2 - k8s.io/apimachinery => k8s.io/apimachinery v0.32.2 - k8s.io/apiserver => k8s.io/apiserver v0.32.2 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.32.2 - k8s.io/client-go => k8s.io/client-go v0.32.2 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.32.2 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.32.2 - k8s.io/code-generator => k8s.io/code-generator v0.32.2 - k8s.io/component-base => k8s.io/component-base v0.32.2 - k8s.io/component-helpers => k8s.io/component-helpers v0.32.2 - k8s.io/controller-manager => k8s.io/controller-manager v0.32.2 - k8s.io/cri-api => k8s.io/cri-api v0.32.2 - k8s.io/cri-client => k8s.io/cri-client v0.32.2 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.32.2 - k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.32.2 - k8s.io/endpointslice => k8s.io/endpointslice v0.32.2 - k8s.io/externaljwt => k8s.io/externaljwt v0.32.2 - k8s.io/kms => k8s.io/kms v0.32.2 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.32.2 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.32.2 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.32.2 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.32.2 - k8s.io/kubectl => k8s.io/kubectl v0.32.2 - k8s.io/kubelet => k8s.io/kubelet v0.32.2 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.32.2 - k8s.io/metrics => k8s.io/metrics v0.32.2 - k8s.io/mount-utils => k8s.io/mount-utils v0.32.2 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.32.2 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.32.2 - k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.32.2 - k8s.io/sample-controller => k8s.io/sample-controller v0.32.2 + 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.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 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.31.0 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.31.0 + k8s.io/code-generator => k8s.io/code-generator v0.31.0 + k8s.io/component-base => k8s.io/component-base v0.31.0 + k8s.io/component-helpers => k8s.io/component-helpers v0.31.0 + k8s.io/controller-manager => k8s.io/controller-manager v0.31.0 + k8s.io/cri-api => k8s.io/cri-api v0.31.0 + k8s.io/cri-client => k8s.io/cri-client v0.31.0 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.31.0 + k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.31.0 + k8s.io/endpointslice => k8s.io/endpointslice v0.31.0 + k8s.io/kms => k8s.io/kms v0.31.0 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.31.0 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.31.0 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.31.0 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.31.0 + k8s.io/kubectl => k8s.io/kubectl v0.31.0 + k8s.io/kubelet => k8s.io/kubelet v0.31.0 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.31.0 + k8s.io/metrics => k8s.io/metrics v0.31.0 + k8s.io/mount-utils => k8s.io/mount-utils v0.31.0 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.31.0 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.31.0 + k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.31.0 + k8s.io/sample-controller => k8s.io/sample-controller v0.31.0 ) diff --git a/go.sum b/go.sum index ef8680da4f..a5189f2a9a 100644 --- a/go.sum +++ b/go.sum @@ -1,58 +1,23 @@ 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 v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps= -cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8= -cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M= -cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= -cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -code.gitea.io/sdk/gitea v0.21.0 h1:69n6oz6kEVHRo1+APQQyizkhrZrLsTLXey9142pfkD4= -code.gitea.io/sdk/gitea v0.21.0/go.mod h1:tnBjVhuKJCn8ibdyyhvUyxrR1Ca2KHEoTWoukNhXQPA= -dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= -dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= +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/42wim/httpsig v1.2.2 h1:ofAYoHUNs/MJOLqQ8hIxeyz2QxOz8qdSVvp3PX/oPgA= -github.com/42wim/httpsig v1.2.2/go.mod h1:P/UYo7ytNBFwc+dg35IubuAUIs8zj5zzFIgUCEl55WY= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0 h1:j8BorDEigD8UFOSZQiSqAMOOleyQOOQPnUAwV+Ls1gA= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4= -github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= -github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 h1:B/dfvscEQtew9dVuoxqxrUKKv8Ih2f55PydknDamU+g= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0/go.mod h1:fiPSssYvltE08HJchL04dOy+RD4hgrjph0cwGGMntdI= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0 h1:+m0M/LFxN43KvULkDNfdXOgrjtg6UYJPFBJyuEcRCAw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0/go.mod h1:PwOyop78lveYMRs6oCxjiVyBdyCgIYH6XHIVZO9/SFQ= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw= @@ -69,16 +34,17 @@ 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.2.8 h1:5atb9sjD9aQ++OOuW4UqERLsVYwxojAGM+rRML7CC2s= -github.com/Azure/kubelogin v0.2.8/go.mod h1:QS1EFQffesODbanqwj1BEUgcgssjYH/Qv0WJGEcRQCk= +github.com/Azure/kubelogin v0.1.6 h1:2TK38wwjODYVWlHuI7wijwGmsigpDkXWmy9eqXBmMnw= +github.com/Azure/kubelogin v0.1.6/go.mod h1:NxlvRs9CambNudRXrk63zpPgG7PHzqZwsn0v82cuFRE= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= -github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= -github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +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= github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -88,102 +54,122 @@ github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lpr github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/OvyFlash/telegram-bot-api v0.0.0-20241219171906-3f2ca0c14ada h1:5ZtieioZyyfiJsGvjpj3d5Eso/3YjJJhNQ1M8at5U5k= -github.com/OvyFlash/telegram-bot-api v0.0.0-20241219171906-3f2ca0c14ada/go.mod h1:2nRUdsKyWhvezqW/rBGWEQdcTQeTtnbSNd2dgx76WYA= -github.com/PagerDuty/go-pagerduty v1.8.0 h1:MTFqTffIcAervB83U7Bx6HERzLbyaSPL/+oxH3zyluI= -github.com/PagerDuty/go-pagerduty v1.8.0/go.mod h1:nzIeAqyFSJAFkjWKvMzug0JtwDg+V+UoCWjFrfFH5mI= -github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= -github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= -github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20240116134246-a8cbe886bab0 h1:ztLQGVQsey3BjCoh0TvHc/iKTQmkio2OmsIxhuu+EeY= -github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20240116134246-a8cbe886bab0/go.mod h1:rjP7sIipbZcagro/6TCk6X0ZeFT2eyudH5+fve/cbBA= -github.com/TomOnTime/utfutil v1.0.0 h1:/0Ivgo2OjXJxo8i7zgvs7ewSFZMLwCRGm3P5Umowb90= -github.com/TomOnTime/utfutil v1.0.0/go.mod h1:l9lZmOniizVSuIliSkEf87qivMRlSNzbdBFKjuLRg1c= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OvyFlash/telegram-bot-api/v5 v5.0.0-20240108230938-63e5c59035bf h1:a7VKhbjKYPO8twGy/1AxMpM2Fp0qT7bf25fmCVMVu4s= +github.com/OvyFlash/telegram-bot-api/v5 v5.0.0-20240108230938-63e5c59035bf/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8= +github.com/PagerDuty/go-pagerduty v1.7.0 h1:S1NcMKECxT5hJwV4VT+QzeSsSiv4oWl1s2821dUqG/8= +github.com/PagerDuty/go-pagerduty v1.7.0/go.mod h1:PuFyJKRz1liIAH4h5KVXVD18Obpp1ZXRdxHvmGXooro= +github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= +github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20210112200207-10ab4d695d60 h1:prBTRx78AQnXzivNT9Crhu564W/zPPr3ibSlpT9xKcE= +github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20210112200207-10ab4d695d60/go.mod h1:rjP7sIipbZcagro/6TCk6X0ZeFT2eyudH5+fve/cbBA= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d h1:WtAMR0fPCOfK7TPGZ8ZpLLY18HRvL7XJ3xcs0wnREgo= +github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d/go.mod h1:WML6KOYjeU8N6YyusMjj2qRvaPNUEvrQvaxuFcMRFJY= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE= -github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= -github.com/alicebob/miniredis/v2 v2.34.0 h1:mBFWMaJSNL9RwdGRyEDoAAv8OQc5UlEhLDQggTglU/0= -github.com/alicebob/miniredis/v2 v2.34.0/go.mod h1:kWShP4b58T1CW0Y5dViCd5ztzrDqRWqM3nksiyXk5s8= +github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= +github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= +github.com/alicebob/miniredis/v2 v2.33.0 h1:uvTF0EDeu9RLnUEG27Db5I68ESoIxTiXbNUiji6lZrA= +github.com/alicebob/miniredis/v2 v2.33.0/go.mod h1:MhP4a3EU7aENRi9aO+tHfTBZicLqQevyi/DJpoj6mi0= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antonmedv/expr v1.15.1 h1:mxeRIkH8GQJo4MRRFgp0ArlV4AA+0DmcJNXEsG70rGU= +github.com/antonmedv/expr v1.15.1/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4JUv1ihsE= +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.20250520182409-89c110b5952e h1:65x5+7Vz3HPjFoj7+mFyCckgHrAhPwy4rnDp/AveD18= -github.com/argoproj/gitops-engine v0.7.1-0.20250520182409-89c110b5952e/go.mod h1:duVhxDW7M7M7+19IBCVth2REOS11gmqzTWwj4u8N7aQ= -github.com/argoproj/notifications-engine v0.4.1-0.20250309174002-87bf0576a872 h1:ADGAdyN9ty0+RmTT/yn+xV9vwkqvLn9O1ccqeP0Zeas= -github.com/argoproj/notifications-engine v0.4.1-0.20250309174002-87bf0576a872/go.mod h1:d1RazGXWvKRFv9//rg4MRRR7rbvbE7XLgTSMT5fITTE= -github.com/argoproj/pkg/v2 v2.0.1 h1:O/gCETzB/3+/hyFL/7d/VM/6pSOIRWIiBOTb2xqAHvc= -github.com/argoproj/pkg/v2 v2.0.1/go.mod h1:sdifF6sUTx9ifs38ZaiNMRJuMpSCBB9GulHfbPgQeRE= +github.com/argoproj/gitops-engine v0.7.1-0.20250521000818-c08b0a72c1f1 h1:Ze4U6kV49vSzlUBhH10HkO52bYKAIXS4tHr/MlNDfdU= +github.com/argoproj/gitops-engine v0.7.1-0.20250521000818-c08b0a72c1f1/go.mod h1:WsnykM8idYRUnneeT31cM/Fq/ZsjkefCbjiD8ioCJkU= +github.com/argoproj/notifications-engine v0.4.1-0.20241007194503-2fef5c9049fd h1:lOVVoK89j9Nd4+JYJiKAaMNYC1402C0jICROOfUPWn0= +github.com/argoproj/notifications-engine v0.4.1-0.20241007194503-2fef5c9049fd/go.mod h1:N0A4sEws2soZjEpY4hgZpQS8mRIEw6otzwfkgc3g9uQ= +github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= +github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1/go.mod h1:CZHlkyAD1/+FbEn6cB2DQTj48IoLGvEYsWEvtzP3238= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= -github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM= -github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= -github.com/aws/aws-sdk-go-v2/config v1.29.9 h1:Kg+fAYNaJeGXp1vmjtidss8O2uXIsXwaRqsQJKXVr+0= -github.com/aws/aws-sdk-go-v2/config v1.29.9/go.mod h1:oU3jj2O53kgOU4TXq/yipt6ryiooYjlkqqVaZk7gY/U= -github.com/aws/aws-sdk-go-v2/credentials v1.17.62 h1:fvtQY3zFzYJ9CfixuAQ96IxDrBajbBWGqjNTCa79ocU= -github.com/aws/aws-sdk-go-v2/credentials v1.17.62/go.mod h1:ElETBxIQqcxej++Cs8GyPBbgMys5DgQPTwo7cUPDKt8= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY= -github.com/aws/aws-sdk-go-v2/service/sqs v1.38.1 h1:ZtgZeMPJH8+/vNs9vJFFLI0QEzYbcN0p7x1/FFwyROc= -github.com/aws/aws-sdk-go-v2/service/sqs v1.38.1/go.mod h1:Bar4MrRxeqdn6XIh8JGfiXuFRmyrrsZNTJotxEJmWW0= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.1 h1:8JdC7Gr9NROg1Rusk25IcZeTO59zLxsKgE0gkh5O6h0= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.1/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.1 h1:KwuLovgQPcdjNMfFt9OhUd9a2OwcOKhxfvF4glTzLuA= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 h1:PZV5W8yk4OtH1JAuhV2PXwwO9v5G5Aoj+eMCn4T+1Kc= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.17/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4= -github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ= -github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.44.289/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= +github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU= +github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= +github.com/aws/aws-sdk-go-v2/config v1.25.12 h1:mF4cMuNh/2G+d19nWnm1vJ/ak0qK6SbqF0KtSX9pxu0= +github.com/aws/aws-sdk-go-v2/config v1.25.12/go.mod h1:lOvvqtZP9p29GIjOTuA/76HiVk0c/s8qRcFRq2+E2uc= +github.com/aws/aws-sdk-go-v2/credentials v1.16.16 h1:8q6Rliyv0aUFAVtzaldUEcS+T5gbadPbWdV1WcAddK8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.16/go.mod h1:UHVZrdUsv63hPXFo1H7c5fEneoVo9UXiz36QG1GEPi0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 h1:uR9lXYjdPX0xY+NhvaJ4dD8rpSRz5VY81ccIIoNG+lw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino= +github.com/aws/aws-sdk-go-v2/service/sqs v1.29.7 h1:tRNrFDGRm81e6nTX5Q4CFblea99eAfm0dxXazGpLceU= +github.com/aws/aws-sdk-go-v2/service/sqs v1.29.7/go.mod h1:8GWUDux5Z2h6z2efAtr54RdHXtLm8sq7Rg85ZNY/CZM= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 h1:eajuO3nykDPdYicLlP3AGgOyVN3MOlFmZv7WGTuJPow= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.7/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 h1:QPMJf+Jw8E1l7zqhZmMlFw6w1NmfkfiSK8mS4zOx3BA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U= +github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= +github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= -github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38= -github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= -github.com/bombsimon/logrusr/v4 v4.1.0 h1:uZNPbwusB0eUXlO8hIUwStE6Lr5bLN6IgYgG+75kuh4= -github.com/bombsimon/logrusr/v4 v4.1.0/go.mod h1:pjfHC5e59CvjTBIU3V3sGhFWFAnsnhOR03TRc6im0l8= -github.com/bradleyfalzon/ghinstallation/v2 v2.15.0 h1:7r2rPUM04rgszMP0U1UZ1M5VoVVIlsaBSnpABfYxcQY= -github.com/bradleyfalzon/ghinstallation/v2 v2.15.0/go.mod h1:PoH9Vhy82OeRFZfxsVrk3mfQhVkEzou9OOwPOsEhiXE= +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.12.0 h1:k8oVjGhZel2qmCUsYwSE34jPNT9DL2wCBOtugsHv26g= +github.com/bradleyfalzon/ghinstallation/v2 v2.12.0/go.mod h1:V4gJcNyAftH0rXpRp1SUVUuh+ACxOH1xOk/ZzkRHltg= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/bwmarrin/discordgo v0.19.0/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q= -github.com/casbin/casbin/v2 v2.105.0 h1:dLj5P6pLApBRat9SADGiLxLZjiDPvA1bsPkyV4PGx6I= -github.com/casbin/casbin/v2 v2.105.0/go.mod h1:Ee33aqGrmES+GNL17L0h9X28wXuo829wnNUnS0edAco= -github.com/casbin/govaluate v1.3.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A= -github.com/casbin/govaluate v1.7.0 h1:Es2j2K2jv7br+QHJhxKcdoOa4vND0g0TqsO6rJeqJbA= -github.com/casbin/govaluate v1.7.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/casbin/casbin/v2 v2.102.0 h1:weq9iSThUSL21SH3VrwoKa2DgRsaYMfjRNX/yOU3Foo= +github.com/casbin/casbin/v2 v2.102.0/go.mod h1:LO7YPez4dX3LgoTCqSQAleQDo0S0BeZBDxYnPUl95Ng= +github.com/casbin/govaluate v1.2.0 h1:wXCXFmqyY+1RwiKfYo3jMKyrtZmOL3kHwaqDyCPOYak= +github.com/casbin/govaluate v1.2.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -191,24 +177,39 @@ github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNS github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= github.com/chainguard-dev/git-urls v1.0.2 h1:pSpT7ifrpc5X55n4aTTm7FFUE+ZQHKiqpiwNkJrVcKQ= github.com/chainguard-dev/git-urls v1.0.2/go.mod h1:rbGgj10OS7UgZlbzdUQIQpT0k/D4+An04HJY7Ol+Y/o= +github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= +github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs= +github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= -github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27/go.mod h1:VQx0hjo2oUeQkQUET7wRwradO6f+fN5jzXgB/zROxxE= -github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk= -github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU= -github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= -github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= +github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= 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.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= -github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= +github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= 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= @@ -216,57 +217,66 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0= github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE= github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= -github.com/desertbit/timer v1.0.1 h1:yRpYNn5Vaaj6QXecdLMPMJsW81JLiI1eokUft5nBmeo= -github.com/desertbit/timer v1.0.1/go.mod h1:htRrYeY5V/t4iu1xCJ5XsQvp4xve8QulXXctAzxqcwE= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= -github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= -github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +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/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= -github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= -github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM= +github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ= +github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v5.9.11+incompatible h1:ixHHqfcGvxhWkniF1tWxBHA0yb4Z+d1UQi45df52xW8= -github.com/evanphx/json-patch v5.9.11+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= -github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= -github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4= -github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= -github.com/expr-lang/expr v1.17.3 h1:myeTTuDFz7k6eFe/JPlep/UsiIjVhG61FMHFu63U7j0= -github.com/expr-lang/expr v1.17.3/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4= +github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= +github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= +github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/expr-lang/expr v1.17.0 h1:+vpszOyzKLQXC9VF+wA8cVA0tlA984/Wabc/1hF9Whg= +github.com/expr-lang/expr v1.17.0/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= -github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gfleury/go-bitbucket-v1 v0.0.0-20240917142304-df385efaac68 h1:iJXWkoIPk3e8RVHhQE/gXfP2TP3OLQ9vVPNSJ+oL6mM= -github.com/gfleury/go-bitbucket-v1 v0.0.0-20240917142304-df385efaac68/go.mod h1:bB7XwdZF40tLVnu9n5A9TjI2ddNZtLYImtwYwmcmnRo= -github.com/gfleury/go-bitbucket-v1/test/bb-mock-server v0.0.0-20230825095122-9bc1711434ab h1:BeG9dDWckFi/p5Gvqq3wTEDXsUV4G6bdvjEHMOT2B8E= -github.com/gfleury/go-bitbucket-v1/test/bb-mock-server v0.0.0-20230825095122-9bc1711434ab/go.mod h1:VssB0kb1cETNaFFC/0mHVCj+7i5TS2xraYq+tl9JLwE= +github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e h1:C3DkNr9pxqXqCrmRHO7s3XgZS3zpi9GEA01GuWZODfo= +github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e/go.mod h1:LB3osS9X2JMYmTzcCArHHLrndBAfcVLQAvUddfs+ONs= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -285,21 +295,28 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ= -github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= +github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-jose/go-jose/v4 v4.1.0 h1:cYSYxd3pw5zd2FSXk2vGdn9igQU2PS8MuxrCOCl0FdY= -github.com/go-jose/go-jose/v4 v4.1.0/go.mod h1:GG/vqmYm3Von2nYiB2vGTXzdoNKE5tix5tuc6iAd+sw= +github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= +github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= +github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= 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.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= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -310,8 +327,11 @@ github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC0 github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco= @@ -322,6 +342,8 @@ github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9Z github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= @@ -337,9 +359,11 @@ github.com/go-playground/webhooks/v6 v6.4.0 h1:KLa6y7bD19N48rxJDHM0DpE3T4grV7GxM github.com/go-playground/webhooks/v6 v6.4.0/go.mod h1:5lBxopx+cAJiBI4+kyRbuHrEi+hYRDdRHuRR4Ya5Ums= github.com/go-redis/cache/v9 v9.0.0 h1:0thdtFo0xJi0/WXbRVu8B066z8OvVymXTJGaXrVWnN0= github.com/go-redis/cache/v9 v9.0.0/go.mod h1:cMwi1N8ASBOufbIvk7cdXe2PbPjK/WMRL95FFHWsSgI= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= @@ -356,9 +380,11 @@ github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= -github.com/gogits/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 h1:04sojTxgYxu1L4Hn7Tgf7UVtIosVa6CuHtvNY+7T1K4= -github.com/gogits/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85/go.mod h1:cY2AIrMgHm6oOHmR7jY+9TtjzSjQ3iG7tURJG3Y6XH0= +github.com/gogits/go-gogs-client v0.0.0-20200905025246-8bb8a50cb355 h1:HTVNOdTWO/gHYeFnr/HwpYwY6tgMcYd+Rgf1XrHnORY= +github.com/gogits/go-gogs-client v0.0.0-20200905025246-8bb8a50cb355/go.mod h1:cY2AIrMgHm6oOHmR7jY+9TtjzSjQ3iG7tURJG3Y6XH0= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 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= @@ -369,187 +395,212 @@ github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= -github.com/golang/glog v1.2.4/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= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= -github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-github/v69 v69.2.0 h1:wR+Wi/fN2zdUx9YxSmYE0ktiX9IAR/BeePzeaUUbEHE= -github.com/google/go-github/v69 v69.2.0/go.mod h1:xne4jymxLR6Uj9b7J7PyTpkMYstEMMwGZa0Aehh1azM= -github.com/google/go-github/v71 v71.0.0 h1:Zi16OymGKZZMm8ZliffVVJ/Q9YZreDKONCr+WUd0Z30= -github.com/google/go-github/v71 v71.0.0/go.mod h1:URZXObp2BLlMjwu0O8g4y6VBneUj2bCHgnI8FfgZ51M= -github.com/google/go-jsonnet v0.21.0 h1:43Bk3K4zMRP/aAZm9Po2uSEjY6ALCkYUVIcz9HLGMvA= -github.com/google/go-jsonnet v0.21.0/go.mod h1:tCGAu8cpUpEZcdGMmdOu37nh8bGgqubhI5v2iSk3KJQ= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= +github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg= +github.com/google/go-github/v66 v66.0.0 h1:ADJsaXj9UotwdgK8/iFZtv7MLc8E8WBl62WLd/D/9+M= +github.com/google/go-github/v66 v66.0.0/go.mod h1:+4SO9Zkuyf8ytMj0csN1NR/5OTR+MfqPp8P8dVlcvY4= +github.com/google/go-jsonnet v0.20.0 h1:WG4TTSARuV7bSm4PMB4ohjxe33IHT5WVTrJSU33uT4g= +github.com/google/go-jsonnet v0.20.0/go.mod h1:VbgWF9JX7ztlv770x/TolZNGGFfiHEVx9G6ca2eUmeA= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= -github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.1-0.20241114170450-2d3c2a9cc518 h1:UBg1xk+oAsIVbFuGg6hdfAm7EvCv3EL80vFxJNsslqw= -github.com/google/uuid v1.6.1-0.20241114170450-2d3c2a9cc518/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= -github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= -github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo= github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= -github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= -github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gosimple/slug v1.15.0 h1:wRZHsRrRcs6b0XnxMUBM6WK1U1Vg5B0R7VkIf1Xzobo= -github.com/gosimple/slug v1.15.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= +github.com/gosimple/slug v1.14.0 h1:RtTL/71mJNDfpUbCOmnf/XFkzKRtD6wL6Uy+3akm4Es= +github.com/gosimple/slug v1.14.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= -github.com/gregdel/pushover v1.3.1 h1:4bMLITOZ15+Zpi6qqoGqOPuVHCwSUvMCgVnN5Xhilfo= -github.com/gregdel/pushover v1.3.1/go.mod h1:EcaO66Nn1StkpEm1iKtBTV3d2A16SoMsVER1PthX7to= +github.com/gregdel/pushover v1.2.1 h1:IPPJCdzXz60gMqnlzS0ZAW5z5aS1gI4nU+YM0Pe+ssA= +github.com/gregdel/pushover v1.2.1/go.mod h1:EcaO66Nn1StkpEm1iKtBTV3d2A16SoMsVER1PthX7to= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= -github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= -github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-retryablehttp v0.5.1/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/improbable-eng/grpc-web v0.15.1-0.20230209220825-1d9bbb09a099 h1:k07oXM8RqIaaSEF09Frr/iRMlwx2qvx6vRo2XuPIeW8= -github.com/improbable-eng/grpc-web v0.15.1-0.20230209220825-1d9bbb09a099/go.mod h1:Vkb7Iy2LTlRGIAubpODgfeKPzu8nsh1gO+vvZAiZrcs= +github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= +github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/itchyny/gojq v0.12.17 h1:8av8eGduDb5+rvEdaOO+zQUjA04MS0m3Ps8HiD+fceg= github.com/itchyny/gojq v0.12.17/go.mod h1:WBrEMkgAfAGO1LUcGOckBl5O726KPp+OlkKug0I/FEY= github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q= github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg= -github.com/jarcoal/httpmock v1.4.0 h1:BvhqnH0JAYbNudL2GMJKgOHe2CtKlzJ/5rWKyp+hc2k= -github.com/jarcoal/httpmock v1.4.0/go.mod h1:ftW1xULwo+j0R0JJkJIIi7UKigZUXCLLanykgjwBXL0= github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jeremywohl/flatten v1.0.2-0.20211013061545-07e4a09fb8e4 h1:4mRgApcowAtxNLwOQ93jhHMLFgkX2D5yM53mtZSk6Nw= -github.com/jeremywohl/flatten v1.0.2-0.20211013061545-07e4a09fb8e4/go.mod h1:4AmD/VxjWcI5SRB0n6szE2A6s2fsNHDLO0nAlMHgfLQ= +github.com/jeremywohl/flatten v1.0.1 h1:LrsxmB3hfwJuE+ptGOijix1PIfOoKLJ3Uee/mzbgtrs= +github.com/jeremywohl/flatten v1.0.1/go.mod h1:4AmD/VxjWcI5SRB0n6szE2A6s2fsNHDLO0nAlMHgfLQ= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= -github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= -github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -557,52 +608,71 @@ 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.85 h1:WSKYSmpgasEmtnsr+TEhD2UtiZjCZpeTBF5T4f6/d8k= -github.com/ktrysmt/go-bitbucket v0.9.85/go.mod h1:ZgvxUOaC6eHrNaC/DbjFvJUXaKpKeDYvfhh4U592jcs= +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= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5/go.mod h1:c2mYKRyMb1BPkO5St0c/ps62L4S0W2NAkaTXj9qEI+0= github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018/go.mod h1:sFlOUpQL1YcjhFVXhg1CG8ZASEs/Mf1oVb6H75JL/zg= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/mailgun/mailgun-go v2.0.0+incompatible/go.mod h1:NWTyU+O4aczg/nsGhQnvHL6v2n5Gy6Sv5tNDVvC6FbU= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/malexdev/utfutil v0.0.0-20180510171754-00c8d4a8e7a8 h1:A6SLdFpRzUUF5v9F/7T1fu3DERmOCgTwwP6x54eyFfU= +github.com/malexdev/utfutil v0.0.0-20180510171754-00c8d4a8e7a8/go.mod h1:UtpLyb/EupVKXF/N0b4NRe1DNg+QYJsnsHQ038romhM= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-zglob v0.0.6 h1:mP8RnmCgho4oaUYDIDn6GNxYk+qJGUs8fJLn+twYj2A= github.com/mattn/go-zglob v0.0.6/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/maxatome/go-testdeep v1.14.0 h1:rRlLv1+kI8eOI3OaBXZwb3O7xY3exRzdW5QyX48g9wI= -github.com/maxatome/go-testdeep v1.14.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= -github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.1-0.20241014080628-3045bdf43455 h1:7rDE4oHmFDgf+4fqnT5vztz7Bmcos1tr17VisCXgs/o= -github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.1-0.20241014080628-3045bdf43455/go.mod h1:mDunUZ1IUJdJIRHvFb+LPBUtxe3AYB5MI6BMXNg8194= +github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5 h1:YH424zrwLTlyHSH/GzLMJeu5zhYVZSx5RQxGKm1h96s= +github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5/go.mod h1:PoGiBqKSQK1vIfQ+yVaFcGjDySHvym6FM1cNYnwzbrY= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= +github.com/minio/minio-go/v7 v7.0.58/go.mod h1:NUDy4A4oXPq1l2yK6LTSvCEzAMeIcoz9lcj5dbzSrRE= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= -github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8= +github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -615,6 +685,7 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY 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/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= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -623,20 +694,28 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nlopes/slack v0.5.0/go.mod h1:jVI4BBK3lSktibKahxBF74txcK2vyvkza1z/+rRnVAM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 h1:r3FaAI0NZK3hSmtTDrBVREhKULp8oUeqLT5Eyl2mSPo= -github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= -github.com/olekukonko/ll v0.0.8-0.20250516010636-22ea57d81985 h1:V2wKiwjwAfRJRtUP6pC7wt4opeF14enO0du2dRV6Llo= -github.com/olekukonko/ll v0.0.8-0.20250516010636-22ea57d81985/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v1.0.6 h1:/T45mIHc5hcEvibgzBzvMy7ruT+RjgoQRvkHbnl6OWA= -github.com/olekukonko/tablewriter v1.0.6/go.mod h1:SJ0MV1aHb/89fLcsBMXMp30Xg3g5eGoOUu0RptEk4AU= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= @@ -650,8 +729,19 @@ github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8Ay github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= -github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= -github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= +github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -664,111 +754,164 @@ github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= -github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= -github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= +github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= -github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.23 h1:EFOD/cRfMeq+PCibHddoRTXu8CTN1m8Oj1Tk6eoz8Dw= -github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.23/go.mod h1:1BK0BG3Mz//zeujilvvu3GJ0jnyZwFdT9XjznoPv6kk= -github.com/patrickmn/go-cache v2.1.1-0.20191004192108-46f407853014+incompatible h1:IWzUvJ72xMjmrjR9q3H1PF+jwdN0uNQiR2t1BLNalyo= -github.com/patrickmn/go-cache v2.1.1-0.20191004192108-46f407853014+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/opsgenie/opsgenie-go-sdk-v2 v1.0.5 h1:AnS8ZCC5dle8P4X4FZ+IOlX9v0jAkCMiZDIzRnYwBbs= +github.com/opsgenie/opsgenie-go-sdk-v2 v1.0.5/go.mod h1:f0ezb0R/mrB9Hpm5RrIS6EX3ydjsR2nAB88nYYXZcNY= +github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= 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= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang 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.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= +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= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= -github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/r3labs/diff/v3 v3.0.1 h1:CBKqf3XmNRHXKmdU7mZP1w7TV0pDyVCis1AUHtA4Xtg= -github.com/r3labs/diff/v3 v3.0.1/go.mod h1:f1S9bourRbiM66NskseyUdo0fTmEE0qKrikYJX63dgo= +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.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI= -github.com/redis/go-redis/v9 v9.8.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= +github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM= +github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA= 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= -github.com/robfig/cron/v3 v3.0.2-0.20210106135023-bc59245fe10e h1:0xChnl3lhHiXbgSJKgChye0D+DvoItkOdkGcwelDXH0= -github.com/robfig/cron/v3 v3.0.2-0.20210106135023-bc59245fe10e/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a h1:3QH7VyOaaiUHNrA9Se4YQIRkDTCw1EJls9xTUCaCeRM= +github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a/go.mod h1:4r5QyqhjIWCcK8DO4KMclc5Iknq5qVBAlbYYzAbUScQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 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.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= -github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= +github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= -github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= -github.com/slack-go/slack v0.16.0 h1:khp/WCFv+Hb/B/AJaAwvcxKun0hM6grN0bUZ8xG60P8= -github.com/slack-go/slack v0.16.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= +github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= +github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= +github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c h1:fyKiXKO1/I/B6Y2U8T7WdQGWzwehOuGIrljPtt7YTTI= +github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= +github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= +github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM= github.com/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4= -github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= -github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= +github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= -github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -785,110 +928,128 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/vmihailenco/go-tinylfu v0.2.2 h1:H1eiG6HM36iniK6+21n9LLpzx1G9R3DJa2UjUjbynsI= github.com/vmihailenco/go-tinylfu v0.2.2/go.mod h1:CutYi2Q9puTxfcolkliPq4npPuofg9N9t8JVrjzwa3Q= +github.com/vmihailenco/msgpack/v5 v5.3.4 h1:qMKAwOV+meBw2Y8k9cVwAy7qErtYCwBzZ2ellBfvnqc= github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= -github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= 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.114.0 h1:0wQr/KBckwrZPfEMjRqpUz0HmsKKON9UhCYv9KDy19M= +github.com/xanzy/go-gitlab v0.114.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= -gitlab.com/gitlab-org/api/client-go v0.116.0 h1:Dy534gtZPMrnm3fAcmQRMadrcoUyFO4FQ4rXlSAdHAw= -gitlab.com/gitlab-org/api/client-go v0.116.0/go.mod h1:B29OfnZklmaoiR7uHANh9jTyfWEgmXvZLVEnosw2Dx0= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.mongodb.org/mongo-driver v1.17.1 h1:Wic5cJIwJgSpBhe3lx3+/RybR5PiYRMpVFgO7cOHyIM= go.mongodb.org/mongo-driver v1.17.1/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/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/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= -go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= -go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo= -go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= -go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= -go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= -go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= -go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= -go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= -go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= -go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= -go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= -go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 h1:yMkBS9yViCc7U7yeLzJPM2XizlfdVvBRSmsQDWu6qc0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0/go.mod h1:n8MR6/liuGB5EmTETUBeU5ZgqMOlqKRxUaqPQBOANZ8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= +go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 h1:9kV11HXBHZAvuPUZxmMWrH8hZn/6UnHX4K0mu36vNsU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0/go.mod h1:JyA0FHXe22E1NeNiHmVp7kFHglnexDQ7uRWDiiJ1hKQ= +go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= +go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= +go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= +go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= +go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= +go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= +go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= +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.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.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= -go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +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= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +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.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= 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-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= @@ -898,16 +1059,9 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -917,46 +1071,42 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -967,88 +1117,95 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +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.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= 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-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +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.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= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +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= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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-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= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1059,25 +1216,47 @@ golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +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.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +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= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= -golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= +golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1086,58 +1265,40 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +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.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +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.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +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.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +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= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= @@ -1145,12 +1306,24 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 h1:juzzlx91nWAOsHuOVfXZPMXHtJEKouZvY9bBbwlOeYs= gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45/go.mod h1:41y72mzHT7+jFNgyBpJRrZWuZJcLmLrTpq6iGgOFJMQ= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= @@ -1158,95 +1331,55 @@ gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuB gomodules.xyz/notify v0.1.1 h1:1tTuoyswmPvzqPCTEDQK8SZ3ukCxLsonAAwst2+y1a0= gomodules.xyz/notify v0.1.1/go.mod h1:QgQyU4xEA/plJcDeT66J2Go2V7U4c0pD9wjo7HfFil4= gomodules.xyz/version v0.1.0/go.mod h1:Y8xuV02mL/45psyPKG3NCVOwvAOy6T5Kx0l3rCjKSjU= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.223.0 h1:JUTaWEriXmEy5AhvdMgksGGPEFsYfUKaPEYXd4c3Wvc= -google.golang.org/api v0.223.0/go.mod h1:C+RS7Z+dDwds2b+zoAk5hN/eSfsiCn0UDrYof/M4d2M= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= +google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= -google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0= -google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2 h1:DMTIbak9GhdaSxEjvVzAeNZvyc03I61duqNbnm3SU0M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 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.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA= -google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= +google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 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.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= @@ -1255,16 +1388,21 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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/dnaeon/go-vcr.v4 v4.0.2 h1:7T5VYf2ifyK01ETHbJPl5A6XTpUljD4Trw3GEDcdedk= -gopkg.in/dnaeon/go-vcr.v4 v4.0.2/go.mod h1:65yxh9goQVrudqofKtHA4JNFWd6XZRkWfKN4YpMx7KI= +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= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/retry.v1 v1.0.3 h1:a9CArYczAVv6Qs6VGoLMio99GEs7kY9UzSF9+LD+iGs= +gopkg.in/retry.v1 v1.0.3/go.mod h1:FJkXmWiMaAo7xB+xhvDF59zhfjDWyzmyAxiT4dB688g= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= @@ -1273,69 +1411,68 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw= -k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y= -k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscghPCvV4= -k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA= -k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ= -k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= -k8s.io/apiserver v0.32.2 h1:WzyxAu4mvLkQxwD9hGa4ZfExo3yZZaYzoYvvVDlM6vw= -k8s.io/apiserver v0.32.2/go.mod h1:PEwREHiHNU2oFdte7BjzA1ZyjWjuckORLIK/wLV5goM= -k8s.io/cli-runtime v0.32.2 h1:aKQR4foh9qeyckKRkNXUccP9moxzffyndZAvr+IXMks= -k8s.io/cli-runtime v0.32.2/go.mod h1:a/JpeMztz3xDa7GCyyShcwe55p8pbcCVQxvqZnIwXN8= -k8s.io/client-go v0.32.2 h1:4dYCD4Nz+9RApM2b/3BtVvBHw54QjMFUl1OLcJG5yOA= -k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94= -k8s.io/code-generator v0.32.2 h1:CIvyPrLWP7cMgrqval2qYT839YAwCDeSvGfXgWSNpHQ= -k8s.io/code-generator v0.32.2/go.mod h1:plh7bWk7JztAUkHM4zpbdy0KOMdrhsePcZL2HLWFH7Y= -k8s.io/component-base v0.32.2 h1:1aUL5Vdmu7qNo4ZsE+569PV5zFatM9hl+lb3dEea2zU= -k8s.io/component-base v0.32.2/go.mod h1:PXJ61Vx9Lg+P5mS8TLd7bCIr+eMJRQTyXe8KvkrvJq0= -k8s.io/component-helpers v0.32.2 h1:2usSAm3zNE5yu5DdAdrKBWLfSYNpU4OPjZywJY5ovP8= -k8s.io/component-helpers v0.32.2/go.mod h1:fvQAoiiOP7jUEUBc9qR0PXiBPuB0I56WTxTkkpcI8g8= -k8s.io/controller-manager v0.32.2 h1:/9XuHWEqofO2Aqa4l7KJGckJUcLVRWfx+qnVkdXoStI= -k8s.io/controller-manager v0.32.2/go.mod h1:o5uo2tLCQhuoMt0RfKcQd0eqaNmSKOKiT+0YELCqXOk= -k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 h1:si3PfKm8dDYxgfbeA6orqrtLkvvIeH8UqffFJDl0bz4= -k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= +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.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= +k8s.io/cli-runtime v0.31.0/go.mod h1:vg3H94wsubuvWfSmStDbekvbla5vFGC+zLWqcf+bGDw= +k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8= +k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= +k8s.io/code-generator v0.31.0 h1:w607nrMi1KeDKB3/F/J4lIoOgAwc+gV9ZKew4XRfMp8= +k8s.io/code-generator v0.31.0/go.mod h1:84y4w3es8rOJOUUP1rLsIiGlO1JuEaPFXQPA9e/K6U0= +k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs= +k8s.io/component-base v0.31.0/go.mod h1:TYVuzI1QmN4L5ItVdMSXKvH7/DtvIuas5/mm8YT3rTo= +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/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= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-aggregator v0.32.2 h1:kg9pke+i2qRbJwX1UKwZV4fsCRvmbaCEFk38R4FqHmw= -k8s.io/kube-aggregator v0.32.2/go.mod h1:rRm+xY1yIFIt3zBc727nG5SBLYywywD87klfIAw+7+c= -k8s.io/kube-openapi v0.0.0-20250304201544-e5f78fe3ede9 h1:t0huyHnz6HsokckRxAF1bY0cqPFwzINKCL7yltEjZQc= -k8s.io/kube-openapi v0.0.0-20250304201544-e5f78fe3ede9/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/kubectl v0.32.2 h1:TAkag6+XfSBgkqK9I7ZvwtF0WVtUAvK8ZqTt+5zi1Us= -k8s.io/kubectl v0.32.2/go.mod h1:+h/NQFSPxiDZYX/WZaWw9fwYezGLISP0ud8nQKg+3g8= -k8s.io/kubernetes v1.32.2 h1:mShetlA102UpjRVSGzB+5vjJwy8oPy8FMWrkTH5f37o= -k8s.io/kubernetes v1.32.2/go.mod h1:tiIKO63GcdPRBHW2WiUFm3C0eoLczl3f7qi56Dm1W8I= -k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= -k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-aggregator v0.31.0 h1:3DqSpmqHF8rey7fY+qYXLJms0tYPhxrgWvjpnKVnS0Y= +k8s.io/kube-aggregator v0.31.0/go.mod h1:Fa+OVSpMQC7zbTTz7/QG7FXe9jZ8usuJQej5sMdCrkM= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/kubectl v0.31.0 h1:kANwAAPVY02r4U4jARP/C+Q1sssCcN/1p9Nk+7BQKVg= +k8s.io/kubectl v0.31.0/go.mod h1:pB47hhFypGsaHAPjlwrNbvhXgmuAr01ZBvAIIUaI8d4= +k8s.io/kubernetes v1.31.0 h1:sYAB12TTWexXKp4RxqJMm/7EC+P0mNOgn4Xdj5eu7HM= +k8s.io/kubernetes v1.31.0/go.mod h1:UTpGn7nxrUrPWw5hNIYTAjodcWIvLakgHpLtfrr6GC8= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= layeh.com/gopher-json v0.0.0-20190114024228-97fed8db8427 h1:RZkKxMR3jbQxdCEcglq3j7wY3PRJIopAwBlx1RE71X0= layeh.com/gopher-json v0.0.0-20190114024228-97fed8db8427/go.mod h1:ivKkcY8Zxw5ba0jldhZCYYQfGdb2K6u9tbYK1AwMIBc= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= 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.6.0 h1:X4ELRsiGkrbeox69+9tzTu492FMUu7zJQW6eJU+I2oc= -oras.land/oras-go/v2 v2.6.0/go.mod h1:magiQDfG6H1O9APp+rOsvCPcW1GD2MM7vgnKY0Y+u1o= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/controller-runtime v0.20.4 h1:X3c+Odnxz+iPTRobG4tp092+CvBU9UK0t/bRf+n0DGU= -sigs.k8s.io/controller-runtime v0.20.4/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= -sigs.k8s.io/kustomize/api v0.18.0 h1:hTzp67k+3NEVInwz5BHyzc9rGxIauoXferXyjv5lWPo= -sigs.k8s.io/kustomize/api v0.18.0/go.mod h1:f8isXnX+8b+SGLHQ6yO4JG1rdkZlvhaCf/uZbLVMb0U= -sigs.k8s.io/kustomize/kyaml v0.18.1 h1:WvBo56Wzw3fjS+7vBjN6TeivvpbW9GmRaWZ9CIVmt4E= -sigs.k8s.io/kustomize/kyaml v0.18.1/go.mod h1:C3L2BFVU1jgcddNBE1TxuVLgS46TjObMwW5FT9FcjYo= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= -sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI= -sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= +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.3 h1:XO2GvC9OPftRst6xWCpTgBZO04S2cbp0Qqkj8bX1sPw= +sigs.k8s.io/controller-runtime v0.19.3/go.mod h1:j4j87DqtsThvwTv5/Tc5NFRyyF/RF0ip4+62tbTSIUM= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= +sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0= +sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= +sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/structured-merge-diff/v4 v4.4.4-0.20241211184406-7bf59b3d70ee h1:ipT2c6nEOdAfBwiwW1oI0mkrlPabbXEFmJBrg6B+OR8= +sigs.k8s.io/structured-merge-diff/v4 v4.4.4-0.20241211184406-7bf59b3d70ee/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/hack/bump-major-version.sh b/hack/bump-major-version.sh deleted file mode 100755 index 931bb57ef5..0000000000 --- a/hack/bump-major-version.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -# This script bumps the major version of Argo CD. Before cutting a new major release, run this script and open a PR. - -# Get the current version from go.mod. -CURRENT_VERSION=$(grep 'module github.com/argoproj/argo-cd' go.mod | awk '{print $2}' | sed 's/.*\/v//') - -echo "Upgrading from v${CURRENT_VERSION} to v$((CURRENT_VERSION + 1))..." - -# sed commands in this script use -i.bak for compatibility with both GNU sed and BSD sed. - -for file in .golangci.yaml .goreleaser.yaml .mockery.yaml Makefile Procfile; do - echo "Incrementing the major version in $file..." - sed -i.bak "s/github\.com\/argoproj\/argo-cd\/v${CURRENT_VERSION}/github\.com\/argoproj\/argo-cd\/v$((CURRENT_VERSION + 1))/g" "$file" && echo " Updated $file" && rm "$file.bak" -done - -for file in hack/generate-proto.sh hack/update-codegen.sh hack/update-openapi.sh; do - echo "Incrementing the major version in $file..." - sed -i.bak "s/v${CURRENT_VERSION}/v$((CURRENT_VERSION + 1))/g" "$file" && echo " Update $file" && rm "$file.bak" -done - -echo "Incrementing the major version in proto files..." -find . -name '*.proto' -not -path "./vendor/*" -not -path "./dist/*" -exec sed -i.bak "s/github\.com\/argoproj\/argo-cd\/v${CURRENT_VERSION}/github\.com\/argoproj\/argo-cd\/v$((CURRENT_VERSION + 1))/g" {} \; -exec echo " Updated" {} \; -exec rm {}.bak \; -find . -name '*.proto' -not -path "./vendor/*" -not -path "./dist/*" -exec sed -i.bak "s/github\.com\.argoproj\.argo_cd\.v${CURRENT_VERSION}/github\.com\.argoproj\.argo_cd\.v$((CURRENT_VERSION + 1))/g" {} \; -exec echo " Updated" {} \; -exec rm {}.bak \; - -echo "Incrementing the major version in go files..." -find . -name '*.go' -not -path "./vendor/*" -not -path "./dist/*" -exec sed -i.bak "s/github\.com\/argoproj\/argo-cd\/v${CURRENT_VERSION}/github\.com\/argoproj\/argo-cd\/v$((CURRENT_VERSION + 1))/g" {} \; -exec echo " Updated" {} \; -exec rm {}.bak \; - -echo "Incrementing the major version in go.mod..." -sed -i.bak "s/github\.com\/argoproj\/argo-cd\/v${CURRENT_VERSION}/github\.com\/argoproj\/argo-cd\/v$((CURRENT_VERSION + 1))/g" go.mod && echo " Updated go.mod" && rm go.mod.bak - -echo 'Finished! Now run `make codegen-local && make lint-local && make test-local` to ensure everything is working as expected.' diff --git a/hack/dev-mounter/main.go b/hack/dev-mounter/main.go index 82a81968e6..b74d46c170 100644 --- a/hack/dev-mounter/main.go +++ b/hack/dev-mounter/main.go @@ -9,16 +9,16 @@ import ( "strings" "time" + "github.com/argoproj/pkg/errors" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" - "github.com/argoproj/argo-cd/v3/util/cli" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/util/cli" // load the gcp plugin (required to authenticate against GKE clusters). _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" @@ -34,7 +34,7 @@ func newCommand() *cobra.Command { configMaps []string ) command := cobra.Command{ - Run: func(_ *cobra.Command, _ []string) { + Run: func(cmd *cobra.Command, args []string) { config, err := clientConfig.ClientConfig() errors.CheckError(err) ns, _, err := clientConfig.Namespace() @@ -49,8 +49,8 @@ func newCommand() *cobra.Command { cmNameToPath[parts[0]] = parts[1] } - handledConfigMap := func(obj any) { - cm, ok := obj.(*corev1.ConfigMap) + handledConfigMap := func(obj interface{}) { + cm, ok := obj.(*v1.ConfigMap) if !ok { return } @@ -99,7 +99,7 @@ func newCommand() *cobra.Command { informer := factory.Core().V1().ConfigMaps().Informer() _, err = informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: handledConfigMap, - UpdateFunc: func(_, newObj any) { + UpdateFunc: func(oldObj, newObj interface{}) { handledConfigMap(newObj) }, }) diff --git a/hack/gen-catalog/main.go b/hack/gen-catalog/main.go index 04cd1554f8..c7963dbf83 100644 --- a/hack/gen-catalog/main.go +++ b/hack/gen-catalog/main.go @@ -9,20 +9,19 @@ import ( "path/filepath" "strings" + "github.com/spf13/cobra/doc" + + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/admin" + "github.com/argoproj/notifications-engine/pkg/services" "github.com/argoproj/notifications-engine/pkg/triggers" "github.com/argoproj/notifications-engine/pkg/util/misc" "github.com/olekukonko/tablewriter" - "github.com/olekukonko/tablewriter/renderer" - "github.com/olekukonko/tablewriter/tw" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/spf13/cobra/doc" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/yaml" - - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/admin" ) func main() { @@ -44,8 +43,8 @@ func main() { func newCatalogCommand() *cobra.Command { return &cobra.Command{ Use: "catalog", - Run: func(_ *cobra.Command, _ []string) { - cm := corev1.ConfigMap{ + Run: func(c *cobra.Command, args []string) { + cm := v1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", APIVersion: "v1", @@ -69,14 +68,14 @@ func newCatalogCommand() *cobra.Command { trigger := triggers[name] t, err := yaml.Marshal(trigger) dieOnError(err, "Failed to marshal trigger") - cm.Data["trigger."+name] = string(t) + cm.Data[fmt.Sprintf("trigger.%s", name)] = string(t) }) misc.IterateStringKeyMap(templates, func(name string) { template := templates[name] t, err := yaml.Marshal(template) dieOnError(err, "Failed to marshal template") - cm.Data["template."+name] = string(t) + cm.Data[fmt.Sprintf("template.%s", name)] = string(t) }) d, err := yaml.Marshal(cm) @@ -91,7 +90,7 @@ func newCatalogCommand() *cobra.Command { func newDocsCommand() *cobra.Command { return &cobra.Command{ Use: "docs", - Run: func(_ *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { var builtItDocsData bytes.Buffer wd, err := os.Getwd() dieOnError(err, "Failed to get current working directory") @@ -127,13 +126,11 @@ func generateBuiltInTriggersDocs(out io.Writer, triggers map[string][]triggers.C _, _ = fmt.Fprintln(out, "## Triggers") - r := tw.Rendition{ - Borders: tw.Border{Left: tw.On, Top: tw.Off, Right: tw.On, Bottom: tw.Off}, - Symbols: tw.NewSymbolCustom("pipe-center").WithCenter("|").WithMidLeft("|").WithMidRight("|"), - } - c := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone).Build() - table := tablewriter.NewTable(out, tablewriter.WithConfig(c), tablewriter.WithRenderer(renderer.NewBlueprint(r))) - table.Header("NAME", "DESCRIPTION", "TEMPLATE") + w := tablewriter.NewWriter(out) + w.SetHeader([]string{"NAME", "DESCRIPTION", "TEMPLATE"}) + w.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) + w.SetCenterSeparator("|") + w.SetAutoWrapText(false) misc.IterateStringKeyMap(triggers, func(name string) { t := triggers[name] desc := "" @@ -142,15 +139,9 @@ func generateBuiltInTriggersDocs(out io.Writer, triggers map[string][]triggers.C desc = t[0].Description template = strings.Join(t[0].Send, ",") } - err := table.Append([]string{name, desc, fmt.Sprintf("[%s](#%s)", template, template)}) - if err != nil { - panic(err) - } + w.Append([]string{name, desc, fmt.Sprintf("[%s](#%s)", template, template)}) }) - err := table.Render() - if err != nil { - panic(err) - } + w.Render() _, _ = fmt.Fprintln(out, "") _, _ = fmt.Fprintln(out, "## Templates") diff --git a/hack/gen-crd-spec/main.go b/hack/gen-crd-spec/main.go index c102e9b2f6..16c0022dd1 100644 --- a/hack/gen-crd-spec/main.go +++ b/hack/gen-crd-spec/main.go @@ -8,10 +8,10 @@ import ( "os/exec" "strings" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" "github.com/argoproj/gitops-engine/pkg/utils/kube" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + extensionsobj "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/yaml" ) @@ -22,7 +22,7 @@ var kindToCRDPath = map[string]string{ application.ApplicationSetFullName: "manifests/crds/applicationset-crd.yaml", } -func getCustomResourceDefinitions() map[string]*apiextensionsv1.CustomResourceDefinition { +func getCustomResourceDefinitions() map[string]*extensionsobj.CustomResourceDefinition { crdYamlBytes, err := exec.Command( "controller-gen", "paths=./pkg/apis/application/...", @@ -41,7 +41,7 @@ func getCustomResourceDefinitions() map[string]*apiextensionsv1.CustomResourceDe objs, err := kube.SplitYAML(crdYamlBytes) checkErr(err) - crds := make(map[string]*apiextensionsv1.CustomResourceDefinition) + crds := make(map[string]*extensionsobj.CustomResourceDefinition) for i := range objs { un := objs[i] @@ -80,27 +80,27 @@ func removeValidation(un *unstructured.Unstructured, path string) { unstructured.RemoveNestedField(un.Object, schemaPath...) } -func toCRD(un *unstructured.Unstructured, removeDesc bool) *apiextensionsv1.CustomResourceDefinition { +func toCRD(un *unstructured.Unstructured, removeDesc bool) *extensionsobj.CustomResourceDefinition { if removeDesc { removeDescription(un.Object) } unBytes, err := json.Marshal(un) checkErr(err) - var crd apiextensionsv1.CustomResourceDefinition + var crd extensionsobj.CustomResourceDefinition err = json.Unmarshal(unBytes, &crd) checkErr(err) return &crd } -func removeDescription(v any) { +func removeDescription(v interface{}) { switch v := v.(type) { - case []any: + case []interface{}: for _, v := range v { removeDescription(v) } - case map[string]any: + case map[string]interface{}: if _, ok := v["description"]; ok { _, ok := v["description"].(string) if ok { @@ -134,7 +134,7 @@ func main() { } } -func writeCRDintoFile(crd *apiextensionsv1.CustomResourceDefinition, path string) { +func writeCRDintoFile(crd *extensionsobj.CustomResourceDefinition, path string) { jsonBytes, err := json.Marshal(crd) checkErr(err) diff --git a/hack/gen-docs/main.go b/hack/gen-docs/main.go index a51c59eac9..c39f4628a4 100644 --- a/hack/gen-docs/main.go +++ b/hack/gen-docs/main.go @@ -43,22 +43,22 @@ func updateMkDocsNav(parent string, child string, subchild string, files []strin if e := yaml.Unmarshal(data, &un.Object); e != nil { return e } - nav := un.Object["nav"].([]any) + 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) } - rootnavitemmap := rootitem.(map[any]any) - childnav, _ := findNavItem(rootnavitemmap[parent].([]any), child) + 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) } - childnavmap := childnav.(map[any]any) - childnavitems := childnavmap[child].([]any) + childnavmap := childnav.(map[interface{}]interface{}) + childnavitems := childnavmap[child].([]interface{}) childnavitems = removeNavItem(childnavitems, subchild) - commands := make(map[string]any) + commands := make(map[string]interface{}) commands[subchild] = files childnavmap[child] = append(childnavitems, commands) newmkdocs, err := yaml.Marshal(un.Object) @@ -79,9 +79,9 @@ func trimPrefixes(files []string, prefix string) { } } -func findNavItem(nav []any, key string) (any, int) { +func findNavItem(nav []interface{}, key string) (interface{}, int) { for i, item := range nav { - o, ismap := item.(map[any]any) + o, ismap := item.(map[interface{}]interface{}) if ismap { if _, ok := o[key]; ok { return o, i @@ -91,7 +91,7 @@ func findNavItem(nav []any, key string) (any, int) { return nil, -1 } -func removeNavItem(nav []any, key string) []any { +func removeNavItem(nav []interface{}, key string) []interface{} { _, i := findNavItem(nav, key) if i != -1 { nav = append(nav[:i], nav[i+1:]...) diff --git a/hack/gen-resources/cmd/commands/cmd.go b/hack/gen-resources/cmd/commands/cmd.go index 843bb625b9..5804e4cda8 100644 --- a/hack/gen-resources/cmd/commands/cmd.go +++ b/hack/gen-resources/cmd/commands/cmd.go @@ -6,13 +6,13 @@ import ( "github.com/spf13/cobra" - generator "github.com/argoproj/argo-cd/v3/hack/gen-resources/generators" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/settings" + generator "github.com/argoproj/argo-cd/v2/hack/gen-resources/generators" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/settings" - cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" - "github.com/argoproj/argo-cd/v3/hack/gen-resources/util" - "github.com/argoproj/argo-cd/v3/util/cli" + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/hack/gen-resources/util" + "github.com/argoproj/argo-cd/v2/util/cli" ) const ( @@ -53,7 +53,7 @@ func NewGenerateCommand(opts *util.GenerateOpts) *cobra.Command { Use: "generate [-f file]", Short: "Generate entities", Long: "Generate entities", - Run: func(_ *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { log.Printf("Retrieve configuration from %s", file) err := util.Parse(opts, file) if err != nil { @@ -97,7 +97,7 @@ func NewCleanCommand(opts *util.GenerateOpts) *cobra.Command { Use: "clean", Short: "Clean entities", Long: "Clean entities", - Run: func(_ *cobra.Command, _ []string) { + Run: func(c *cobra.Command, args []string) { argoClientSet := util.ConnectToK8sArgoClientSet() clientSet := util.ConnectToK8sClientSet() settingsMgr := settings.NewSettingsManager(context.TODO(), clientSet, opts.Namespace) diff --git a/hack/gen-resources/cmd/main.go b/hack/gen-resources/cmd/main.go index ac5ea3a86f..512d812874 100644 --- a/hack/gen-resources/cmd/main.go +++ b/hack/gen-resources/cmd/main.go @@ -4,7 +4,7 @@ import ( "fmt" "os" - "github.com/argoproj/argo-cd/v3/hack/gen-resources/cmd/commands" + "github.com/argoproj/argo-cd/v2/hack/gen-resources/cmd/commands" // load the gcp plugin (required to authenticate against GKE clusters). _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" ) diff --git a/hack/gen-resources/generators/application_generator.go b/hack/gen-resources/generators/application_generator.go index cd4713f24f..6d7db8c587 100644 --- a/hack/gen-resources/generators/application_generator.go +++ b/hack/gen-resources/generators/application_generator.go @@ -6,17 +6,18 @@ import ( "math/rand" "time" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/util/settings" - "github.com/argoproj/argo-cd/v3/util/db" + "github.com/argoproj/argo-cd/v2/util/db" - "github.com/argoproj/argo-cd/v3/hack/gen-resources/util" + "github.com/argoproj/argo-cd/v2/hack/gen-resources/util" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" ) type ApplicationGenerator struct { @@ -29,7 +30,7 @@ func NewApplicationGenerator(argoClientSet *appclientset.Clientset, clientSet *k return &ApplicationGenerator{argoClientSet, clientSet, db} } -func (generator *ApplicationGenerator) buildRandomSource(repositories []*v1alpha1.Repository) (*v1alpha1.ApplicationSource, error) { +func (pg *ApplicationGenerator) buildRandomSource(repositories []*v1alpha1.Repository) (*v1alpha1.ApplicationSource, error) { seed := rand.New(rand.NewSource(time.Now().Unix())) repoNumber := seed.Int() % len(repositories) return &v1alpha1.ApplicationSource{ @@ -39,14 +40,15 @@ func (generator *ApplicationGenerator) buildRandomSource(repositories []*v1alpha }, nil } -func (generator *ApplicationGenerator) buildSource(opts *util.GenerateOpts, repositories []*v1alpha1.Repository) (*v1alpha1.ApplicationSource, error) { - if opts.ApplicationOpts.SourceOpts.Strategy == "Random" { - return generator.buildRandomSource(repositories) +func (ag *ApplicationGenerator) buildSource(opts *util.GenerateOpts, repositories []*v1alpha1.Repository) (*v1alpha1.ApplicationSource, error) { + switch opts.ApplicationOpts.SourceOpts.Strategy { + case "Random": + return ag.buildRandomSource(repositories) } - return generator.buildRandomSource(repositories) + return ag.buildRandomSource(repositories) } -func (generator *ApplicationGenerator) buildRandomDestination(opts *util.GenerateOpts, clusters []v1alpha1.Cluster) (*v1alpha1.ApplicationDestination, error) { +func (pg *ApplicationGenerator) buildRandomDestination(opts *util.GenerateOpts, clusters []v1alpha1.Cluster) (*v1alpha1.ApplicationDestination, error) { seed := rand.New(rand.NewSource(time.Now().Unix())) clusterNumber := seed.Int() % len(clusters) return &v1alpha1.ApplicationDestination{ @@ -55,39 +57,40 @@ func (generator *ApplicationGenerator) buildRandomDestination(opts *util.Generat }, nil } -func (generator *ApplicationGenerator) buildDestination(opts *util.GenerateOpts, clusters []v1alpha1.Cluster) (*v1alpha1.ApplicationDestination, error) { - if opts.ApplicationOpts.DestinationOpts.Strategy == "Random" { - return generator.buildRandomDestination(opts, clusters) +func (ag *ApplicationGenerator) buildDestination(opts *util.GenerateOpts, clusters []v1alpha1.Cluster) (*v1alpha1.ApplicationDestination, error) { + switch opts.ApplicationOpts.DestinationOpts.Strategy { + case "Random": + return ag.buildRandomDestination(opts, clusters) } - return generator.buildRandomDestination(opts, clusters) + return ag.buildRandomDestination(opts, clusters) } -func (generator *ApplicationGenerator) Generate(opts *util.GenerateOpts) error { - settingsMgr := settings.NewSettingsManager(context.TODO(), generator.clientSet, opts.Namespace) - repositories, err := db.NewDB(opts.Namespace, settingsMgr, generator.clientSet).ListRepositories(context.TODO()) +func (pg *ApplicationGenerator) Generate(opts *util.GenerateOpts) error { + settingsMgr := settings.NewSettingsManager(context.TODO(), pg.clientSet, opts.Namespace) + repositories, err := db.NewDB(opts.Namespace, settingsMgr, pg.clientSet).ListRepositories(context.TODO()) if err != nil { return err } - clusters, err := db.NewDB(opts.Namespace, settingsMgr, generator.clientSet).ListClusters(context.TODO()) + clusters, err := db.NewDB(opts.Namespace, settingsMgr, pg.clientSet).ListClusters(context.TODO()) if err != nil { return err } - applications := generator.argoClientSet.ArgoprojV1alpha1().Applications(opts.Namespace) + applications := pg.argoClientSet.ArgoprojV1alpha1().Applications(opts.Namespace) for i := 0; i < opts.ApplicationOpts.Samples; i++ { log.Printf("Generate application #%v", i) - source, err := generator.buildSource(opts, repositories) + source, err := pg.buildSource(opts, repositories) if err != nil { return err } log.Printf("Pick source %q", source) - destination, err := generator.buildDestination(opts, clusters.Items) + destination, err := pg.buildDestination(opts, clusters.Items) if err != nil { return err } log.Printf("Pick destination %q", destination) log.Printf("Create application") _, err = applications.Create(context.TODO(), &v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ GenerateName: "application-", Namespace: opts.Namespace, Labels: labels, @@ -97,7 +100,7 @@ func (generator *ApplicationGenerator) Generate(opts *util.GenerateOpts) error { Destination: *destination, Source: source, }, - }, metav1.CreateOptions{}) + }, v1.CreateOptions{}) if err != nil { return err } @@ -105,10 +108,10 @@ func (generator *ApplicationGenerator) Generate(opts *util.GenerateOpts) error { return nil } -func (generator *ApplicationGenerator) Clean(opts *util.GenerateOpts) error { +func (ag *ApplicationGenerator) Clean(opts *util.GenerateOpts) error { log.Printf("Clean applications") - applications := generator.argoClientSet.ArgoprojV1alpha1().Applications(opts.Namespace) - return applications.DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{ + applications := ag.argoClientSet.ArgoprojV1alpha1().Applications(opts.Namespace) + return applications.DeleteCollection(context.TODO(), v1.DeleteOptions{}, v1.ListOptions{ LabelSelector: "app.kubernetes.io/generated-by=argocd-generator", }) } diff --git a/hack/gen-resources/generators/cluster_generator.go b/hack/gen-resources/generators/cluster_generator.go index 4f945d8913..ff5e03e875 100644 --- a/hack/gen-resources/generators/cluster_generator.go +++ b/hack/gen-resources/generators/cluster_generator.go @@ -9,18 +9,23 @@ import ( "strings" "time" + v12 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/argoproj/argo-cd/v2/util/helm" + "gopkg.in/yaml.v2" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + + v1 "k8s.io/api/core/v1" "k8s.io/client-go/rest" "k8s.io/client-go/tools/remotecommand" - "github.com/argoproj/argo-cd/v3/hack/gen-resources/util" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/helm" + "k8s.io/client-go/kubernetes" + + "github.com/argoproj/argo-cd/v2/hack/gen-resources/util" + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/db" ) const POD_PREFIX = "vcluster" @@ -72,7 +77,7 @@ func (cg *ClusterGenerator) getClusterCredentials(namespace string, releaseSuffi } var stdout, stderr, stdin bytes.Buffer - option := &corev1.PodExecOptions{ + option := &v1.PodExecOptions{ Command: cmd, Container: "syncer", Stdin: true, @@ -146,8 +151,8 @@ func (cg *ClusterGenerator) installVCluster(opts *util.GenerateOpts, namespace s return nil } -func (cg *ClusterGenerator) getClusterServerURI(namespace string, releaseSuffix string) (string, error) { - pod, err := cg.clientSet.CoreV1().Pods(namespace).Get(context.TODO(), POD_PREFIX+"-"+releaseSuffix+"-0", metav1.GetOptions{}) +func (cg *ClusterGenerator) getClusterServerUri(namespace string, releaseSuffix string) (string, error) { + pod, err := cg.clientSet.CoreV1().Pods(namespace).Get(context.TODO(), POD_PREFIX+"-"+releaseSuffix+"-0", v12.GetOptions{}) if err != nil { return "", err } @@ -156,10 +161,10 @@ func (cg *ClusterGenerator) getClusterServerURI(namespace string, releaseSuffix return "https://" + pod.Status.PodIP + ":8443", nil } -func (cg *ClusterGenerator) retrieveClusterURI(namespace, releaseSuffix string) string { +func (cg *ClusterGenerator) retrieveClusterUri(namespace, releaseSuffix string) string { for i := 0; i < 10; i++ { log.Print("Attempting to get cluster uri") - uri, err := cg.getClusterServerURI(namespace, releaseSuffix) + uri, err := cg.getClusterServerUri(namespace, releaseSuffix) if err != nil { log.Printf("Failed to get cluster uri due to %s", err.Error()) time.Sleep(10 * time.Second) @@ -203,7 +208,7 @@ func (cg *ClusterGenerator) generate(i int, opts *util.GenerateOpts) error { log.Print("Get cluster server uri") - uri := cg.retrieveClusterURI(namespace, releaseSuffix) + uri := cg.retrieveClusterUri(namespace, releaseSuffix) log.Printf("Cluster server uri is %s", uri) log.Print("Create cluster") @@ -250,7 +255,7 @@ func (cg *ClusterGenerator) Generate(opts *util.GenerateOpts) error { func (cg *ClusterGenerator) Clean(opts *util.GenerateOpts) error { log.Printf("Clean clusters") - namespaces, err := cg.clientSet.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{}) + namespaces, err := cg.clientSet.CoreV1().Namespaces().List(context.TODO(), v12.ListOptions{}) if err != nil { return err } @@ -258,7 +263,7 @@ func (cg *ClusterGenerator) Clean(opts *util.GenerateOpts) error { for _, ns := range namespaces.Items { if strings.HasPrefix(ns.Name, POD_PREFIX) { log.Printf("Delete namespace %s", ns.Name) - err = cg.clientSet.CoreV1().Namespaces().Delete(context.TODO(), ns.Name, metav1.DeleteOptions{}) + err = cg.clientSet.CoreV1().Namespaces().Delete(context.TODO(), ns.Name, v12.DeleteOptions{}) if err != nil { log.Printf("Delete namespace failed due: %s", err.Error()) } @@ -266,7 +271,7 @@ func (cg *ClusterGenerator) Clean(opts *util.GenerateOpts) error { } secrets := cg.clientSet.CoreV1().Secrets(opts.Namespace) - return secrets.DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{ + return secrets.DeleteCollection(context.TODO(), v12.DeleteOptions{}, v12.ListOptions{ LabelSelector: "app.kubernetes.io/generated-by=argocd-generator", }) } diff --git a/hack/gen-resources/generators/generator.go b/hack/gen-resources/generators/generator.go index 3ddd21ec18..8d24b755a8 100644 --- a/hack/gen-resources/generators/generator.go +++ b/hack/gen-resources/generators/generator.go @@ -1,6 +1,6 @@ package generator -import "github.com/argoproj/argo-cd/v3/hack/gen-resources/util" +import "github.com/argoproj/argo-cd/v2/hack/gen-resources/util" var labels = map[string]string{ "app.kubernetes.io/generated-by": "argocd-generator", diff --git a/hack/gen-resources/generators/project_generator.go b/hack/gen-resources/generators/project_generator.go index c33586510f..943ecf0239 100644 --- a/hack/gen-resources/generators/project_generator.go +++ b/hack/gen-resources/generators/project_generator.go @@ -5,11 +5,11 @@ import ( "fmt" "log" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/hack/gen-resources/util" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" + "github.com/argoproj/argo-cd/v2/hack/gen-resources/util" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" ) type ProjectGenerator struct { @@ -25,7 +25,7 @@ func (pg *ProjectGenerator) Generate(opts *util.GenerateOpts) error { for i := 0; i < opts.ProjectOpts.Samples; i++ { log.Printf("Generate project #%v", i) _, err := projects.Create(context.TODO(), &v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ GenerateName: "project-", Namespace: opts.Namespace, Labels: labels, @@ -33,7 +33,7 @@ func (pg *ProjectGenerator) Generate(opts *util.GenerateOpts) error { Spec: v1alpha1.AppProjectSpec{ Description: "generated-project", }, - }, metav1.CreateOptions{}) + }, v1.CreateOptions{}) if err != nil { log.Printf("Project #%v failed to generate", i) return fmt.Errorf("error in generated-project: %w", err) @@ -45,7 +45,7 @@ func (pg *ProjectGenerator) Generate(opts *util.GenerateOpts) error { func (pg *ProjectGenerator) Clean(opts *util.GenerateOpts) error { log.Printf("Clean projects") projects := pg.clientSet.ArgoprojV1alpha1().AppProjects(opts.Namespace) - return projects.DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{ + return projects.DeleteCollection(context.TODO(), v1.DeleteOptions{}, v1.ListOptions{ LabelSelector: "app.kubernetes.io/generated-by=argocd-generator", }) } diff --git a/hack/gen-resources/generators/repo_generator.go b/hack/gen-resources/generators/repo_generator.go index bfdb302a2e..11cc47f023 100644 --- a/hack/gen-resources/generators/repo_generator.go +++ b/hack/gen-resources/generators/repo_generator.go @@ -9,17 +9,17 @@ import ( "log" "net/http" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + v1meta "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/hack/gen-resources/util" + "github.com/argoproj/argo-cd/v2/hack/gen-resources/util" "k8s.io/client-go/kubernetes" ) type Repo struct { Id int `json:"id"` - Url string `json:"html_url"` //nolint:revive //FIXME(var-naming) + Url string `json:"html_url"` } type RepoGenerator struct { @@ -88,8 +88,8 @@ func (rg *RepoGenerator) Generate(opts *util.GenerateOpts) error { secrets := rg.clientSet.CoreV1().Secrets(opts.Namespace) rg.bar.NewOption(0, int64(len(repos))) for _, repo := range repos { - _, err = secrets.Create(context.TODO(), &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + _, err = secrets.Create(context.TODO(), &v1.Secret{ + ObjectMeta: v1meta.ObjectMeta{ GenerateName: "repo-", Namespace: opts.Namespace, Labels: map[string]string{ @@ -105,7 +105,7 @@ func (rg *RepoGenerator) Generate(opts *util.GenerateOpts) error { "url": []byte(repo.Url), "project": []byte("default"), }, - }, metav1.CreateOptions{}) + }, v1meta.CreateOptions{}) rg.bar.Increment() rg.bar.Play() } @@ -119,7 +119,7 @@ func (rg *RepoGenerator) Generate(opts *util.GenerateOpts) error { func (rg *RepoGenerator) Clean(opts *util.GenerateOpts) error { log.Printf("Clean repos") secrets := rg.clientSet.CoreV1().Secrets(opts.Namespace) - return secrets.DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{ + return secrets.DeleteCollection(context.TODO(), v1meta.DeleteOptions{}, v1meta.ListOptions{ LabelSelector: "app.kubernetes.io/generated-by=argocd-generator", }) } diff --git a/hack/gen-resources/util/kube.go b/hack/gen-resources/util/kube.go index 4624a46227..303057ab54 100644 --- a/hack/gen-resources/util/kube.go +++ b/hack/gen-resources/util/kube.go @@ -11,7 +11,7 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" ) type Kube struct { diff --git a/hack/gen-resources/util/progress_bar.go b/hack/gen-resources/util/progress_bar.go index d12f64eb34..66eda264c7 100644 --- a/hack/gen-resources/util/progress_bar.go +++ b/hack/gen-resources/util/progress_bar.go @@ -30,7 +30,7 @@ func (bar *Bar) getPercent() int64 { } func (bar *Bar) Increment() { - bar.cur++ + bar.cur += 1 } func (bar *Bar) Play() { diff --git a/hack/gen-resources/util/sizedwaitgroup.go b/hack/gen-resources/util/sizedwaitgroup.go index 4ddb5192d2..6c6d4fb1c5 100644 --- a/hack/gen-resources/util/sizedwaitgroup.go +++ b/hack/gen-resources/util/sizedwaitgroup.go @@ -87,6 +87,7 @@ func (s *SizedWaitGroup) AddWithContext(ctx context.Context) error { case <-ctx.Done(): return ctx.Err() case s.current <- struct{}{}: + break } s.wg.Add(1) return nil diff --git a/hack/generate-actions-list.sh b/hack/generate-actions-list.sh index 207be27efe..61b0b4c7aa 100755 --- a/hack/generate-actions-list.sh +++ b/hack/generate-actions-list.sh @@ -1,3 +1 @@ -#!/usr/bin/env bash - -find resource_customizations -name action.lua | sed 's/resource_customizations\/\(.*\)\/actions\/\(.*\)\/action.lua/- [\1\/\2](https:\/\/github.com\/argoproj\/argo-cd\/blob\/master\/resource_customizations\/\1\/actions\/\2\/action.lua)/' | sort | uniq > docs/operator-manual/resource_actions_builtin.md +find resource_customizations -name action.lua | sed 's/resource_customizations\/\(.*\)\/actions\/\(.*\)\/action.lua/- [\1\/\2](https:\/\/github.com\/argoproj\/argo-cd\/blob\/master\/resource_customizations\/\1\/actions\/\2\/action.lua)/' | sort | uniq > docs/operator-manual/resource_actions_builtin.md \ No newline at end of file diff --git a/hack/generate-mock.sh b/hack/generate-mock.sh index f05061141e..0371b156ac 100755 --- a/hack/generate-mock.sh +++ b/hack/generate-mock.sh @@ -13,6 +13,6 @@ PROJECT_ROOT=$( PATH="${PROJECT_ROOT}/dist:${PATH}" # output tool versions -mockery version +mockery --version mockery --config ${PROJECT_ROOT}/.mockery.yaml \ No newline at end of file diff --git a/hack/generate-proto.sh b/hack/generate-proto.sh index 6ef90dcf3b..f4f3cfe173 100755 --- a/hack/generate-proto.sh +++ b/hack/generate-proto.sh @@ -31,7 +31,7 @@ export GO111MODULE=off # --apimachinery-packages= option so that go-to-protobuf can locate the types, but prefixed with a # '-' so that go-to-protobuf will not generate .proto files for it. PACKAGES=( - github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1 + github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1 ) APIMACHINERY_PKGS=( +k8s.io/apimachinery/pkg/util/intstr @@ -44,7 +44,7 @@ APIMACHINERY_PKGS=( ) export GO111MODULE=on -[ -e ./v3 ] || ln -s . v3 +[ -e ./v2 ] || ln -s . v2 [ -e "${GOPATH_PROJECT_ROOT}" ] || (mkdir -p "$(dirname "${GOPATH_PROJECT_ROOT}")" && ln -s "${PROJECT_ROOT}" "${GOPATH_PROJECT_ROOT}") # protoc_include is the include directory containing the .proto files distributed with protoc binary @@ -114,7 +114,7 @@ done rm util/askpass/askpass.swagger.json [ -L "${GOPATH_PROJECT_ROOT}" ] && rm -rf "${GOPATH_PROJECT_ROOT}" -[ -L ./v3 ] && rm -rf v3 +[ -L ./v2 ] && rm -rf v2 # collect_swagger gathers swagger files into a subdirectory collect_swagger() { 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 index 1118357324..a322c9fe0b 100644 --- a/hack/get-previous-release/get-previous-version-for-release-notes.go +++ b/hack/get-previous-release/get-previous-version-for-release-notes.go @@ -6,6 +6,7 @@ import ( "os" "os/exec" "regexp" + "strconv" "strings" ) @@ -51,59 +52,61 @@ func extractPatchAndRC(tag string) (string, string, error) { return patch, rc, nil } -func removeInvalidTags(tags []string) []string { - var validTags []string - for _, tag := range tags { - if _, _, err := extractPatchAndRC(tag); err == nil { - validTags = append(validTags, tag) - } - } - return validTags -} - -func removeNewerOrEqualTags(proposedTag string, tags []string) []string { - var validTags []string - for _, tag := range tags { - if semver.Compare(tag, proposedTag) < 0 { - validTags = append(validTags, tag) - } - } - return validTags -} - -func removeTagsFromSameMinorSeries(proposedTag string, tags []string) []string { - var validTags []string - proposedMinor := semver.MajorMinor(proposedTag) - for _, tag := range tags { - if semver.MajorMinor(tag) != proposedMinor { - validTags = append(validTags, tag) - } - } - return validTags -} - -func getMostRecentTag(tags []string) string { - var mostRecentTag string - for _, tag := range tags { - if mostRecentTag == "" || semver.Compare(tag, mostRecentTag) > 0 { - mostRecentTag = tag - } - } - return mostRecentTag -} - func findPreviousTag(proposedTag string, tags []string) (string, error) { - tags = removeInvalidTags(tags) - tags = removeNewerOrEqualTags(proposedTag, tags) + var previousTag string + proposedMajor := semver.Major(proposedTag) + proposedMinor := semver.MajorMinor(proposedTag) - proposedPatch, proposedRC, _ := extractPatchAndRC(proposedTag) // Ignore the error, we already filtered out invalid tags. - if proposedRC == "0" && proposedPatch == "0" { - // If we're cutting the first patch of a new minor release series, don't consider tags in the same minor release - // series. We want to compare to the latest tag in the previous minor release series. - tags = removeTagsFromSameMinorSeries(proposedTag, tags) + proposedPatch, proposedRC, err := extractPatchAndRC(proposedTag) + if err != nil { + return "", err } - previousTag := getMostRecentTag(tags) + // 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, ", ")) } 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 index 8b5f70fcdb..b41f335346 100644 --- 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 @@ -76,13 +76,6 @@ func TestFindPreviousTagRules(t *testing.T) { {"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}, - // Rule 5: If we're releasing a major version RC, get the most recent tag on the previous major release series. - {"Rule 5: major version RC", "v3.0.0-rc1", "v2.13.0-rc3", false}, - // Rule 6: If we're releasing a major version, get the most recent tag on the previous major release series, - // even if it's an RC. - {"Rule 6: major version", "v3.0.0", "v2.13.0-rc3", false}, - // Rule 7: If the proposed tag already exists, don't return it. - {"Rule 7: proposed tag already exists", "v2.12.5", "v2.12.4", false}, } for _, test := range tests { diff --git a/hack/get-previous-release/go.mod b/hack/get-previous-release/go.mod index f3c4714d3b..137bd2b32d 100644 --- a/hack/get-previous-release/go.mod +++ b/hack/get-previous-release/go.mod @@ -1,6 +1,6 @@ module github.com/argoproj/argo-cd/get-previous-release -go 1.23.5 +go 1.22.5 require ( github.com/stretchr/testify v1.9.0 diff --git a/hack/installers/checksums/add-protoc-checksums.sh b/hack/installers/checksums/add-protoc-checksums.sh index 6b61350b36..1c13e6cfae 100755 --- a/hack/installers/checksums/add-protoc-checksums.sh +++ b/hack/installers/checksums/add-protoc-checksums.sh @@ -1,9 +1,7 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # Usage: ./add-protoc-checksums.sh 27.2 # use the desired version -[[ $OSTYPE == 'darwin'* ]] && sha256sum() { shasum -a 256 "$@" ; } - set -e for arch in aarch_64 ppcle_64 s390_64 x86_64; do wget "https://github.com/protocolbuffers/protobuf/releases/download/v$1/protoc-$1-linux-$arch.zip" -O "protoc-$1-linux-$arch.zip" @@ -15,4 +13,4 @@ for arch in aarch_64 x86_64; do wget "https://github.com/protocolbuffers/protobuf/releases/download/v$1/protoc-$1-osx-$arch.zip" -O "protoc-$1-osx-$arch.zip" sha256sum "protoc-$1-osx-$arch.zip" > "protoc-$1-osx-$arch.zip.sha256" rm "protoc-$1-osx-$arch.zip" -done +done \ No newline at end of file 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 0000000000..e69de29bb2 diff --git a/hack/installers/checksums/helm-v-linux-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v-linux-arm64.tar.gz.sha256 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hack/installers/checksums/helm-v-linux-ppc64le.tar.gz.sha256 b/hack/installers/checksums/helm-v-linux-ppc64le.tar.gz.sha256 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hack/installers/checksums/helm-v-linux-s390x.tar.gz.sha256 b/hack/installers/checksums/helm-v-linux-s390x.tar.gz.sha256 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hack/installers/checksums/helm-v3.17.0-darwin-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.0-darwin-amd64.tar.gz.sha256 deleted file mode 100644 index 1ab86a9b4e..0000000000 --- a/hack/installers/checksums/helm-v3.17.0-darwin-amd64.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -0d5fd51cf51eb4b9712d52ecd8f2a3cd865680595cca57db38ee01802bd466ea helm-v3.17.0-darwin-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.0-darwin-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.0-darwin-arm64.tar.gz.sha256 deleted file mode 100644 index e0050b01b0..0000000000 --- a/hack/installers/checksums/helm-v3.17.0-darwin-arm64.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -5db292c69ba756ddbf139abb623b02860feef15c7f1a4ea69b77715b9165a261 helm-v3.17.0-darwin-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.0-linux-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.0-linux-amd64.tar.gz.sha256 deleted file mode 100644 index 3d74e11729..0000000000 --- a/hack/installers/checksums/helm-v3.17.0-linux-amd64.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -fb5d12662fde6eeff36ac4ccacbf3abed96b0ee2de07afdde4edb14e613aee24 helm-v3.17.0-linux-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.0-linux-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.0-linux-arm64.tar.gz.sha256 deleted file mode 100644 index b022aac1a6..0000000000 --- a/hack/installers/checksums/helm-v3.17.0-linux-arm64.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -c4d4be8e80082b7eaa411e3e231d62cf05d01cddfef59b0d01006a7901e11ee4 helm-v3.17.0-linux-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.0-linux-ppc64le.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.0-linux-ppc64le.tar.gz.sha256 deleted file mode 100644 index bc81cf2223..0000000000 --- a/hack/installers/checksums/helm-v3.17.0-linux-ppc64le.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -32833acf72b240e9ca78a3eac630a0ba420e073b02df3030c369a287b8bdc769 helm-v3.17.0-linux-ppc64le.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.0-linux-s390x.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.0-linux-s390x.tar.gz.sha256 deleted file mode 100644 index dd91867df4..0000000000 --- a/hack/installers/checksums/helm-v3.17.0-linux-s390x.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -4b002d673ef35d78843c45cc169faf1040eec75937f19fccce41d2074f459653 helm-v3.17.0-linux-s390x.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.1-darwin-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.1-darwin-amd64.tar.gz.sha256 deleted file mode 100644 index 44bb6f2ff3..0000000000 --- a/hack/installers/checksums/helm-v3.17.1-darwin-amd64.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -aba59ba9511971a71943b5c76f15d52ace1681197bb3f71ed1f0b15caceacb2c helm-v3.17.1-darwin-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.1-darwin-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.1-darwin-arm64.tar.gz.sha256 deleted file mode 100644 index be01968088..0000000000 --- a/hack/installers/checksums/helm-v3.17.1-darwin-arm64.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -b823a213d8d7937222becc63d9c7bb3d15a090e7ecd1f70f3a583ed39657e21b helm-v3.17.1-darwin-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.1-linux-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.1-linux-amd64.tar.gz.sha256 deleted file mode 100644 index 4d39da141f..0000000000 --- a/hack/installers/checksums/helm-v3.17.1-linux-amd64.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -3b66f3cd28409f29832b1b35b43d9922959a32d795003149707fea84cbcd4469 helm-v3.17.1-linux-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.1-linux-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.1-linux-arm64.tar.gz.sha256 deleted file mode 100644 index c565a463a5..0000000000 --- a/hack/installers/checksums/helm-v3.17.1-linux-arm64.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -c86c9b23602d4abbfae39d9634e25ab1d0ea6c4c16c5b154113efe316a402547 helm-v3.17.1-linux-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.1-linux-ppc64le.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.1-linux-ppc64le.tar.gz.sha256 deleted file mode 100644 index 8ffcd2a5d8..0000000000 --- a/hack/installers/checksums/helm-v3.17.1-linux-ppc64le.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -4223394f3fca82a7f8e8d083caf6faf0ee0639d8f235071334579237078a2c2e helm-v3.17.1-linux-ppc64le.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.1-linux-s390x.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.1-linux-s390x.tar.gz.sha256 deleted file mode 100644 index 60d071db69..0000000000 --- a/hack/installers/checksums/helm-v3.17.1-linux-s390x.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -fe47e5ee8abd6baef01bb1c4fc995343121bf5fc7dead1f67e97484a441ba9e8 helm-v3.17.1-linux-s390x.tar.gz diff --git a/hack/installers/checksums/ks_0.13.1_linux_amd64.tar.gz.sha256 b/hack/installers/checksums/ks_0.13.1_linux_amd64.tar.gz.sha256 new file mode 100644 index 0000000000..80783ebcf1 --- /dev/null +++ b/hack/installers/checksums/ks_0.13.1_linux_amd64.tar.gz.sha256 @@ -0,0 +1 @@ +fe76e414e5cba3f093e34e1b433f79cd53915e3153b68cff5ba3273cafd8a2a0 ks_0.13.1_linux_amd64.tar.gz diff --git a/hack/installers/checksums/kubectl_amd64_1.17.8.sha256 b/hack/installers/checksums/kubectl_amd64_1.17.8.sha256 new file mode 100644 index 0000000000..17d31f293e --- /dev/null +++ b/hack/installers/checksums/kubectl_amd64_1.17.8.sha256 @@ -0,0 +1 @@ +01283cbc2b09555cbf2a71c162097552a62a4fd48a0a4c06e34e9b853b815486 kubectl_amd64_1.17.8 diff --git a/hack/installers/checksums/kubectl_arm64_1.17.8.sha256 b/hack/installers/checksums/kubectl_arm64_1.17.8.sha256 new file mode 100644 index 0000000000..c12f65f87e --- /dev/null +++ b/hack/installers/checksums/kubectl_arm64_1.17.8.sha256 @@ -0,0 +1 @@ +4dfd36dbd637b8dca9a7c4e789fb3fe4ca420062c90d3a872ae751dfb9777cb6 kubectl_arm64_1.17.8 diff --git a/hack/installers/checksums/kubectl_ppc64le_1.17.8.sha256 b/hack/installers/checksums/kubectl_ppc64le_1.17.8.sha256 new file mode 100644 index 0000000000..526a51c6ad --- /dev/null +++ b/hack/installers/checksums/kubectl_ppc64le_1.17.8.sha256 @@ -0,0 +1 @@ +4600cc0103f8573fe326a3c80208cc8c948ba2b8b2855da2a242376ce855b9c9 kubectl_ppc64le_1.17.8 diff --git a/hack/installers/checksums/kubectl_s390x_1.17.8.sha256 b/hack/installers/checksums/kubectl_s390x_1.17.8.sha256 new file mode 100644 index 0000000000..111becf0cc --- /dev/null +++ b/hack/installers/checksums/kubectl_s390x_1.17.8.sha256 @@ -0,0 +1 @@ +bc409f75082a0d081cecef2287914ca9990b9c71d199e0cdcc052333a7bc4835 kubectl_s390x_1.17.8 diff --git a/hack/installers/checksums/kubectx-0.6.3.zip.sha256 b/hack/installers/checksums/kubectx-0.6.3.zip.sha256 new file mode 100644 index 0000000000..187d6b97ce --- /dev/null +++ b/hack/installers/checksums/kubectx-0.6.3.zip.sha256 @@ -0,0 +1 @@ +4e501055d37829d3b3834c5883017a785e56bf9b8b8712040a504a7ead04472d kubectx-0.6.3.zip diff --git a/hack/installers/checksums/kustomize_5.6.0_darwin_amd64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.6.0_darwin_amd64.tar.gz.sha256 deleted file mode 100644 index 5120851af7..0000000000 --- a/hack/installers/checksums/kustomize_5.6.0_darwin_amd64.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -3432be97f9fb4899148bf2485ccf9080e5e7702758eb16c92cd2f2f335e12a03 kustomize_5.6.0_darwin_amd64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.6.0_darwin_arm64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.6.0_darwin_arm64.tar.gz.sha256 deleted file mode 100644 index b892e6d074..0000000000 --- a/hack/installers/checksums/kustomize_5.6.0_darwin_arm64.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -791d9497d2973d4af17c9c0c2b3991ce82e61d1a2bf79f4ef78dd9dce25a6d3d kustomize_5.6.0_darwin_arm64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.6.0_linux_amd64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.6.0_linux_amd64.tar.gz.sha256 deleted file mode 100644 index 3fb8830359..0000000000 --- a/hack/installers/checksums/kustomize_5.6.0_linux_amd64.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -54e4031ddc4e7fc59e408da29e7c646e8e57b8088c51b84b3df0864f47b5148f kustomize_5.6.0_linux_amd64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.6.0_linux_arm64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.6.0_linux_arm64.tar.gz.sha256 deleted file mode 100644 index ed60e32bac..0000000000 --- a/hack/installers/checksums/kustomize_5.6.0_linux_arm64.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -ad8ab62d4f6d59a8afda0eec4ba2e5cd2f86bf1afeea4b78d06daac945eb0660 kustomize_5.6.0_linux_arm64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.6.0_linux_ppc64le.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.6.0_linux_ppc64le.tar.gz.sha256 deleted file mode 100644 index 1fa69f0dc8..0000000000 --- a/hack/installers/checksums/kustomize_5.6.0_linux_ppc64le.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -377ac4cc7d1536aeba6c34e9407bcd0ba48193bc1c3fdb6cc69bcade583e5fa7 kustomize_5.6.0_linux_ppc64le.tar.gz diff --git a/hack/installers/checksums/kustomize_5.6.0_linux_s390x.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.6.0_linux_s390x.tar.gz.sha256 deleted file mode 100644 index 0b96e34873..0000000000 --- a/hack/installers/checksums/kustomize_5.6.0_linux_s390x.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -e633bddd040a1d1acedac655044c2d2bcbba048481662ff6035ea1205ee9a869 kustomize_5.6.0_linux_s390x.tar.gz diff --git a/hack/installers/checksums/protoc-29.3-linux-aarch_64.zip.sha256 b/hack/installers/checksums/protoc-29.3-linux-aarch_64.zip.sha256 deleted file mode 100644 index 70eaa8da0b..0000000000 --- a/hack/installers/checksums/protoc-29.3-linux-aarch_64.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -6427349140e01f06e049e707a58709a4f221ae73ab9a0425bc4a00c8d0e1ab32 protoc-29.3-linux-aarch_64.zip diff --git a/hack/installers/checksums/protoc-29.3-linux-ppcle_64.zip.sha256 b/hack/installers/checksums/protoc-29.3-linux-ppcle_64.zip.sha256 deleted file mode 100644 index 2ee5e6f47a..0000000000 --- a/hack/installers/checksums/protoc-29.3-linux-ppcle_64.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -0e9894ec2e3992b14d183e7ceac16465d6a6ee73e1d234695d80e6d1e947014c protoc-29.3-linux-ppcle_64.zip diff --git a/hack/installers/checksums/protoc-29.3-linux-s390_64.zip.sha256 b/hack/installers/checksums/protoc-29.3-linux-s390_64.zip.sha256 deleted file mode 100644 index 41b2a90968..0000000000 --- a/hack/installers/checksums/protoc-29.3-linux-s390_64.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -637857fdbab0b1334bdb2b08733f0be49685e693011b6104809491ac62fbd4d5 protoc-29.3-linux-s390_64.zip diff --git a/hack/installers/checksums/protoc-29.3-linux-x86_64.zip.sha256 b/hack/installers/checksums/protoc-29.3-linux-x86_64.zip.sha256 deleted file mode 100644 index 26a4c38516..0000000000 --- a/hack/installers/checksums/protoc-29.3-linux-x86_64.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -3e866620c5be27664f3d2fa2d656b5f3e09b5152b42f1bedbf427b333e90021a protoc-29.3-linux-x86_64.zip diff --git a/hack/installers/checksums/protoc-29.3-osx-aarch_64.zip.sha256 b/hack/installers/checksums/protoc-29.3-osx-aarch_64.zip.sha256 deleted file mode 100644 index ed99cc6029..0000000000 --- a/hack/installers/checksums/protoc-29.3-osx-aarch_64.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -2b8a3403cd097f95f3ba656e14b76c732b6b26d7f183330b11e36ef2bc028765 protoc-29.3-osx-aarch_64.zip diff --git a/hack/installers/checksums/protoc-29.3-osx-x86_64.zip.sha256 b/hack/installers/checksums/protoc-29.3-osx-x86_64.zip.sha256 deleted file mode 100644 index 0ee298e945..0000000000 --- a/hack/installers/checksums/protoc-29.3-osx-x86_64.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -9a788036d8f9854f7b03c305df4777cf0e54e5b081e25bf15252da87e0e90875 protoc-29.3-osx-x86_64.zip diff --git a/hack/installers/install-codegen-go-tools.sh b/hack/installers/install-codegen-go-tools.sh index 2ae495ff81..02e0327561 100755 --- a/hack/installers/install-codegen-go-tools.sh +++ b/hack/installers/install-codegen-go-tools.sh @@ -45,7 +45,7 @@ go_mod_install k8s.io/code-generator/cmd/lister-gen go_mod_install k8s.io/kube-openapi/cmd/openapi-gen # controller-gen is run by ./hack/gen-crd-spec to generate the CRDs -go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.18.0 +go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.14.0 # swagger cli is used to generate swagger docs go install github.com/go-swagger/go-swagger/cmd/swagger@v0.28.0 @@ -54,4 +54,4 @@ go install github.com/go-swagger/go-swagger/cmd/swagger@v0.28.0 go install golang.org/x/tools/cmd/goimports@v0.1.8 # mockery is used to generate mock -go install github.com/vektra/mockery/v3@v3.2.5 \ No newline at end of file +go install github.com/vektra/mockery/v2@v2.53.4 diff --git a/hack/installers/install-gotestsum.sh b/hack/installers/install-gotestsum.sh index 2ed97cf79e..27b497696c 100755 --- a/hack/installers/install-gotestsum.sh +++ b/hack/installers/install-gotestsum.sh @@ -4,24 +4,23 @@ set -eux -o pipefail # Code from: https://github.com/argoproj/argo-rollouts/blob/f650a1fd0ba7beb2125e1598410515edd572776f/hack/installers/install-dev-tools.sh PROJECT_ROOT=$(cd $(dirname ${BASH_SOURCE})/../..; pwd) -INSTALL_PATH="${BIN:-$INSTALL_PATH}" -INSTALL_PATH="${INSTALL_PATH:-$PROJECT_ROOT/dist}" -PATH="${INSTALL_PATH}:${PATH}" -[ -d $INSTALL_PATH ] || mkdir -p $INSTALL_PATH +DIST_PATH="${PROJECT_ROOT}/dist" +PATH="${DIST_PATH}:${PATH}" -# renovate: datasource=github-releases depName=gotestyourself/gotestsum packageName=gotestyourself/gotestsum -GOTESTSUM_VERSION=1.12.2 +mkdir -p ${DIST_PATH} + +gotestsum_version=1.11.0 OS=$(go env GOOS) ARCH=$(go env GOARCH) -export TARGET_FILE=gotestsum_${GOTESTSUM_VERSION}_${OS}_${ARCH}.tar.gz +export TARGET_FILE=gotestsum_${gotestsum_version}_${OS}_${ARCH}.tar.gz temp_path="/tmp/${TARGET_FILE}" -url=https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_${OS}_${ARCH}.tar.gz +url=https://github.com/gotestyourself/gotestsum/releases/download/v${gotestsum_version}/gotestsum_${gotestsum_version}_${OS}_${ARCH}.tar.gz [ -e ${temp_path} ] || curl -sLf --retry 3 -o ${temp_path} ${url} -mkdir -p /tmp/gotestsum-${GOTESTSUM_VERSION} -tar -xvzf ${temp_path} -C /tmp/gotestsum-${GOTESTSUM_VERSION} -sudo cp /tmp/gotestsum-${GOTESTSUM_VERSION}/gotestsum ${INSTALL_PATH}/gotestsum -sudo chmod +x ${INSTALL_PATH}/gotestsum +mkdir -p /tmp/gotestsum-${gotestsum_version} +tar -xvzf ${temp_path} -C /tmp/gotestsum-${gotestsum_version} +cp /tmp/gotestsum-${gotestsum_version}/gotestsum ${DIST_PATH}/gotestsum +chmod +x ${DIST_PATH}/gotestsum gotestsum --version diff --git a/hack/installers/install-kubectl-linux.sh b/hack/installers/install-kubectl-linux.sh new file mode 100755 index 0000000000..abf60757b6 --- /dev/null +++ b/hack/installers/install-kubectl-linux.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -eux -o pipefail + +. $(dirname $0)/../tool-versions.sh + +export TARGET_FILE=kubectl_${ARCHITECTURE}_${kubectl_version} + +# NOTE: keep the version synced with https://storage.googleapis.com/kubernetes-release/release/stable.txt +[ -e $DOWNLOADS/${TARGET_FILE} ] || curl -sLf --retry 3 -o ${DOWNLOADS}/${TARGET_FILE} https://storage.googleapis.com/kubernetes-release/release/v${kubectl_version}/bin/linux/$ARCHITECTURE/kubectl +$(dirname $0)/compare-chksum.sh +sudo install -m 0755 ${DOWNLOADS}/${TARGET_FILE} $BIN/kubectl diff --git a/hack/installers/install-kubectx-linux.sh b/hack/installers/install-kubectx-linux.sh new file mode 100755 index 0000000000..3787d3be46 --- /dev/null +++ b/hack/installers/install-kubectx-linux.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -eux -o pipefail + +. $(dirname $0)/../tool-versions.sh + +export TARGET_FILE=kubectx-${kubectx_version}.zip + +[ -e $DOWNLOADS/${TARGET_FILE} ] || curl -sLf --retry 3 -o $DOWNLOADS/${TARGET_FILE} https://github.com/ahmetb/kubectx/archive/v${kubectx_version}.zip +$(dirname $0)/compare-chksum.sh +unzip $DOWNLOADS/${TARGET_FILE} kubectx-${kubectx_version}/kubectx -d $DOWNLOADS +unzip $DOWNLOADS/${TARGET_FILE} kubectx-${kubectx_version}/kubens -d $DOWNLOADS +sudo install -m 0755 $DOWNLOADS/kubectx-${kubectx_version}/kubectx $BIN/kubectx +sudo install -m 0755 $DOWNLOADS/kubectx-${kubectx_version}/kubens $BIN/kubens \ No newline at end of file diff --git a/hack/installers/install-lint-tools.sh b/hack/installers/install-lint-tools.sh index 09caae63d0..2436be419a 100755 --- a/hack/installers/install-lint-tools.sh +++ b/hack/installers/install-lint-tools.sh @@ -4,4 +4,4 @@ set -eux -o pipefail # renovate: datasource=go packageName=github.com/golangci/golangci-lint GOLANGCI_LINT_VERSION=2.1.6 -GO111MODULE=on go install "github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v${GOLANGCI_LINT_VERSION}" +GO111MODULE=on go install "github.com/golangci/golangci-lint/cmd/golangci-lint@v${GOLANGCI_LINT_VERSION}" diff --git a/hack/installers/install-protoc.sh b/hack/installers/install-protoc.sh index 1128bc8b92..f0fb244064 100755 --- a/hack/installers/install-protoc.sh +++ b/hack/installers/install-protoc.sh @@ -41,7 +41,8 @@ $(dirname $0)/compare-chksum.sh mkdir -p /tmp/protoc-${protoc_version} unzip -o $DOWNLOADS/${TARGET_FILE} -d /tmp/protoc-${protoc_version} mkdir -p ${DIST_PATH}/protoc-include -sudo install -m 0755 /tmp/protoc-${protoc_version}/bin/protoc ${DIST_PATH}/protoc -(cd /tmp/protoc-${protoc_version}/include/ && find -- * -type d -exec install -m 0755 -d "${DIST_PATH}/protoc-include/{}" \;) -(cd /tmp/protoc-${protoc_version}/include/ && find -- * -type f -exec install -m 0644 "/tmp/protoc-${protoc_version}/include/{}" "${DIST_PATH}/protoc-include/{}" \;) +cp /tmp/protoc-${protoc_version}/bin/protoc ${DIST_PATH}/protoc +chmod +x ${DIST_PATH}/protoc +cp -a /tmp/protoc-${protoc_version}/include/* ${DIST_PATH}/protoc-include +chmod -R +rx ${DIST_PATH}/protoc-include protoc --version diff --git a/hack/k8s/main.go b/hack/k8s/main.go index ddaf99f13e..99a9ca2deb 100644 --- a/hack/k8s/main.go +++ b/hack/k8s/main.go @@ -2,6 +2,7 @@ package main import ( "context" + "fmt" "os" "os/exec" "path/filepath" @@ -9,7 +10,7 @@ import ( "k8s.io/client-go/kubernetes" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/util/errors" "github.com/argoproj/gitops-engine/pkg/utils/kube" "sigs.k8s.io/controller-runtime/pkg/envtest" @@ -28,7 +29,7 @@ func main() { kubeConfigPath = os.Args[1] } - println("Kubeconfig is available at " + kubeConfigPath) + println(fmt.Sprintf("Kubeconfig is available at %s", kubeConfigPath)) errors.CheckError(kube.WriteKubeConfig(cfg, "default", kubeConfigPath)) client, err := kubernetes.NewForConfig(cfg) errors.CheckError(err) @@ -45,7 +46,7 @@ func main() { errors.CheckError(err) cmd := exec.Command("kubectl", "apply", "-k", "manifests/base/config") - cmd.Env = []string{"KUBECONFIG=" + kubeConfigPath} + cmd.Env = []string{fmt.Sprintf("KUBECONFIG=%s", kubeConfigPath)} errors.CheckError(cmd.Run()) <-context.Background().Done() } diff --git a/hack/known_types/main.go b/hack/known_types/main.go index b6c914fd19..247fadffd9 100644 --- a/hack/known_types/main.go +++ b/hack/known_types/main.go @@ -23,11 +23,11 @@ const ( ) func newCommand() *cobra.Command { - var docsOutputPath string + var docsOutputPath string = "" command := &cobra.Command{ Use: "go run github.com/argoproj/argo-cd/hack/known_types ALIAS PACKAGE_PATH OUTPUT_PATH", Example: "go run github.com/argoproj/argo-cd/hack/known_types corev1 k8s.io/api/core/v1 corev1_known_types.go", - RunE: func(_ *cobra.Command, args []string) error { + RunE: func(c *cobra.Command, args []string) error { if len(args) < 3 { return errors.New("alias and package are not specified") } @@ -65,7 +65,7 @@ func newCommand() *cobra.Command { docs = append(docs, fmt.Sprintf("%s/%s", shortPackagePath, typeName.Name())) mapItems = append(mapItems, fmt.Sprintf(` - knownTypes["%s/%s"] = func() any { + knownTypes["%s/%s"] = func() interface{} { return &%s.%s{} }`, shortPackagePath, typeName.Name(), alias, typeName.Name())) } diff --git a/hack/test.sh b/hack/test.sh index 1b9b92c0c4..c13718063b 100755 --- a/hack/test.sh +++ b/hack/test.sh @@ -15,4 +15,4 @@ fi mkdir -p $TEST_RESULTS -GODEBUG="tarinsecurepath=0,zipinsecurepath=0" gotestsum --rerun-fails-report=rerunreport.txt --junitfile=$TEST_RESULTS/junit.xml --format=testname --rerun-fails="$RERUN_FAILS" --packages="$PACKAGES" -- -cover $TEST_FLAGS $* +GODEBUG="tarinsecurepath=0,zipinsecurepath=0" ${DIST_DIR}/gotestsum --rerun-fails-report=rerunreport.txt --junitfile=$TEST_RESULTS/junit.xml --format=testname --rerun-fails="$RERUN_FAILS" --packages="$PACKAGES" -- -cover $TEST_FLAGS $* diff --git a/hack/tool-versions.sh b/hack/tool-versions.sh index 8a3b0952c8..5ff690de48 100644 --- a/hack/tool-versions.sh +++ b/hack/tool-versions.sh @@ -11,6 +11,8 @@ # Use ./hack/installers/checksums/add-helm-checksums.sh and # add-kustomize-checksums.sh to help download checksums. ############################################################################### -helm3_version=3.17.1 -kustomize5_version=5.6.0 -protoc_version=29.3 +helm3_version=3.16.3 +kubectl_version=1.17.8 +kubectx_version=0.6.3 +kustomize5_version=5.4.3 +protoc_version=27.2 diff --git a/hack/trigger-release.sh b/hack/trigger-release.sh index b226e43603..b7f843fad7 100755 --- a/hack/trigger-release.sh +++ b/hack/trigger-release.sh @@ -14,7 +14,7 @@ fi # Target (version) tag must match version scheme vMAJOR.MINOR.PATCH with an # optional pre-release tag. -if ! echo "${NEW_TAG}" | grep -E -q '^v[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)*$'; then +if ! echo "${NEW_TAG}" | egrep -q '^v[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)*$'; then echo "!! Malformed version tag: '${NEW_TAG}', must match 'vMAJOR.MINOR.PATCH(-rcX)'" >&2 exit 1 fi diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 8926ed394a..a2169c945b 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -36,7 +36,7 @@ sed -e '/go install/d' ${PROJECT_ROOT}/vendor/k8s.io/code-generator/kube_codegen # are in the path and invoke them without assumption of their location sed -i.bak -e 's#${gobin}/##g' ${TARGET_SCRIPT} -[ -e ./v3 ] || ln -s . v3 +[ -e ./v2 ] || ln -s . v2 [ -e "${GOPATH_PROJECT_ROOT}" ] || (mkdir -p "$(dirname "${GOPATH_PROJECT_ROOT}")" && ln -s "${PROJECT_ROOT}" "${GOPATH_PROJECT_ROOT}") # shellcheck source=pkg/apis/application/v1alpha1/kube_codegen.sh @@ -45,7 +45,7 @@ sed -i.bak -e 's#${gobin}/##g' ${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/v3/pkg/client \ + --output-pkg github.com/argoproj/argo-cd/v2/pkg/client \ --boilerplate "${PROJECT_ROOT}/hack/custom-boilerplate.go.txt" \ --with-watch @@ -53,4 +53,4 @@ rm ${TARGET_SCRIPT} rm ${TARGET_SCRIPT}.bak [ -L "${GOPATH_PROJECT_ROOT}" ] && rm -rf "${GOPATH_PROJECT_ROOT}" -[ -L ./v3 ] && rm -rf v3 +[ -L ./v2 ] && rm -rf v2 diff --git a/hack/update-openapi.sh b/hack/update-openapi.sh index 292b89c29c..39d821b992 100755 --- a/hack/update-openapi.sh +++ b/hack/update-openapi.sh @@ -15,18 +15,18 @@ GOPATH_PROJECT_ROOT="${GOPATH}/src/github.com/argoproj/argo-cd" VERSION="v1alpha1" -[ -e ./v3 ] || ln -s . v3 +[ -e ./v2 ] || ln -s . v2 [ -e "${GOPATH_PROJECT_ROOT}" ] || (mkdir -p "$(dirname "${GOPATH_PROJECT_ROOT}")" && ln -s "${PROJECT_ROOT}" "${GOPATH_PROJECT_ROOT}") openapi-gen \ --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ - --output-pkg github.com/argoproj/argo-cd/v3/pkg/apis/application/${VERSION} \ + --output-pkg github.com/argoproj/argo-cd/v2/pkg/apis/application/${VERSION} \ --report-filename pkg/apis/api-rules/violation_exceptions.list \ --output-dir "${GOPATH}/src" \ $@ [ -L "${GOPATH_PROJECT_ROOT}" ] && rm -rf "${GOPATH_PROJECT_ROOT}" -[ -L ./v3 ] && rm -rf v3 +[ -L ./v2 ] && rm -rf v2 export GO111MODULE=on go build -o ./dist/gen-crd-spec "${PROJECT_ROOT}/hack/gen-crd-spec" diff --git a/hack/update-supported-versions.sh b/hack/update-supported-versions.sh index 428b102fcc..caf327a27f 100755 --- a/hack/update-supported-versions.sh +++ b/hack/update-supported-versions.sh @@ -7,9 +7,8 @@ argocd_minor_version=$(git rev-parse --abbrev-ref HEAD | sed 's/release-//') argocd_major_version_num=$(echo "$argocd_minor_version" | sed -E 's/\.[0-9]+//') argocd_minor_version_num=$(echo "$argocd_minor_version" | sed -E 's/[0-9]+\.//') -minor_version_decrement=0 -for _ in {1..3}; do - minor_version_num=$((argocd_minor_version_num - minor_version_decrement)) +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 @@ -20,22 +19,9 @@ for _ in {1..3}; do jq --arg minor_version "$minor_version" --raw-input --slurp --raw-output \ 'split("\n")[:-1] | map(sub("\\.[0-9]+$"; "")) | join(", ") | "| \($minor_version) | \(.) |"') out+="$line\n" - - minor_version_decrement=$((minor_version_decrement + 1)) - - # If we're at minor version 0, there's no further version back in this series. Instead, move to the latest version in - # the previous major release series. - if [ "$argocd_minor_version_num" -eq 0 ]; then - argocd_major_version_num=$((argocd_major_version_num - 1)) - # Get the latest minor version in the previous series. - argocd_minor_version_num=$(git tag -l "v$argocd_major_version_num.*" | sort -V | tail -n 1 | sed -E 's/\.[0-9]+$//' | sed -E 's/^v[0-9]+\.//') - - # Don't decrement the minor version, since we're switching to the previous major release series. We want the latest - # minor version in that series. - minor_version_decrement=0 - fi done git checkout "release-$argocd_minor_version" + printf "$out" > docs/operator-manual/tested-kubernetes-versions.md diff --git a/kustomize b/kustomize new file mode 100755 index 0000000000..1577ba57c1 Binary files /dev/null and b/kustomize differ diff --git a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml index bf65aed35b..fa7646bb9e 100644 --- a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml +++ b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml @@ -85,12 +85,6 @@ spec: name: argocd-cmd-params-cm key: controller.log.level optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: log.format.timestamp - optional: true - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION valueFrom: configMapKeyRef: @@ -253,6 +247,12 @@ spec: name: argocd-cmd-params-cm key: controller.cluster.cache.events.processing.interval optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: commit.server + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/manifests/base/application-controller-roles/argocd-application-controller-role.yaml b/manifests/base/application-controller-roles/argocd-application-controller-role.yaml index f0e2e240ea..a672268eb1 100644 --- a/manifests/base/application-controller-roles/argocd-application-controller-role.yaml +++ b/manifests/base/application-controller-roles/argocd-application-controller-role.yaml @@ -20,7 +20,6 @@ rules: - argoproj.io resources: - applications - - applicationsets - appprojects verbs: - create diff --git a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml index e33d3917f0..2b842467fb 100644 --- a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml +++ b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml @@ -88,12 +88,6 @@ spec: name: argocd-cmd-params-cm key: controller.log.level optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: log.format.timestamp - optional: true - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION valueFrom: configMapKeyRef: @@ -202,12 +196,6 @@ spec: name: argocd-cmd-params-cm key: otlp.headers optional: true - - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.attrs - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -268,6 +256,12 @@ spec: name: argocd-cmd-params-cm key: controller.cluster.cache.events.processing.interval optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: commit.server + optional: true - name: KUBECACHEDIR value: /tmp/kubecache image: quay.io/argoproj/argocd:latest diff --git a/manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml b/manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml index 8c7d765057..f4df48823a 100644 --- a/manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml +++ b/manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml @@ -85,12 +85,6 @@ spec: key: applicationsetcontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: log.format.timestamp - optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN valueFrom: configMapKeyRef: diff --git a/manifests/base/commit-server/argocd-commit-server-deployment.yaml b/manifests/base/commit-server/argocd-commit-server-deployment.yaml index b682b0d724..2eba928020 100644 --- a/manifests/base/commit-server/argocd-commit-server-deployment.yaml +++ b/manifests/base/commit-server/argocd-commit-server-deployment.yaml @@ -48,12 +48,6 @@ spec: name: argocd-cmd-params-cm key: commitserver.log.level optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: log.format.timestamp - optional: true ports: - containerPort: 8086 - containerPort: 8087 @@ -92,6 +86,26 @@ spec: # We need a writeable temp directory for the askpass socket file. - name: tmp mountPath: /tmp + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:latest + name: copyutil + securityContext: + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files volumes: - name: ssh-known-hosts configMap: @@ -117,6 +131,8 @@ spec: path: tls.key - key: ca.crt path: ca.crt + - emptyDir: {} + name: var-files affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: diff --git a/manifests/base/commit-server/kustomization.yaml b/manifests/base/commit-server/kustomization.yaml index 931ba25273..1bcd539811 100644 --- a/manifests/base/commit-server/kustomization.yaml +++ b/manifests/base/commit-server/kustomization.yaml @@ -12,4 +12,4 @@ resources: images: - name: quay.io/argoproj/argocd newName: quay.io/argoproj/argocd - newTag: latest + newTag: v2.14.15 diff --git a/manifests/base/config/argocd-cm.yaml b/manifests/base/config/argocd-cm.yaml index 393d3fe657..fdabb71178 100644 --- a/manifests/base/config/argocd-cm.yaml +++ b/manifests/base/config/argocd-cm.yaml @@ -5,114 +5,3 @@ metadata: labels: app.kubernetes.io/name: argocd-cm app.kubernetes.io/part-of: argocd -data: - ### Default configuration for ignoreResourceUpdates. - # The ignoreResourceUpdates list contains K8s resource's properties that are known to be frequently updated - # by controllers and operators. These resources, when watched by argo, will cause many unnecessary updates. - # Ignoring status for all resources. An update will still be sent if the status update causes the health to change. - resource.customizations.ignoreResourceUpdates.all: | - jsonPointers: - - /status - # Some Application fields are generated and not related to the application updates itself - # The Application itself is already watched by the controller lister, but this configuration is applied for apps of apps - resource.customizations.ignoreResourceUpdates.argoproj.io_Application: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - - '.metadata.annotations."argocd.argoproj.io/refresh"' - - '.metadata.annotations."argocd.argoproj.io/hydrate"' - - '.operation' - resource.customizations.ignoreResourceUpdates.argoproj.io_Rollout: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - # Legacy annotations used on HPA autoscaling/v1 - resource.customizations.ignoreResourceUpdates.autoscaling_HorizontalPodAutoscaler: | - jqPathExpressions: - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/behavior"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/conditions"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/metrics"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/current-metrics"' - # Ignore the cluster-autoscaler status - resource.customizations.ignoreResourceUpdates.ConfigMap: | - jqPathExpressions: - # Ignore the cluster-autoscaler status - - '.metadata.annotations."cluster-autoscaler.kubernetes.io/last-updated"' - # Ignore the annotation of the legacy Leases election - - '.metadata.annotations."control-plane.alpha.kubernetes.io/leader"' - # Ignore the common scaling annotations - resource.customizations.ignoreResourceUpdates.apps_ReplicaSet: | - jqPathExpressions: - - '.metadata.annotations."deployment.kubernetes.io/desired-replicas"' - - '.metadata.annotations."deployment.kubernetes.io/max-replicas"' - - '.metadata.annotations."rollout.argoproj.io/desired-replicas"' - # Ignores update if EndpointSlice is not excluded globally - resource.customizations.ignoreResourceUpdates.discovery.k8s.io_EndpointSlice: | - jsonPointers: - - /metadata - - /endpoints - - /ports - # Ignores update if Endpoints is not excluded globally - resource.customizations.ignoreResourceUpdates.Endpoints: | - jsonPointers: - - /metadata - - /subsets - - ### Default configuration for exclusions. - # The exclusion list are K8s resources that we assume will never be declared in Git, - # and are never child objects of managed resources that need to be presented in the resource tree. - # This list contains high volume and high churn metadata objects which we exclude for performance - # reasons, reducing connections and load to the K8s API servers of managed clusters. - resource.exclusions: | - ### Network resources created by the Kubernetes control plane and excluded to reduce the number of watched events and UI clutter - - apiGroups: - - '' - - discovery.k8s.io - kinds: - - Endpoints - - EndpointSlice - ### Internal Kubernetes resources excluded reduce the number of watched events - - apiGroups: - - coordination.k8s.io - kinds: - - Lease - ### Internal Kubernetes Authz/Authn resources excluded reduce the number of watched events - - apiGroups: - - authentication.k8s.io - - authorization.k8s.io - kinds: - - SelfSubjectReview - - TokenReview - - LocalSubjectAccessReview - - SelfSubjectAccessReview - - SelfSubjectRulesReview - - SubjectAccessReview - ### Intermediate Certificate Request excluded reduce the number of watched events - - apiGroups: - - certificates.k8s.io - kinds: - - CertificateSigningRequest - - apiGroups: - - cert-manager.io - kinds: - - CertificateRequest - ### Cilium internal resources excluded reduce the number of watched events and UI Clutter - - apiGroups: - - cilium.io - kinds: - - CiliumIdentity - - CiliumEndpoint - - CiliumEndpointSlice - ### Kyverno intermediate and reporting resources excluded reduce the number of watched events and improve performance - - apiGroups: - - kyverno.io - - reports.kyverno.io - - wgpolicyk8s.io - kinds: - - PolicyReport - - ClusterPolicyReport - - EphemeralReport - - ClusterEphemeralReport - - AdmissionReport - - ClusterAdmissionReport - - BackgroundScanReport - - ClusterBackgroundScanReport - - UpdateRequest diff --git a/manifests/base/dex/argocd-dex-server-deployment.yaml b/manifests/base/dex/argocd-dex-server-deployment.yaml index 1c1203b63e..87d7d0a2fb 100644 --- a/manifests/base/dex/argocd-dex-server-deployment.yaml +++ b/manifests/base/dex/argocd-dex-server-deployment.yaml @@ -37,7 +37,7 @@ spec: type: RuntimeDefault containers: - name: dex - image: ghcr.io/dexidp/dex:v2.43.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always command: [/shared/argocd-dex, rundex] env: @@ -53,12 +53,6 @@ spec: key: dexserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: log.format.timestamp - optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: diff --git a/manifests/base/kustomization.yaml b/manifests/base/kustomization.yaml index e80274cddc..69bfba0409 100644 --- a/manifests/base/kustomization.yaml +++ b/manifests/base/kustomization.yaml @@ -5,7 +5,7 @@ kind: Kustomization images: - name: quay.io/argoproj/argocd newName: quay.io/argoproj/argocd - newTag: latest + newTag: v2.14.15 resources: - ./application-controller - ./dex diff --git a/manifests/base/notification/argocd-notifications-controller-deployment.yaml b/manifests/base/notification/argocd-notifications-controller-deployment.yaml index ca75e94841..c3a533e5a4 100644 --- a/manifests/base/notification/argocd-notifications-controller-deployment.yaml +++ b/manifests/base/notification/argocd-notifications-controller-deployment.yaml @@ -48,12 +48,6 @@ spec: key: notificationscontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: log.format.timestamp - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/base/redis/argocd-redis-deployment.yaml b/manifests/base/redis/argocd-redis-deployment.yaml index 9dd65610d7..cbfebb8a21 100644 --- a/manifests/base/redis/argocd-redis-deployment.yaml +++ b/manifests/base/redis/argocd-redis-deployment.yaml @@ -40,7 +40,7 @@ spec: serviceAccountName: argocd-redis containers: - name: redis - image: redis:7.2.7-alpine + image: redis:7.0.15-alpine imagePullPolicy: Always args: - "--save" diff --git a/manifests/base/repo-server/argocd-repo-server-deployment.yaml b/manifests/base/repo-server/argocd-repo-server-deployment.yaml index 1b582f91ee..02a11fabe9 100644 --- a/manifests/base/repo-server/argocd-repo-server-deployment.yaml +++ b/manifests/base/repo-server/argocd-repo-server-deployment.yaml @@ -47,12 +47,6 @@ spec: name: argocd-cmd-params-cm key: reposerver.log.level optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: log.format.timestamp - optional: true - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT valueFrom: configMapKeyRef: @@ -143,12 +137,6 @@ spec: name: argocd-cmd-params-cm key: otlp.headers optional: true - - name: ARGOCD_REPO_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.attrs - optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: diff --git a/manifests/base/server/argocd-server-deployment.yaml b/manifests/base/server/argocd-server-deployment.yaml index 71c2e01ce4..5b0d688e80 100644 --- a/manifests/base/server/argocd-server-deployment.yaml +++ b/manifests/base/server/argocd-server-deployment.yaml @@ -232,12 +232,6 @@ spec: name: argocd-cmd-params-cm key: otlp.headers optional: true - - name: ARGOCD_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.attrs - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -304,12 +298,6 @@ spec: name: argocd-cmd-params-cm key: hydrator.enabled optional: true - - name: ARGOCD_SYNC_WITH_REPLACE_ALLOWED - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.sync.replace.allowed - optional: true volumeMounts: - name: ssh-known-hosts mountPath: /app/config/ssh diff --git a/manifests/core-install-with-hydrator.yaml b/manifests/core-install-with-hydrator.yaml index 1feb53fcfd..ca6143db2d 100644 --- a/manifests/core-install-with-hydrator.yaml +++ b/manifests/core-install-with-hydrator.yaml @@ -380,11 +380,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by - not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -398,10 +393,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -769,11 +760,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -787,10 +773,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1268,11 +1250,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize from - failing when components do not exist locally by not appending - them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1286,10 +1263,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to apply - common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1705,11 +1678,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by not - appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1723,10 +1691,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1883,10 +1847,6 @@ spec: description: 'AllowEmpty allows apps have zero live resources (default: false)' type: boolean - enabled: - description: Enable allows apps to explicitly control automated - sync - type: boolean prune: description: 'Prune specifies whether to delete resources from the cluster that are not found in the sources anymore @@ -1990,13 +1950,12 @@ spec: format: date-time type: string message: - description: |- - Message is a human-readable informational message describing the health status - - Deprecated: this field is not used and will be removed in a future release. + description: Message is a human-readable informational message + describing the health status type: string status: - description: Status holds the status code of the application + description: Status holds the status code of the application or + resource type: string type: object history: @@ -2260,11 +2219,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2278,10 +2232,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -2651,11 +2601,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2669,11 +2614,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -3193,12 +3133,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do not - exist locally by not appending them to kustomization - file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3212,11 +3146,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates - or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors @@ -3606,12 +3535,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do - not exist locally by not appending them to - kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3625,11 +3548,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies - whether to apply common labels to resource - templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource @@ -4131,11 +4049,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4149,11 +4062,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4535,11 +4443,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4553,11 +4456,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4730,22 +4628,19 @@ spec: description: Resources is a list of Kubernetes resources managed by this application items: - description: ResourceStatus holds the current synchronization and - health status of a Kubernetes resource. + description: |- + ResourceStatus holds the current sync and health status of a resource + TODO: describe members of this type properties: group: - description: Group represents the API group of the resource - (e.g., "apps" for Deployments). type: string health: - description: Health indicates the health status of the resource - (e.g., Healthy, Degraded, Progressing). + description: HealthStatus contains information about the currently + observed health state of an application or resource properties: lastTransitionTime: - description: |- - LastTransitionTime is the time the HealthStatus was set or updated - - Deprecated: this field is not used and will be removed in a future release. + description: LastTransitionTime is the time the HealthStatus + was set or updated format: date-time type: string message: @@ -4753,46 +4648,30 @@ spec: describing the health status type: string status: - description: Status holds the status code of the resource + description: Status holds the status code of the application + or resource type: string type: object hook: - description: Hook is true if the resource is used as a lifecycle - hook in an Argo CD application. type: boolean kind: - description: Kind specifies the type of the resource (e.g., - "Deployment", "Service"). type: string name: - description: Name is the unique name of the resource within - the namespace. type: string namespace: - description: Namespace defines the Kubernetes namespace where - the resource is located. type: string requiresDeletionConfirmation: - description: RequiresDeletionConfirmation is true if the resource - requires explicit user confirmation before deletion. type: boolean requiresPruning: - description: RequiresPruning is true if the resource needs to - be pruned (deleted) as part of synchronization. type: boolean status: - description: Status represents the synchronization state of - the resource (e.g., Synced, OutOfSync). + description: SyncStatusCode is a type which represents possible + comparison results type: string syncWave: - description: |- - SyncWave determines the order in which resources are applied during a sync operation. - Lower values are applied first. format: int64 type: integer version: - description: Version indicates the API version of the resource - (e.g., "v1", "v1beta1"). type: string type: object type: array @@ -5278,11 +5157,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5296,11 +5170,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -5682,11 +5551,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5700,11 +5564,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -6157,16 +6016,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6433,16 +6288,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6553,8 +6404,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -6839,16 +6688,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7115,16 +6960,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7235,8 +7076,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -7303,8 +7142,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -7522,16 +7359,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7798,16 +7631,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7918,8 +7747,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8183,16 +8010,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8459,16 +8282,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8579,8 +8398,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8869,16 +8686,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9145,16 +8958,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9265,8 +9074,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -9551,16 +9358,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9827,16 +9630,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9947,8 +9746,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10015,8 +9812,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -10234,16 +10029,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10510,16 +10301,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10630,8 +10417,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10895,16 +10680,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11171,16 +10952,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11291,8 +11068,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -11564,16 +11339,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11840,16 +11611,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11960,8 +11727,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12163,10 +11928,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -12456,16 +12217,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12732,16 +12489,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12852,8 +12605,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12899,10 +12650,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -13343,16 +13090,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13619,16 +13362,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13739,8 +13478,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14021,16 +13758,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14297,16 +14030,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14417,8 +14146,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14709,16 +14436,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14985,16 +14708,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15105,8 +14824,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15391,16 +15108,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15667,16 +15380,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15787,8 +15496,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15855,8 +15562,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -16074,16 +15779,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16350,16 +16051,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16470,8 +16167,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -16735,16 +16430,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17011,16 +16702,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17131,8 +16818,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -17404,16 +17089,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17680,16 +17361,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17800,8 +17477,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -18003,10 +17678,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -18296,16 +17967,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -18572,16 +18239,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -18692,8 +18355,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -18739,10 +18400,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -19183,16 +18840,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -19459,16 +19112,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -19579,8 +19228,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -19865,16 +19512,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20141,16 +19784,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20261,8 +19900,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -20533,16 +20170,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20809,16 +20442,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20929,8 +20558,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -21132,10 +20759,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -21425,16 +21048,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -21701,16 +21320,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -21821,8 +21436,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -21868,10 +21481,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -22312,16 +21921,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -22588,16 +22193,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -22708,8 +22309,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -23065,16 +22664,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -23341,16 +22936,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -23461,8 +23052,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -23695,7 +23284,6 @@ spec: type: array description: description: Description contains optional project description - maxLength: 255 type: string destinationServiceAccounts: description: DestinationServiceAccounts holds information about the @@ -23890,10 +23478,6 @@ spec: description: SyncWindow contains the kind, time, duration and attributes that are used to assign the syncWindows to apps properties: - andOperator: - description: UseAndOperator use AND operator for matching applications, - namespaces and clusters instead of the default OR operator - type: boolean applications: description: Applications contains a list of applications that the window will apply to @@ -23906,11 +23490,6 @@ spec: items: type: string type: array - description: - description: Description of the sync that will be applied to - the schedule, can be used to add any information such as a - ticket number for example - type: string duration: description: Duration is the amount of time the sync window will be open @@ -24043,7 +23622,6 @@ rules: - argoproj.io resources: - applications - - applicationsets - appprojects verbs: - create @@ -24247,100 +23825,6 @@ subjects: namespace: argocd --- apiVersion: v1 -data: - resource.customizations.ignoreResourceUpdates.ConfigMap: | - jqPathExpressions: - # Ignore the cluster-autoscaler status - - '.metadata.annotations."cluster-autoscaler.kubernetes.io/last-updated"' - # Ignore the annotation of the legacy Leases election - - '.metadata.annotations."control-plane.alpha.kubernetes.io/leader"' - resource.customizations.ignoreResourceUpdates.Endpoints: | - jsonPointers: - - /metadata - - /subsets - resource.customizations.ignoreResourceUpdates.all: | - jsonPointers: - - /status - resource.customizations.ignoreResourceUpdates.apps_ReplicaSet: | - jqPathExpressions: - - '.metadata.annotations."deployment.kubernetes.io/desired-replicas"' - - '.metadata.annotations."deployment.kubernetes.io/max-replicas"' - - '.metadata.annotations."rollout.argoproj.io/desired-replicas"' - resource.customizations.ignoreResourceUpdates.argoproj.io_Application: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - - '.metadata.annotations."argocd.argoproj.io/refresh"' - - '.metadata.annotations."argocd.argoproj.io/hydrate"' - - '.operation' - resource.customizations.ignoreResourceUpdates.argoproj.io_Rollout: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - resource.customizations.ignoreResourceUpdates.autoscaling_HorizontalPodAutoscaler: | - jqPathExpressions: - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/behavior"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/conditions"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/metrics"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/current-metrics"' - resource.customizations.ignoreResourceUpdates.discovery.k8s.io_EndpointSlice: | - jsonPointers: - - /metadata - - /endpoints - - /ports - resource.exclusions: | - ### Network resources created by the Kubernetes control plane and excluded to reduce the number of watched events and UI clutter - - apiGroups: - - '' - - discovery.k8s.io - kinds: - - Endpoints - - EndpointSlice - ### Internal Kubernetes resources excluded reduce the number of watched events - - apiGroups: - - coordination.k8s.io - kinds: - - Lease - ### Internal Kubernetes Authz/Authn resources excluded reduce the number of watched events - - apiGroups: - - authentication.k8s.io - - authorization.k8s.io - kinds: - - SelfSubjectReview - - TokenReview - - LocalSubjectAccessReview - - SelfSubjectAccessReview - - SelfSubjectRulesReview - - SubjectAccessReview - ### Intermediate Certificate Request excluded reduce the number of watched events - - apiGroups: - - certificates.k8s.io - kinds: - - CertificateSigningRequest - - apiGroups: - - cert-manager.io - kinds: - - CertificateRequest - ### Cilium internal resources excluded reduce the number of watched events and UI Clutter - - apiGroups: - - cilium.io - kinds: - - CiliumIdentity - - CiliumEndpoint - - CiliumEndpointSlice - ### Kyverno intermediate and reporting resources excluded reduce the number of watched events and improve performance - - apiGroups: - - kyverno.io - - reports.kyverno.io - - wgpolicyk8s.io - kinds: - - PolicyReport - - ClusterPolicyReport - - EphemeralReport - - ClusterEphemeralReport - - AdmissionReport - - ClusterAdmissionReport - - BackgroundScanReport - - ClusterBackgroundScanReport - - UpdateRequest kind: ConfigMap metadata: labels: @@ -24591,12 +24075,6 @@ spec: key: applicationsetcontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN valueFrom: configMapKeyRef: @@ -24687,7 +24165,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -24807,13 +24285,7 @@ spec: key: commitserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -24853,6 +24325,26 @@ spec: name: gpg-keyring - mountPath: /tmp name: tmp + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:v2.14.15 + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files serviceAccountName: argocd-commit-server volumes: - configMap: @@ -24879,6 +24371,8 @@ spec: path: ca.crt optional: true secretName: argocd-commit-server-tls + - emptyDir: {} + name: var-files --- apiVersion: apps/v1 kind: Deployment @@ -24925,7 +24419,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: redis:7.2.7-alpine + image: redis:7.0.15-alpine imagePullPolicy: Always name: redis ports: @@ -24941,7 +24435,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -25022,12 +24516,6 @@ spec: key: reposerver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT valueFrom: configMapKeyRef: @@ -25118,12 +24606,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_REPO_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -25214,7 +24696,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -25266,7 +24748,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -25420,12 +24902,6 @@ spec: key: controller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION valueFrom: configMapKeyRef: @@ -25534,12 +25010,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -25600,9 +25070,15 @@ spec: key: controller.cluster.cache.events.processing.interval name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER + valueFrom: + configMapKeyRef: + key: commit.server + name: argocd-cmd-params-cm + optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index b388728758..57ede2b758 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -380,11 +380,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by - not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -398,10 +393,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -769,11 +760,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -787,10 +773,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1268,11 +1250,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize from - failing when components do not exist locally by not appending - them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1286,10 +1263,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to apply - common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1705,11 +1678,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by not - appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1723,10 +1691,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1883,10 +1847,6 @@ spec: description: 'AllowEmpty allows apps have zero live resources (default: false)' type: boolean - enabled: - description: Enable allows apps to explicitly control automated - sync - type: boolean prune: description: 'Prune specifies whether to delete resources from the cluster that are not found in the sources anymore @@ -1990,13 +1950,12 @@ spec: format: date-time type: string message: - description: |- - Message is a human-readable informational message describing the health status - - Deprecated: this field is not used and will be removed in a future release. + description: Message is a human-readable informational message + describing the health status type: string status: - description: Status holds the status code of the application + description: Status holds the status code of the application or + resource type: string type: object history: @@ -2260,11 +2219,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2278,10 +2232,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -2651,11 +2601,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2669,11 +2614,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -3193,12 +3133,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do not - exist locally by not appending them to kustomization - file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3212,11 +3146,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates - or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors @@ -3606,12 +3535,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do - not exist locally by not appending them to - kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3625,11 +3548,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies - whether to apply common labels to resource - templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource @@ -4131,11 +4049,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4149,11 +4062,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4535,11 +4443,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4553,11 +4456,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4730,22 +4628,19 @@ spec: description: Resources is a list of Kubernetes resources managed by this application items: - description: ResourceStatus holds the current synchronization and - health status of a Kubernetes resource. + description: |- + ResourceStatus holds the current sync and health status of a resource + TODO: describe members of this type properties: group: - description: Group represents the API group of the resource - (e.g., "apps" for Deployments). type: string health: - description: Health indicates the health status of the resource - (e.g., Healthy, Degraded, Progressing). + description: HealthStatus contains information about the currently + observed health state of an application or resource properties: lastTransitionTime: - description: |- - LastTransitionTime is the time the HealthStatus was set or updated - - Deprecated: this field is not used and will be removed in a future release. + description: LastTransitionTime is the time the HealthStatus + was set or updated format: date-time type: string message: @@ -4753,46 +4648,30 @@ spec: describing the health status type: string status: - description: Status holds the status code of the resource + description: Status holds the status code of the application + or resource type: string type: object hook: - description: Hook is true if the resource is used as a lifecycle - hook in an Argo CD application. type: boolean kind: - description: Kind specifies the type of the resource (e.g., - "Deployment", "Service"). type: string name: - description: Name is the unique name of the resource within - the namespace. type: string namespace: - description: Namespace defines the Kubernetes namespace where - the resource is located. type: string requiresDeletionConfirmation: - description: RequiresDeletionConfirmation is true if the resource - requires explicit user confirmation before deletion. type: boolean requiresPruning: - description: RequiresPruning is true if the resource needs to - be pruned (deleted) as part of synchronization. type: boolean status: - description: Status represents the synchronization state of - the resource (e.g., Synced, OutOfSync). + description: SyncStatusCode is a type which represents possible + comparison results type: string syncWave: - description: |- - SyncWave determines the order in which resources are applied during a sync operation. - Lower values are applied first. format: int64 type: integer version: - description: Version indicates the API version of the resource - (e.g., "v1", "v1beta1"). type: string type: object type: array @@ -5278,11 +5157,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5296,11 +5170,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -5682,11 +5551,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5700,11 +5564,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -6157,16 +6016,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6433,16 +6288,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6553,8 +6404,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -6839,16 +6688,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7115,16 +6960,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7235,8 +7076,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -7303,8 +7142,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -7522,16 +7359,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7798,16 +7631,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7918,8 +7747,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8183,16 +8010,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8459,16 +8282,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8579,8 +8398,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8869,16 +8686,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9145,16 +8958,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9265,8 +9074,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -9551,16 +9358,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9827,16 +9630,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9947,8 +9746,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10015,8 +9812,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -10234,16 +10029,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10510,16 +10301,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10630,8 +10417,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10895,16 +10680,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11171,16 +10952,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11291,8 +11068,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -11564,16 +11339,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11840,16 +11611,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11960,8 +11727,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12163,10 +11928,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -12456,16 +12217,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12732,16 +12489,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12852,8 +12605,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12899,10 +12650,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -13343,16 +13090,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13619,16 +13362,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13739,8 +13478,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14021,16 +13758,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14297,16 +14030,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14417,8 +14146,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14709,16 +14436,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14985,16 +14708,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15105,8 +14824,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15391,16 +15108,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15667,16 +15380,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15787,8 +15496,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15855,8 +15562,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -16074,16 +15779,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16350,16 +16051,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16470,8 +16167,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -16735,16 +16430,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17011,16 +16702,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17131,8 +16818,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -17404,16 +17089,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17680,16 +17361,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17800,8 +17477,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -18003,10 +17678,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -18296,16 +17967,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -18572,16 +18239,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -18692,8 +18355,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -18739,10 +18400,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -19183,16 +18840,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -19459,16 +19112,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -19579,8 +19228,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -19865,16 +19512,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20141,16 +19784,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20261,8 +19900,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -20533,16 +20170,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20809,16 +20442,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20929,8 +20558,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -21132,10 +20759,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -21425,16 +21048,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -21701,16 +21320,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -21821,8 +21436,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -21868,10 +21481,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -22312,16 +21921,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -22588,16 +22193,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -22708,8 +22309,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -23065,16 +22664,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -23341,16 +22936,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -23461,8 +23052,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -23695,7 +23284,6 @@ spec: type: array description: description: Description contains optional project description - maxLength: 255 type: string destinationServiceAccounts: description: DestinationServiceAccounts holds information about the @@ -23890,10 +23478,6 @@ spec: description: SyncWindow contains the kind, time, duration and attributes that are used to assign the syncWindows to apps properties: - andOperator: - description: UseAndOperator use AND operator for matching applications, - namespaces and clusters instead of the default OR operator - type: boolean applications: description: Applications contains a list of applications that the window will apply to @@ -23906,11 +23490,6 @@ spec: items: type: string type: array - description: - description: Description of the sync that will be applied to - the schedule, can be used to add any information such as a - ticket number for example - type: string duration: description: Duration is the amount of time the sync window will be open @@ -24034,7 +23613,6 @@ rules: - argoproj.io resources: - applications - - applicationsets - appprojects verbs: - create @@ -24238,100 +23816,6 @@ subjects: namespace: argocd --- apiVersion: v1 -data: - resource.customizations.ignoreResourceUpdates.ConfigMap: | - jqPathExpressions: - # Ignore the cluster-autoscaler status - - '.metadata.annotations."cluster-autoscaler.kubernetes.io/last-updated"' - # Ignore the annotation of the legacy Leases election - - '.metadata.annotations."control-plane.alpha.kubernetes.io/leader"' - resource.customizations.ignoreResourceUpdates.Endpoints: | - jsonPointers: - - /metadata - - /subsets - resource.customizations.ignoreResourceUpdates.all: | - jsonPointers: - - /status - resource.customizations.ignoreResourceUpdates.apps_ReplicaSet: | - jqPathExpressions: - - '.metadata.annotations."deployment.kubernetes.io/desired-replicas"' - - '.metadata.annotations."deployment.kubernetes.io/max-replicas"' - - '.metadata.annotations."rollout.argoproj.io/desired-replicas"' - resource.customizations.ignoreResourceUpdates.argoproj.io_Application: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - - '.metadata.annotations."argocd.argoproj.io/refresh"' - - '.metadata.annotations."argocd.argoproj.io/hydrate"' - - '.operation' - resource.customizations.ignoreResourceUpdates.argoproj.io_Rollout: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - resource.customizations.ignoreResourceUpdates.autoscaling_HorizontalPodAutoscaler: | - jqPathExpressions: - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/behavior"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/conditions"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/metrics"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/current-metrics"' - resource.customizations.ignoreResourceUpdates.discovery.k8s.io_EndpointSlice: | - jsonPointers: - - /metadata - - /endpoints - - /ports - resource.exclusions: | - ### Network resources created by the Kubernetes control plane and excluded to reduce the number of watched events and UI clutter - - apiGroups: - - '' - - discovery.k8s.io - kinds: - - Endpoints - - EndpointSlice - ### Internal Kubernetes resources excluded reduce the number of watched events - - apiGroups: - - coordination.k8s.io - kinds: - - Lease - ### Internal Kubernetes Authz/Authn resources excluded reduce the number of watched events - - apiGroups: - - authentication.k8s.io - - authorization.k8s.io - kinds: - - SelfSubjectReview - - TokenReview - - LocalSubjectAccessReview - - SelfSubjectAccessReview - - SelfSubjectRulesReview - - SubjectAccessReview - ### Intermediate Certificate Request excluded reduce the number of watched events - - apiGroups: - - certificates.k8s.io - kinds: - - CertificateSigningRequest - - apiGroups: - - cert-manager.io - kinds: - - CertificateRequest - ### Cilium internal resources excluded reduce the number of watched events and UI Clutter - - apiGroups: - - cilium.io - kinds: - - CiliumIdentity - - CiliumEndpoint - - CiliumEndpointSlice - ### Kyverno intermediate and reporting resources excluded reduce the number of watched events and improve performance - - apiGroups: - - kyverno.io - - reports.kyverno.io - - wgpolicyk8s.io - kinds: - - PolicyReport - - ClusterPolicyReport - - EphemeralReport - - ClusterEphemeralReport - - AdmissionReport - - ClusterAdmissionReport - - BackgroundScanReport - - ClusterBackgroundScanReport - - UpdateRequest kind: ConfigMap metadata: labels: @@ -24559,12 +24043,6 @@ spec: key: applicationsetcontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN valueFrom: configMapKeyRef: @@ -24655,7 +24133,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -24759,7 +24237,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: redis:7.2.7-alpine + image: redis:7.0.15-alpine imagePullPolicy: Always name: redis ports: @@ -24775,7 +24253,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -24856,12 +24334,6 @@ spec: key: reposerver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT valueFrom: configMapKeyRef: @@ -24952,12 +24424,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_REPO_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -25048,7 +24514,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -25100,7 +24566,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -25254,12 +24720,6 @@ spec: key: controller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION valueFrom: configMapKeyRef: @@ -25368,12 +24828,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -25434,9 +24888,15 @@ spec: key: controller.cluster.cache.events.processing.interval name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER + valueFrom: + configMapKeyRef: + key: commit.server + name: argocd-cmd-params-cm + optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/core-install/kustomization.yaml b/manifests/core-install/kustomization.yaml index 07a82b3707..928adc52d8 100644 --- a/manifests/core-install/kustomization.yaml +++ b/manifests/core-install/kustomization.yaml @@ -12,4 +12,4 @@ resources: images: - name: quay.io/argoproj/argocd newName: quay.io/argoproj/argocd - newTag: latest + newTag: v2.14.15 diff --git a/manifests/crds/application-crd.yaml b/manifests/crds/application-crd.yaml index 92f86af99b..e2dac9a68b 100644 --- a/manifests/crds/application-crd.yaml +++ b/manifests/crds/application-crd.yaml @@ -379,11 +379,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by - not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -397,10 +392,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -768,11 +759,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -786,10 +772,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1267,11 +1249,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize from - failing when components do not exist locally by not appending - them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1285,10 +1262,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to apply - common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1704,11 +1677,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by not - appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1722,10 +1690,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1882,10 +1846,6 @@ spec: description: 'AllowEmpty allows apps have zero live resources (default: false)' type: boolean - enabled: - description: Enable allows apps to explicitly control automated - sync - type: boolean prune: description: 'Prune specifies whether to delete resources from the cluster that are not found in the sources anymore @@ -1989,13 +1949,12 @@ spec: format: date-time type: string message: - description: |- - Message is a human-readable informational message describing the health status - - Deprecated: this field is not used and will be removed in a future release. + description: Message is a human-readable informational message + describing the health status type: string status: - description: Status holds the status code of the application + description: Status holds the status code of the application or + resource type: string type: object history: @@ -2259,11 +2218,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2277,10 +2231,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -2650,11 +2600,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2668,11 +2613,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -3192,12 +3132,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do not - exist locally by not appending them to kustomization - file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3211,11 +3145,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates - or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors @@ -3605,12 +3534,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do - not exist locally by not appending them to - kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3624,11 +3547,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies - whether to apply common labels to resource - templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource @@ -4130,11 +4048,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4148,11 +4061,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4534,11 +4442,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4552,11 +4455,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4729,22 +4627,19 @@ spec: description: Resources is a list of Kubernetes resources managed by this application items: - description: ResourceStatus holds the current synchronization and - health status of a Kubernetes resource. + description: |- + ResourceStatus holds the current sync and health status of a resource + TODO: describe members of this type properties: group: - description: Group represents the API group of the resource - (e.g., "apps" for Deployments). type: string health: - description: Health indicates the health status of the resource - (e.g., Healthy, Degraded, Progressing). + description: HealthStatus contains information about the currently + observed health state of an application or resource properties: lastTransitionTime: - description: |- - LastTransitionTime is the time the HealthStatus was set or updated - - Deprecated: this field is not used and will be removed in a future release. + description: LastTransitionTime is the time the HealthStatus + was set or updated format: date-time type: string message: @@ -4752,46 +4647,30 @@ spec: describing the health status type: string status: - description: Status holds the status code of the resource + description: Status holds the status code of the application + or resource type: string type: object hook: - description: Hook is true if the resource is used as a lifecycle - hook in an Argo CD application. type: boolean kind: - description: Kind specifies the type of the resource (e.g., - "Deployment", "Service"). type: string name: - description: Name is the unique name of the resource within - the namespace. type: string namespace: - description: Namespace defines the Kubernetes namespace where - the resource is located. type: string requiresDeletionConfirmation: - description: RequiresDeletionConfirmation is true if the resource - requires explicit user confirmation before deletion. type: boolean requiresPruning: - description: RequiresPruning is true if the resource needs to - be pruned (deleted) as part of synchronization. type: boolean status: - description: Status represents the synchronization state of - the resource (e.g., Synced, OutOfSync). + description: SyncStatusCode is a type which represents possible + comparison results type: string syncWave: - description: |- - SyncWave determines the order in which resources are applied during a sync operation. - Lower values are applied first. format: int64 type: integer version: - description: Version indicates the API version of the resource - (e.g., "v1", "v1beta1"). type: string type: object type: array @@ -5277,11 +5156,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5295,11 +5169,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -5681,11 +5550,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5699,11 +5563,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or diff --git a/manifests/crds/applicationset-crd.yaml b/manifests/crds/applicationset-crd.yaml index 8cb86b7b94..97b4cf0339 100644 --- a/manifests/crds/applicationset-crd.yaml +++ b/manifests/crds/applicationset-crd.yaml @@ -271,16 +271,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -547,16 +543,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -667,8 +659,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -953,16 +943,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -1229,16 +1215,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -1349,8 +1331,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -1417,8 +1397,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -1636,16 +1614,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -1912,16 +1886,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -2032,8 +2002,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -2297,16 +2265,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -2573,16 +2537,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -2693,8 +2653,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -2983,16 +2941,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -3259,16 +3213,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -3379,8 +3329,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -3665,16 +3613,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -3941,16 +3885,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -4061,8 +4001,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -4129,8 +4067,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -4348,16 +4284,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -4624,16 +4556,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -4744,8 +4672,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -5009,16 +4935,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -5285,16 +5207,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -5405,8 +5323,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -5678,16 +5594,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -5954,16 +5866,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6074,8 +5982,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -6277,10 +6183,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -6570,16 +6472,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6846,16 +6744,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6966,8 +6860,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -7013,10 +6905,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -7457,16 +7345,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7733,16 +7617,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7853,8 +7733,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8135,16 +8013,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8411,16 +8285,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8531,8 +8401,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8823,16 +8691,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9099,16 +8963,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9219,8 +9079,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -9505,16 +9363,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9781,16 +9635,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9901,8 +9751,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -9969,8 +9817,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -10188,16 +10034,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10464,16 +10306,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10584,8 +10422,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10849,16 +10685,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11125,16 +10957,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11245,8 +11073,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -11518,16 +11344,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11794,16 +11616,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11914,8 +11732,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12117,10 +11933,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -12410,16 +12222,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12686,16 +12494,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12806,8 +12610,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12853,10 +12655,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -13297,16 +13095,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13573,16 +13367,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13693,8 +13483,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -13979,16 +13767,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14255,16 +14039,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14375,8 +14155,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14647,16 +14425,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14923,16 +14697,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15043,8 +14813,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15246,10 +15014,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -15539,16 +15303,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15815,16 +15575,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15935,8 +15691,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15982,10 +15736,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -16426,16 +16176,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16702,16 +16448,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16822,8 +16564,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -17179,16 +16919,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17455,16 +17191,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17575,8 +17307,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: diff --git a/manifests/crds/appproject-crd.yaml b/manifests/crds/appproject-crd.yaml index 64b15b9b42..a72a8de146 100644 --- a/manifests/crds/appproject-crd.yaml +++ b/manifests/crds/appproject-crd.yaml @@ -84,7 +84,6 @@ spec: type: array description: description: Description contains optional project description - maxLength: 255 type: string destinationServiceAccounts: description: DestinationServiceAccounts holds information about the @@ -279,10 +278,6 @@ spec: description: SyncWindow contains the kind, time, duration and attributes that are used to assign the syncWindows to apps properties: - andOperator: - description: UseAndOperator use AND operator for matching applications, - namespaces and clusters instead of the default OR operator - type: boolean applications: description: Applications contains a list of applications that the window will apply to @@ -295,11 +290,6 @@ spec: items: type: string type: array - description: - description: Description of the sync that will be applied to - the schedule, can be used to add any information such as a - ticket number for example - type: string duration: description: Duration is the amount of time the sync window will be open diff --git a/manifests/ha/base/kustomization.yaml b/manifests/ha/base/kustomization.yaml index ae40b96e86..3f53bc8650 100644 --- a/manifests/ha/base/kustomization.yaml +++ b/manifests/ha/base/kustomization.yaml @@ -12,7 +12,7 @@ patches: images: - name: quay.io/argoproj/argocd newName: quay.io/argoproj/argocd - newTag: latest + newTag: v2.14.15 resources: - ../../base/application-controller - ../../base/applicationset-controller diff --git a/manifests/ha/base/redis-ha/chart/requirements.lock b/manifests/ha/base/redis-ha/chart/requirements.lock index 4bd73cda7e..25a568b262 100644 --- a/manifests/ha/base/redis-ha/chart/requirements.lock +++ b/manifests/ha/base/redis-ha/chart/requirements.lock @@ -1,6 +1,6 @@ dependencies: - name: redis-ha repository: https://dandydeveloper.github.io/charts - version: 4.33.2 -digest: sha256:dfb01cb345d8e0c3cf41294ca9b7eae8272083f3ed165cf58d35e492403cf0aa -generated: "2025-03-04T08:25:54.199096-08:00" + version: 4.26.6 +digest: sha256:c363f48ea8339c4bdb7c8a2cca62aa487b69d0a52a6fe6267fbbbbc07e468abd +generated: "2024-04-10T11:02:32.957812-07:00" diff --git a/manifests/ha/base/redis-ha/chart/requirements.yaml b/manifests/ha/base/redis-ha/chart/requirements.yaml index 45cb68d04e..618eecda6d 100644 --- a/manifests/ha/base/redis-ha/chart/requirements.yaml +++ b/manifests/ha/base/redis-ha/chart/requirements.yaml @@ -1,4 +1,4 @@ dependencies: - name: redis-ha - version: 4.33.2 + version: 4.26.6 repository: https://dandydeveloper.github.io/charts diff --git a/manifests/ha/base/redis-ha/chart/upstream.yaml b/manifests/ha/base/redis-ha/chart/upstream.yaml index ba87e074d7..79e356f983 100644 --- a/manifests/ha/base/redis-ha/chart/upstream.yaml +++ b/manifests/ha/base/redis-ha/chart/upstream.yaml @@ -9,7 +9,7 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 app: argocd-redis-ha secrets: - name: argocd-redis @@ -23,7 +23,7 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 app: argocd-redis-ha --- # Source: redis-ha/charts/redis-ha/templates/redis-ha-configmap.yaml @@ -35,7 +35,7 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 app: argocd-redis-ha data: redis.conf: | @@ -304,7 +304,7 @@ data: identify_announce_ip if [ -z "${ANNOUNCE_IP}" ]; then - "Error: Could not resolve the announce ip for this pod" + "Error: Could not resolve the announce ip for this pod." exit 1 elif [ "${MASTER}" ]; then find_master @@ -701,10 +701,6 @@ data: stats enable stats uri /stats stats refresh 10s - # Additional configuration - global - maxconn 4096 - haproxy_init.sh: | HAPROXY_CONF=/data/haproxy.cfg cp /readonly/haproxy.cfg "$HAPROXY_CONF" @@ -779,7 +775,7 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 app: argocd-redis-ha data: redis_liveness.sh: | @@ -790,12 +786,11 @@ data: -p 6379 \ ping ) + if [ "$response" != "PONG" ] && [ "${response:0:7}" != "LOADING" ] ; then + echo "$response" + exit 1 + fi echo "response=$response" - case $response in - PONG|LOADING*) ;; - *) exit 1 ;; - esac - exit 0 redis_readiness.sh: | response=$( redis-cli \ @@ -805,33 +800,10 @@ data: ping ) if [ "$response" != "PONG" ] ; then - echo "ping=$response" - exit 1 - fi - - response=$( - redis-cli \ - -a "${AUTH}" --no-auth-warning \ - -h localhost \ - -p 6379 \ - role - ) - role=$( echo "$response" | sed "1!d" ) - if [ "$role" = "master" ]; then - echo "role=$role" - exit 0 - elif [ "$role" = "slave" ]; then - repl=$( echo "$response" | sed "4!d" ) - echo "role=$role; repl=$repl" - if [ "$repl" = "connected" ]; then - exit 0 - else - exit 1 - fi - else - echo "role=$role" + echo "$response" exit 1 fi + echo "response=$response" sentinel_liveness.sh: | response=$( redis-cli \ @@ -855,7 +827,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 rules: - apiGroups: - "" @@ -874,7 +846,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy rules: - apiGroups: @@ -894,7 +866,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 subjects: - kind: ServiceAccount name: argocd-redis-ha @@ -913,7 +885,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy subjects: - kind: ServiceAccount @@ -933,7 +905,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 annotations: spec: publishNotReadyAddresses: true @@ -962,7 +934,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 annotations: spec: publishNotReadyAddresses: true @@ -991,7 +963,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 annotations: spec: publishNotReadyAddresses: true @@ -1020,7 +992,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 annotations: spec: type: ClusterIP @@ -1048,7 +1020,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy annotations: spec: @@ -1076,7 +1048,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 spec: strategy: type: RollingUpdate @@ -1096,16 +1068,15 @@ spec: prometheus.io/port: "9101" prometheus.io/scrape: "true" prometheus.io/path: "/metrics" - checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953 + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 spec: # Needed when using unmodified rbac-setup.yml serviceAccountName: argocd-redis-ha-haproxy - securityContext: + securityContext: fsGroup: 99 runAsNonRoot: true runAsUser: 99 - automountServiceAccountToken: true nodeSelector: {} tolerations: @@ -1120,7 +1091,7 @@ spec: topologyKey: kubernetes.io/hostname initContainers: - name: config-init - image: public.ecr.aws/docker/library/haproxy:3.0.8-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine imagePullPolicy: IfNotPresent resources: {} @@ -1128,7 +1099,7 @@ spec: - sh args: - /readonly/haproxy_init.sh - securityContext: + securityContext: allowPrivilegeEscalation: false capabilities: drop: @@ -1144,9 +1115,9 @@ spec: mountPath: /data containers: - name: haproxy - image: public.ecr.aws/docker/library/haproxy:3.0.8-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine imagePullPolicy: IfNotPresent - securityContext: + securityContext: allowPrivilegeEscalation: false capabilities: drop: @@ -1163,18 +1134,16 @@ spec: livenessProbe: httpGet: path: /healthz - port: probe + port: 8888 initialDelaySeconds: 5 periodSeconds: 3 readinessProbe: httpGet: path: /healthz - port: probe + port: 8888 initialDelaySeconds: 5 periodSeconds: 3 ports: - - name: probe - containerPort: 8888 - name: redis containerPort: 6379 - name: metrics-port @@ -1210,7 +1179,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.33.2 + chart: redis-ha-4.26.6 annotations: {} spec: @@ -1226,7 +1195,7 @@ spec: template: metadata: annotations: - checksum/init-config: bd30e83dfdad9912b6c1cc32a8c26d7d01429a0730f5ee7af380fb593e874d54 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: release: argocd app: redis-ha @@ -1242,7 +1211,7 @@ spec: release: argocd argocd-redis-ha: replica topologyKey: kubernetes.io/hostname - securityContext: + securityContext: fsGroup: 1000 runAsNonRoot: true runAsUser: 1000 @@ -1250,7 +1219,7 @@ spec: automountServiceAccountToken: false initContainers: - name: config-init - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent resources: {} @@ -1258,7 +1227,7 @@ spec: - sh args: - /readonly-config/init.sh - securityContext: + securityContext: allowPrivilegeEscalation: false capabilities: drop: @@ -1266,7 +1235,7 @@ spec: runAsNonRoot: true runAsUser: 1000 seccompProfile: - type: RuntimeDefault + type: RuntimeDefault env: - name: SENTINEL_ID_0 value: 3c0d9c0320bb34888c2df5757c718ce6ca992ce6 @@ -1287,16 +1256,15 @@ spec: mountPath: /data - containers: - name: redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - redis-server args: - /data/conf/redis.conf - securityContext: + securityContext: allowPrivilegeEscalation: false capabilities: drop: @@ -1333,17 +1301,6 @@ spec: - sh - -c - /health/redis_readiness.sh - startupProbe: - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 15 - successThreshold: 1 - failureThreshold: 3 - exec: - command: - - sh - - -c - - /health/redis_readiness.sh resources: {} ports: @@ -1364,13 +1321,13 @@ spec: - /bin/sh - /readonly-config/trigger-failover-if-master.sh - name: sentinel - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - redis-sentinel args: - /data/conf/sentinel.conf - securityContext: + securityContext: allowPrivilegeEscalation: false capabilities: drop: @@ -1407,17 +1364,6 @@ spec: - sh - -c - /health/sentinel_liveness.sh - startupProbe: - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 15 - successThreshold: 1 - failureThreshold: 3 - exec: - command: - - sh - - -c - - /health/sentinel_liveness.sh resources: {} ports: @@ -1437,13 +1383,13 @@ spec: - sleep 30; redis-cli -p 26379 sentinel reset argocd - name: split-brain-fix - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - sh args: - /readonly-config/fix-split-brain.sh - securityContext: + securityContext: allowPrivilegeEscalation: false capabilities: drop: @@ -1451,7 +1397,7 @@ spec: runAsNonRoot: true runAsUser: 1000 seccompProfile: - type: RuntimeDefault + type: RuntimeDefault env: - name: SENTINEL_ID_0 value: 3c0d9c0320bb34888c2df5757c718ce6ca992ce6 diff --git a/manifests/ha/base/redis-ha/chart/values.yaml b/manifests/ha/base/redis-ha/chart/values.yaml index 22ba8c241c..47e0910c1a 100644 --- a/manifests/ha/base/redis-ha/chart/values.yaml +++ b/manifests/ha/base/redis-ha/chart/values.yaml @@ -14,20 +14,17 @@ redis-ha: IPv6: enabled: false image: - tag: 3.0.8-alpine + tag: 2.6.17-alpine + containerSecurityContext: null timeout: server: 6m client: 6m checkInterval: 3s metrics: enabled: true - extraConfig: | - global - maxconn 4096 - serviceAccount: - automountToken: true image: - tag: 7.2.7-alpine + tag: 7.0.15-alpine + containerSecurityContext: null sentinel: bind: '0.0.0.0' lifecycle: diff --git a/manifests/ha/install-with-hydrator.yaml b/manifests/ha/install-with-hydrator.yaml index d8020d1d6b..6aebbd50bb 100644 --- a/manifests/ha/install-with-hydrator.yaml +++ b/manifests/ha/install-with-hydrator.yaml @@ -380,11 +380,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by - not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -398,10 +393,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -769,11 +760,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -787,10 +773,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1268,11 +1250,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize from - failing when components do not exist locally by not appending - them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1286,10 +1263,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to apply - common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1705,11 +1678,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by not - appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1723,10 +1691,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1883,10 +1847,6 @@ spec: description: 'AllowEmpty allows apps have zero live resources (default: false)' type: boolean - enabled: - description: Enable allows apps to explicitly control automated - sync - type: boolean prune: description: 'Prune specifies whether to delete resources from the cluster that are not found in the sources anymore @@ -1990,13 +1950,12 @@ spec: format: date-time type: string message: - description: |- - Message is a human-readable informational message describing the health status - - Deprecated: this field is not used and will be removed in a future release. + description: Message is a human-readable informational message + describing the health status type: string status: - description: Status holds the status code of the application + description: Status holds the status code of the application or + resource type: string type: object history: @@ -2260,11 +2219,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2278,10 +2232,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -2651,11 +2601,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2669,11 +2614,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -3193,12 +3133,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do not - exist locally by not appending them to kustomization - file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3212,11 +3146,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates - or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors @@ -3606,12 +3535,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do - not exist locally by not appending them to - kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3625,11 +3548,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies - whether to apply common labels to resource - templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource @@ -4131,11 +4049,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4149,11 +4062,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4535,11 +4443,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4553,11 +4456,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4730,22 +4628,19 @@ spec: description: Resources is a list of Kubernetes resources managed by this application items: - description: ResourceStatus holds the current synchronization and - health status of a Kubernetes resource. + description: |- + ResourceStatus holds the current sync and health status of a resource + TODO: describe members of this type properties: group: - description: Group represents the API group of the resource - (e.g., "apps" for Deployments). type: string health: - description: Health indicates the health status of the resource - (e.g., Healthy, Degraded, Progressing). + description: HealthStatus contains information about the currently + observed health state of an application or resource properties: lastTransitionTime: - description: |- - LastTransitionTime is the time the HealthStatus was set or updated - - Deprecated: this field is not used and will be removed in a future release. + description: LastTransitionTime is the time the HealthStatus + was set or updated format: date-time type: string message: @@ -4753,46 +4648,30 @@ spec: describing the health status type: string status: - description: Status holds the status code of the resource + description: Status holds the status code of the application + or resource type: string type: object hook: - description: Hook is true if the resource is used as a lifecycle - hook in an Argo CD application. type: boolean kind: - description: Kind specifies the type of the resource (e.g., - "Deployment", "Service"). type: string name: - description: Name is the unique name of the resource within - the namespace. type: string namespace: - description: Namespace defines the Kubernetes namespace where - the resource is located. type: string requiresDeletionConfirmation: - description: RequiresDeletionConfirmation is true if the resource - requires explicit user confirmation before deletion. type: boolean requiresPruning: - description: RequiresPruning is true if the resource needs to - be pruned (deleted) as part of synchronization. type: boolean status: - description: Status represents the synchronization state of - the resource (e.g., Synced, OutOfSync). + description: SyncStatusCode is a type which represents possible + comparison results type: string syncWave: - description: |- - SyncWave determines the order in which resources are applied during a sync operation. - Lower values are applied first. format: int64 type: integer version: - description: Version indicates the API version of the resource - (e.g., "v1", "v1beta1"). type: string type: object type: array @@ -5278,11 +5157,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5296,11 +5170,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -5682,11 +5551,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5700,11 +5564,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -6157,16 +6016,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6433,16 +6288,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6553,8 +6404,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -6839,16 +6688,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7115,16 +6960,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7235,8 +7076,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -7303,8 +7142,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -7522,16 +7359,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7798,16 +7631,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7918,8 +7747,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8183,16 +8010,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8459,16 +8282,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8579,8 +8398,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8869,16 +8686,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9145,16 +8958,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9265,8 +9074,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -9551,16 +9358,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9827,16 +9630,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9947,8 +9746,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10015,8 +9812,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -10234,16 +10029,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10510,16 +10301,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10630,8 +10417,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10895,16 +10680,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11171,16 +10952,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11291,8 +11068,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -11564,16 +11339,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11840,16 +11611,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11960,8 +11727,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12163,10 +11928,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -12456,16 +12217,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12732,16 +12489,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12852,8 +12605,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12899,10 +12650,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -13343,16 +13090,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13619,16 +13362,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13739,8 +13478,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14021,16 +13758,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14297,16 +14030,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14417,8 +14146,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14709,16 +14436,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14985,16 +14708,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15105,8 +14824,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15391,16 +15108,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15667,16 +15380,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15787,8 +15496,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15855,8 +15562,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -16074,16 +15779,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16350,16 +16051,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16470,8 +16167,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -16735,16 +16430,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17011,16 +16702,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17131,8 +16818,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -17404,16 +17089,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17680,16 +17361,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17800,8 +17477,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -18003,10 +17678,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -18296,16 +17967,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -18572,16 +18239,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -18692,8 +18355,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -18739,10 +18400,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -19183,16 +18840,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -19459,16 +19112,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -19579,8 +19228,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -19865,16 +19512,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20141,16 +19784,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20261,8 +19900,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -20533,16 +20170,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20809,16 +20442,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20929,8 +20558,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -21132,10 +20759,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -21425,16 +21048,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -21701,16 +21320,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -21821,8 +21436,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -21868,10 +21481,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -22312,16 +21921,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -22588,16 +22193,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -22708,8 +22309,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -23065,16 +22664,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -23341,16 +22936,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -23461,8 +23052,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -23695,7 +23284,6 @@ spec: type: array description: description: Description contains optional project description - maxLength: 255 type: string destinationServiceAccounts: description: DestinationServiceAccounts holds information about the @@ -23890,10 +23478,6 @@ spec: description: SyncWindow contains the kind, time, duration and attributes that are used to assign the syncWindows to apps properties: - andOperator: - description: UseAndOperator use AND operator for matching applications, - namespaces and clusters instead of the default OR operator - type: boolean applications: description: Applications contains a list of applications that the window will apply to @@ -23906,11 +23490,6 @@ spec: items: type: string type: array - description: - description: Description of the sync that will be applied to - the schedule, can be used to add any information such as a - ticket number for example - type: string duration: description: Duration is the amount of time the sync window will be open @@ -24081,7 +23660,6 @@ rules: - argoproj.io resources: - applications - - applicationsets - appprojects verbs: - create @@ -24656,100 +24234,6 @@ subjects: namespace: argocd --- apiVersion: v1 -data: - resource.customizations.ignoreResourceUpdates.ConfigMap: | - jqPathExpressions: - # Ignore the cluster-autoscaler status - - '.metadata.annotations."cluster-autoscaler.kubernetes.io/last-updated"' - # Ignore the annotation of the legacy Leases election - - '.metadata.annotations."control-plane.alpha.kubernetes.io/leader"' - resource.customizations.ignoreResourceUpdates.Endpoints: | - jsonPointers: - - /metadata - - /subsets - resource.customizations.ignoreResourceUpdates.all: | - jsonPointers: - - /status - resource.customizations.ignoreResourceUpdates.apps_ReplicaSet: | - jqPathExpressions: - - '.metadata.annotations."deployment.kubernetes.io/desired-replicas"' - - '.metadata.annotations."deployment.kubernetes.io/max-replicas"' - - '.metadata.annotations."rollout.argoproj.io/desired-replicas"' - resource.customizations.ignoreResourceUpdates.argoproj.io_Application: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - - '.metadata.annotations."argocd.argoproj.io/refresh"' - - '.metadata.annotations."argocd.argoproj.io/hydrate"' - - '.operation' - resource.customizations.ignoreResourceUpdates.argoproj.io_Rollout: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - resource.customizations.ignoreResourceUpdates.autoscaling_HorizontalPodAutoscaler: | - jqPathExpressions: - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/behavior"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/conditions"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/metrics"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/current-metrics"' - resource.customizations.ignoreResourceUpdates.discovery.k8s.io_EndpointSlice: | - jsonPointers: - - /metadata - - /endpoints - - /ports - resource.exclusions: | - ### Network resources created by the Kubernetes control plane and excluded to reduce the number of watched events and UI clutter - - apiGroups: - - '' - - discovery.k8s.io - kinds: - - Endpoints - - EndpointSlice - ### Internal Kubernetes resources excluded reduce the number of watched events - - apiGroups: - - coordination.k8s.io - kinds: - - Lease - ### Internal Kubernetes Authz/Authn resources excluded reduce the number of watched events - - apiGroups: - - authentication.k8s.io - - authorization.k8s.io - kinds: - - SelfSubjectReview - - TokenReview - - LocalSubjectAccessReview - - SelfSubjectAccessReview - - SelfSubjectRulesReview - - SubjectAccessReview - ### Intermediate Certificate Request excluded reduce the number of watched events - - apiGroups: - - certificates.k8s.io - kinds: - - CertificateSigningRequest - - apiGroups: - - cert-manager.io - kinds: - - CertificateRequest - ### Cilium internal resources excluded reduce the number of watched events and UI Clutter - - apiGroups: - - cilium.io - kinds: - - CiliumIdentity - - CiliumEndpoint - - CiliumEndpointSlice - ### Kyverno intermediate and reporting resources excluded reduce the number of watched events and improve performance - - apiGroups: - - kyverno.io - - reports.kyverno.io - - wgpolicyk8s.io - kinds: - - PolicyReport - - ClusterPolicyReport - - EphemeralReport - - ClusterEphemeralReport - - AdmissionReport - - ClusterAdmissionReport - - BackgroundScanReport - - ClusterBackgroundScanReport - - UpdateRequest kind: ConfigMap metadata: labels: @@ -25117,8 +24601,7 @@ data: 1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge 2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter - if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n# - Additional configuration\nglobal\n maxconn 4096\n" + if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n" haproxy_init.sh: | HAPROXY_CONF=/data/haproxy.cfg cp /readonly/haproxy.cfg "$HAPROXY_CONF" @@ -25391,7 +24874,7 @@ data: identify_announce_ip if [ -z "${ANNOUNCE_IP}" ]; then - "Error: Could not resolve the announce ip for this pod" + "Error: Could not resolve the announce ip for this pod." exit 1 elif [ "${MASTER}" ]; then find_master @@ -25486,12 +24969,11 @@ data: -p 6379 \ ping ) + if [ "$response" != "PONG" ] && [ "${response:0:7}" != "LOADING" ] ; then + echo "$response" + exit 1 + fi echo "response=$response" - case $response in - PONG|LOADING*) ;; - *) exit 1 ;; - esac - exit 0 redis_readiness.sh: | response=$( redis-cli \ @@ -25501,33 +24983,10 @@ data: ping ) if [ "$response" != "PONG" ] ; then - echo "ping=$response" - exit 1 - fi - - response=$( - redis-cli \ - -a "${AUTH}" --no-auth-warning \ - -h localhost \ - -p 6379 \ - role - ) - role=$( echo "$response" | sed "1!d" ) - if [ "$role" = "master" ]; then - echo "role=$role" - exit 0 - elif [ "$role" = "slave" ]; then - repl=$( echo "$response" | sed "4!d" ) - echo "role=$role; repl=$repl" - if [ "$repl" = "connected" ]; then - exit 0 - else - exit 1 - fi - else - echo "role=$role" + echo "$response" exit 1 fi + echo "response=$response" sentinel_liveness.sh: | response=$( redis-cli \ @@ -25957,12 +25416,6 @@ spec: key: applicationsetcontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN valueFrom: configMapKeyRef: @@ -26053,7 +25506,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -26173,13 +25626,7 @@ spec: key: commitserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -26219,6 +25666,26 @@ spec: name: gpg-keyring - mountPath: /tmp name: tmp + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:v2.14.15 + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files serviceAccountName: argocd-commit-server volumes: - configMap: @@ -26245,6 +25712,8 @@ spec: path: ca.crt optional: true secretName: argocd-commit-server-tls + - emptyDir: {} + name: var-files --- apiVersion: apps/v1 kind: Deployment @@ -26289,19 +25758,13 @@ spec: key: dexserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.43.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always name: dex ports: @@ -26330,7 +25793,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: copyutil securityContext: @@ -26402,12 +25865,6 @@ spec: key: notificationscontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -26426,7 +25883,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -26486,7 +25943,7 @@ spec: template: metadata: annotations: - checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953 + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 prometheus.io/path: /metrics prometheus.io/port: "9101" prometheus.io/scrape: "true" @@ -26501,7 +25958,6 @@ spec: matchLabels: app.kubernetes.io/name: argocd-redis-ha-haproxy topologyKey: kubernetes.io/hostname - automountServiceAccountToken: true containers: - env: - name: AUTH @@ -26509,19 +25965,17 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/haproxy:3.0.8-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: httpGet: path: /healthz - port: probe + port: 8888 initialDelaySeconds: 5 periodSeconds: 3 name: haproxy ports: - - containerPort: 8888 - name: probe - containerPort: 6379 name: redis - containerPort: 9101 @@ -26529,7 +25983,7 @@ spec: readinessProbe: httpGet: path: /healthz - port: probe + port: 8888 initialDelaySeconds: 5 periodSeconds: 3 securityContext: @@ -26550,7 +26004,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -26566,7 +26020,7 @@ spec: - /readonly/haproxy_init.sh command: - sh - image: public.ecr.aws/docker/library/haproxy:3.0.8-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: @@ -26657,12 +26111,6 @@ spec: key: reposerver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT valueFrom: configMapKeyRef: @@ -26753,12 +26201,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_REPO_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -26849,7 +26291,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -26901,7 +26343,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -27197,12 +26639,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -27269,13 +26705,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SYNC_WITH_REPLACE_ALLOWED - valueFrom: - configMapKeyRef: - key: server.sync.replace.allowed - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: httpGet: @@ -27465,12 +26895,6 @@ spec: key: controller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION valueFrom: configMapKeyRef: @@ -27579,12 +27003,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -27645,9 +27063,15 @@ spec: key: controller.cluster.cache.events.processing.interval name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER + valueFrom: + configMapKeyRef: + key: commit.server + name: argocd-cmd-params-cm + optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-application-controller ports: @@ -27722,7 +27146,7 @@ spec: template: metadata: annotations: - checksum/init-config: bd30e83dfdad9912b6c1cc32a8c26d7d01429a0730f5ee7af380fb593e874d54 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: app.kubernetes.io/name: argocd-redis-ha spec: @@ -27745,7 +27169,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -27787,17 +27211,6 @@ spec: readOnlyRootFilesystem: true seccompProfile: type: RuntimeDefault - startupProbe: - exec: - command: - - sh - - -c - - /health/redis_readiness.sh - failureThreshold: 3 - initialDelaySeconds: 5 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 15 volumeMounts: - mountPath: /readonly-config name: config @@ -27816,7 +27229,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: postStart: @@ -27859,17 +27272,6 @@ spec: readOnlyRootFilesystem: true seccompProfile: type: RuntimeDefault - startupProbe: - exec: - command: - - sh - - -c - - /health/sentinel_liveness.sh - failureThreshold: 3 - initialDelaySeconds: 5 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 15 volumeMounts: - mountPath: /data name: data @@ -27891,7 +27293,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -27926,7 +27328,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 801d81972f..2d56d3a396 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -380,11 +380,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by - not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -398,10 +393,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -769,11 +760,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -787,10 +773,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1268,11 +1250,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize from - failing when components do not exist locally by not appending - them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1286,10 +1263,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to apply - common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1705,11 +1678,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by not - appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1723,10 +1691,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1883,10 +1847,6 @@ spec: description: 'AllowEmpty allows apps have zero live resources (default: false)' type: boolean - enabled: - description: Enable allows apps to explicitly control automated - sync - type: boolean prune: description: 'Prune specifies whether to delete resources from the cluster that are not found in the sources anymore @@ -1990,13 +1950,12 @@ spec: format: date-time type: string message: - description: |- - Message is a human-readable informational message describing the health status - - Deprecated: this field is not used and will be removed in a future release. + description: Message is a human-readable informational message + describing the health status type: string status: - description: Status holds the status code of the application + description: Status holds the status code of the application or + resource type: string type: object history: @@ -2260,11 +2219,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2278,10 +2232,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -2651,11 +2601,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2669,11 +2614,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -3193,12 +3133,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do not - exist locally by not appending them to kustomization - file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3212,11 +3146,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates - or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors @@ -3606,12 +3535,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do - not exist locally by not appending them to - kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3625,11 +3548,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies - whether to apply common labels to resource - templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource @@ -4131,11 +4049,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4149,11 +4062,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4535,11 +4443,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4553,11 +4456,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4730,22 +4628,19 @@ spec: description: Resources is a list of Kubernetes resources managed by this application items: - description: ResourceStatus holds the current synchronization and - health status of a Kubernetes resource. + description: |- + ResourceStatus holds the current sync and health status of a resource + TODO: describe members of this type properties: group: - description: Group represents the API group of the resource - (e.g., "apps" for Deployments). type: string health: - description: Health indicates the health status of the resource - (e.g., Healthy, Degraded, Progressing). + description: HealthStatus contains information about the currently + observed health state of an application or resource properties: lastTransitionTime: - description: |- - LastTransitionTime is the time the HealthStatus was set or updated - - Deprecated: this field is not used and will be removed in a future release. + description: LastTransitionTime is the time the HealthStatus + was set or updated format: date-time type: string message: @@ -4753,46 +4648,30 @@ spec: describing the health status type: string status: - description: Status holds the status code of the resource + description: Status holds the status code of the application + or resource type: string type: object hook: - description: Hook is true if the resource is used as a lifecycle - hook in an Argo CD application. type: boolean kind: - description: Kind specifies the type of the resource (e.g., - "Deployment", "Service"). type: string name: - description: Name is the unique name of the resource within - the namespace. type: string namespace: - description: Namespace defines the Kubernetes namespace where - the resource is located. type: string requiresDeletionConfirmation: - description: RequiresDeletionConfirmation is true if the resource - requires explicit user confirmation before deletion. type: boolean requiresPruning: - description: RequiresPruning is true if the resource needs to - be pruned (deleted) as part of synchronization. type: boolean status: - description: Status represents the synchronization state of - the resource (e.g., Synced, OutOfSync). + description: SyncStatusCode is a type which represents possible + comparison results type: string syncWave: - description: |- - SyncWave determines the order in which resources are applied during a sync operation. - Lower values are applied first. format: int64 type: integer version: - description: Version indicates the API version of the resource - (e.g., "v1", "v1beta1"). type: string type: object type: array @@ -5278,11 +5157,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5296,11 +5170,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -5682,11 +5551,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5700,11 +5564,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -6157,16 +6016,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6433,16 +6288,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6553,8 +6404,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -6839,16 +6688,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7115,16 +6960,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7235,8 +7076,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -7303,8 +7142,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -7522,16 +7359,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7798,16 +7631,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7918,8 +7747,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8183,16 +8010,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8459,16 +8282,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8579,8 +8398,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8869,16 +8686,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9145,16 +8958,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9265,8 +9074,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -9551,16 +9358,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9827,16 +9630,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9947,8 +9746,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10015,8 +9812,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -10234,16 +10029,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10510,16 +10301,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10630,8 +10417,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10895,16 +10680,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11171,16 +10952,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11291,8 +11068,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -11564,16 +11339,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11840,16 +11611,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11960,8 +11727,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12163,10 +11928,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -12456,16 +12217,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12732,16 +12489,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12852,8 +12605,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12899,10 +12650,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -13343,16 +13090,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13619,16 +13362,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13739,8 +13478,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14021,16 +13758,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14297,16 +14030,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14417,8 +14146,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14709,16 +14436,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14985,16 +14708,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15105,8 +14824,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15391,16 +15108,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15667,16 +15380,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15787,8 +15496,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15855,8 +15562,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -16074,16 +15779,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16350,16 +16051,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16470,8 +16167,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -16735,16 +16430,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17011,16 +16702,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17131,8 +16818,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -17404,16 +17089,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17680,16 +17361,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17800,8 +17477,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -18003,10 +17678,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -18296,16 +17967,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -18572,16 +18239,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -18692,8 +18355,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -18739,10 +18400,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -19183,16 +18840,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -19459,16 +19112,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -19579,8 +19228,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -19865,16 +19512,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20141,16 +19784,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20261,8 +19900,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -20533,16 +20170,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20809,16 +20442,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20929,8 +20558,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -21132,10 +20759,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -21425,16 +21048,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -21701,16 +21320,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -21821,8 +21436,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -21868,10 +21481,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -22312,16 +21921,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -22588,16 +22193,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -22708,8 +22309,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -23065,16 +22664,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -23341,16 +22936,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -23461,8 +23052,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -23695,7 +23284,6 @@ spec: type: array description: description: Description contains optional project description - maxLength: 255 type: string destinationServiceAccounts: description: DestinationServiceAccounts holds information about the @@ -23890,10 +23478,6 @@ spec: description: SyncWindow contains the kind, time, duration and attributes that are used to assign the syncWindows to apps properties: - andOperator: - description: UseAndOperator use AND operator for matching applications, - namespaces and clusters instead of the default OR operator - type: boolean applications: description: Applications contains a list of applications that the window will apply to @@ -23906,11 +23490,6 @@ spec: items: type: string type: array - description: - description: Description of the sync that will be applied to - the schedule, can be used to add any information such as a - ticket number for example - type: string duration: description: Duration is the amount of time the sync window will be open @@ -24072,7 +23651,6 @@ rules: - argoproj.io resources: - applications - - applicationsets - appprojects verbs: - create @@ -24647,100 +24225,6 @@ subjects: namespace: argocd --- apiVersion: v1 -data: - resource.customizations.ignoreResourceUpdates.ConfigMap: | - jqPathExpressions: - # Ignore the cluster-autoscaler status - - '.metadata.annotations."cluster-autoscaler.kubernetes.io/last-updated"' - # Ignore the annotation of the legacy Leases election - - '.metadata.annotations."control-plane.alpha.kubernetes.io/leader"' - resource.customizations.ignoreResourceUpdates.Endpoints: | - jsonPointers: - - /metadata - - /subsets - resource.customizations.ignoreResourceUpdates.all: | - jsonPointers: - - /status - resource.customizations.ignoreResourceUpdates.apps_ReplicaSet: | - jqPathExpressions: - - '.metadata.annotations."deployment.kubernetes.io/desired-replicas"' - - '.metadata.annotations."deployment.kubernetes.io/max-replicas"' - - '.metadata.annotations."rollout.argoproj.io/desired-replicas"' - resource.customizations.ignoreResourceUpdates.argoproj.io_Application: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - - '.metadata.annotations."argocd.argoproj.io/refresh"' - - '.metadata.annotations."argocd.argoproj.io/hydrate"' - - '.operation' - resource.customizations.ignoreResourceUpdates.argoproj.io_Rollout: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - resource.customizations.ignoreResourceUpdates.autoscaling_HorizontalPodAutoscaler: | - jqPathExpressions: - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/behavior"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/conditions"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/metrics"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/current-metrics"' - resource.customizations.ignoreResourceUpdates.discovery.k8s.io_EndpointSlice: | - jsonPointers: - - /metadata - - /endpoints - - /ports - resource.exclusions: | - ### Network resources created by the Kubernetes control plane and excluded to reduce the number of watched events and UI clutter - - apiGroups: - - '' - - discovery.k8s.io - kinds: - - Endpoints - - EndpointSlice - ### Internal Kubernetes resources excluded reduce the number of watched events - - apiGroups: - - coordination.k8s.io - kinds: - - Lease - ### Internal Kubernetes Authz/Authn resources excluded reduce the number of watched events - - apiGroups: - - authentication.k8s.io - - authorization.k8s.io - kinds: - - SelfSubjectReview - - TokenReview - - LocalSubjectAccessReview - - SelfSubjectAccessReview - - SelfSubjectRulesReview - - SubjectAccessReview - ### Intermediate Certificate Request excluded reduce the number of watched events - - apiGroups: - - certificates.k8s.io - kinds: - - CertificateSigningRequest - - apiGroups: - - cert-manager.io - kinds: - - CertificateRequest - ### Cilium internal resources excluded reduce the number of watched events and UI Clutter - - apiGroups: - - cilium.io - kinds: - - CiliumIdentity - - CiliumEndpoint - - CiliumEndpointSlice - ### Kyverno intermediate and reporting resources excluded reduce the number of watched events and improve performance - - apiGroups: - - kyverno.io - - reports.kyverno.io - - wgpolicyk8s.io - kinds: - - PolicyReport - - ClusterPolicyReport - - EphemeralReport - - ClusterEphemeralReport - - AdmissionReport - - ClusterAdmissionReport - - BackgroundScanReport - - ClusterBackgroundScanReport - - UpdateRequest kind: ConfigMap metadata: labels: @@ -25108,8 +24592,7 @@ data: 1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge 2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter - if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n# - Additional configuration\nglobal\n maxconn 4096\n" + if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n" haproxy_init.sh: | HAPROXY_CONF=/data/haproxy.cfg cp /readonly/haproxy.cfg "$HAPROXY_CONF" @@ -25382,7 +24865,7 @@ data: identify_announce_ip if [ -z "${ANNOUNCE_IP}" ]; then - "Error: Could not resolve the announce ip for this pod" + "Error: Could not resolve the announce ip for this pod." exit 1 elif [ "${MASTER}" ]; then find_master @@ -25477,12 +24960,11 @@ data: -p 6379 \ ping ) + if [ "$response" != "PONG" ] && [ "${response:0:7}" != "LOADING" ] ; then + echo "$response" + exit 1 + fi echo "response=$response" - case $response in - PONG|LOADING*) ;; - *) exit 1 ;; - esac - exit 0 redis_readiness.sh: | response=$( redis-cli \ @@ -25492,33 +24974,10 @@ data: ping ) if [ "$response" != "PONG" ] ; then - echo "ping=$response" - exit 1 - fi - - response=$( - redis-cli \ - -a "${AUTH}" --no-auth-warning \ - -h localhost \ - -p 6379 \ - role - ) - role=$( echo "$response" | sed "1!d" ) - if [ "$role" = "master" ]; then - echo "role=$role" - exit 0 - elif [ "$role" = "slave" ]; then - repl=$( echo "$response" | sed "4!d" ) - echo "role=$role; repl=$repl" - if [ "$repl" = "connected" ]; then - exit 0 - else - exit 1 - fi - else - echo "role=$role" + echo "$response" exit 1 fi + echo "response=$response" sentinel_liveness.sh: | response=$( redis-cli \ @@ -25927,12 +25386,6 @@ spec: key: applicationsetcontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN valueFrom: configMapKeyRef: @@ -26023,7 +25476,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -26125,19 +25578,13 @@ spec: key: dexserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.43.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always name: dex ports: @@ -26166,7 +25613,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: copyutil securityContext: @@ -26238,12 +25685,6 @@ spec: key: notificationscontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -26262,7 +25703,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -26322,7 +25763,7 @@ spec: template: metadata: annotations: - checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953 + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 prometheus.io/path: /metrics prometheus.io/port: "9101" prometheus.io/scrape: "true" @@ -26337,7 +25778,6 @@ spec: matchLabels: app.kubernetes.io/name: argocd-redis-ha-haproxy topologyKey: kubernetes.io/hostname - automountServiceAccountToken: true containers: - env: - name: AUTH @@ -26345,19 +25785,17 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/haproxy:3.0.8-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: httpGet: path: /healthz - port: probe + port: 8888 initialDelaySeconds: 5 periodSeconds: 3 name: haproxy ports: - - containerPort: 8888 - name: probe - containerPort: 6379 name: redis - containerPort: 9101 @@ -26365,7 +25803,7 @@ spec: readinessProbe: httpGet: path: /healthz - port: probe + port: 8888 initialDelaySeconds: 5 periodSeconds: 3 securityContext: @@ -26386,7 +25824,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -26402,7 +25840,7 @@ spec: - /readonly/haproxy_init.sh command: - sh - image: public.ecr.aws/docker/library/haproxy:3.0.8-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: @@ -26493,12 +25931,6 @@ spec: key: reposerver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT valueFrom: configMapKeyRef: @@ -26589,12 +26021,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_REPO_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -26685,7 +26111,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -26737,7 +26163,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -27033,12 +26459,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -27105,13 +26525,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SYNC_WITH_REPLACE_ALLOWED - valueFrom: - configMapKeyRef: - key: server.sync.replace.allowed - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: httpGet: @@ -27301,12 +26715,6 @@ spec: key: controller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION valueFrom: configMapKeyRef: @@ -27415,12 +26823,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -27481,9 +26883,15 @@ spec: key: controller.cluster.cache.events.processing.interval name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER + valueFrom: + configMapKeyRef: + key: commit.server + name: argocd-cmd-params-cm + optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-application-controller ports: @@ -27558,7 +26966,7 @@ spec: template: metadata: annotations: - checksum/init-config: bd30e83dfdad9912b6c1cc32a8c26d7d01429a0730f5ee7af380fb593e874d54 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: app.kubernetes.io/name: argocd-redis-ha spec: @@ -27581,7 +26989,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -27623,17 +27031,6 @@ spec: readOnlyRootFilesystem: true seccompProfile: type: RuntimeDefault - startupProbe: - exec: - command: - - sh - - -c - - /health/redis_readiness.sh - failureThreshold: 3 - initialDelaySeconds: 5 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 15 volumeMounts: - mountPath: /readonly-config name: config @@ -27652,7 +27049,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: postStart: @@ -27695,17 +27092,6 @@ spec: readOnlyRootFilesystem: true seccompProfile: type: RuntimeDefault - startupProbe: - exec: - command: - - sh - - -c - - /health/sentinel_liveness.sh - failureThreshold: 3 - initialDelaySeconds: 5 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 15 volumeMounts: - mountPath: /data name: data @@ -27727,7 +27113,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -27762,7 +27148,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: diff --git a/manifests/ha/namespace-install-with-hydrator.yaml b/manifests/ha/namespace-install-with-hydrator.yaml index e3f0928807..07b90c4286 100644 --- a/manifests/ha/namespace-install-with-hydrator.yaml +++ b/manifests/ha/namespace-install-with-hydrator.yaml @@ -104,7 +104,6 @@ rules: - argoproj.io resources: - applications - - applicationsets - appprojects verbs: - create @@ -465,100 +464,6 @@ subjects: name: argocd-server --- apiVersion: v1 -data: - resource.customizations.ignoreResourceUpdates.ConfigMap: | - jqPathExpressions: - # Ignore the cluster-autoscaler status - - '.metadata.annotations."cluster-autoscaler.kubernetes.io/last-updated"' - # Ignore the annotation of the legacy Leases election - - '.metadata.annotations."control-plane.alpha.kubernetes.io/leader"' - resource.customizations.ignoreResourceUpdates.Endpoints: | - jsonPointers: - - /metadata - - /subsets - resource.customizations.ignoreResourceUpdates.all: | - jsonPointers: - - /status - resource.customizations.ignoreResourceUpdates.apps_ReplicaSet: | - jqPathExpressions: - - '.metadata.annotations."deployment.kubernetes.io/desired-replicas"' - - '.metadata.annotations."deployment.kubernetes.io/max-replicas"' - - '.metadata.annotations."rollout.argoproj.io/desired-replicas"' - resource.customizations.ignoreResourceUpdates.argoproj.io_Application: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - - '.metadata.annotations."argocd.argoproj.io/refresh"' - - '.metadata.annotations."argocd.argoproj.io/hydrate"' - - '.operation' - resource.customizations.ignoreResourceUpdates.argoproj.io_Rollout: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - resource.customizations.ignoreResourceUpdates.autoscaling_HorizontalPodAutoscaler: | - jqPathExpressions: - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/behavior"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/conditions"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/metrics"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/current-metrics"' - resource.customizations.ignoreResourceUpdates.discovery.k8s.io_EndpointSlice: | - jsonPointers: - - /metadata - - /endpoints - - /ports - resource.exclusions: | - ### Network resources created by the Kubernetes control plane and excluded to reduce the number of watched events and UI clutter - - apiGroups: - - '' - - discovery.k8s.io - kinds: - - Endpoints - - EndpointSlice - ### Internal Kubernetes resources excluded reduce the number of watched events - - apiGroups: - - coordination.k8s.io - kinds: - - Lease - ### Internal Kubernetes Authz/Authn resources excluded reduce the number of watched events - - apiGroups: - - authentication.k8s.io - - authorization.k8s.io - kinds: - - SelfSubjectReview - - TokenReview - - LocalSubjectAccessReview - - SelfSubjectAccessReview - - SelfSubjectRulesReview - - SubjectAccessReview - ### Intermediate Certificate Request excluded reduce the number of watched events - - apiGroups: - - certificates.k8s.io - kinds: - - CertificateSigningRequest - - apiGroups: - - cert-manager.io - kinds: - - CertificateRequest - ### Cilium internal resources excluded reduce the number of watched events and UI Clutter - - apiGroups: - - cilium.io - kinds: - - CiliumIdentity - - CiliumEndpoint - - CiliumEndpointSlice - ### Kyverno intermediate and reporting resources excluded reduce the number of watched events and improve performance - - apiGroups: - - kyverno.io - - reports.kyverno.io - - wgpolicyk8s.io - kinds: - - PolicyReport - - ClusterPolicyReport - - EphemeralReport - - ClusterEphemeralReport - - AdmissionReport - - ClusterAdmissionReport - - BackgroundScanReport - - ClusterBackgroundScanReport - - UpdateRequest kind: ConfigMap metadata: labels: @@ -926,8 +831,7 @@ data: 1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge 2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter - if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n# - Additional configuration\nglobal\n maxconn 4096\n" + if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n" haproxy_init.sh: | HAPROXY_CONF=/data/haproxy.cfg cp /readonly/haproxy.cfg "$HAPROXY_CONF" @@ -1200,7 +1104,7 @@ data: identify_announce_ip if [ -z "${ANNOUNCE_IP}" ]; then - "Error: Could not resolve the announce ip for this pod" + "Error: Could not resolve the announce ip for this pod." exit 1 elif [ "${MASTER}" ]; then find_master @@ -1295,12 +1199,11 @@ data: -p 6379 \ ping ) + if [ "$response" != "PONG" ] && [ "${response:0:7}" != "LOADING" ] ; then + echo "$response" + exit 1 + fi echo "response=$response" - case $response in - PONG|LOADING*) ;; - *) exit 1 ;; - esac - exit 0 redis_readiness.sh: | response=$( redis-cli \ @@ -1310,33 +1213,10 @@ data: ping ) if [ "$response" != "PONG" ] ; then - echo "ping=$response" - exit 1 - fi - - response=$( - redis-cli \ - -a "${AUTH}" --no-auth-warning \ - -h localhost \ - -p 6379 \ - role - ) - role=$( echo "$response" | sed "1!d" ) - if [ "$role" = "master" ]; then - echo "role=$role" - exit 0 - elif [ "$role" = "slave" ]; then - repl=$( echo "$response" | sed "4!d" ) - echo "role=$role; repl=$repl" - if [ "$repl" = "connected" ]; then - exit 0 - else - exit 1 - fi - else - echo "role=$role" + echo "$response" exit 1 fi + echo "response=$response" sentinel_liveness.sh: | response=$( redis-cli \ @@ -1766,12 +1646,6 @@ spec: key: applicationsetcontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN valueFrom: configMapKeyRef: @@ -1862,7 +1736,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -1982,13 +1856,7 @@ spec: key: commitserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -2028,6 +1896,26 @@ spec: name: gpg-keyring - mountPath: /tmp name: tmp + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:v2.14.15 + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files serviceAccountName: argocd-commit-server volumes: - configMap: @@ -2054,6 +1942,8 @@ spec: path: ca.crt optional: true secretName: argocd-commit-server-tls + - emptyDir: {} + name: var-files --- apiVersion: apps/v1 kind: Deployment @@ -2098,19 +1988,13 @@ spec: key: dexserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.43.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always name: dex ports: @@ -2139,7 +2023,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: copyutil securityContext: @@ -2211,12 +2095,6 @@ spec: key: notificationscontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -2235,7 +2113,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -2295,7 +2173,7 @@ spec: template: metadata: annotations: - checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953 + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 prometheus.io/path: /metrics prometheus.io/port: "9101" prometheus.io/scrape: "true" @@ -2310,7 +2188,6 @@ spec: matchLabels: app.kubernetes.io/name: argocd-redis-ha-haproxy topologyKey: kubernetes.io/hostname - automountServiceAccountToken: true containers: - env: - name: AUTH @@ -2318,19 +2195,17 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/haproxy:3.0.8-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: httpGet: path: /healthz - port: probe + port: 8888 initialDelaySeconds: 5 periodSeconds: 3 name: haproxy ports: - - containerPort: 8888 - name: probe - containerPort: 6379 name: redis - containerPort: 9101 @@ -2338,7 +2213,7 @@ spec: readinessProbe: httpGet: path: /healthz - port: probe + port: 8888 initialDelaySeconds: 5 periodSeconds: 3 securityContext: @@ -2359,7 +2234,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -2375,7 +2250,7 @@ spec: - /readonly/haproxy_init.sh command: - sh - image: public.ecr.aws/docker/library/haproxy:3.0.8-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: @@ -2466,12 +2341,6 @@ spec: key: reposerver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT valueFrom: configMapKeyRef: @@ -2562,12 +2431,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_REPO_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -2658,7 +2521,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -2710,7 +2573,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -3006,12 +2869,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -3078,13 +2935,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SYNC_WITH_REPLACE_ALLOWED - valueFrom: - configMapKeyRef: - key: server.sync.replace.allowed - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: httpGet: @@ -3274,12 +3125,6 @@ spec: key: controller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION valueFrom: configMapKeyRef: @@ -3388,12 +3233,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -3454,9 +3293,15 @@ spec: key: controller.cluster.cache.events.processing.interval name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER + valueFrom: + configMapKeyRef: + key: commit.server + name: argocd-cmd-params-cm + optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-application-controller ports: @@ -3531,7 +3376,7 @@ spec: template: metadata: annotations: - checksum/init-config: bd30e83dfdad9912b6c1cc32a8c26d7d01429a0730f5ee7af380fb593e874d54 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: app.kubernetes.io/name: argocd-redis-ha spec: @@ -3554,7 +3399,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -3596,17 +3441,6 @@ spec: readOnlyRootFilesystem: true seccompProfile: type: RuntimeDefault - startupProbe: - exec: - command: - - sh - - -c - - /health/redis_readiness.sh - failureThreshold: 3 - initialDelaySeconds: 5 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 15 volumeMounts: - mountPath: /readonly-config name: config @@ -3625,7 +3459,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: postStart: @@ -3668,17 +3502,6 @@ spec: readOnlyRootFilesystem: true seccompProfile: type: RuntimeDefault - startupProbe: - exec: - command: - - sh - - -c - - /health/sentinel_liveness.sh - failureThreshold: 3 - initialDelaySeconds: 5 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 15 volumeMounts: - mountPath: /data name: data @@ -3700,7 +3523,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -3735,7 +3558,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index c22cffa53f..fd592afa17 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -95,7 +95,6 @@ rules: - argoproj.io resources: - applications - - applicationsets - appprojects verbs: - create @@ -456,100 +455,6 @@ subjects: name: argocd-server --- apiVersion: v1 -data: - resource.customizations.ignoreResourceUpdates.ConfigMap: | - jqPathExpressions: - # Ignore the cluster-autoscaler status - - '.metadata.annotations."cluster-autoscaler.kubernetes.io/last-updated"' - # Ignore the annotation of the legacy Leases election - - '.metadata.annotations."control-plane.alpha.kubernetes.io/leader"' - resource.customizations.ignoreResourceUpdates.Endpoints: | - jsonPointers: - - /metadata - - /subsets - resource.customizations.ignoreResourceUpdates.all: | - jsonPointers: - - /status - resource.customizations.ignoreResourceUpdates.apps_ReplicaSet: | - jqPathExpressions: - - '.metadata.annotations."deployment.kubernetes.io/desired-replicas"' - - '.metadata.annotations."deployment.kubernetes.io/max-replicas"' - - '.metadata.annotations."rollout.argoproj.io/desired-replicas"' - resource.customizations.ignoreResourceUpdates.argoproj.io_Application: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - - '.metadata.annotations."argocd.argoproj.io/refresh"' - - '.metadata.annotations."argocd.argoproj.io/hydrate"' - - '.operation' - resource.customizations.ignoreResourceUpdates.argoproj.io_Rollout: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - resource.customizations.ignoreResourceUpdates.autoscaling_HorizontalPodAutoscaler: | - jqPathExpressions: - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/behavior"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/conditions"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/metrics"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/current-metrics"' - resource.customizations.ignoreResourceUpdates.discovery.k8s.io_EndpointSlice: | - jsonPointers: - - /metadata - - /endpoints - - /ports - resource.exclusions: | - ### Network resources created by the Kubernetes control plane and excluded to reduce the number of watched events and UI clutter - - apiGroups: - - '' - - discovery.k8s.io - kinds: - - Endpoints - - EndpointSlice - ### Internal Kubernetes resources excluded reduce the number of watched events - - apiGroups: - - coordination.k8s.io - kinds: - - Lease - ### Internal Kubernetes Authz/Authn resources excluded reduce the number of watched events - - apiGroups: - - authentication.k8s.io - - authorization.k8s.io - kinds: - - SelfSubjectReview - - TokenReview - - LocalSubjectAccessReview - - SelfSubjectAccessReview - - SelfSubjectRulesReview - - SubjectAccessReview - ### Intermediate Certificate Request excluded reduce the number of watched events - - apiGroups: - - certificates.k8s.io - kinds: - - CertificateSigningRequest - - apiGroups: - - cert-manager.io - kinds: - - CertificateRequest - ### Cilium internal resources excluded reduce the number of watched events and UI Clutter - - apiGroups: - - cilium.io - kinds: - - CiliumIdentity - - CiliumEndpoint - - CiliumEndpointSlice - ### Kyverno intermediate and reporting resources excluded reduce the number of watched events and improve performance - - apiGroups: - - kyverno.io - - reports.kyverno.io - - wgpolicyk8s.io - kinds: - - PolicyReport - - ClusterPolicyReport - - EphemeralReport - - ClusterEphemeralReport - - AdmissionReport - - ClusterAdmissionReport - - BackgroundScanReport - - ClusterBackgroundScanReport - - UpdateRequest kind: ConfigMap metadata: labels: @@ -917,8 +822,7 @@ data: 1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge 2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter - if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n# - Additional configuration\nglobal\n maxconn 4096\n" + if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n" haproxy_init.sh: | HAPROXY_CONF=/data/haproxy.cfg cp /readonly/haproxy.cfg "$HAPROXY_CONF" @@ -1191,7 +1095,7 @@ data: identify_announce_ip if [ -z "${ANNOUNCE_IP}" ]; then - "Error: Could not resolve the announce ip for this pod" + "Error: Could not resolve the announce ip for this pod." exit 1 elif [ "${MASTER}" ]; then find_master @@ -1286,12 +1190,11 @@ data: -p 6379 \ ping ) + if [ "$response" != "PONG" ] && [ "${response:0:7}" != "LOADING" ] ; then + echo "$response" + exit 1 + fi echo "response=$response" - case $response in - PONG|LOADING*) ;; - *) exit 1 ;; - esac - exit 0 redis_readiness.sh: | response=$( redis-cli \ @@ -1301,33 +1204,10 @@ data: ping ) if [ "$response" != "PONG" ] ; then - echo "ping=$response" - exit 1 - fi - - response=$( - redis-cli \ - -a "${AUTH}" --no-auth-warning \ - -h localhost \ - -p 6379 \ - role - ) - role=$( echo "$response" | sed "1!d" ) - if [ "$role" = "master" ]; then - echo "role=$role" - exit 0 - elif [ "$role" = "slave" ]; then - repl=$( echo "$response" | sed "4!d" ) - echo "role=$role; repl=$repl" - if [ "$repl" = "connected" ]; then - exit 0 - else - exit 1 - fi - else - echo "role=$role" + echo "$response" exit 1 fi + echo "response=$response" sentinel_liveness.sh: | response=$( redis-cli \ @@ -1736,12 +1616,6 @@ spec: key: applicationsetcontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN valueFrom: configMapKeyRef: @@ -1832,7 +1706,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -1934,19 +1808,13 @@ spec: key: dexserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.43.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always name: dex ports: @@ -1975,7 +1843,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: copyutil securityContext: @@ -2047,12 +1915,6 @@ spec: key: notificationscontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -2071,7 +1933,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -2131,7 +1993,7 @@ spec: template: metadata: annotations: - checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953 + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 prometheus.io/path: /metrics prometheus.io/port: "9101" prometheus.io/scrape: "true" @@ -2146,7 +2008,6 @@ spec: matchLabels: app.kubernetes.io/name: argocd-redis-ha-haproxy topologyKey: kubernetes.io/hostname - automountServiceAccountToken: true containers: - env: - name: AUTH @@ -2154,19 +2015,17 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/haproxy:3.0.8-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: httpGet: path: /healthz - port: probe + port: 8888 initialDelaySeconds: 5 periodSeconds: 3 name: haproxy ports: - - containerPort: 8888 - name: probe - containerPort: 6379 name: redis - containerPort: 9101 @@ -2174,7 +2033,7 @@ spec: readinessProbe: httpGet: path: /healthz - port: probe + port: 8888 initialDelaySeconds: 5 periodSeconds: 3 securityContext: @@ -2195,7 +2054,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -2211,7 +2070,7 @@ spec: - /readonly/haproxy_init.sh command: - sh - image: public.ecr.aws/docker/library/haproxy:3.0.8-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: @@ -2302,12 +2161,6 @@ spec: key: reposerver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT valueFrom: configMapKeyRef: @@ -2398,12 +2251,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_REPO_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -2494,7 +2341,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -2546,7 +2393,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -2842,12 +2689,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -2914,13 +2755,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SYNC_WITH_REPLACE_ALLOWED - valueFrom: - configMapKeyRef: - key: server.sync.replace.allowed - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: httpGet: @@ -3110,12 +2945,6 @@ spec: key: controller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION valueFrom: configMapKeyRef: @@ -3224,12 +3053,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -3290,9 +3113,15 @@ spec: key: controller.cluster.cache.events.processing.interval name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER + valueFrom: + configMapKeyRef: + key: commit.server + name: argocd-cmd-params-cm + optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-application-controller ports: @@ -3367,7 +3196,7 @@ spec: template: metadata: annotations: - checksum/init-config: bd30e83dfdad9912b6c1cc32a8c26d7d01429a0730f5ee7af380fb593e874d54 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: app.kubernetes.io/name: argocd-redis-ha spec: @@ -3390,7 +3219,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -3432,17 +3261,6 @@ spec: readOnlyRootFilesystem: true seccompProfile: type: RuntimeDefault - startupProbe: - exec: - command: - - sh - - -c - - /health/redis_readiness.sh - failureThreshold: 3 - initialDelaySeconds: 5 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 15 volumeMounts: - mountPath: /readonly-config name: config @@ -3461,7 +3279,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: postStart: @@ -3504,17 +3322,6 @@ spec: readOnlyRootFilesystem: true seccompProfile: type: RuntimeDefault - startupProbe: - exec: - command: - - sh - - -c - - /health/sentinel_liveness.sh - failureThreshold: 3 - initialDelaySeconds: 5 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 15 volumeMounts: - mountPath: /data name: data @@ -3536,7 +3343,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -3571,7 +3378,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: public.ecr.aws/docker/library/redis:7.2.7-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: diff --git a/manifests/install-with-hydrator.yaml b/manifests/install-with-hydrator.yaml index 3970649c6e..27901214db 100644 --- a/manifests/install-with-hydrator.yaml +++ b/manifests/install-with-hydrator.yaml @@ -380,11 +380,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by - not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -398,10 +393,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -769,11 +760,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -787,10 +773,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1268,11 +1250,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize from - failing when components do not exist locally by not appending - them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1286,10 +1263,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to apply - common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1705,11 +1678,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by not - appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1723,10 +1691,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1883,10 +1847,6 @@ spec: description: 'AllowEmpty allows apps have zero live resources (default: false)' type: boolean - enabled: - description: Enable allows apps to explicitly control automated - sync - type: boolean prune: description: 'Prune specifies whether to delete resources from the cluster that are not found in the sources anymore @@ -1990,13 +1950,12 @@ spec: format: date-time type: string message: - description: |- - Message is a human-readable informational message describing the health status - - Deprecated: this field is not used and will be removed in a future release. + description: Message is a human-readable informational message + describing the health status type: string status: - description: Status holds the status code of the application + description: Status holds the status code of the application or + resource type: string type: object history: @@ -2260,11 +2219,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2278,10 +2232,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -2651,11 +2601,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2669,11 +2614,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -3193,12 +3133,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do not - exist locally by not appending them to kustomization - file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3212,11 +3146,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates - or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors @@ -3606,12 +3535,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do - not exist locally by not appending them to - kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3625,11 +3548,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies - whether to apply common labels to resource - templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource @@ -4131,11 +4049,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4149,11 +4062,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4535,11 +4443,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4553,11 +4456,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4730,22 +4628,19 @@ spec: description: Resources is a list of Kubernetes resources managed by this application items: - description: ResourceStatus holds the current synchronization and - health status of a Kubernetes resource. + description: |- + ResourceStatus holds the current sync and health status of a resource + TODO: describe members of this type properties: group: - description: Group represents the API group of the resource - (e.g., "apps" for Deployments). type: string health: - description: Health indicates the health status of the resource - (e.g., Healthy, Degraded, Progressing). + description: HealthStatus contains information about the currently + observed health state of an application or resource properties: lastTransitionTime: - description: |- - LastTransitionTime is the time the HealthStatus was set or updated - - Deprecated: this field is not used and will be removed in a future release. + description: LastTransitionTime is the time the HealthStatus + was set or updated format: date-time type: string message: @@ -4753,46 +4648,30 @@ spec: describing the health status type: string status: - description: Status holds the status code of the resource + description: Status holds the status code of the application + or resource type: string type: object hook: - description: Hook is true if the resource is used as a lifecycle - hook in an Argo CD application. type: boolean kind: - description: Kind specifies the type of the resource (e.g., - "Deployment", "Service"). type: string name: - description: Name is the unique name of the resource within - the namespace. type: string namespace: - description: Namespace defines the Kubernetes namespace where - the resource is located. type: string requiresDeletionConfirmation: - description: RequiresDeletionConfirmation is true if the resource - requires explicit user confirmation before deletion. type: boolean requiresPruning: - description: RequiresPruning is true if the resource needs to - be pruned (deleted) as part of synchronization. type: boolean status: - description: Status represents the synchronization state of - the resource (e.g., Synced, OutOfSync). + description: SyncStatusCode is a type which represents possible + comparison results type: string syncWave: - description: |- - SyncWave determines the order in which resources are applied during a sync operation. - Lower values are applied first. format: int64 type: integer version: - description: Version indicates the API version of the resource - (e.g., "v1", "v1beta1"). type: string type: object type: array @@ -5278,11 +5157,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5296,11 +5170,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -5682,11 +5551,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5700,11 +5564,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -6157,16 +6016,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6433,16 +6288,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6553,8 +6404,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -6839,16 +6688,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7115,16 +6960,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7235,8 +7076,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -7303,8 +7142,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -7522,16 +7359,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7798,16 +7631,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7918,8 +7747,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8183,16 +8010,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8459,16 +8282,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8579,8 +8398,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8869,16 +8686,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9145,16 +8958,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9265,8 +9074,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -9551,16 +9358,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9827,16 +9630,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9947,8 +9746,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10015,8 +9812,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -10234,16 +10029,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10510,16 +10301,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10630,8 +10417,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10895,16 +10680,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11171,16 +10952,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11291,8 +11068,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -11564,16 +11339,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11840,16 +11611,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11960,8 +11727,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12163,10 +11928,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -12456,16 +12217,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12732,16 +12489,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12852,8 +12605,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12899,10 +12650,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -13343,16 +13090,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13619,16 +13362,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13739,8 +13478,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14021,16 +13758,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14297,16 +14030,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14417,8 +14146,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14709,16 +14436,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14985,16 +14708,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15105,8 +14824,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15391,16 +15108,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15667,16 +15380,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15787,8 +15496,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15855,8 +15562,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -16074,16 +15779,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16350,16 +16051,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16470,8 +16167,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -16735,16 +16430,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17011,16 +16702,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17131,8 +16818,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -17404,16 +17089,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17680,16 +17361,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17800,8 +17477,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -18003,10 +17678,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -18296,16 +17967,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -18572,16 +18239,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -18692,8 +18355,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -18739,10 +18400,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -19183,16 +18840,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -19459,16 +19112,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -19579,8 +19228,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -19865,16 +19512,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20141,16 +19784,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20261,8 +19900,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -20533,16 +20170,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20809,16 +20442,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20929,8 +20558,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -21132,10 +20759,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -21425,16 +21048,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -21701,16 +21320,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -21821,8 +21436,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -21868,10 +21481,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -22312,16 +21921,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -22588,16 +22193,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -22708,8 +22309,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -23065,16 +22664,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -23341,16 +22936,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -23461,8 +23052,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -23695,7 +23284,6 @@ spec: type: array description: description: Description contains optional project description - maxLength: 255 type: string destinationServiceAccounts: description: DestinationServiceAccounts holds information about the @@ -23890,10 +23478,6 @@ spec: description: SyncWindow contains the kind, time, duration and attributes that are used to assign the syncWindows to apps properties: - andOperator: - description: UseAndOperator use AND operator for matching applications, - namespaces and clusters instead of the default OR operator - type: boolean applications: description: Applications contains a list of applications that the window will apply to @@ -23906,11 +23490,6 @@ spec: items: type: string type: array - description: - description: Description of the sync that will be applied to - the schedule, can be used to add any information such as a - ticket number for example - type: string duration: description: Duration is the amount of time the sync window will be open @@ -24070,7 +23649,6 @@ rules: - argoproj.io resources: - applications - - applicationsets - appprojects verbs: - create @@ -24607,100 +24185,6 @@ subjects: namespace: argocd --- apiVersion: v1 -data: - resource.customizations.ignoreResourceUpdates.ConfigMap: | - jqPathExpressions: - # Ignore the cluster-autoscaler status - - '.metadata.annotations."cluster-autoscaler.kubernetes.io/last-updated"' - # Ignore the annotation of the legacy Leases election - - '.metadata.annotations."control-plane.alpha.kubernetes.io/leader"' - resource.customizations.ignoreResourceUpdates.Endpoints: | - jsonPointers: - - /metadata - - /subsets - resource.customizations.ignoreResourceUpdates.all: | - jsonPointers: - - /status - resource.customizations.ignoreResourceUpdates.apps_ReplicaSet: | - jqPathExpressions: - - '.metadata.annotations."deployment.kubernetes.io/desired-replicas"' - - '.metadata.annotations."deployment.kubernetes.io/max-replicas"' - - '.metadata.annotations."rollout.argoproj.io/desired-replicas"' - resource.customizations.ignoreResourceUpdates.argoproj.io_Application: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - - '.metadata.annotations."argocd.argoproj.io/refresh"' - - '.metadata.annotations."argocd.argoproj.io/hydrate"' - - '.operation' - resource.customizations.ignoreResourceUpdates.argoproj.io_Rollout: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - resource.customizations.ignoreResourceUpdates.autoscaling_HorizontalPodAutoscaler: | - jqPathExpressions: - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/behavior"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/conditions"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/metrics"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/current-metrics"' - resource.customizations.ignoreResourceUpdates.discovery.k8s.io_EndpointSlice: | - jsonPointers: - - /metadata - - /endpoints - - /ports - resource.exclusions: | - ### Network resources created by the Kubernetes control plane and excluded to reduce the number of watched events and UI clutter - - apiGroups: - - '' - - discovery.k8s.io - kinds: - - Endpoints - - EndpointSlice - ### Internal Kubernetes resources excluded reduce the number of watched events - - apiGroups: - - coordination.k8s.io - kinds: - - Lease - ### Internal Kubernetes Authz/Authn resources excluded reduce the number of watched events - - apiGroups: - - authentication.k8s.io - - authorization.k8s.io - kinds: - - SelfSubjectReview - - TokenReview - - LocalSubjectAccessReview - - SelfSubjectAccessReview - - SelfSubjectRulesReview - - SubjectAccessReview - ### Intermediate Certificate Request excluded reduce the number of watched events - - apiGroups: - - certificates.k8s.io - kinds: - - CertificateSigningRequest - - apiGroups: - - cert-manager.io - kinds: - - CertificateRequest - ### Cilium internal resources excluded reduce the number of watched events and UI Clutter - - apiGroups: - - cilium.io - kinds: - - CiliumIdentity - - CiliumEndpoint - - CiliumEndpointSlice - ### Kyverno intermediate and reporting resources excluded reduce the number of watched events and improve performance - - apiGroups: - - kyverno.io - - reports.kyverno.io - - wgpolicyk8s.io - kinds: - - PolicyReport - - ClusterPolicyReport - - EphemeralReport - - ClusterEphemeralReport - - AdmissionReport - - ClusterAdmissionReport - - BackgroundScanReport - - ClusterBackgroundScanReport - - UpdateRequest kind: ConfigMap metadata: labels: @@ -25051,12 +24535,6 @@ spec: key: applicationsetcontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN valueFrom: configMapKeyRef: @@ -25147,7 +24625,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -25267,13 +24745,7 @@ spec: key: commitserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -25313,6 +24785,26 @@ spec: name: gpg-keyring - mountPath: /tmp name: tmp + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:v2.14.15 + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files serviceAccountName: argocd-commit-server volumes: - configMap: @@ -25339,6 +24831,8 @@ spec: path: ca.crt optional: true secretName: argocd-commit-server-tls + - emptyDir: {} + name: var-files --- apiVersion: apps/v1 kind: Deployment @@ -25383,19 +24877,13 @@ spec: key: dexserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.43.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always name: dex ports: @@ -25424,7 +24912,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: copyutil securityContext: @@ -25496,12 +24984,6 @@ spec: key: notificationscontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -25520,7 +25002,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -25606,7 +25088,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: redis:7.2.7-alpine + image: redis:7.0.15-alpine imagePullPolicy: Always name: redis ports: @@ -25622,7 +25104,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -25703,12 +25185,6 @@ spec: key: reposerver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT valueFrom: configMapKeyRef: @@ -25799,12 +25275,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_REPO_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -25895,7 +25365,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -25947,7 +25417,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -26241,12 +25711,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -26313,13 +25777,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SYNC_WITH_REPLACE_ALLOWED - valueFrom: - configMapKeyRef: - key: server.sync.replace.allowed - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: httpGet: @@ -26509,12 +25967,6 @@ spec: key: controller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION valueFrom: configMapKeyRef: @@ -26623,12 +26075,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -26689,9 +26135,15 @@ spec: key: controller.cluster.cache.events.processing.interval name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER + valueFrom: + configMapKeyRef: + key: commit.server + name: argocd-cmd-params-cm + optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/install.yaml b/manifests/install.yaml index 8c89a3ab39..f0ff9b2c96 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -380,11 +380,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by - not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -398,10 +393,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -769,11 +760,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -787,10 +773,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1268,11 +1250,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize from - failing when components do not exist locally by not appending - them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1286,10 +1263,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to apply - common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1705,11 +1678,6 @@ spec: description: ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally by not - appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -1723,10 +1691,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether to - apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1883,10 +1847,6 @@ spec: description: 'AllowEmpty allows apps have zero live resources (default: false)' type: boolean - enabled: - description: Enable allows apps to explicitly control automated - sync - type: boolean prune: description: 'Prune specifies whether to delete resources from the cluster that are not found in the sources anymore @@ -1990,13 +1950,12 @@ spec: format: date-time type: string message: - description: |- - Message is a human-readable informational message describing the health status - - Deprecated: this field is not used and will be removed in a future release. + description: Message is a human-readable informational message + describing the health status type: string status: - description: Status holds the status code of the application + description: Status holds the status code of the application or + resource type: string type: object history: @@ -2260,11 +2219,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2278,10 +2232,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -2651,11 +2601,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -2669,11 +2614,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -3193,12 +3133,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do not - exist locally by not appending them to kustomization - file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3212,11 +3146,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates - or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors @@ -3606,12 +3535,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents - kustomize from failing when components do - not exist locally by not appending them to - kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -3625,11 +3548,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies - whether to apply common labels to resource - templates or not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource @@ -4131,11 +4049,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4149,11 +4062,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4535,11 +4443,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -4553,11 +4456,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4730,22 +4628,19 @@ spec: description: Resources is a list of Kubernetes resources managed by this application items: - description: ResourceStatus holds the current synchronization and - health status of a Kubernetes resource. + description: |- + ResourceStatus holds the current sync and health status of a resource + TODO: describe members of this type properties: group: - description: Group represents the API group of the resource - (e.g., "apps" for Deployments). type: string health: - description: Health indicates the health status of the resource - (e.g., Healthy, Degraded, Progressing). + description: HealthStatus contains information about the currently + observed health state of an application or resource properties: lastTransitionTime: - description: |- - LastTransitionTime is the time the HealthStatus was set or updated - - Deprecated: this field is not used and will be removed in a future release. + description: LastTransitionTime is the time the HealthStatus + was set or updated format: date-time type: string message: @@ -4753,46 +4648,30 @@ spec: describing the health status type: string status: - description: Status holds the status code of the resource + description: Status holds the status code of the application + or resource type: string type: object hook: - description: Hook is true if the resource is used as a lifecycle - hook in an Argo CD application. type: boolean kind: - description: Kind specifies the type of the resource (e.g., - "Deployment", "Service"). type: string name: - description: Name is the unique name of the resource within - the namespace. type: string namespace: - description: Namespace defines the Kubernetes namespace where - the resource is located. type: string requiresDeletionConfirmation: - description: RequiresDeletionConfirmation is true if the resource - requires explicit user confirmation before deletion. type: boolean requiresPruning: - description: RequiresPruning is true if the resource needs to - be pruned (deleted) as part of synchronization. type: boolean status: - description: Status represents the synchronization state of - the resource (e.g., Synced, OutOfSync). + description: SyncStatusCode is a type which represents possible + comparison results type: string syncWave: - description: |- - SyncWave determines the order in which resources are applied during a sync operation. - Lower values are applied first. format: int64 type: integer version: - description: Version indicates the API version of the resource - (e.g., "v1", "v1beta1"). type: string type: object type: array @@ -5278,11 +5157,6 @@ spec: force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5296,11 +5170,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -5682,11 +5551,6 @@ spec: to force applying common labels to resources for Kustomize apps type: boolean - ignoreMissingComponents: - description: IgnoreMissingComponents prevents kustomize - from failing when components do not exist locally - by not appending them to kustomization file - type: boolean images: description: Images is a list of Kustomize image override specifications @@ -5700,11 +5564,6 @@ spec: KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster. type: string - labelIncludeTemplates: - description: LabelIncludeTemplates specifies whether - to apply common labels to resource templates or - not - type: boolean labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -6157,16 +6016,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6433,16 +6288,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -6553,8 +6404,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -6839,16 +6688,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7115,16 +6960,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7235,8 +7076,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -7303,8 +7142,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -7522,16 +7359,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7798,16 +7631,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -7918,8 +7747,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8183,16 +8010,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8459,16 +8282,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -8579,8 +8398,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -8869,16 +8686,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9145,16 +8958,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9265,8 +9074,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -9551,16 +9358,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9827,16 +9630,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -9947,8 +9746,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10015,8 +9812,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -10234,16 +10029,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10510,16 +10301,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -10630,8 +10417,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -10895,16 +10680,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11171,16 +10952,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11291,8 +11068,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -11564,16 +11339,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11840,16 +11611,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -11960,8 +11727,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12163,10 +11928,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -12456,16 +12217,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12732,16 +12489,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -12852,8 +12605,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -12899,10 +12650,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -13343,16 +13090,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13619,16 +13362,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -13739,8 +13478,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14021,16 +13758,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14297,16 +14030,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14417,8 +14146,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -14709,16 +14436,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -14985,16 +14708,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15105,8 +14824,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15391,16 +15108,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15667,16 +15380,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -15787,8 +15496,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -15855,8 +15562,6 @@ spec: files: items: properties: - exclude: - type: boolean path: type: string required: @@ -16074,16 +15779,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16350,16 +16051,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -16470,8 +16167,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -16735,16 +16430,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17011,16 +16702,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17131,8 +16818,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -17404,16 +17089,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17680,16 +17361,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -17800,8 +17477,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -18003,10 +17678,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -18296,16 +17967,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -18572,16 +18239,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -18692,8 +18355,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -18739,10 +18400,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -19183,16 +18840,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -19459,16 +19112,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -19579,8 +19228,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -19865,16 +19512,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20141,16 +19784,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20261,8 +19900,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -20533,16 +20170,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20809,16 +20442,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -20929,8 +20558,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -21132,10 +20759,6 @@ spec: type: string insecure: type: boolean - labels: - items: - type: string - type: array owner: type: string repo: @@ -21425,16 +21048,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -21701,16 +21320,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -21821,8 +21436,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -21868,10 +21481,6 @@ spec: - metadata - spec type: object - values: - additionalProperties: - type: string - type: object type: object scmProvider: properties: @@ -22312,16 +21921,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -22588,16 +22193,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -22708,8 +22309,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -23065,16 +22664,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -23341,16 +22936,12 @@ spec: type: boolean forceCommonLabels: type: boolean - ignoreMissingComponents: - type: boolean images: items: type: string type: array kubeVersion: type: string - labelIncludeTemplates: - type: boolean labelWithoutSelector: type: boolean namePrefix: @@ -23461,8 +23052,6 @@ spec: properties: allowEmpty: type: boolean - enabled: - type: boolean prune: type: boolean selfHeal: @@ -23695,7 +23284,6 @@ spec: type: array description: description: Description contains optional project description - maxLength: 255 type: string destinationServiceAccounts: description: DestinationServiceAccounts holds information about the @@ -23890,10 +23478,6 @@ spec: description: SyncWindow contains the kind, time, duration and attributes that are used to assign the syncWindows to apps properties: - andOperator: - description: UseAndOperator use AND operator for matching applications, - namespaces and clusters instead of the default OR operator - type: boolean applications: description: Applications contains a list of applications that the window will apply to @@ -23906,11 +23490,6 @@ spec: items: type: string type: array - description: - description: Description of the sync that will be applied to - the schedule, can be used to add any information such as a - ticket number for example - type: string duration: description: Duration is the amount of time the sync window will be open @@ -24061,7 +23640,6 @@ rules: - argoproj.io resources: - applications - - applicationsets - appprojects verbs: - create @@ -24598,100 +24176,6 @@ subjects: namespace: argocd --- apiVersion: v1 -data: - resource.customizations.ignoreResourceUpdates.ConfigMap: | - jqPathExpressions: - # Ignore the cluster-autoscaler status - - '.metadata.annotations."cluster-autoscaler.kubernetes.io/last-updated"' - # Ignore the annotation of the legacy Leases election - - '.metadata.annotations."control-plane.alpha.kubernetes.io/leader"' - resource.customizations.ignoreResourceUpdates.Endpoints: | - jsonPointers: - - /metadata - - /subsets - resource.customizations.ignoreResourceUpdates.all: | - jsonPointers: - - /status - resource.customizations.ignoreResourceUpdates.apps_ReplicaSet: | - jqPathExpressions: - - '.metadata.annotations."deployment.kubernetes.io/desired-replicas"' - - '.metadata.annotations."deployment.kubernetes.io/max-replicas"' - - '.metadata.annotations."rollout.argoproj.io/desired-replicas"' - resource.customizations.ignoreResourceUpdates.argoproj.io_Application: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - - '.metadata.annotations."argocd.argoproj.io/refresh"' - - '.metadata.annotations."argocd.argoproj.io/hydrate"' - - '.operation' - resource.customizations.ignoreResourceUpdates.argoproj.io_Rollout: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - resource.customizations.ignoreResourceUpdates.autoscaling_HorizontalPodAutoscaler: | - jqPathExpressions: - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/behavior"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/conditions"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/metrics"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/current-metrics"' - resource.customizations.ignoreResourceUpdates.discovery.k8s.io_EndpointSlice: | - jsonPointers: - - /metadata - - /endpoints - - /ports - resource.exclusions: | - ### Network resources created by the Kubernetes control plane and excluded to reduce the number of watched events and UI clutter - - apiGroups: - - '' - - discovery.k8s.io - kinds: - - Endpoints - - EndpointSlice - ### Internal Kubernetes resources excluded reduce the number of watched events - - apiGroups: - - coordination.k8s.io - kinds: - - Lease - ### Internal Kubernetes Authz/Authn resources excluded reduce the number of watched events - - apiGroups: - - authentication.k8s.io - - authorization.k8s.io - kinds: - - SelfSubjectReview - - TokenReview - - LocalSubjectAccessReview - - SelfSubjectAccessReview - - SelfSubjectRulesReview - - SubjectAccessReview - ### Intermediate Certificate Request excluded reduce the number of watched events - - apiGroups: - - certificates.k8s.io - kinds: - - CertificateSigningRequest - - apiGroups: - - cert-manager.io - kinds: - - CertificateRequest - ### Cilium internal resources excluded reduce the number of watched events and UI Clutter - - apiGroups: - - cilium.io - kinds: - - CiliumIdentity - - CiliumEndpoint - - CiliumEndpointSlice - ### Kyverno intermediate and reporting resources excluded reduce the number of watched events and improve performance - - apiGroups: - - kyverno.io - - reports.kyverno.io - - wgpolicyk8s.io - kinds: - - PolicyReport - - ClusterPolicyReport - - EphemeralReport - - ClusterEphemeralReport - - AdmissionReport - - ClusterAdmissionReport - - BackgroundScanReport - - ClusterBackgroundScanReport - - UpdateRequest kind: ConfigMap metadata: labels: @@ -25019,12 +24503,6 @@ spec: key: applicationsetcontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN valueFrom: configMapKeyRef: @@ -25115,7 +24593,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -25217,19 +24695,13 @@ spec: key: dexserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.43.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always name: dex ports: @@ -25258,7 +24730,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: copyutil securityContext: @@ -25330,12 +24802,6 @@ spec: key: notificationscontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -25354,7 +24820,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -25440,7 +24906,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: redis:7.2.7-alpine + image: redis:7.0.15-alpine imagePullPolicy: Always name: redis ports: @@ -25456,7 +24922,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -25537,12 +25003,6 @@ spec: key: reposerver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT valueFrom: configMapKeyRef: @@ -25633,12 +25093,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_REPO_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -25729,7 +25183,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -25781,7 +25235,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -26075,12 +25529,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -26147,13 +25595,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SYNC_WITH_REPLACE_ALLOWED - valueFrom: - configMapKeyRef: - key: server.sync.replace.allowed - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: httpGet: @@ -26343,12 +25785,6 @@ spec: key: controller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION valueFrom: configMapKeyRef: @@ -26457,12 +25893,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -26523,9 +25953,15 @@ spec: key: controller.cluster.cache.events.processing.interval name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER + valueFrom: + configMapKeyRef: + key: commit.server + name: argocd-cmd-params-cm + optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/namespace-install-with-hydrator.yaml b/manifests/namespace-install-with-hydrator.yaml index a86a9f8cd1..0a4fae12b9 100644 --- a/manifests/namespace-install-with-hydrator.yaml +++ b/manifests/namespace-install-with-hydrator.yaml @@ -93,7 +93,6 @@ rules: - argoproj.io resources: - applications - - applicationsets - appprojects verbs: - create @@ -416,100 +415,6 @@ subjects: name: argocd-server --- apiVersion: v1 -data: - resource.customizations.ignoreResourceUpdates.ConfigMap: | - jqPathExpressions: - # Ignore the cluster-autoscaler status - - '.metadata.annotations."cluster-autoscaler.kubernetes.io/last-updated"' - # Ignore the annotation of the legacy Leases election - - '.metadata.annotations."control-plane.alpha.kubernetes.io/leader"' - resource.customizations.ignoreResourceUpdates.Endpoints: | - jsonPointers: - - /metadata - - /subsets - resource.customizations.ignoreResourceUpdates.all: | - jsonPointers: - - /status - resource.customizations.ignoreResourceUpdates.apps_ReplicaSet: | - jqPathExpressions: - - '.metadata.annotations."deployment.kubernetes.io/desired-replicas"' - - '.metadata.annotations."deployment.kubernetes.io/max-replicas"' - - '.metadata.annotations."rollout.argoproj.io/desired-replicas"' - resource.customizations.ignoreResourceUpdates.argoproj.io_Application: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - - '.metadata.annotations."argocd.argoproj.io/refresh"' - - '.metadata.annotations."argocd.argoproj.io/hydrate"' - - '.operation' - resource.customizations.ignoreResourceUpdates.argoproj.io_Rollout: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - resource.customizations.ignoreResourceUpdates.autoscaling_HorizontalPodAutoscaler: | - jqPathExpressions: - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/behavior"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/conditions"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/metrics"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/current-metrics"' - resource.customizations.ignoreResourceUpdates.discovery.k8s.io_EndpointSlice: | - jsonPointers: - - /metadata - - /endpoints - - /ports - resource.exclusions: | - ### Network resources created by the Kubernetes control plane and excluded to reduce the number of watched events and UI clutter - - apiGroups: - - '' - - discovery.k8s.io - kinds: - - Endpoints - - EndpointSlice - ### Internal Kubernetes resources excluded reduce the number of watched events - - apiGroups: - - coordination.k8s.io - kinds: - - Lease - ### Internal Kubernetes Authz/Authn resources excluded reduce the number of watched events - - apiGroups: - - authentication.k8s.io - - authorization.k8s.io - kinds: - - SelfSubjectReview - - TokenReview - - LocalSubjectAccessReview - - SelfSubjectAccessReview - - SelfSubjectRulesReview - - SubjectAccessReview - ### Intermediate Certificate Request excluded reduce the number of watched events - - apiGroups: - - certificates.k8s.io - kinds: - - CertificateSigningRequest - - apiGroups: - - cert-manager.io - kinds: - - CertificateRequest - ### Cilium internal resources excluded reduce the number of watched events and UI Clutter - - apiGroups: - - cilium.io - kinds: - - CiliumIdentity - - CiliumEndpoint - - CiliumEndpointSlice - ### Kyverno intermediate and reporting resources excluded reduce the number of watched events and improve performance - - apiGroups: - - kyverno.io - - reports.kyverno.io - - wgpolicyk8s.io - kinds: - - PolicyReport - - ClusterPolicyReport - - EphemeralReport - - ClusterEphemeralReport - - AdmissionReport - - ClusterAdmissionReport - - BackgroundScanReport - - ClusterBackgroundScanReport - - UpdateRequest kind: ConfigMap metadata: labels: @@ -860,12 +765,6 @@ spec: key: applicationsetcontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN valueFrom: configMapKeyRef: @@ -956,7 +855,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -1076,13 +975,7 @@ spec: key: commitserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -1122,6 +1015,26 @@ spec: name: gpg-keyring - mountPath: /tmp name: tmp + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:v2.14.15 + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files serviceAccountName: argocd-commit-server volumes: - configMap: @@ -1148,6 +1061,8 @@ spec: path: ca.crt optional: true secretName: argocd-commit-server-tls + - emptyDir: {} + name: var-files --- apiVersion: apps/v1 kind: Deployment @@ -1192,19 +1107,13 @@ spec: key: dexserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.43.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always name: dex ports: @@ -1233,7 +1142,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: copyutil securityContext: @@ -1305,12 +1214,6 @@ spec: key: notificationscontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -1329,7 +1232,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -1415,7 +1318,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: redis:7.2.7-alpine + image: redis:7.0.15-alpine imagePullPolicy: Always name: redis ports: @@ -1431,7 +1334,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -1512,12 +1415,6 @@ spec: key: reposerver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT valueFrom: configMapKeyRef: @@ -1608,12 +1505,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_REPO_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -1704,7 +1595,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -1756,7 +1647,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -2050,12 +1941,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -2122,13 +2007,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SYNC_WITH_REPLACE_ALLOWED - valueFrom: - configMapKeyRef: - key: server.sync.replace.allowed - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: httpGet: @@ -2318,12 +2197,6 @@ spec: key: controller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION valueFrom: configMapKeyRef: @@ -2432,12 +2305,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -2498,9 +2365,15 @@ spec: key: controller.cluster.cache.events.processing.interval name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER + valueFrom: + configMapKeyRef: + key: commit.server + name: argocd-cmd-params-cm + optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 752b64b10c..393331bcb1 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -84,7 +84,6 @@ rules: - argoproj.io resources: - applications - - applicationsets - appprojects verbs: - create @@ -407,100 +406,6 @@ subjects: name: argocd-server --- apiVersion: v1 -data: - resource.customizations.ignoreResourceUpdates.ConfigMap: | - jqPathExpressions: - # Ignore the cluster-autoscaler status - - '.metadata.annotations."cluster-autoscaler.kubernetes.io/last-updated"' - # Ignore the annotation of the legacy Leases election - - '.metadata.annotations."control-plane.alpha.kubernetes.io/leader"' - resource.customizations.ignoreResourceUpdates.Endpoints: | - jsonPointers: - - /metadata - - /subsets - resource.customizations.ignoreResourceUpdates.all: | - jsonPointers: - - /status - resource.customizations.ignoreResourceUpdates.apps_ReplicaSet: | - jqPathExpressions: - - '.metadata.annotations."deployment.kubernetes.io/desired-replicas"' - - '.metadata.annotations."deployment.kubernetes.io/max-replicas"' - - '.metadata.annotations."rollout.argoproj.io/desired-replicas"' - resource.customizations.ignoreResourceUpdates.argoproj.io_Application: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - - '.metadata.annotations."argocd.argoproj.io/refresh"' - - '.metadata.annotations."argocd.argoproj.io/hydrate"' - - '.operation' - resource.customizations.ignoreResourceUpdates.argoproj.io_Rollout: | - jqPathExpressions: - - '.metadata.annotations."notified.notifications.argoproj.io"' - resource.customizations.ignoreResourceUpdates.autoscaling_HorizontalPodAutoscaler: | - jqPathExpressions: - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/behavior"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/conditions"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/metrics"' - - '.metadata.annotations."autoscaling.alpha.kubernetes.io/current-metrics"' - resource.customizations.ignoreResourceUpdates.discovery.k8s.io_EndpointSlice: | - jsonPointers: - - /metadata - - /endpoints - - /ports - resource.exclusions: | - ### Network resources created by the Kubernetes control plane and excluded to reduce the number of watched events and UI clutter - - apiGroups: - - '' - - discovery.k8s.io - kinds: - - Endpoints - - EndpointSlice - ### Internal Kubernetes resources excluded reduce the number of watched events - - apiGroups: - - coordination.k8s.io - kinds: - - Lease - ### Internal Kubernetes Authz/Authn resources excluded reduce the number of watched events - - apiGroups: - - authentication.k8s.io - - authorization.k8s.io - kinds: - - SelfSubjectReview - - TokenReview - - LocalSubjectAccessReview - - SelfSubjectAccessReview - - SelfSubjectRulesReview - - SubjectAccessReview - ### Intermediate Certificate Request excluded reduce the number of watched events - - apiGroups: - - certificates.k8s.io - kinds: - - CertificateSigningRequest - - apiGroups: - - cert-manager.io - kinds: - - CertificateRequest - ### Cilium internal resources excluded reduce the number of watched events and UI Clutter - - apiGroups: - - cilium.io - kinds: - - CiliumIdentity - - CiliumEndpoint - - CiliumEndpointSlice - ### Kyverno intermediate and reporting resources excluded reduce the number of watched events and improve performance - - apiGroups: - - kyverno.io - - reports.kyverno.io - - wgpolicyk8s.io - kinds: - - PolicyReport - - ClusterPolicyReport - - EphemeralReport - - ClusterEphemeralReport - - AdmissionReport - - ClusterAdmissionReport - - BackgroundScanReport - - ClusterBackgroundScanReport - - UpdateRequest kind: ConfigMap metadata: labels: @@ -828,12 +733,6 @@ spec: key: applicationsetcontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN valueFrom: configMapKeyRef: @@ -924,7 +823,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -1026,19 +925,13 @@ spec: key: dexserver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.43.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always name: dex ports: @@ -1067,7 +960,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: copyutil securityContext: @@ -1139,12 +1032,6 @@ spec: key: notificationscontroller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -1163,7 +1050,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -1249,7 +1136,7 @@ spec: secretKeyRef: key: auth name: argocd-redis - image: redis:7.2.7-alpine + image: redis:7.0.15-alpine imagePullPolicy: Always name: redis ports: @@ -1265,7 +1152,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -1346,12 +1233,6 @@ spec: key: reposerver.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT valueFrom: configMapKeyRef: @@ -1442,12 +1323,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_REPO_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -1538,7 +1413,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -1590,7 +1465,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -1884,12 +1759,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SERVER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -1956,13 +1825,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - - name: ARGOCD_SYNC_WITH_REPLACE_ALLOWED - valueFrom: - configMapKeyRef: - key: server.sync.replace.allowed - name: argocd-cmd-params-cm - optional: true - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always livenessProbe: httpGet: @@ -2152,12 +2015,6 @@ spec: key: controller.log.level name: argocd-cmd-params-cm optional: true - - name: ARGOCD_LOG_FORMAT_TIMESTAMP - valueFrom: - configMapKeyRef: - key: log.format.timestamp - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION valueFrom: configMapKeyRef: @@ -2266,12 +2123,6 @@ spec: key: otlp.headers name: argocd-cmd-params-cm optional: true - - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS - valueFrom: - configMapKeyRef: - key: otlp.attrs - name: argocd-cmd-params-cm - optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -2332,9 +2183,15 @@ spec: key: controller.cluster.cache.events.processing.interval name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER + valueFrom: + configMapKeyRef: + key: commit.server + name: argocd-cmd-params-cm + optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:latest + image: quay.io/argoproj/argocd:v2.14.15 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/mkdocs.yml b/mkdocs.yml index 58e4d6b8dd..d2d59fdd6b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -74,7 +74,6 @@ nav: - operator-manual/notifications/troubleshooting.md - operator-manual/notifications/troubleshooting-commands.md - operator-manual/notifications/troubleshooting-errors.md - - operator-manual/notifications/examples.md - Notification Services: - operator-manual/notifications/services/alertmanager.md - operator-manual/notifications/services/awssqs.md @@ -131,8 +130,6 @@ nav: - operator-manual/server-commands/additional-configuration-method.md - Upgrading: - operator-manual/upgrading/overview.md - - operator-manual/upgrading/2.14-3.0.md - - operator-manual/upgrading/2.13-2.14.md - operator-manual/upgrading/2.12-2.13.md - operator-manual/upgrading/2.11-2.12.md - operator-manual/upgrading/2.10-2.11.md @@ -167,7 +164,6 @@ nav: - user-guide/tool_detection.md - user-guide/projects.md - user-guide/private-repositories.md - - user-guide/plugins.md - user-guide/multiple_sources.md - GnuPG verification: user-guide/gpg-verification.md - user-guide/auto_sync.md diff --git a/notification_controller/controller/controller.go b/notification_controller/controller/controller.go index 6af91bd35d..5137e0dfc1 100644 --- a/notification_controller/controller/controller.go +++ b/notification_controller/controller/controller.go @@ -6,17 +6,17 @@ import ( "fmt" "time" - "github.com/argoproj/argo-cd/v3/util/glob" + "github.com/argoproj/argo-cd/v2/util/glob" - "github.com/argoproj/argo-cd/v3/util/notification/k8s" + "github.com/argoproj/argo-cd/v2/util/notification/k8s" - service "github.com/argoproj/argo-cd/v3/util/notification/argocd" + service "github.com/argoproj/argo-cd/v2/util/notification/argocd" - argocert "github.com/argoproj/argo-cd/v3/util/cert" + argocert "github.com/argoproj/argo-cd/v2/util/cert" "k8s.io/apimachinery/pkg/runtime/schema" - "github.com/argoproj/argo-cd/v3/util/notification/settings" + "github.com/argoproj/argo-cd/v2/util/notification/settings" "github.com/argoproj/notifications-engine/pkg/api" "github.com/argoproj/notifications-engine/pkg/controller" @@ -24,7 +24,7 @@ import ( "github.com/argoproj/notifications-engine/pkg/subscriptions" httputil "github.com/argoproj/notifications-engine/pkg/util/http" log "github.com/sirupsen/logrus" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" @@ -32,7 +32,7 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) const ( @@ -78,7 +78,7 @@ func NewController( appProjInformer := newInformer(newAppProjClient(client, namespace), namespace, []string{namespace}, "") var notificationConfigNamespace string if selfServiceNotificationEnabled { - notificationConfigNamespace = metav1.NamespaceAll + notificationConfigNamespace = v1.NamespaceAll } else { notificationConfigNamespace = namespace } @@ -93,7 +93,7 @@ func NewController( appProjInformer: appProjInformer, apiFactory: apiFactory, } - skipProcessingOpt := controller.WithSkipProcessing(func(obj metav1.Object) (bool, string) { + skipProcessingOpt := controller.WithSkipProcessing(func(obj v1.Object) (bool, string) { app, ok := (obj).(*unstructured.Unstructured) if !ok { return false, "" @@ -125,7 +125,7 @@ func checkAppNotInAdditionalNamespaces(app *unstructured.Unstructured, namespace return namespace != app.GetNamespace() && !glob.MatchStringInList(applicationNamespaces, app.GetNamespace(), glob.REGEXP) } -func (c *notificationController) alterDestinations(obj metav1.Object, destinations services.Destinations, cfg api.Config) services.Destinations { +func (c *notificationController) alterDestinations(obj v1.Object, destinations services.Destinations, cfg api.Config) services.Destinations { app, ok := (obj).(*unstructured.Unstructured) if !ok { return destinations @@ -141,7 +141,7 @@ func (c *notificationController) alterDestinations(obj metav1.Object, destinatio func newInformer(resClient dynamic.ResourceInterface, controllerNamespace string, applicationNamespaces []string, selector string) cache.SharedIndexInformer { informer := cache.NewSharedIndexInformer( &cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { // We are only interested in apps that exist in namespaces the // user wants to be enabled. options.LabelSelector = selector @@ -158,7 +158,7 @@ func newInformer(resClient dynamic.ResourceInterface, controllerNamespace string appList.Items = newItems return appList, nil }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { options.LabelSelector = selector return resClient.Watch(context.TODO(), options) }, @@ -191,7 +191,7 @@ func (c *notificationController) Init(ctx context.Context) error { go c.configMapInformer.Run(ctx.Done()) if !cache.WaitForCacheSync(ctx.Done(), c.appInformer.HasSynced, c.appProjInformer.HasSynced, c.secretInformer.HasSynced, c.configMapInformer.HasSynced) { - return errors.New("timed out waiting for caches to sync") + return errors.New("Timed out waiting for caches to sync") } return nil } diff --git a/notification_controller/controller/controller_test.go b/notification_controller/controller/controller_test.go index 1793394599..ca901cf2c1 100644 --- a/notification_controller/controller/controller_test.go +++ b/notification_controller/controller/controller_test.go @@ -14,7 +14,7 @@ import ( k8sfake "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/tools/cache" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestIsAppSyncStatusRefreshed(t *testing.T) { @@ -29,8 +29,8 @@ func TestIsAppSyncStatusRefreshed(t *testing.T) { { name: "No OperationState", app: &unstructured.Unstructured{ - Object: map[string]any{ - "status": map[string]any{}, + Object: map[string]interface{}{ + "status": map[string]interface{}{}, }, }, expectedValue: true, @@ -38,9 +38,9 @@ func TestIsAppSyncStatusRefreshed(t *testing.T) { { name: "No FinishedAt, Completed Phase", app: &unstructured.Unstructured{ - Object: map[string]any{ - "status": map[string]any{ - "operationState": map[string]any{ + Object: map[string]interface{}{ + "status": map[string]interface{}{ + "operationState": map[string]interface{}{ "phase": "Succeeded", }, }, @@ -51,9 +51,9 @@ func TestIsAppSyncStatusRefreshed(t *testing.T) { { name: "FinishedAt After ReconciledAt & ObservedAt", app: &unstructured.Unstructured{ - Object: map[string]any{ - "status": map[string]any{ - "operationState": map[string]any{ + Object: map[string]interface{}{ + "status": map[string]interface{}{ + "operationState": map[string]interface{}{ "finishedAt": "2021-01-01T01:05:00Z", "phase": "Succeeded", }, @@ -67,9 +67,9 @@ func TestIsAppSyncStatusRefreshed(t *testing.T) { { name: "FinishedAt Before ReconciledAt & ObservedAt", app: &unstructured.Unstructured{ - Object: map[string]any{ - "status": map[string]any{ - "operationState": map[string]any{ + Object: map[string]interface{}{ + "status": map[string]interface{}{ + "operationState": map[string]interface{}{ "finishedAt": "2021-01-01T01:02:00Z", "phase": "Succeeded", }, @@ -92,8 +92,8 @@ func TestIsAppSyncStatusRefreshed(t *testing.T) { func TestGetAppProj_invalidProjectNestedString(t *testing.T) { app := &unstructured.Unstructured{ - Object: map[string]any{ - "spec": map[string]any{}, + Object: map[string]interface{}{ + "spec": map[string]interface{}{}, }, } informer := cache.NewSharedIndexInformer(nil, nil, 0, nil) @@ -105,7 +105,9 @@ func TestGetAppProj_invalidProjectNestedString(t *testing.T) { func TestInit(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.SchemeBuilder.AddToScheme(scheme) - require.NoErrorf(t, err, "Error registering the resource") + if err != nil { + t.Fatalf("Error registering the resource: %v", err) + } dynamicClient := fake.NewSimpleDynamicClient(scheme) k8sClient := k8sfake.NewSimpleClientset() appLabelSelector := "app=test" @@ -127,7 +129,7 @@ func TestInit(t *testing.T) { assert.NotNil(t, nc) - ctx, cancel := context.WithTimeout(t.Context(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() err = nc.Init(ctx) @@ -139,7 +141,9 @@ func TestInit(t *testing.T) { func TestInitTimeout(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.SchemeBuilder.AddToScheme(scheme) - require.NoErrorf(t, err, "Error registering the resource") + if err != nil { + t.Fatalf("Error registering the resource: %v", err) + } dynamicClient := fake.NewSimpleDynamicClient(scheme) k8sClient := k8sfake.NewSimpleClientset() appLabelSelector := "app=test" @@ -160,19 +164,20 @@ func TestInitTimeout(t *testing.T) { assert.NotNil(t, nc) // Use a short timeout to simulate a timeout during cache synchronization - ctx, cancel := context.WithTimeout(t.Context(), 1*time.Millisecond) + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond) defer cancel() err = nc.Init(ctx) // Expect an error & add assertion for the error message - assert.EqualError(t, err, "timed out waiting for caches to sync") + require.Error(t, err) + assert.Equal(t, "Timed out waiting for caches to sync", err.Error()) } func TestCheckAppNotInAdditionalNamespaces(t *testing.T) { app := &unstructured.Unstructured{ - Object: map[string]any{ - "spec": map[string]any{}, + Object: map[string]interface{}{ + "spec": map[string]interface{}{}, }, } namespace := "argocd" diff --git a/notifications_catalog/install.yaml b/notifications_catalog/install.yaml index 120d053a8d..25aebf826e 100644 --- a/notifications_catalog/install.yaml +++ b/notifications_catalog/install.yaml @@ -60,7 +60,7 @@ data: }, { "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 }} + "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", @@ -88,7 +88,7 @@ data: "name":"Open Repository", "targets":[{ "os":"default", - "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 }} + "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' @@ -137,7 +137,7 @@ data: }, { "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 }} + "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":{{- 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 }} + "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' @@ -214,7 +214,7 @@ data: }, { "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 }} + "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}} , @@ -238,7 +238,7 @@ data: "name":"Open Repository", "targets":[{ "os":"default", - "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 }} + "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' @@ -291,7 +291,7 @@ data: }, { "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 }} + "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}} , @@ -315,7 +315,7 @@ data: "name":"Open Repository", "targets":[{ "os":"default", - "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 }} + "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}}. @@ -368,7 +368,7 @@ data: }, { "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 }} + "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}} , @@ -392,7 +392,7 @@ data: "name":"Open Repository", "targets":[{ "os":"default", - "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 }} + "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' @@ -444,7 +444,7 @@ data: }, { "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 }} + "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}} , @@ -468,7 +468,7 @@ data: "name":"Open Repository", "targets":[{ "os":"default", - "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 }} + "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' @@ -491,36 +491,30 @@ data: send: - app-deployed when: app.status.operationState != nil and app.status.operationState.phase in ['Succeeded'] - and app.status.health.status == 'Healthy' and (!time.Parse(app.status.health.lastTransitionTime).Add(1 - * time.Minute).Before(time.Parse(app.status.operationState.finishedAt)) or time.Parse(app.status.health.lastTransitionTime).Before(time.Parse(app.status.operationState.startedAt))) + and app.status.health.status == 'Healthy' trigger.on-health-degraded: | - description: Application has degraded - oncePer: app.status.operationState?.syncResult?.revision send: - app-health-degraded when: app.status.health.status == 'Degraded' trigger.on-sync-failed: | - description: Application syncing has failed - oncePer: app.status.operationState?.syncResult?.revision send: - app-sync-failed when: app.status.operationState != nil and app.status.operationState.phase in ['Error', 'Failed'] trigger.on-sync-running: | - description: Application is being synced - oncePer: app.status.operationState?.syncResult?.revision send: - app-sync-running when: app.status.operationState != nil and app.status.operationState.phase in ['Running'] trigger.on-sync-status-unknown: | - description: Application status is 'Unknown' - oncePer: app.status.operationState?.syncResult?.revision send: - app-sync-status-unknown when: app.status.sync.status == 'Unknown' trigger.on-sync-succeeded: | - description: Application syncing has succeeded - oncePer: app.status.operationState?.syncResult?.revision send: - app-sync-succeeded when: app.status.operationState != nil and app.status.operationState.phase in ['Succeeded'] diff --git a/notifications_catalog/templates/app-deployed.yaml b/notifications_catalog/templates/app-deployed.yaml index 058f7fd776..8e55db33e5 100644 --- a/notifications_catalog/templates/app-deployed.yaml +++ b/notifications_catalog/templates/app-deployed.yaml @@ -44,7 +44,7 @@ teams: }, { "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 }} + "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":{{- 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 }} + "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-health-degraded.yaml b/notifications_catalog/templates/app-health-degraded.yaml index cf6983f770..1737bfa97e 100644 --- a/notifications_catalog/templates/app-health-degraded.yaml +++ b/notifications_catalog/templates/app-health-degraded.yaml @@ -40,7 +40,7 @@ teams: }, { "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 }} + "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":{{- 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 }} + "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 710f42fc1a..509aacd365 100644 --- a/notifications_catalog/templates/app-sync-failed.yaml +++ b/notifications_catalog/templates/app-sync-failed.yaml @@ -44,7 +44,7 @@ teams: }, { "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 }} + "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":{{- 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 }} + "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-running.yaml b/notifications_catalog/templates/app-sync-running.yaml index 3260221ab5..55dc9f9b10 100644 --- a/notifications_catalog/templates/app-sync-running.yaml +++ b/notifications_catalog/templates/app-sync-running.yaml @@ -43,7 +43,7 @@ teams: }, { "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 }} + "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":{{- 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 }} + "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-status-unknown.yaml b/notifications_catalog/templates/app-sync-status-unknown.yaml index 674dfac5cc..69d3e22363 100644 --- a/notifications_catalog/templates/app-sync-status-unknown.yaml +++ b/notifications_catalog/templates/app-sync-status-unknown.yaml @@ -44,7 +44,7 @@ teams: }, { "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 }} + "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":{{- 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 }} + "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-succeeded.yaml b/notifications_catalog/templates/app-sync-succeeded.yaml index c4d10d7284..2f88860f18 100644 --- a/notifications_catalog/templates/app-sync-succeeded.yaml +++ b/notifications_catalog/templates/app-sync-succeeded.yaml @@ -44,7 +44,7 @@ teams: }, { "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 }} + "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":{{- 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 }} + "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/triggers/on-deployed.yaml b/notifications_catalog/triggers/on-deployed.yaml index 6fa6dbc328..486fb15bd9 100644 --- a/notifications_catalog/triggers/on-deployed.yaml +++ b/notifications_catalog/triggers/on-deployed.yaml @@ -1,4 +1,4 @@ -- when: app.status.operationState != nil and app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy' and (!time.Parse(app.status.health.lastTransitionTime).Add(1 * time.Minute).Before(time.Parse(app.status.operationState.finishedAt)) or time.Parse(app.status.health.lastTransitionTime).Before(time.Parse(app.status.operationState.startedAt))) +- when: app.status.operationState != nil and app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy' description: Application is synced and healthy. Triggered once per commit. send: [app-deployed] oncePer: app.status.operationState?.syncResult?.revision diff --git a/notifications_catalog/triggers/on-health-degraded.yaml b/notifications_catalog/triggers/on-health-degraded.yaml index f12fb93fd4..fe434de7c2 100644 --- a/notifications_catalog/triggers/on-health-degraded.yaml +++ b/notifications_catalog/triggers/on-health-degraded.yaml @@ -1,4 +1,3 @@ - when: app.status.health.status == 'Degraded' description: Application has degraded send: [app-health-degraded] - oncePer: app.status.operationState?.syncResult?.revision diff --git a/notifications_catalog/triggers/on-sync-failed.yaml b/notifications_catalog/triggers/on-sync-failed.yaml index 7d74e4ca11..b19afc561b 100644 --- a/notifications_catalog/triggers/on-sync-failed.yaml +++ b/notifications_catalog/triggers/on-sync-failed.yaml @@ -1,4 +1,3 @@ - when: app.status.operationState != nil and app.status.operationState.phase in ['Error', 'Failed'] description: Application syncing has failed send: [app-sync-failed] - oncePer: app.status.operationState?.syncResult?.revision diff --git a/notifications_catalog/triggers/on-sync-running.yaml b/notifications_catalog/triggers/on-sync-running.yaml index f4406e9599..8ed62c9bf9 100644 --- a/notifications_catalog/triggers/on-sync-running.yaml +++ b/notifications_catalog/triggers/on-sync-running.yaml @@ -1,4 +1,3 @@ - when: app.status.operationState != nil and app.status.operationState.phase in ['Running'] description: Application is being synced send: [app-sync-running] - oncePer: app.status.operationState?.syncResult?.revision diff --git a/notifications_catalog/triggers/on-sync-status-unknown.yaml b/notifications_catalog/triggers/on-sync-status-unknown.yaml index 41d8e02d33..de92c15f18 100644 --- a/notifications_catalog/triggers/on-sync-status-unknown.yaml +++ b/notifications_catalog/triggers/on-sync-status-unknown.yaml @@ -1,4 +1,3 @@ - when: app.status.sync.status == 'Unknown' description: Application status is 'Unknown' send: [app-sync-status-unknown] - oncePer: app.status.operationState?.syncResult?.revision diff --git a/notifications_catalog/triggers/on-sync-succeeded.yaml b/notifications_catalog/triggers/on-sync-succeeded.yaml index e13d9e0f91..c3eb0e1aea 100644 --- a/notifications_catalog/triggers/on-sync-succeeded.yaml +++ b/notifications_catalog/triggers/on-sync-succeeded.yaml @@ -1,4 +1,3 @@ - when: app.status.operationState != nil and app.status.operationState.phase in ['Succeeded'] description: Application syncing has succeeded send: [app-sync-succeeded] - oncePer: app.status.operationState?.syncResult?.revision diff --git a/pkg/apiclient/account/account.pb.go b/pkg/apiclient/account/account.pb.go index 79371a02bf..b6ff0cd6ed 100644 --- a/pkg/apiclient/account/account.pb.go +++ b/pkg/apiclient/account/account.pb.go @@ -780,51 +780,51 @@ func init() { proto.RegisterFile("server/account/account.proto", fileDescriptor_ var fileDescriptor_56d089a9b5e998c0 = []byte{ // 738 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xcd, 0x6e, 0xd3, 0x4a, - 0x14, 0x96, 0x93, 0xa6, 0x3f, 0x27, 0xb9, 0xe9, 0xed, 0xdc, 0x36, 0xd7, 0x32, 0x21, 0xa4, 0xd3, - 0xaa, 0x0d, 0x41, 0xad, 0x45, 0x8b, 0x10, 0xaa, 0x60, 0xd1, 0x16, 0x84, 0x2a, 0xb1, 0x80, 0xf0, - 0xb3, 0x28, 0xab, 0x89, 0x33, 0x0a, 0x43, 0x13, 0xdb, 0xf5, 0x8c, 0x13, 0x50, 0x94, 0x0d, 0x3c, - 0x02, 0x5b, 0x1e, 0x88, 0x25, 0x12, 0x2f, 0x80, 0x2a, 0x1e, 0x04, 0x79, 0x3c, 0xe3, 0x38, 0x4e, - 0x8a, 0x58, 0xd9, 0xe7, 0x67, 0xce, 0xf7, 0x9d, 0x6f, 0xce, 0xb1, 0xa1, 0xca, 0x69, 0x30, 0xa0, - 0x81, 0x4d, 0x1c, 0xc7, 0x0b, 0x5d, 0xa1, 0x9f, 0xfb, 0x7e, 0xe0, 0x09, 0x0f, 0x2d, 0x29, 0xd3, - 0xaa, 0x76, 0x3d, 0xaf, 0xdb, 0xa3, 0x36, 0xf1, 0x99, 0x4d, 0x5c, 0xd7, 0x13, 0x44, 0x30, 0xcf, - 0xe5, 0x71, 0x1a, 0x1e, 0xc2, 0xc6, 0x6b, 0xbf, 0x43, 0x04, 0x7d, 0x4e, 0x38, 0x1f, 0x7a, 0x41, - 0xa7, 0x45, 0x2f, 0x43, 0xca, 0x05, 0xaa, 0x43, 0xd1, 0xa5, 0x43, 0xed, 0x35, 0x8d, 0xba, 0xd1, - 0x58, 0x69, 0xa5, 0x5d, 0xa8, 0x01, 0xab, 0x4e, 0x18, 0x04, 0xd4, 0x15, 0x49, 0x56, 0x4e, 0x66, - 0x65, 0xdd, 0x08, 0xc1, 0x82, 0x4b, 0xfa, 0xd4, 0xcc, 0xcb, 0xb0, 0x7c, 0xc7, 0x26, 0x54, 0xb2, - 0xc0, 0xdc, 0xf7, 0x5c, 0x4e, 0xb1, 0x03, 0xc5, 0x53, 0xe2, 0x9e, 0x69, 0x22, 0x16, 0x2c, 0x07, - 0x94, 0x7b, 0x61, 0xe0, 0x50, 0xc5, 0x22, 0xb1, 0x51, 0x05, 0x16, 0x89, 0x13, 0xb5, 0xa3, 0x90, - 0x95, 0x15, 0x91, 0xe7, 0x61, 0x3b, 0x39, 0x16, 0xe3, 0xa6, 0x5d, 0x78, 0x1b, 0x4a, 0x31, 0x48, - 0x0c, 0x8a, 0xd6, 0xa1, 0x30, 0x20, 0xbd, 0x50, 0x43, 0xc4, 0x06, 0xde, 0x85, 0xb5, 0xa7, 0x54, - 0x1c, 0xc7, 0x4a, 0x6a, 0x42, 0xba, 0x1b, 0x23, 0xd5, 0xcd, 0x67, 0x03, 0x96, 0x54, 0xda, 0xbc, - 0x38, 0x32, 0x61, 0x89, 0xba, 0xa4, 0xdd, 0xa3, 0xb1, 0x46, 0xcb, 0x2d, 0x6d, 0x22, 0x0c, 0x25, - 0x87, 0xf8, 0xa4, 0xcd, 0x7a, 0x4c, 0x30, 0xca, 0xcd, 0x7c, 0x3d, 0xdf, 0x58, 0x69, 0x4d, 0xf9, - 0xd0, 0x0e, 0x2c, 0x0a, 0xef, 0x82, 0xba, 0xdc, 0x5c, 0xa8, 0xe7, 0x1b, 0xc5, 0x83, 0xf2, 0xbe, - 0xbe, 0xeb, 0x57, 0x91, 0xbb, 0xa5, 0xa2, 0xf8, 0x3e, 0x94, 0x14, 0x09, 0xfe, 0x8c, 0x71, 0x81, - 0x76, 0xa0, 0xc0, 0x04, 0xed, 0x73, 0xd3, 0x90, 0xc7, 0xfe, 0x4d, 0x8e, 0xe9, 0x8e, 0xe2, 0x30, - 0x7e, 0x01, 0x05, 0x59, 0x08, 0x95, 0x21, 0xc7, 0xf4, 0x5d, 0xe7, 0x58, 0x27, 0xd2, 0x9e, 0x71, - 0x1e, 0xd2, 0xce, 0xb1, 0x90, 0xbc, 0xf3, 0xad, 0xc4, 0x46, 0x55, 0x58, 0xa1, 0x1f, 0x7c, 0x16, - 0x50, 0x7e, 0x2c, 0xa4, 0xc2, 0xf9, 0xd6, 0xc4, 0x81, 0x0f, 0x00, 0x64, 0xc9, 0x98, 0xc8, 0xf6, - 0x34, 0x91, 0x2c, 0x7f, 0x45, 0xe3, 0x0d, 0xa0, 0xd3, 0x80, 0x12, 0x41, 0x63, 0xef, 0xf5, 0x72, - 0xa7, 0xb0, 0xcf, 0x5c, 0x45, 0x6c, 0xe2, 0x50, 0x5d, 0xe4, 0x75, 0x17, 0xf8, 0x0e, 0xfc, 0x37, - 0x55, 0x77, 0x72, 0xe5, 0x52, 0x37, 0x7d, 0xe5, 0xd2, 0xc0, 0x0f, 0x00, 0x3d, 0xa6, 0x3d, 0xfa, - 0x17, 0x24, 0x62, 0x98, 0x5c, 0x02, 0xb3, 0x0e, 0x28, 0x6a, 0x76, 0x7a, 0x5a, 0xf0, 0x2a, 0xfc, - 0xf3, 0xa4, 0xef, 0x8b, 0x8f, 0x1a, 0xf6, 0xe0, 0x6b, 0x01, 0xca, 0x2a, 0xe7, 0x25, 0x0d, 0x06, - 0xcc, 0xa1, 0x68, 0x08, 0x0b, 0xd1, 0x30, 0xa2, 0xf5, 0x44, 0x97, 0xd4, 0x02, 0x58, 0x1b, 0x19, - 0xaf, 0x5a, 0x93, 0x93, 0x4f, 0x3f, 0x7e, 0x7d, 0xc9, 0x3d, 0x44, 0x47, 0x72, 0xb3, 0x07, 0x77, - 0x93, 0xef, 0x80, 0x43, 0xdc, 0x3d, 0x66, 0x8f, 0xf4, 0xa8, 0x8f, 0xed, 0x51, 0xbc, 0x15, 0x63, - 0x7b, 0x94, 0xda, 0x80, 0x47, 0xcd, 0xe6, 0x18, 0x0d, 0xa0, 0x3c, 0xbd, 0x84, 0xa8, 0x96, 0x80, - 0xcd, 0xfd, 0x2c, 0x58, 0xb7, 0xae, 0x8d, 0x2b, 0x5a, 0x5b, 0x92, 0xd6, 0x4d, 0xcb, 0xcc, 0xd2, - 0xf2, 0x55, 0xe6, 0x91, 0xd1, 0x44, 0x6f, 0xa1, 0x94, 0x92, 0x8a, 0xa3, 0x1b, 0x49, 0xd5, 0x59, - 0x05, 0x53, 0xfd, 0xa7, 0x87, 0x1b, 0xff, 0x2f, 0x81, 0xd6, 0xd0, 0x6a, 0x06, 0x08, 0x9d, 0x03, - 0x4c, 0x96, 0x16, 0x59, 0xc9, 0xe9, 0x99, 0x4d, 0xb6, 0x66, 0x16, 0x02, 0xd7, 0x64, 0x51, 0x13, - 0x55, 0xb2, 0xec, 0x47, 0xd1, 0x95, 0x8f, 0xd1, 0x25, 0x14, 0x53, 0xa3, 0x94, 0xe2, 0x3d, 0x3b, - 0xb8, 0x56, 0x75, 0x7e, 0x50, 0xe9, 0xb4, 0x2b, 0x91, 0x36, 0x71, 0x75, 0x3e, 0x92, 0x2d, 0xa7, - 0x31, 0xd2, 0xaa, 0x0f, 0xc5, 0xd4, 0x40, 0xa6, 0x20, 0x67, 0xc7, 0xd4, 0xaa, 0x24, 0xc1, 0xa9, - 0x99, 0xc3, 0xb7, 0x25, 0xd8, 0x56, 0x73, 0xf3, 0x4f, 0x60, 0xf6, 0x88, 0x75, 0xc6, 0x27, 0x27, - 0xdf, 0xae, 0x6a, 0xc6, 0xf7, 0xab, 0x9a, 0xf1, 0xf3, 0xaa, 0x66, 0x9c, 0xdf, 0xeb, 0x32, 0xf1, - 0x2e, 0x6c, 0xef, 0x3b, 0x5e, 0xdf, 0x26, 0x41, 0xd7, 0xf3, 0x03, 0xef, 0xbd, 0x7c, 0xd9, 0x73, - 0x3a, 0xf6, 0xe0, 0xd0, 0xf6, 0x2f, 0xba, 0x51, 0x49, 0xa7, 0xc7, 0xe8, 0xe4, 0x0f, 0xd4, 0x5e, - 0x94, 0xff, 0x96, 0xc3, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x18, 0x8a, 0x2b, 0x33, 0xa2, 0x06, + 0x14, 0x96, 0x93, 0xa6, 0x3f, 0x27, 0xb9, 0xe9, 0xed, 0xdc, 0x36, 0xd7, 0xf2, 0xcd, 0x0d, 0xe9, + 0xb4, 0x6a, 0x43, 0x50, 0x6b, 0x11, 0x10, 0x42, 0x15, 0x2c, 0xda, 0x82, 0x50, 0x25, 0x16, 0x10, + 0x7e, 0x16, 0x65, 0x35, 0x71, 0x46, 0x61, 0x68, 0x62, 0xbb, 0x9e, 0x71, 0x02, 0x8a, 0xb2, 0x81, + 0x47, 0x60, 0xcb, 0x03, 0xb1, 0x44, 0xe2, 0x05, 0x50, 0xc5, 0x83, 0x20, 0x8f, 0x67, 0x1c, 0xc7, + 0x49, 0x11, 0x2b, 0xfb, 0xfc, 0xcc, 0xf9, 0xbe, 0xf3, 0xcd, 0x39, 0x36, 0x54, 0x39, 0x0d, 0x86, + 0x34, 0xb0, 0x89, 0xe3, 0x78, 0xa1, 0x2b, 0xf4, 0xf3, 0xd0, 0x0f, 0x3c, 0xe1, 0xa1, 0x15, 0x65, + 0x5a, 0xd5, 0x9e, 0xe7, 0xf5, 0xfa, 0xd4, 0x26, 0x3e, 0xb3, 0x89, 0xeb, 0x7a, 0x82, 0x08, 0xe6, + 0xb9, 0x3c, 0x4e, 0xc3, 0x23, 0xd8, 0x7a, 0xe5, 0x77, 0x89, 0xa0, 0xcf, 0x08, 0xe7, 0x23, 0x2f, + 0xe8, 0xb6, 0xe9, 0x65, 0x48, 0xb9, 0x40, 0x75, 0x28, 0xba, 0x74, 0xa4, 0xbd, 0xa6, 0x51, 0x37, + 0x1a, 0x6b, 0xed, 0xb4, 0x0b, 0x35, 0x60, 0xdd, 0x09, 0x83, 0x80, 0xba, 0x22, 0xc9, 0xca, 0xc9, + 0xac, 0xac, 0x1b, 0x21, 0x58, 0x72, 0xc9, 0x80, 0x9a, 0x79, 0x19, 0x96, 0xef, 0xd8, 0x84, 0x4a, + 0x16, 0x98, 0xfb, 0x9e, 0xcb, 0x29, 0x76, 0xa0, 0x78, 0x4a, 0xdc, 0x33, 0x4d, 0xc4, 0x82, 0xd5, + 0x80, 0x72, 0x2f, 0x0c, 0x1c, 0xaa, 0x58, 0x24, 0x36, 0xaa, 0xc0, 0x32, 0x71, 0xa2, 0x76, 0x14, + 0xb2, 0xb2, 0x22, 0xf2, 0x3c, 0xec, 0x24, 0xc7, 0x62, 0xdc, 0xb4, 0x0b, 0xef, 0x42, 0x29, 0x06, + 0x89, 0x41, 0xd1, 0x26, 0x14, 0x86, 0xa4, 0x1f, 0x6a, 0x88, 0xd8, 0xc0, 0xfb, 0xb0, 0xf1, 0x84, + 0x8a, 0xe3, 0x58, 0x49, 0x4d, 0x48, 0x77, 0x63, 0xa4, 0xba, 0xf9, 0x64, 0xc0, 0x8a, 0x4a, 0x5b, + 0x14, 0x47, 0x26, 0xac, 0x50, 0x97, 0x74, 0xfa, 0x34, 0xd6, 0x68, 0xb5, 0xad, 0x4d, 0x84, 0xa1, + 0xe4, 0x10, 0x9f, 0x74, 0x58, 0x9f, 0x09, 0x46, 0xb9, 0x99, 0xaf, 0xe7, 0x1b, 0x6b, 0xed, 0x19, + 0x1f, 0xda, 0x83, 0x65, 0xe1, 0x5d, 0x50, 0x97, 0x9b, 0x4b, 0xf5, 0x7c, 0xa3, 0xd8, 0x2a, 0x1f, + 0xea, 0xbb, 0x7e, 0x19, 0xb9, 0xdb, 0x2a, 0x8a, 0xef, 0x41, 0x49, 0x91, 0xe0, 0x4f, 0x19, 0x17, + 0x68, 0x0f, 0x0a, 0x4c, 0xd0, 0x01, 0x37, 0x0d, 0x79, 0xec, 0xef, 0xe4, 0x98, 0xee, 0x28, 0x0e, + 0xe3, 0xe7, 0x50, 0x90, 0x85, 0x50, 0x19, 0x72, 0x4c, 0xdf, 0x75, 0x8e, 0x75, 0x23, 0xed, 0x19, + 0xe7, 0x21, 0xed, 0x1e, 0x0b, 0xc9, 0x3b, 0xdf, 0x4e, 0x6c, 0x54, 0x85, 0x35, 0xfa, 0xde, 0x67, + 0x01, 0xe5, 0xc7, 0x42, 0x2a, 0x9c, 0x6f, 0x4f, 0x1d, 0xb8, 0x05, 0x20, 0x4b, 0xc6, 0x44, 0x76, + 0x67, 0x89, 0x64, 0xf9, 0x2b, 0x1a, 0xaf, 0x01, 0x9d, 0x06, 0x94, 0x08, 0x1a, 0x7b, 0xaf, 0x97, + 0x3b, 0x85, 0x7d, 0xe6, 0x2a, 0x62, 0x53, 0x87, 0xea, 0x22, 0xaf, 0xbb, 0xc0, 0xb7, 0xe0, 0x9f, + 0x99, 0xba, 0xd3, 0x2b, 0x97, 0xba, 0xe9, 0x2b, 0x97, 0x06, 0xbe, 0x0f, 0xe8, 0x11, 0xed, 0xd3, + 0x3f, 0x20, 0x11, 0xc3, 0xe4, 0x12, 0x98, 0x4d, 0x40, 0x51, 0xb3, 0xb3, 0xd3, 0x82, 0xd7, 0xe1, + 0xaf, 0xc7, 0x03, 0x5f, 0x7c, 0xd0, 0xb0, 0xad, 0x2f, 0x05, 0x28, 0xab, 0x9c, 0x17, 0x34, 0x18, + 0x32, 0x87, 0xa2, 0x11, 0x2c, 0x45, 0xc3, 0x88, 0x36, 0x13, 0x5d, 0x52, 0x0b, 0x60, 0x6d, 0x65, + 0xbc, 0x6a, 0x4d, 0x4e, 0x3e, 0x7e, 0xff, 0xf9, 0x39, 0xf7, 0x00, 0x1d, 0xc9, 0xcd, 0x1e, 0xde, + 0x4e, 0xbe, 0x03, 0x0e, 0x71, 0x0f, 0x98, 0x3d, 0xd6, 0xa3, 0x3e, 0xb1, 0xc7, 0xf1, 0x56, 0x4c, + 0xec, 0x71, 0x6a, 0x03, 0x1e, 0x36, 0x9b, 0x13, 0x34, 0x84, 0xf2, 0xec, 0x12, 0xa2, 0x5a, 0x02, + 0xb6, 0xf0, 0xb3, 0x60, 0xdd, 0xb8, 0x36, 0xae, 0x68, 0xed, 0x48, 0x5a, 0xff, 0x5b, 0x66, 0x96, + 0x96, 0xaf, 0x32, 0x8f, 0x8c, 0x26, 0x7a, 0x03, 0xa5, 0x94, 0x54, 0x1c, 0xfd, 0x97, 0x54, 0x9d, + 0x57, 0x30, 0xd5, 0x7f, 0x7a, 0xb8, 0xf1, 0xbf, 0x12, 0x68, 0x03, 0xad, 0x67, 0x80, 0xd0, 0x39, + 0xc0, 0x74, 0x69, 0x91, 0x95, 0x9c, 0x9e, 0xdb, 0x64, 0x6b, 0x6e, 0x21, 0x70, 0x4d, 0x16, 0x35, + 0x51, 0x25, 0xcb, 0x7e, 0x1c, 0x5d, 0xf9, 0x04, 0x5d, 0x42, 0x31, 0x35, 0x4a, 0x29, 0xde, 0xf3, + 0x83, 0x6b, 0x55, 0x17, 0x07, 0x95, 0x4e, 0xfb, 0x12, 0x69, 0x1b, 0x57, 0x17, 0x23, 0xd9, 0x72, + 0x1a, 0x23, 0xad, 0x06, 0x50, 0x4c, 0x0d, 0x64, 0x0a, 0x72, 0x7e, 0x4c, 0xad, 0x4a, 0x12, 0x9c, + 0x99, 0x39, 0x7c, 0x53, 0x82, 0xed, 0x34, 0xb7, 0x7f, 0x07, 0x66, 0x8f, 0x59, 0x77, 0x72, 0x72, + 0xf2, 0xf5, 0xaa, 0x66, 0x7c, 0xbb, 0xaa, 0x19, 0x3f, 0xae, 0x6a, 0xc6, 0xf9, 0xdd, 0x1e, 0x13, + 0x6f, 0xc3, 0xce, 0xa1, 0xe3, 0x0d, 0x6c, 0x12, 0xf4, 0x3c, 0x3f, 0xf0, 0xde, 0xc9, 0x97, 0x03, + 0xa7, 0x6b, 0x0f, 0x5b, 0xb6, 0x7f, 0xd1, 0x8b, 0x4a, 0x3a, 0x7d, 0x46, 0xa7, 0x7f, 0xa0, 0xce, + 0xb2, 0xfc, 0xb7, 0xdc, 0xf9, 0x15, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x62, 0xcc, 0x3d, 0xa2, 0x06, 0x00, 0x00, } diff --git a/pkg/apiclient/apiclient.go b/pkg/apiclient/apiclient.go index 12c1d92d4f..76a3acffb2 100644 --- a/pkg/apiclient/apiclient.go +++ b/pkg/apiclient/apiclient.go @@ -16,9 +16,10 @@ import ( "time" "github.com/coreos/go-oidc/v3/oidc" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" "github.com/golang/protobuf/ptypes/empty" - grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/retry" + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry" "github.com/hashicorp/go-retryablehttp" log "github.com/sirupsen/logrus" "golang.org/x/oauth2" @@ -29,30 +30,30 @@ import ( "google.golang.org/grpc/status" "k8s.io/client-go/tools/clientcmd" - "github.com/argoproj/argo-cd/v3/common" - accountpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/account" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - applicationsetpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/applicationset" - certificatepkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/certificate" - clusterpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster" - gpgkeypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/gpgkey" - notificationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/notification" - projectpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/project" - repocredspkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repocreds" - repositorypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repository" - sessionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" - settingspkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/settings" - versionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/version" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/env" - grpc_util "github.com/argoproj/argo-cd/v3/util/grpc" - http_util "github.com/argoproj/argo-cd/v3/util/http" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/kube" - "github.com/argoproj/argo-cd/v3/util/localconfig" - oidcutil "github.com/argoproj/argo-cd/v3/util/oidc" - tls_util "github.com/argoproj/argo-cd/v3/util/tls" + "github.com/argoproj/argo-cd/v2/common" + accountpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/account" + applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + applicationsetpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/applicationset" + certificatepkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/certificate" + clusterpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster" + gpgkeypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/gpgkey" + notificationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/notification" + projectpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/project" + repocredspkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repocreds" + repositorypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository" + sessionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" + settingspkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/settings" + versionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/version" + "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/env" + grpc_util "github.com/argoproj/argo-cd/v2/util/grpc" + http_util "github.com/argoproj/argo-cd/v2/util/http" + argoio "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/kube" + "github.com/argoproj/argo-cd/v2/util/localconfig" + oidcutil "github.com/argoproj/argo-cd/v2/util/oidc" + tls_util "github.com/argoproj/argo-cd/v2/util/tls" ) const ( @@ -118,7 +119,7 @@ type ClientOptions struct { PortForward bool PortForwardNamespace string Headers []string - HttpRetryMax int //nolint:revive //FIXME(var-naming) + HttpRetryMax int KubeOverrides *clientcmd.ConfigOverrides AppControllerName string ServerName string @@ -221,7 +222,6 @@ func NewClient(opts *ClientOptions) (Client, error) { } // Make sure we got the server address and auth token from somewhere if c.ServerAddr == "" { - //nolint:staticcheck // First letter of error is intentionally capitalized. return nil, errors.New("Argo CD server address unspecified") } // Override auth-token if specified in env variable or CLI flag @@ -287,13 +287,13 @@ func NewClient(opts *ClientOptions) (Client, error) { // if a call to grpc failed, then try again with GRPCWeb conn, versionIf, err := c.NewVersionClient() if err == nil { - defer utilio.Close(conn) + defer argoio.Close(conn) _, err = versionIf.Version(context.Background(), &empty.Empty{}) } if err != nil { c.GRPCWeb = true conn, versionIf := c.NewVersionClientOrDie() - defer utilio.Close(conn) + defer argoio.Close(conn) _, err := versionIf.Version(context.Background(), &empty.Empty{}) if err == nil { @@ -320,30 +320,29 @@ func (c *client) OIDCConfig(ctx context.Context, set *settingspkg.Settings) (*oa var clientID string var issuerURL string var scopes []string - switch { - case set.OIDCConfig != nil && set.OIDCConfig.Issuer != "": + if set.OIDCConfig != nil && set.OIDCConfig.Issuer != "" { if set.OIDCConfig.CLIClientID != "" { clientID = set.OIDCConfig.CLIClientID } else { clientID = set.OIDCConfig.ClientID } issuerURL = set.OIDCConfig.Issuer - scopes = oidcutil.GetScopesOrDefault(set.OIDCConfig.Scopes) - case set.DexConfig != nil && len(set.DexConfig.Connectors) > 0: + scopes = set.OIDCConfig.Scopes + } else if set.DexConfig != nil && len(set.DexConfig.Connectors) > 0 { clientID = common.ArgoCDCLIClientAppID - scopes = append(oidcutil.GetScopesOrDefault(nil), common.DexFederatedScope) issuerURL = fmt.Sprintf("%s%s", set.URL, common.DexAPIEndpoint) - default: + } else { return nil, nil, fmt.Errorf("%s is not configured with SSO", c.ServerAddr) } provider, err := oidc.NewProvider(ctx, issuerURL) if err != nil { - return nil, nil, fmt.Errorf("failed to query provider %q: %w", issuerURL, err) + return nil, nil, fmt.Errorf("Failed to query provider %q: %w", issuerURL, err) } oidcConf, err := oidcutil.ParseConfig(provider) if err != nil { - return nil, nil, fmt.Errorf("failed to parse provider config: %w", err) + return nil, nil, fmt.Errorf("Failed to parse provider config: %w", err) } + scopes = oidcutil.GetScopesOrDefault(scopes) if oidcutil.OfflineAccess(oidcConf.ScopesSupported) { scopes = append(scopes, oidc.ScopeOfflineAccess) } @@ -404,8 +403,7 @@ func (c *client) refreshAuthToken(localCfg *localconfig.LocalConfig, ctxName, co if err != nil { return err } - validator := jwt.NewValidator() - if validator.Validate(claims) == nil { + if claims.Valid() == nil { // token is still valid return nil } @@ -523,7 +521,7 @@ func (c *client) newConn() (*grpc.ClientConn, io.Closer, error) { dialOpts = append(dialOpts, grpc.WithPerRPCCredentials(endpointCredentials)) dialOpts = append(dialOpts, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(MaxGRPCMessageSize), grpc.MaxCallSendMsgSize(MaxGRPCMessageSize))) dialOpts = append(dialOpts, grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(retryOpts...))) - dialOpts = append(dialOpts, grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(retryOpts...))) + dialOpts = append(dialOpts, grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(grpc_retry.UnaryClientInterceptor(retryOpts...)))) dialOpts = append(dialOpts, grpc.WithUnaryInterceptor(grpc_util.OTELUnaryClientInterceptor())) dialOpts = append(dialOpts, grpc.WithStreamInterceptor(grpc_util.OTELStreamClientInterceptor())) @@ -544,7 +542,7 @@ func (c *client) newConn() (*grpc.ClientConn, io.Closer, error) { } conn, e := grpc_util.BlockingDial(ctx, network, serverAddr, creds, dialOpts...) closers = append(closers, conn) - return conn, utilio.NewCloser(func() error { + return conn, argoio.NewCloser(func() error { var firstErr error for i := range closers { err := closers[i].Close() @@ -561,7 +559,7 @@ func (c *client) tlsConfig() (*tls.Config, error) { if len(c.CertPEMData) > 0 { cp := tls_util.BestEffortSystemCertPool() if !cp.AppendCertsFromPEM(c.CertPEMData) { - return nil, errors.New("credentials: failed to append certificates") + return nil, fmt.Errorf("credentials: failed to append certificates") } tlsConfig.RootCAs = cp } diff --git a/pkg/apiclient/apiclient_test.go b/pkg/apiclient/apiclient_test.go index 8fabaa8fb9..221b20eb07 100644 --- a/pkg/apiclient/apiclient_test.go +++ b/pkg/apiclient/apiclient_test.go @@ -12,7 +12,7 @@ func Test_parseHeaders(t *testing.T) { headerString := []string{"foo:", "foo1:bar1", "foo2:bar2:bar2"} headers, err := parseHeaders(headerString) require.NoError(t, err) - assert.Empty(t, headers.Get("foo")) + assert.Equal(t, "", headers.Get("foo")) assert.Equal(t, "bar1", headers.Get("foo1")) assert.Equal(t, "bar2:bar2", headers.Get("foo2")) }) diff --git a/pkg/apiclient/application/application.pb.go b/pkg/apiclient/application/application.pb.go index 8b72807e85..2f73469d10 100644 --- a/pkg/apiclient/application/application.pb.go +++ b/pkg/apiclient/application/application.pb.go @@ -10,8 +10,8 @@ package application import ( context "context" fmt "fmt" - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - apiclient "github.com/argoproj/argo-cd/v3/reposerver/apiclient" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + apiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" @@ -1717,82 +1717,26 @@ func (m *ApplicationResourceDeleteRequest) GetProject() string { return "" } -type ResourceActionParameters struct { +type ResourceActionRunRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` - Value *string `protobuf:"bytes,2,req,name=value" json:"value,omitempty"` + Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` + ResourceName *string `protobuf:"bytes,3,req,name=resourceName" json:"resourceName,omitempty"` + Version *string `protobuf:"bytes,4,req,name=version" json:"version,omitempty"` + Group *string `protobuf:"bytes,5,opt,name=group" json:"group,omitempty"` + Kind *string `protobuf:"bytes,6,req,name=kind" json:"kind,omitempty"` + Action *string `protobuf:"bytes,7,req,name=action" json:"action,omitempty"` + AppNamespace *string `protobuf:"bytes,8,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,9,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } -func (m *ResourceActionParameters) Reset() { *m = ResourceActionParameters{} } -func (m *ResourceActionParameters) String() string { return proto.CompactTextString(m) } -func (*ResourceActionParameters) ProtoMessage() {} -func (*ResourceActionParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{20} -} -func (m *ResourceActionParameters) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceActionParameters) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ResourceActionParameters.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ResourceActionParameters) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceActionParameters.Merge(m, src) -} -func (m *ResourceActionParameters) XXX_Size() int { - return m.Size() -} -func (m *ResourceActionParameters) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceActionParameters.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceActionParameters proto.InternalMessageInfo - -func (m *ResourceActionParameters) GetName() string { - if m != nil && m.Name != nil { - return *m.Name - } - return "" -} - -func (m *ResourceActionParameters) GetValue() string { - if m != nil && m.Value != nil { - return *m.Value - } - return "" -} - -type ResourceActionRunRequest struct { - Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` - Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` - ResourceName *string `protobuf:"bytes,3,req,name=resourceName" json:"resourceName,omitempty"` - Version *string `protobuf:"bytes,4,req,name=version" json:"version,omitempty"` - Group *string `protobuf:"bytes,5,opt,name=group" json:"group,omitempty"` - Kind *string `protobuf:"bytes,6,req,name=kind" json:"kind,omitempty"` - Action *string `protobuf:"bytes,7,req,name=action" json:"action,omitempty"` - AppNamespace *string `protobuf:"bytes,8,opt,name=appNamespace" json:"appNamespace,omitempty"` - Project *string `protobuf:"bytes,9,opt,name=project" json:"project,omitempty"` - ResourceActionParameters []*ResourceActionParameters `protobuf:"bytes,10,rep,name=resourceActionParameters" json:"resourceActionParameters,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - func (m *ResourceActionRunRequest) Reset() { *m = ResourceActionRunRequest{} } func (m *ResourceActionRunRequest) String() string { return proto.CompactTextString(m) } func (*ResourceActionRunRequest) ProtoMessage() {} func (*ResourceActionRunRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{21} + return fileDescriptor_df6e82b174b5eaec, []int{20} } func (m *ResourceActionRunRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1884,13 +1828,6 @@ func (m *ResourceActionRunRequest) GetProject() string { return "" } -func (m *ResourceActionRunRequest) GetResourceActionParameters() []*ResourceActionParameters { - if m != nil { - return m.ResourceActionParameters - } - return nil -} - type ResourceActionsListResponse struct { Actions []*v1alpha1.ResourceAction `protobuf:"bytes,1,rep,name=actions" json:"actions,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -1902,7 +1839,7 @@ func (m *ResourceActionsListResponse) Reset() { *m = ResourceActionsList func (m *ResourceActionsListResponse) String() string { return proto.CompactTextString(m) } func (*ResourceActionsListResponse) ProtoMessage() {} func (*ResourceActionsListResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{22} + return fileDescriptor_df6e82b174b5eaec, []int{21} } func (m *ResourceActionsListResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1949,7 +1886,7 @@ func (m *ApplicationResourceResponse) Reset() { *m = ApplicationResource func (m *ApplicationResourceResponse) String() string { return proto.CompactTextString(m) } func (*ApplicationResourceResponse) ProtoMessage() {} func (*ApplicationResourceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{23} + return fileDescriptor_df6e82b174b5eaec, []int{22} } func (m *ApplicationResourceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2002,7 +1939,6 @@ type ApplicationPodLogsQuery struct { Previous *bool `protobuf:"varint,14,opt,name=previous" json:"previous,omitempty"` AppNamespace *string `protobuf:"bytes,15,opt,name=appNamespace" json:"appNamespace,omitempty"` Project *string `protobuf:"bytes,16,opt,name=project" json:"project,omitempty"` - MatchCase *bool `protobuf:"varint,17,opt,name=matchCase" json:"matchCase,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -2012,7 +1948,7 @@ func (m *ApplicationPodLogsQuery) Reset() { *m = ApplicationPodLogsQuery func (m *ApplicationPodLogsQuery) String() string { return proto.CompactTextString(m) } func (*ApplicationPodLogsQuery) ProtoMessage() {} func (*ApplicationPodLogsQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{24} + return fileDescriptor_df6e82b174b5eaec, []int{23} } func (m *ApplicationPodLogsQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2153,13 +2089,6 @@ func (m *ApplicationPodLogsQuery) GetProject() string { return "" } -func (m *ApplicationPodLogsQuery) GetMatchCase() bool { - if m != nil && m.MatchCase != nil { - return *m.MatchCase - } - return false -} - type LogEntry struct { Content *string `protobuf:"bytes,1,req,name=content" json:"content,omitempty"` // deprecated in favor of timeStampStr since meta.v1.Time don't support nano time @@ -2176,7 +2105,7 @@ func (m *LogEntry) Reset() { *m = LogEntry{} } func (m *LogEntry) String() string { return proto.CompactTextString(m) } func (*LogEntry) ProtoMessage() {} func (*LogEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{25} + return fileDescriptor_df6e82b174b5eaec, []int{24} } func (m *LogEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2253,7 +2182,7 @@ func (m *OperationTerminateRequest) Reset() { *m = OperationTerminateReq func (m *OperationTerminateRequest) String() string { return proto.CompactTextString(m) } func (*OperationTerminateRequest) ProtoMessage() {} func (*OperationTerminateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{26} + return fileDescriptor_df6e82b174b5eaec, []int{25} } func (m *OperationTerminateRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2316,7 +2245,7 @@ func (m *ApplicationSyncWindowsQuery) Reset() { *m = ApplicationSyncWind func (m *ApplicationSyncWindowsQuery) String() string { return proto.CompactTextString(m) } func (*ApplicationSyncWindowsQuery) ProtoMessage() {} func (*ApplicationSyncWindowsQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{27} + return fileDescriptor_df6e82b174b5eaec, []int{26} } func (m *ApplicationSyncWindowsQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2379,7 +2308,7 @@ func (m *ApplicationSyncWindowsResponse) Reset() { *m = ApplicationSyncW func (m *ApplicationSyncWindowsResponse) String() string { return proto.CompactTextString(m) } func (*ApplicationSyncWindowsResponse) ProtoMessage() {} func (*ApplicationSyncWindowsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{28} + return fileDescriptor_df6e82b174b5eaec, []int{27} } func (m *ApplicationSyncWindowsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2443,7 +2372,7 @@ func (m *ApplicationSyncWindow) Reset() { *m = ApplicationSyncWindow{} } func (m *ApplicationSyncWindow) String() string { return proto.CompactTextString(m) } func (*ApplicationSyncWindow) ProtoMessage() {} func (*ApplicationSyncWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{29} + return fileDescriptor_df6e82b174b5eaec, []int{28} } func (m *ApplicationSyncWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2510,7 +2439,7 @@ func (m *OperationTerminateResponse) Reset() { *m = OperationTerminateRe func (m *OperationTerminateResponse) String() string { return proto.CompactTextString(m) } func (*OperationTerminateResponse) ProtoMessage() {} func (*OperationTerminateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{30} + return fileDescriptor_df6e82b174b5eaec, []int{29} } func (m *OperationTerminateResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2557,7 +2486,7 @@ func (m *ResourcesQuery) Reset() { *m = ResourcesQuery{} } func (m *ResourcesQuery) String() string { return proto.CompactTextString(m) } func (*ResourcesQuery) ProtoMessage() {} func (*ResourcesQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{31} + return fileDescriptor_df6e82b174b5eaec, []int{30} } func (m *ResourcesQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2653,7 +2582,7 @@ func (m *ManagedResourcesResponse) Reset() { *m = ManagedResourcesRespon func (m *ManagedResourcesResponse) String() string { return proto.CompactTextString(m) } func (*ManagedResourcesResponse) ProtoMessage() {} func (*ManagedResourcesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{32} + return fileDescriptor_df6e82b174b5eaec, []int{31} } func (m *ManagedResourcesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2703,7 +2632,7 @@ func (m *LinkInfo) Reset() { *m = LinkInfo{} } func (m *LinkInfo) String() string { return proto.CompactTextString(m) } func (*LinkInfo) ProtoMessage() {} func (*LinkInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{33} + return fileDescriptor_df6e82b174b5eaec, []int{32} } func (m *LinkInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2771,7 +2700,7 @@ func (m *LinksResponse) Reset() { *m = LinksResponse{} } func (m *LinksResponse) String() string { return proto.CompactTextString(m) } func (*LinksResponse) ProtoMessage() {} func (*LinksResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{34} + return fileDescriptor_df6e82b174b5eaec, []int{33} } func (m *LinksResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2820,7 +2749,7 @@ func (m *ListAppLinksRequest) Reset() { *m = ListAppLinksRequest{} } func (m *ListAppLinksRequest) String() string { return proto.CompactTextString(m) } func (*ListAppLinksRequest) ProtoMessage() {} func (*ListAppLinksRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{35} + return fileDescriptor_df6e82b174b5eaec, []int{34} } func (m *ListAppLinksRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2891,7 +2820,6 @@ func init() { proto.RegisterType((*ApplicationResourceRequest)(nil), "application.ApplicationResourceRequest") proto.RegisterType((*ApplicationResourcePatchRequest)(nil), "application.ApplicationResourcePatchRequest") proto.RegisterType((*ApplicationResourceDeleteRequest)(nil), "application.ApplicationResourceDeleteRequest") - proto.RegisterType((*ResourceActionParameters)(nil), "application.ResourceActionParameters") proto.RegisterType((*ResourceActionRunRequest)(nil), "application.ResourceActionRunRequest") proto.RegisterType((*ResourceActionsListResponse)(nil), "application.ResourceActionsListResponse") proto.RegisterType((*ApplicationResourceResponse)(nil), "application.ApplicationResourceResponse") @@ -2914,183 +2842,179 @@ func init() { } var fileDescriptor_df6e82b174b5eaec = []byte{ - // 2801 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x4d, 0x8c, 0x1c, 0x47, - 0x15, 0xa6, 0x66, 0x76, 0x76, 0x67, 0xdf, 0xec, 0x7a, 0xed, 0x8a, 0xbd, 0x74, 0xc6, 0x1b, 0x33, - 0x69, 0xdb, 0xf1, 0x64, 0xed, 0x9d, 0xb1, 0x37, 0x01, 0x92, 0x4d, 0x22, 0x70, 0xd6, 0x8e, 0xb3, - 0xb0, 0x76, 0x4c, 0xaf, 0x83, 0x51, 0x38, 0x40, 0xa5, 0xbb, 0x76, 0xa6, 0xd9, 0x9e, 0xee, 0x76, - 0x77, 0xcf, 0x84, 0x55, 0xc8, 0x25, 0x88, 0x5b, 0x04, 0x02, 0x82, 0xc4, 0x01, 0x01, 0x4a, 0x14, - 0x09, 0x21, 0x10, 0x17, 0x84, 0x90, 0x10, 0x12, 0x1c, 0x40, 0x70, 0x40, 0x8a, 0x40, 0xe2, 0x8c, - 0x22, 0xc4, 0x0d, 0xb8, 0xe4, 0x8c, 0x50, 0x55, 0x57, 0x75, 0x57, 0xcf, 0x4f, 0xcf, 0x2c, 0x33, - 0x28, 0xbe, 0xf5, 0xab, 0xa9, 0x7a, 0xef, 0x7b, 0xaf, 0x5e, 0xbd, 0xf7, 0xea, 0xd5, 0xc0, 0xb9, - 0x90, 0x06, 0x3d, 0x1a, 0x34, 0x89, 0xef, 0x3b, 0xb6, 0x49, 0x22, 0xdb, 0x73, 0xd5, 0xef, 0x86, - 0x1f, 0x78, 0x91, 0x87, 0x2b, 0xca, 0x50, 0x75, 0xad, 0xe5, 0x79, 0x2d, 0x87, 0x36, 0x89, 0x6f, - 0x37, 0x89, 0xeb, 0x7a, 0x11, 0x1f, 0x0e, 0xe3, 0xa9, 0x55, 0xfd, 0xe0, 0x89, 0xb0, 0x61, 0x7b, - 0xfc, 0x57, 0xd3, 0x0b, 0x68, 0xb3, 0x77, 0xa5, 0xd9, 0xa2, 0x2e, 0x0d, 0x48, 0x44, 0x2d, 0x31, - 0xe7, 0xf1, 0x74, 0x4e, 0x87, 0x98, 0x6d, 0xdb, 0xa5, 0xc1, 0x61, 0xd3, 0x3f, 0x68, 0xb1, 0x81, - 0xb0, 0xd9, 0xa1, 0x11, 0x19, 0xb6, 0x6a, 0xb7, 0x65, 0x47, 0xed, 0xee, 0xcb, 0x0d, 0xd3, 0xeb, - 0x34, 0x49, 0xd0, 0xf2, 0xfc, 0xc0, 0xfb, 0x12, 0xff, 0xd8, 0x30, 0xad, 0x66, 0xef, 0xb1, 0x94, - 0x81, 0xaa, 0x4b, 0xef, 0x0a, 0x71, 0xfc, 0x36, 0x19, 0xe4, 0x76, 0x7d, 0x0c, 0xb7, 0x80, 0xfa, - 0x9e, 0xb0, 0x0d, 0xff, 0xb4, 0x23, 0x2f, 0x38, 0x54, 0x3e, 0x63, 0x36, 0xfa, 0xfb, 0x08, 0x8e, - 0x5f, 0x4d, 0xe5, 0x7d, 0xa6, 0x4b, 0x83, 0x43, 0x8c, 0x61, 0xce, 0x25, 0x1d, 0xaa, 0xa1, 0x1a, - 0xaa, 0x2f, 0x1a, 0xfc, 0x1b, 0x6b, 0xb0, 0x10, 0xd0, 0xfd, 0x80, 0x86, 0x6d, 0xad, 0xc0, 0x87, - 0x25, 0x89, 0xab, 0x50, 0x66, 0xc2, 0xa9, 0x19, 0x85, 0x5a, 0xb1, 0x56, 0xac, 0x2f, 0x1a, 0x09, - 0x8d, 0xeb, 0xb0, 0x12, 0xd0, 0xd0, 0xeb, 0x06, 0x26, 0xfd, 0x2c, 0x0d, 0x42, 0xdb, 0x73, 0xb5, - 0x39, 0xbe, 0xba, 0x7f, 0x98, 0x71, 0x09, 0xa9, 0x43, 0xcd, 0xc8, 0x0b, 0xb4, 0x12, 0x9f, 0x92, - 0xd0, 0x0c, 0x0f, 0x03, 0xae, 0xcd, 0xc7, 0x78, 0xd8, 0x37, 0xd6, 0x61, 0x89, 0xf8, 0xfe, 0x2d, - 0xd2, 0xa1, 0xa1, 0x4f, 0x4c, 0xaa, 0x2d, 0xf0, 0xdf, 0x32, 0x63, 0x0c, 0xb3, 0x40, 0xa2, 0x95, - 0x39, 0x30, 0x49, 0xea, 0xdb, 0xb0, 0x78, 0xcb, 0xb3, 0xe8, 0x68, 0x75, 0xfb, 0xd9, 0x17, 0x06, - 0xd9, 0xeb, 0xbf, 0x43, 0x70, 0xca, 0xa0, 0x3d, 0x9b, 0xe1, 0xbf, 0x49, 0x23, 0x62, 0x91, 0x88, - 0xf4, 0x73, 0x2c, 0x24, 0x1c, 0xab, 0x50, 0x0e, 0xc4, 0x64, 0xad, 0xc0, 0xc7, 0x13, 0x7a, 0x40, - 0x5a, 0x31, 0x5f, 0x99, 0xd8, 0x84, 0x92, 0xc4, 0x35, 0xa8, 0xc4, 0xb6, 0xdc, 0x71, 0x2d, 0xfa, - 0x65, 0x6e, 0xbd, 0x92, 0xa1, 0x0e, 0xe1, 0x35, 0x58, 0xec, 0xc5, 0x76, 0xde, 0xb1, 0xb8, 0x15, - 0x4b, 0x46, 0x3a, 0xa0, 0xff, 0x03, 0xc1, 0x19, 0xc5, 0x07, 0x0c, 0xb1, 0x33, 0xd7, 0x7b, 0xd4, - 0x8d, 0xc2, 0xd1, 0x0a, 0x5d, 0x82, 0x13, 0x72, 0x13, 0xfb, 0xed, 0x34, 0xf8, 0x03, 0x53, 0x51, - 0x1d, 0x94, 0x2a, 0xaa, 0x63, 0x4c, 0x11, 0x49, 0xbf, 0xb8, 0x73, 0x4d, 0xa8, 0xa9, 0x0e, 0x0d, - 0x18, 0xaa, 0x94, 0x6f, 0xa8, 0xf9, 0x8c, 0xa1, 0xf4, 0x77, 0x11, 0x68, 0x8a, 0xa2, 0x37, 0x89, - 0x6b, 0xef, 0xd3, 0x30, 0x9a, 0x74, 0xcf, 0xd0, 0x0c, 0xf7, 0xac, 0x0e, 0x2b, 0xb1, 0x56, 0xb7, - 0xd9, 0x79, 0x64, 0xf1, 0x47, 0x2b, 0xd5, 0x8a, 0xf5, 0xa2, 0xd1, 0x3f, 0xcc, 0xf6, 0x4e, 0xca, - 0x0c, 0xb5, 0x79, 0xee, 0xc6, 0xe9, 0x80, 0xfe, 0x30, 0x2c, 0x3e, 0x67, 0x3b, 0x74, 0xbb, 0xdd, - 0x75, 0x0f, 0xf0, 0x49, 0x28, 0x99, 0xec, 0x83, 0xeb, 0xb0, 0x64, 0xc4, 0x84, 0xfe, 0x4d, 0x04, - 0x0f, 0x8f, 0xd2, 0xfa, 0xae, 0x1d, 0xb5, 0xd9, 0xfa, 0x70, 0x94, 0xfa, 0x66, 0x9b, 0x9a, 0x07, - 0x61, 0xb7, 0x23, 0x5d, 0x56, 0xd2, 0xd3, 0xa9, 0xaf, 0xff, 0x18, 0x41, 0x7d, 0x2c, 0xa6, 0xbb, - 0x01, 0xf1, 0x7d, 0x1a, 0xe0, 0xe7, 0xa0, 0x74, 0x8f, 0xfd, 0xc0, 0x0f, 0x68, 0x65, 0xb3, 0xd1, - 0x50, 0x03, 0xfc, 0x58, 0x2e, 0xcf, 0x7f, 0xc8, 0x88, 0x97, 0xe3, 0x86, 0x34, 0x4f, 0x81, 0xf3, - 0x59, 0xcd, 0xf0, 0x49, 0xac, 0xc8, 0xe6, 0xf3, 0x69, 0xcf, 0xce, 0xc3, 0x9c, 0x4f, 0x82, 0x48, - 0x3f, 0x05, 0x0f, 0x64, 0x8f, 0x87, 0xef, 0xb9, 0x21, 0xd5, 0x7f, 0x95, 0xf5, 0xa6, 0xed, 0x80, - 0x92, 0x88, 0x1a, 0xf4, 0x5e, 0x97, 0x86, 0x11, 0x3e, 0x00, 0x35, 0xe7, 0x70, 0xab, 0x56, 0x36, - 0x77, 0x1a, 0x69, 0xd0, 0x6e, 0xc8, 0xa0, 0xcd, 0x3f, 0xbe, 0x60, 0x5a, 0x8d, 0xde, 0x63, 0x0d, - 0xff, 0xa0, 0xd5, 0x60, 0x29, 0x20, 0x83, 0x4c, 0xa6, 0x00, 0x55, 0x55, 0x43, 0xe5, 0x8e, 0x57, - 0x61, 0xbe, 0xeb, 0x87, 0x34, 0x88, 0xb8, 0x66, 0x65, 0x43, 0x50, 0x6c, 0xff, 0x7a, 0xc4, 0xb1, - 0x2d, 0x12, 0xc5, 0xfb, 0x53, 0x36, 0x12, 0x5a, 0xff, 0x75, 0x16, 0xfd, 0x8b, 0xbe, 0xf5, 0x41, - 0xa1, 0x57, 0x51, 0x16, 0xb2, 0x28, 0x55, 0x0f, 0x2a, 0x66, 0x3d, 0xe8, 0xe7, 0x59, 0xfc, 0xd7, - 0xa8, 0x43, 0x53, 0xfc, 0xc3, 0x9c, 0x59, 0x83, 0x05, 0x93, 0x84, 0x26, 0xb1, 0xa4, 0x14, 0x49, - 0xb2, 0x40, 0xe6, 0x07, 0x9e, 0x4f, 0x5a, 0x9c, 0xd3, 0x6d, 0xcf, 0xb1, 0xcd, 0x43, 0x21, 0x6e, - 0xf0, 0x87, 0x01, 0xc7, 0x9f, 0xcb, 0x77, 0xfc, 0x52, 0x16, 0xf6, 0x59, 0xa8, 0xec, 0x1d, 0xba, - 0xe6, 0x0b, 0x7e, 0x7c, 0xb8, 0x4f, 0x42, 0xc9, 0x8e, 0x68, 0x27, 0xd4, 0x10, 0x3f, 0xd8, 0x31, - 0xa1, 0xff, 0xa7, 0x04, 0xab, 0x8a, 0x6e, 0x6c, 0x41, 0x9e, 0x66, 0x79, 0x51, 0x6a, 0x15, 0xe6, - 0xad, 0xe0, 0xd0, 0xe8, 0xba, 0xc2, 0x01, 0x04, 0xc5, 0x04, 0xfb, 0x41, 0xd7, 0x8d, 0xe1, 0x97, - 0x8d, 0x98, 0xc0, 0xfb, 0x50, 0x0e, 0x23, 0x56, 0x65, 0xb4, 0x0e, 0x39, 0xf0, 0xca, 0xe6, 0xa7, - 0xa6, 0xdb, 0x74, 0x06, 0x7d, 0x4f, 0x70, 0x34, 0x12, 0xde, 0xf8, 0x1e, 0x8b, 0x69, 0x71, 0xa0, - 0x0b, 0xb5, 0x85, 0x5a, 0xb1, 0x5e, 0xd9, 0xdc, 0x9b, 0x5e, 0xd0, 0x0b, 0x3e, 0xab, 0x90, 0x94, - 0x0c, 0x66, 0xa4, 0x52, 0x58, 0x18, 0xed, 0x88, 0xf8, 0x10, 0x8a, 0x6a, 0x20, 0x1d, 0xc0, 0x9f, - 0x83, 0x92, 0xed, 0xee, 0x7b, 0xa1, 0xb6, 0xc8, 0xc1, 0x3c, 0x3b, 0x1d, 0x98, 0x1d, 0x77, 0xdf, - 0x33, 0x62, 0x86, 0xf8, 0x1e, 0x2c, 0x07, 0x34, 0x0a, 0x0e, 0xa5, 0x15, 0x34, 0xe0, 0x76, 0xfd, - 0xf4, 0x74, 0x12, 0x0c, 0x95, 0xa5, 0x91, 0x95, 0x80, 0xb7, 0xa0, 0x12, 0xa6, 0x3e, 0xa6, 0x55, - 0xb8, 0x40, 0x2d, 0xc3, 0x48, 0xf1, 0x41, 0x43, 0x9d, 0x3c, 0xe0, 0xdd, 0x4b, 0xf9, 0xde, 0xbd, - 0x3c, 0x36, 0xab, 0x1d, 0x9b, 0x20, 0xab, 0xad, 0xf4, 0x67, 0xb5, 0x7f, 0x23, 0x58, 0x1b, 0x08, - 0x4e, 0x7b, 0x3e, 0xcd, 0x3d, 0x06, 0x04, 0xe6, 0x42, 0x9f, 0x9a, 0x3c, 0x53, 0x55, 0x36, 0x6f, - 0xce, 0x2c, 0x5a, 0x71, 0xb9, 0x9c, 0x75, 0x5e, 0x40, 0x9d, 0x32, 0x2e, 0xfc, 0x00, 0xc1, 0x87, - 0x15, 0x99, 0xb7, 0x49, 0x64, 0xb6, 0xf3, 0x94, 0x65, 0xe7, 0x97, 0xcd, 0x11, 0x79, 0x39, 0x26, - 0x98, 0x55, 0xf9, 0xc7, 0x9d, 0x43, 0x9f, 0x01, 0x64, 0xbf, 0xa4, 0x03, 0x53, 0x16, 0x4f, 0x3f, - 0x41, 0x50, 0x55, 0x63, 0xb8, 0xe7, 0x38, 0x2f, 0x13, 0xf3, 0x20, 0x0f, 0xe4, 0x31, 0x28, 0xd8, - 0x16, 0x47, 0x58, 0x34, 0x0a, 0xb6, 0x75, 0xc4, 0x60, 0xd4, 0x0f, 0x77, 0x3e, 0x1f, 0xee, 0x42, - 0x16, 0xee, 0xfb, 0x7d, 0x70, 0x65, 0x48, 0xc8, 0x81, 0xbb, 0x06, 0x8b, 0x6e, 0x5f, 0x21, 0x9b, - 0x0e, 0x0c, 0x29, 0x60, 0x0b, 0x03, 0x05, 0xac, 0x06, 0x0b, 0xbd, 0xe4, 0x9a, 0xc3, 0x7e, 0x96, - 0x24, 0x53, 0xb1, 0x15, 0x78, 0x5d, 0x5f, 0x18, 0x3d, 0x26, 0x18, 0x8a, 0x03, 0xdb, 0x65, 0x25, - 0x39, 0x47, 0xc1, 0xbe, 0x8f, 0x7e, 0xb1, 0xc9, 0xa8, 0xfd, 0xd3, 0x02, 0x7c, 0x64, 0x88, 0xda, - 0x63, 0xfd, 0xe9, 0xfe, 0xd0, 0x3d, 0xf1, 0xea, 0x85, 0x91, 0x5e, 0x5d, 0x1e, 0xe7, 0xd5, 0x8b, - 0xf9, 0xf6, 0x82, 0xac, 0xbd, 0x7e, 0x54, 0x80, 0xda, 0x10, 0x7b, 0x8d, 0x2f, 0x27, 0xee, 0x1b, - 0x83, 0xed, 0x7b, 0x81, 0xf0, 0x92, 0xb2, 0x11, 0x13, 0xec, 0x9c, 0x79, 0x81, 0xdf, 0x26, 0x2e, - 0xf7, 0x8e, 0xb2, 0x21, 0xa8, 0x29, 0x4d, 0x75, 0x0d, 0x34, 0x69, 0x9e, 0xab, 0x66, 0x1c, 0xa4, - 0x02, 0xd2, 0xa1, 0x11, 0x0d, 0xc2, 0x51, 0x21, 0xaa, 0x47, 0x9c, 0x2e, 0x95, 0x21, 0x8a, 0x13, - 0xfa, 0x3f, 0x0b, 0xfd, 0x6c, 0x8c, 0xae, 0x7b, 0xff, 0x1b, 0x7a, 0x15, 0xe6, 0x09, 0x47, 0x2b, - 0x5c, 0x53, 0x50, 0x03, 0x26, 0x2d, 0xe7, 0x9b, 0x74, 0x31, 0x9b, 0x2f, 0x09, 0x68, 0xc1, 0x08, - 0x93, 0x6a, 0xc0, 0x2b, 0x91, 0xf3, 0x99, 0xf4, 0x34, 0xca, 0xfe, 0xc6, 0x48, 0x36, 0xfa, 0xd7, - 0x10, 0x9c, 0xce, 0x2e, 0x0b, 0x77, 0xed, 0x30, 0x92, 0xb7, 0x18, 0xbc, 0x0f, 0x0b, 0xb1, 0x2a, - 0x71, 0x0d, 0x5a, 0xd9, 0xdc, 0x9d, 0xb6, 0x32, 0xc9, 0xec, 0xad, 0x64, 0xae, 0x3f, 0x09, 0xa7, - 0x87, 0x86, 0x63, 0x01, 0xa3, 0x0a, 0x65, 0x59, 0x8d, 0x89, 0xdd, 0x4f, 0x68, 0xfd, 0xed, 0xb9, - 0x6c, 0x6e, 0xf4, 0xac, 0x5d, 0xaf, 0x95, 0xd3, 0x98, 0xc8, 0xf7, 0x18, 0xb6, 0x1b, 0x9e, 0xa5, - 0xf4, 0x20, 0x24, 0xc9, 0xd6, 0x99, 0x9e, 0x1b, 0x11, 0xdb, 0xa5, 0x81, 0x48, 0xdf, 0xe9, 0x00, - 0xdb, 0xe9, 0xd0, 0x76, 0x4d, 0xba, 0x47, 0x4d, 0xcf, 0xb5, 0x42, 0xee, 0x32, 0x45, 0x23, 0x33, - 0x86, 0x9f, 0x87, 0x45, 0x4e, 0xdf, 0xb1, 0x3b, 0x71, 0xbe, 0xaa, 0x6c, 0xae, 0x37, 0xe2, 0x66, - 0x61, 0x43, 0x6d, 0x16, 0xa6, 0x36, 0xec, 0xd0, 0x88, 0x34, 0x7a, 0x57, 0x1a, 0x6c, 0x85, 0x91, - 0x2e, 0x66, 0x58, 0x22, 0x62, 0x3b, 0xbb, 0xb6, 0xcb, 0x2b, 0x64, 0x26, 0x2a, 0x1d, 0x60, 0xde, - 0xb8, 0xef, 0x39, 0x8e, 0xf7, 0x8a, 0x3c, 0xe0, 0x31, 0xc5, 0x56, 0x75, 0xdd, 0xc8, 0x76, 0xb8, - 0xfc, 0xd8, 0xd7, 0xd2, 0x01, 0xbe, 0xca, 0x76, 0x22, 0x1a, 0x88, 0x93, 0x2d, 0xa8, 0xc4, 0xdf, - 0x2b, 0x71, 0xff, 0x4b, 0x06, 0x96, 0xf8, 0x64, 0x2c, 0xa9, 0x27, 0xa3, 0xff, 0xb4, 0x2d, 0x0f, - 0x69, 0xe2, 0xf0, 0x76, 0x20, 0xed, 0xd9, 0x5e, 0x97, 0x15, 0x7f, 0xbc, 0x46, 0x92, 0xf4, 0xc0, - 0x69, 0x59, 0xc9, 0x3f, 0x2d, 0xc7, 0xb3, 0xa7, 0x85, 0x97, 0xf0, 0x91, 0xd9, 0xde, 0x26, 0x21, - 0xd5, 0x4e, 0x70, 0xd6, 0xe9, 0x80, 0xfe, 0x1b, 0x04, 0xe5, 0x5d, 0xaf, 0x75, 0xdd, 0x8d, 0x82, - 0x43, 0x7e, 0xd9, 0xf3, 0xdc, 0x88, 0xba, 0xd2, 0x9b, 0x24, 0xc9, 0xb6, 0x28, 0xb2, 0x3b, 0x74, - 0x2f, 0x22, 0x1d, 0x5f, 0x94, 0x8a, 0x47, 0xda, 0xa2, 0x64, 0x31, 0x33, 0x9b, 0x43, 0xc2, 0x88, - 0x87, 0x9c, 0xb2, 0xc1, 0xbf, 0x99, 0x82, 0xc9, 0x84, 0xbd, 0x28, 0x10, 0xf1, 0x26, 0x33, 0xa6, - 0x3a, 0x60, 0x29, 0xc6, 0x26, 0x48, 0xbd, 0x03, 0x0f, 0x26, 0x77, 0x98, 0x3b, 0x34, 0xe8, 0xd8, - 0x2e, 0xc9, 0x4f, 0x42, 0x13, 0x74, 0x29, 0x73, 0xae, 0xd0, 0x5e, 0xe6, 0x48, 0xb2, 0x2b, 0xc1, - 0x5d, 0xdb, 0xb5, 0xbc, 0x57, 0x72, 0x8e, 0xd6, 0x74, 0x02, 0xff, 0x9c, 0x6d, 0x34, 0x2a, 0x12, - 0x93, 0x38, 0xf0, 0x3c, 0x2c, 0xb3, 0x88, 0xd1, 0xa3, 0xe2, 0x07, 0x11, 0x94, 0xf4, 0x51, 0x3d, - 0x9f, 0x94, 0x87, 0x91, 0x5d, 0x88, 0x77, 0x61, 0x85, 0x84, 0xa1, 0xdd, 0x72, 0xa9, 0x25, 0x79, - 0x15, 0x26, 0xe6, 0xd5, 0xbf, 0x34, 0xee, 0x1e, 0xf0, 0x19, 0x62, 0xbf, 0x25, 0xa9, 0x7f, 0x15, - 0xc1, 0xa9, 0xa1, 0x4c, 0x92, 0x73, 0x85, 0x94, 0x3c, 0x52, 0x85, 0x72, 0x68, 0xb6, 0xa9, 0xd5, - 0x75, 0x64, 0x5e, 0x4c, 0x68, 0xf6, 0x9b, 0xd5, 0x8d, 0x77, 0x5f, 0xe4, 0xb1, 0x84, 0xc6, 0x67, - 0x00, 0x3a, 0xc4, 0xed, 0x12, 0x87, 0x43, 0x98, 0xe3, 0x10, 0x94, 0x11, 0x7d, 0x0d, 0xaa, 0xc3, - 0x5c, 0x47, 0xb4, 0xaa, 0xfe, 0x85, 0xe0, 0x98, 0x0c, 0xb9, 0x62, 0x77, 0xeb, 0xb0, 0xa2, 0x98, - 0xe1, 0x56, 0xba, 0xd1, 0xfd, 0xc3, 0x63, 0xc2, 0xa9, 0xf4, 0x92, 0x62, 0xf6, 0xad, 0xa0, 0x97, - 0xe9, 0xf6, 0x4f, 0x9c, 0x70, 0xd1, 0x8c, 0xca, 0xe0, 0xaf, 0x80, 0x76, 0x93, 0xb8, 0xa4, 0x45, - 0xad, 0x44, 0xed, 0xc4, 0xc5, 0xbe, 0xa8, 0xf6, 0x5c, 0xa6, 0xee, 0x70, 0x24, 0x15, 0xa3, 0xbd, - 0xbf, 0x2f, 0xfb, 0x37, 0x01, 0x94, 0x77, 0x6d, 0xf7, 0x60, 0xc7, 0xdd, 0xf7, 0x98, 0xc6, 0x91, - 0x1d, 0x39, 0xd2, 0xba, 0x31, 0x81, 0x8f, 0x43, 0xb1, 0x1b, 0x38, 0xc2, 0x03, 0xd8, 0x27, 0xae, - 0x41, 0xc5, 0xa2, 0xa1, 0x19, 0xd8, 0xbe, 0xd8, 0x7f, 0xde, 0xfb, 0x56, 0x86, 0xd8, 0x3e, 0xd8, - 0xa6, 0xe7, 0x6e, 0x3b, 0x24, 0x0c, 0x65, 0x7a, 0x4a, 0x06, 0xf4, 0xa7, 0x61, 0x99, 0xc9, 0x4c, - 0xd5, 0xbc, 0x98, 0x55, 0xf3, 0x54, 0x06, 0xbe, 0x84, 0x27, 0x11, 0x13, 0x78, 0x80, 0x55, 0x05, - 0x57, 0x7d, 0x5f, 0x30, 0x99, 0xb0, 0x1e, 0x2b, 0x0e, 0xcb, 0xae, 0x43, 0x5b, 0xbe, 0x9b, 0x7f, - 0x3d, 0x0b, 0x58, 0x3d, 0x27, 0x34, 0xe8, 0xd9, 0x26, 0xc5, 0xdf, 0x42, 0x30, 0xc7, 0x44, 0xe3, - 0x87, 0x46, 0x1d, 0x4b, 0xee, 0xaf, 0xd5, 0xd9, 0xdd, 0xe7, 0x99, 0x34, 0x7d, 0xed, 0xf5, 0xbf, - 0xfc, 0xfd, 0xdb, 0x85, 0x55, 0x7c, 0x92, 0x3f, 0xf4, 0xf5, 0xae, 0xa8, 0x8f, 0x6e, 0x21, 0x7e, - 0x03, 0x01, 0x16, 0x55, 0x92, 0xf2, 0x14, 0x82, 0x2f, 0x8e, 0x82, 0x38, 0xe4, 0xc9, 0xa4, 0xfa, - 0x90, 0x92, 0x55, 0x1a, 0xa6, 0x17, 0x50, 0x96, 0x43, 0xf8, 0x04, 0x0e, 0x60, 0x9d, 0x03, 0x38, - 0x87, 0xf5, 0x61, 0x00, 0x9a, 0xaf, 0x32, 0x8b, 0xbe, 0xd6, 0xa4, 0xb1, 0xdc, 0xb7, 0x10, 0x94, - 0xee, 0xf2, 0xab, 0xd0, 0x18, 0x23, 0xed, 0xcd, 0xcc, 0x48, 0x5c, 0x1c, 0x47, 0xab, 0x9f, 0xe5, - 0x48, 0x1f, 0xc2, 0xa7, 0x25, 0xd2, 0x30, 0x0a, 0x28, 0xe9, 0x64, 0x00, 0x5f, 0x46, 0xf8, 0x1d, - 0x04, 0xf3, 0x71, 0x0f, 0x1c, 0x9f, 0x1f, 0x85, 0x32, 0xd3, 0x23, 0xaf, 0xce, 0xae, 0xa1, 0xac, - 0x3f, 0xca, 0x31, 0x9e, 0xd5, 0x87, 0x6e, 0xe7, 0x56, 0xa6, 0xdd, 0xfc, 0x26, 0x82, 0xe2, 0x0d, - 0x3a, 0xd6, 0xdf, 0x66, 0x08, 0x6e, 0xc0, 0x80, 0x43, 0xb6, 0x1a, 0xbf, 0x8d, 0xe0, 0xc1, 0x1b, - 0x34, 0x1a, 0x9e, 0x1e, 0x71, 0x7d, 0x7c, 0xce, 0x12, 0x6e, 0x77, 0x71, 0x82, 0x99, 0x49, 0x5e, - 0x68, 0x72, 0x64, 0x8f, 0xe2, 0x0b, 0x79, 0x4e, 0x18, 0x1e, 0xba, 0xe6, 0x2b, 0x02, 0xc7, 0x1f, - 0x11, 0x1c, 0xef, 0x7f, 0xf2, 0xc4, 0x7a, 0xdf, 0x1d, 0x65, 0xc8, 0x8b, 0x68, 0xf5, 0xd6, 0xb4, - 0x51, 0x36, 0xcb, 0x54, 0xbf, 0xca, 0x91, 0x3f, 0x85, 0x9f, 0xcc, 0x43, 0x9e, 0x34, 0x14, 0x9b, - 0xaf, 0xca, 0xcf, 0xd7, 0xf8, 0xf3, 0x3c, 0x87, 0xfd, 0x27, 0x04, 0x27, 0x25, 0xdf, 0xed, 0x36, - 0x09, 0xa2, 0x6b, 0x94, 0x55, 0xd8, 0xe1, 0x44, 0xfa, 0x4c, 0x99, 0x35, 0x54, 0x79, 0xfa, 0x75, - 0xae, 0xcb, 0x27, 0xf0, 0x33, 0x47, 0xd6, 0xc5, 0x64, 0x6c, 0x2c, 0x01, 0xfb, 0x75, 0x04, 0x4b, - 0x37, 0x68, 0x74, 0x33, 0x69, 0x6a, 0x9f, 0x9f, 0xe8, 0xa1, 0xac, 0xba, 0xd6, 0x50, 0xfe, 0x15, - 0x20, 0x7f, 0x4a, 0x5c, 0x64, 0x83, 0x83, 0xbb, 0x80, 0xcf, 0xe7, 0x81, 0x4b, 0x1b, 0xe9, 0x6f, - 0x21, 0x38, 0xa5, 0x82, 0x48, 0x1f, 0x18, 0x3f, 0x7a, 0xb4, 0x67, 0x3b, 0xf1, 0xf8, 0x37, 0x06, - 0xdd, 0x26, 0x47, 0x77, 0x49, 0x1f, 0xee, 0xc0, 0x9d, 0x01, 0x14, 0x5b, 0x68, 0xbd, 0x8e, 0xf0, - 0x6f, 0x11, 0xcc, 0xc7, 0x3d, 0xe5, 0xd1, 0x36, 0xca, 0x3c, 0x88, 0xcd, 0x32, 0x1a, 0x88, 0xdd, - 0xae, 0x5e, 0x1e, 0x6e, 0x50, 0x75, 0xbd, 0x74, 0xd5, 0x06, 0xb7, 0x72, 0x36, 0x8c, 0xfd, 0x02, - 0x01, 0xa4, 0x7d, 0x71, 0xfc, 0x68, 0xbe, 0x1e, 0x4a, 0xef, 0xbc, 0x3a, 0xdb, 0xce, 0xb8, 0xde, - 0xe0, 0xfa, 0xd4, 0xab, 0xb5, 0xdc, 0x18, 0xe2, 0x53, 0x73, 0x2b, 0xee, 0xa1, 0xff, 0x10, 0x41, - 0x89, 0xb7, 0x23, 0xf1, 0xb9, 0x51, 0x98, 0xd5, 0x6e, 0xe5, 0x2c, 0x4d, 0xff, 0x08, 0x87, 0x5a, - 0xdb, 0xcc, 0x0b, 0xc4, 0x5b, 0x68, 0x1d, 0xf7, 0x60, 0x3e, 0x6e, 0x00, 0x8e, 0x76, 0x8f, 0x4c, - 0x83, 0xb0, 0x5a, 0xcb, 0x29, 0x0c, 0x62, 0x47, 0x15, 0x39, 0x60, 0x7d, 0x5c, 0x0e, 0x98, 0x63, - 0x61, 0x1a, 0x9f, 0xcd, 0x0b, 0xe2, 0xff, 0x07, 0xc3, 0x5c, 0xe4, 0xe8, 0xce, 0xeb, 0xb5, 0x71, - 0x79, 0x80, 0x59, 0xe7, 0xbb, 0x08, 0x8e, 0xf7, 0x17, 0xd7, 0xf8, 0xf4, 0xd0, 0x3e, 0x95, 0xc8, - 0x49, 0x59, 0x2b, 0x8e, 0x2a, 0xcc, 0xf5, 0x4f, 0x72, 0x14, 0x5b, 0xf8, 0x89, 0xb1, 0x27, 0xe3, - 0x96, 0x8c, 0x3a, 0x8c, 0xd1, 0x46, 0xfa, 0xc8, 0xf7, 0x4b, 0x04, 0x4b, 0x92, 0xef, 0x9d, 0x80, - 0xd2, 0x7c, 0x58, 0xb3, 0x3b, 0x08, 0x4c, 0x96, 0xfe, 0x34, 0x87, 0xff, 0x31, 0xfc, 0xf8, 0x84, - 0xf0, 0x25, 0xec, 0x8d, 0x88, 0x21, 0xfd, 0x3d, 0x82, 0x13, 0x77, 0x63, 0xbf, 0xff, 0x80, 0xf0, - 0x6f, 0x73, 0xfc, 0xcf, 0xe0, 0xa7, 0x72, 0xea, 0xbc, 0x71, 0x6a, 0x5c, 0x46, 0xf8, 0x67, 0x08, - 0xca, 0xf2, 0x71, 0x08, 0x5f, 0x18, 0x79, 0x30, 0xb2, 0xcf, 0x47, 0xb3, 0x74, 0x66, 0x51, 0xd4, - 0xe8, 0xe7, 0x72, 0xd3, 0xa9, 0x90, 0xcf, 0x1c, 0xfa, 0x4d, 0x04, 0x38, 0xb9, 0x33, 0x27, 0xb7, - 0x68, 0xfc, 0x48, 0x46, 0xd4, 0xc8, 0xc6, 0x4c, 0xf5, 0xc2, 0xd8, 0x79, 0xd9, 0x54, 0xba, 0x9e, - 0x9b, 0x4a, 0xbd, 0x44, 0xfe, 0xd7, 0x11, 0x54, 0x6e, 0xd0, 0xe4, 0x0e, 0x92, 0x63, 0xcb, 0xec, - 0xdb, 0x56, 0xb5, 0x3e, 0x7e, 0xa2, 0x40, 0x74, 0x89, 0x23, 0x7a, 0x04, 0xe7, 0x9b, 0x4a, 0x02, - 0xf8, 0x1e, 0x82, 0xe5, 0xdb, 0xaa, 0x8b, 0xe2, 0x4b, 0xe3, 0x24, 0x65, 0x22, 0xf9, 0xe4, 0xb8, - 0x1e, 0xe3, 0xb8, 0x36, 0xf4, 0x89, 0x70, 0x6d, 0x89, 0x67, 0xa2, 0xef, 0xa3, 0xf8, 0x12, 0xdb, - 0xd7, 0xed, 0xfe, 0x5f, 0xed, 0x96, 0xd3, 0x34, 0xd7, 0x1f, 0xe7, 0xf8, 0x1a, 0xf8, 0xd2, 0x24, - 0xf8, 0x9a, 0xa2, 0x05, 0x8e, 0xbf, 0x83, 0xe0, 0x04, 0x7f, 0xec, 0x50, 0x19, 0xe3, 0xbc, 0x0e, - 0x7f, 0xfa, 0x34, 0x32, 0x41, 0x8a, 0xf9, 0x38, 0x07, 0x75, 0x45, 0x3f, 0x12, 0x28, 0xe6, 0xff, - 0xdf, 0x40, 0x70, 0x4c, 0xe6, 0x33, 0xb1, 0xb1, 0x1b, 0xe3, 0x6c, 0x76, 0xd4, 0xfc, 0x27, 0x3c, - 0x6d, 0x7d, 0x32, 0x4f, 0x7b, 0x07, 0xc1, 0x82, 0x68, 0xf3, 0xe7, 0x54, 0x09, 0xca, 0x3b, 0x40, - 0xb5, 0xaf, 0xbd, 0x21, 0xfa, 0xc0, 0xfa, 0xe7, 0xb9, 0xd8, 0x17, 0x71, 0x33, 0x4f, 0xac, 0xef, - 0x59, 0x61, 0xf3, 0x55, 0xd1, 0x84, 0x7d, 0xad, 0xe9, 0x78, 0xad, 0xf0, 0x25, 0x1d, 0xe7, 0xe6, - 0x42, 0x36, 0xe7, 0x32, 0xc2, 0x11, 0x2c, 0x32, 0xbf, 0xe0, 0x3d, 0x13, 0x5c, 0xeb, 0xeb, 0xb0, - 0x0c, 0xb4, 0x53, 0xaa, 0xd5, 0x81, 0x1e, 0x4c, 0x9a, 0xfc, 0xc4, 0x0d, 0x16, 0x3f, 0x9c, 0x2b, - 0x96, 0x0b, 0x7a, 0x03, 0xc1, 0x09, 0xd5, 0xd1, 0x63, 0xf1, 0x13, 0xbb, 0x79, 0x1e, 0x0a, 0x51, - 0x4f, 0xe3, 0xf5, 0x89, 0x7c, 0x88, 0xc3, 0x79, 0xf6, 0xb9, 0x3f, 0xbc, 0x77, 0x06, 0xbd, 0xfb, - 0xde, 0x19, 0xf4, 0xb7, 0xf7, 0xce, 0xa0, 0x97, 0x9e, 0x98, 0xec, 0x5f, 0xce, 0xa6, 0x63, 0x53, - 0x37, 0x52, 0xd9, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x20, 0x14, 0xaf, 0x73, 0xcb, 0x2d, 0x00, - 0x00, + // 2742 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x4d, 0x8c, 0x1b, 0x49, + 0x15, 0xa6, 0xec, 0xf1, 0x8c, 0xe7, 0x79, 0x26, 0x93, 0xd4, 0x26, 0x83, 0xd7, 0x99, 0x0d, 0xde, + 0x4e, 0xb2, 0x71, 0x26, 0x19, 0x3b, 0x31, 0x01, 0x65, 0x67, 0x77, 0x05, 0xc9, 0xe4, 0x17, 0x26, + 0xd9, 0xd0, 0x93, 0x10, 0xb4, 0x1c, 0xa0, 0xb6, 0xbb, 0xc6, 0xd3, 0x4c, 0xbb, 0xbb, 0xd3, 0xdd, + 0x76, 0x18, 0x85, 0x5c, 0x16, 0xed, 0x05, 0xad, 0x40, 0xc0, 0x1e, 0x10, 0x42, 0x80, 0x16, 0xad, + 0x84, 0x10, 0x88, 0x0b, 0x42, 0x48, 0x08, 0x09, 0x0e, 0x20, 0x38, 0x20, 0xad, 0xe0, 0xc8, 0x05, + 0x45, 0x88, 0x23, 0x5c, 0xf6, 0x8c, 0x50, 0x55, 0x57, 0x75, 0x57, 0xfb, 0xa7, 0xed, 0xc1, 0x46, + 0x9b, 0x5b, 0xbf, 0x72, 0xd5, 0x7b, 0xdf, 0x7b, 0xf5, 0xea, 0xbd, 0x57, 0xaf, 0x0c, 0x27, 0x02, + 0xea, 0x77, 0xa9, 0xdf, 0x20, 0x9e, 0x67, 0x5b, 0x06, 0x09, 0x2d, 0xd7, 0x51, 0xbf, 0xeb, 0x9e, + 0xef, 0x86, 0x2e, 0x2e, 0x29, 0x43, 0x95, 0x95, 0x96, 0xeb, 0xb6, 0x6c, 0xda, 0x20, 0x9e, 0xd5, + 0x20, 0x8e, 0xe3, 0x86, 0x7c, 0x38, 0x88, 0xa6, 0x56, 0xb4, 0xdd, 0x8b, 0x41, 0xdd, 0x72, 0xf9, + 0xaf, 0x86, 0xeb, 0xd3, 0x46, 0xf7, 0x7c, 0xa3, 0x45, 0x1d, 0xea, 0x93, 0x90, 0x9a, 0x62, 0xce, + 0x85, 0x64, 0x4e, 0x9b, 0x18, 0x3b, 0x96, 0x43, 0xfd, 0xbd, 0x86, 0xb7, 0xdb, 0x62, 0x03, 0x41, + 0xa3, 0x4d, 0x43, 0x32, 0x68, 0xd5, 0x66, 0xcb, 0x0a, 0x77, 0x3a, 0xaf, 0xd7, 0x0d, 0xb7, 0xdd, + 0x20, 0x7e, 0xcb, 0xf5, 0x7c, 0xf7, 0x4b, 0xfc, 0x63, 0xcd, 0x30, 0x1b, 0xdd, 0x66, 0xc2, 0x40, + 0xd5, 0xa5, 0x7b, 0x9e, 0xd8, 0xde, 0x0e, 0xe9, 0xe7, 0x76, 0x75, 0x04, 0x37, 0x9f, 0x7a, 0xae, + 0xb0, 0x0d, 0xff, 0xb4, 0x42, 0xd7, 0xdf, 0x53, 0x3e, 0x23, 0x36, 0xda, 0xfb, 0x08, 0x0e, 0x5e, + 0x4a, 0xe4, 0x7d, 0xa6, 0x43, 0xfd, 0x3d, 0x8c, 0x61, 0xc6, 0x21, 0x6d, 0x5a, 0x46, 0x55, 0x54, + 0x9b, 0xd7, 0xf9, 0x37, 0x2e, 0xc3, 0x9c, 0x4f, 0xb7, 0x7d, 0x1a, 0xec, 0x94, 0x73, 0x7c, 0x58, + 0x92, 0xb8, 0x02, 0x45, 0x26, 0x9c, 0x1a, 0x61, 0x50, 0xce, 0x57, 0xf3, 0xb5, 0x79, 0x3d, 0xa6, + 0x71, 0x0d, 0x96, 0x7c, 0x1a, 0xb8, 0x1d, 0xdf, 0xa0, 0x9f, 0xa5, 0x7e, 0x60, 0xb9, 0x4e, 0x79, + 0x86, 0xaf, 0xee, 0x1d, 0x66, 0x5c, 0x02, 0x6a, 0x53, 0x23, 0x74, 0xfd, 0x72, 0x81, 0x4f, 0x89, + 0x69, 0x86, 0x87, 0x01, 0x2f, 0xcf, 0x46, 0x78, 0xd8, 0x37, 0xd6, 0x60, 0x81, 0x78, 0xde, 0x6d, + 0xd2, 0xa6, 0x81, 0x47, 0x0c, 0x5a, 0x9e, 0xe3, 0xbf, 0xa5, 0xc6, 0x18, 0x66, 0x81, 0xa4, 0x5c, + 0xe4, 0xc0, 0x24, 0xa9, 0x6d, 0xc0, 0xfc, 0x6d, 0xd7, 0xa4, 0xc3, 0xd5, 0xed, 0x65, 0x9f, 0xeb, + 0x67, 0xaf, 0xfd, 0x1e, 0xc1, 0x11, 0x9d, 0x76, 0x2d, 0x86, 0xff, 0x16, 0x0d, 0x89, 0x49, 0x42, + 0xd2, 0xcb, 0x31, 0x17, 0x73, 0xac, 0x40, 0xd1, 0x17, 0x93, 0xcb, 0x39, 0x3e, 0x1e, 0xd3, 0x7d, + 0xd2, 0xf2, 0xd9, 0xca, 0x44, 0x26, 0x94, 0x24, 0xae, 0x42, 0x29, 0xb2, 0xe5, 0x4d, 0xc7, 0xa4, + 0x5f, 0xe6, 0xd6, 0x2b, 0xe8, 0xea, 0x10, 0x5e, 0x81, 0xf9, 0x6e, 0x64, 0xe7, 0x9b, 0x26, 0xb7, + 0x62, 0x41, 0x4f, 0x06, 0xb4, 0x7f, 0x22, 0x38, 0xa6, 0xf8, 0x80, 0x2e, 0x76, 0xe6, 0x6a, 0x97, + 0x3a, 0x61, 0x30, 0x5c, 0xa1, 0xb3, 0x70, 0x48, 0x6e, 0x62, 0xaf, 0x9d, 0xfa, 0x7f, 0x60, 0x2a, + 0xaa, 0x83, 0x52, 0x45, 0x75, 0x8c, 0x29, 0x22, 0xe9, 0x7b, 0x37, 0xaf, 0x08, 0x35, 0xd5, 0xa1, + 0x3e, 0x43, 0x15, 0xb2, 0x0d, 0x35, 0x9b, 0x32, 0x94, 0xf6, 0x1e, 0x82, 0xb2, 0xa2, 0xe8, 0x2d, + 0xe2, 0x58, 0xdb, 0x34, 0x08, 0xc7, 0xdd, 0x33, 0x34, 0xc5, 0x3d, 0xab, 0xc1, 0x52, 0xa4, 0xd5, + 0x1d, 0x76, 0x1e, 0x59, 0xfc, 0x29, 0x17, 0xaa, 0xf9, 0x5a, 0x5e, 0xef, 0x1d, 0x66, 0x7b, 0x27, + 0x65, 0x06, 0xe5, 0x59, 0xee, 0xc6, 0xc9, 0x80, 0xf6, 0x3c, 0xcc, 0x5f, 0xb3, 0x6c, 0xba, 0xb1, + 0xd3, 0x71, 0x76, 0xf1, 0x61, 0x28, 0x18, 0xec, 0x83, 0xeb, 0xb0, 0xa0, 0x47, 0x84, 0xf6, 0x4d, + 0x04, 0xcf, 0x0f, 0xd3, 0xfa, 0xbe, 0x15, 0xee, 0xb0, 0xf5, 0xc1, 0x30, 0xf5, 0x8d, 0x1d, 0x6a, + 0xec, 0x06, 0x9d, 0xb6, 0x74, 0x59, 0x49, 0x4f, 0xa6, 0xbe, 0xf6, 0x13, 0x04, 0xb5, 0x91, 0x98, + 0xee, 0xfb, 0xc4, 0xf3, 0xa8, 0x8f, 0xaf, 0x41, 0xe1, 0x01, 0xfb, 0x81, 0x1f, 0xd0, 0x52, 0xb3, + 0x5e, 0x57, 0x03, 0xfc, 0x48, 0x2e, 0x37, 0x3e, 0xa4, 0x47, 0xcb, 0x71, 0x5d, 0x9a, 0x27, 0xc7, + 0xf9, 0x2c, 0xa7, 0xf8, 0xc4, 0x56, 0x64, 0xf3, 0xf9, 0xb4, 0xcb, 0xb3, 0x30, 0xe3, 0x11, 0x3f, + 0xd4, 0x8e, 0xc0, 0x33, 0xe9, 0xe3, 0xe1, 0xb9, 0x4e, 0x40, 0xb5, 0x5f, 0xa7, 0xbd, 0x69, 0xc3, + 0xa7, 0x24, 0xa4, 0x3a, 0x7d, 0xd0, 0xa1, 0x41, 0x88, 0x77, 0x41, 0xcd, 0x39, 0xdc, 0xaa, 0xa5, + 0xe6, 0xcd, 0x7a, 0x12, 0xb4, 0xeb, 0x32, 0x68, 0xf3, 0x8f, 0x2f, 0x18, 0x66, 0xbd, 0xdb, 0xac, + 0x7b, 0xbb, 0xad, 0x3a, 0x4b, 0x01, 0x29, 0x64, 0x32, 0x05, 0xa8, 0xaa, 0xea, 0x2a, 0x77, 0xbc, + 0x0c, 0xb3, 0x1d, 0x2f, 0xa0, 0x7e, 0xc8, 0x35, 0x2b, 0xea, 0x82, 0x62, 0xfb, 0xd7, 0x25, 0xb6, + 0x65, 0x92, 0x30, 0xda, 0x9f, 0xa2, 0x1e, 0xd3, 0xda, 0x6f, 0xd2, 0xe8, 0xef, 0x79, 0xe6, 0x07, + 0x85, 0x5e, 0x45, 0x99, 0x4b, 0xa3, 0x54, 0x3d, 0x28, 0x9f, 0xf6, 0xa0, 0x5f, 0xa4, 0xf1, 0x5f, + 0xa1, 0x36, 0x4d, 0xf0, 0x0f, 0x72, 0xe6, 0x32, 0xcc, 0x19, 0x24, 0x30, 0x88, 0x29, 0xa5, 0x48, + 0x92, 0x05, 0x32, 0xcf, 0x77, 0x3d, 0xd2, 0xe2, 0x9c, 0xee, 0xb8, 0xb6, 0x65, 0xec, 0x09, 0x71, + 0xfd, 0x3f, 0xf4, 0x39, 0xfe, 0x4c, 0xb6, 0xe3, 0x17, 0xd2, 0xb0, 0x8f, 0x43, 0x69, 0x6b, 0xcf, + 0x31, 0x5e, 0xf5, 0xa2, 0xc3, 0x7d, 0x18, 0x0a, 0x56, 0x48, 0xdb, 0x41, 0x19, 0xf1, 0x83, 0x1d, + 0x11, 0xda, 0x7f, 0x0a, 0xb0, 0xac, 0xe8, 0xc6, 0x16, 0x64, 0x69, 0x96, 0x15, 0xa5, 0x96, 0x61, + 0xd6, 0xf4, 0xf7, 0xf4, 0x8e, 0x23, 0x1c, 0x40, 0x50, 0x4c, 0xb0, 0xe7, 0x77, 0x9c, 0x08, 0x7e, + 0x51, 0x8f, 0x08, 0xbc, 0x0d, 0xc5, 0x20, 0x64, 0x55, 0x46, 0x6b, 0x8f, 0x03, 0x2f, 0x35, 0x3f, + 0x35, 0xd9, 0xa6, 0x33, 0xe8, 0x5b, 0x82, 0xa3, 0x1e, 0xf3, 0xc6, 0x0f, 0x58, 0x4c, 0x8b, 0x02, + 0x5d, 0x50, 0x9e, 0xab, 0xe6, 0x6b, 0xa5, 0xe6, 0xd6, 0xe4, 0x82, 0x5e, 0xf5, 0x58, 0x85, 0xa4, + 0x64, 0x30, 0x3d, 0x91, 0xc2, 0xc2, 0x68, 0x5b, 0xc4, 0x87, 0x40, 0x54, 0x03, 0xc9, 0x00, 0xfe, + 0x1c, 0x14, 0x2c, 0x67, 0xdb, 0x0d, 0xca, 0xf3, 0x1c, 0xcc, 0xe5, 0xc9, 0xc0, 0xdc, 0x74, 0xb6, + 0x5d, 0x3d, 0x62, 0x88, 0x1f, 0xc0, 0xa2, 0x4f, 0x43, 0x7f, 0x4f, 0x5a, 0xa1, 0x0c, 0xdc, 0xae, + 0x9f, 0x9e, 0x4c, 0x82, 0xae, 0xb2, 0xd4, 0xd3, 0x12, 0xf0, 0x3a, 0x94, 0x82, 0xc4, 0xc7, 0xca, + 0x25, 0x2e, 0xb0, 0x9c, 0x62, 0xa4, 0xf8, 0xa0, 0xae, 0x4e, 0xee, 0xf3, 0xee, 0x85, 0x6c, 0xef, + 0x5e, 0x1c, 0x99, 0xd5, 0x0e, 0x8c, 0x91, 0xd5, 0x96, 0x7a, 0xb3, 0xda, 0xbf, 0x11, 0xac, 0xf4, + 0x05, 0xa7, 0x2d, 0x8f, 0x66, 0x1e, 0x03, 0x02, 0x33, 0x81, 0x47, 0x0d, 0x9e, 0xa9, 0x4a, 0xcd, + 0x5b, 0x53, 0x8b, 0x56, 0x5c, 0x2e, 0x67, 0x9d, 0x15, 0x50, 0x27, 0x8c, 0x0b, 0x3f, 0x40, 0xf0, + 0x61, 0x45, 0xe6, 0x1d, 0x12, 0x1a, 0x3b, 0x59, 0xca, 0xb2, 0xf3, 0xcb, 0xe6, 0x88, 0xbc, 0x1c, + 0x11, 0xcc, 0xaa, 0xfc, 0xe3, 0xee, 0x9e, 0xc7, 0x00, 0xb2, 0x5f, 0x92, 0x81, 0x09, 0x8b, 0xa7, + 0x9f, 0x22, 0xa8, 0xa8, 0x31, 0xdc, 0xb5, 0xed, 0xd7, 0x89, 0xb1, 0x9b, 0x05, 0xf2, 0x00, 0xe4, + 0x2c, 0x93, 0x23, 0xcc, 0xeb, 0x39, 0xcb, 0xdc, 0x67, 0x30, 0xea, 0x85, 0x3b, 0x9b, 0x0d, 0x77, + 0x2e, 0x0d, 0xf7, 0xfd, 0x1e, 0xb8, 0x32, 0x24, 0x64, 0xc0, 0x5d, 0x81, 0x79, 0xa7, 0xa7, 0x90, + 0x4d, 0x06, 0x06, 0x14, 0xb0, 0xb9, 0xbe, 0x02, 0xb6, 0x0c, 0x73, 0xdd, 0xf8, 0x9a, 0xc3, 0x7e, + 0x96, 0x24, 0x53, 0xb1, 0xe5, 0xbb, 0x1d, 0x4f, 0x18, 0x3d, 0x22, 0x18, 0x8a, 0x5d, 0xcb, 0x61, + 0x25, 0x39, 0x47, 0xc1, 0xbe, 0xf7, 0x7f, 0xb1, 0x49, 0xa9, 0xfd, 0xb3, 0x1c, 0x7c, 0x64, 0x80, + 0xda, 0x23, 0xfd, 0xe9, 0xe9, 0xd0, 0x3d, 0xf6, 0xea, 0xb9, 0xa1, 0x5e, 0x5d, 0x1c, 0xe5, 0xd5, + 0xf3, 0xd9, 0xf6, 0x82, 0xb4, 0xbd, 0x7e, 0x9c, 0x83, 0xea, 0x00, 0x7b, 0x8d, 0x2e, 0x27, 0x9e, + 0x1a, 0x83, 0x6d, 0xbb, 0xbe, 0xf0, 0x92, 0xa2, 0x1e, 0x11, 0xec, 0x9c, 0xb9, 0xbe, 0xb7, 0x43, + 0x1c, 0xee, 0x1d, 0x45, 0x5d, 0x50, 0x13, 0x9a, 0xea, 0x6b, 0x39, 0x28, 0x4b, 0xfb, 0x5c, 0x32, + 0xb8, 0xb5, 0x3a, 0xce, 0xd3, 0x6f, 0xa2, 0x65, 0x98, 0x25, 0x1c, 0xad, 0x70, 0x2a, 0x41, 0xf5, + 0x19, 0xa3, 0x98, 0x6d, 0x8c, 0xf9, 0xb4, 0x31, 0xde, 0x44, 0x70, 0x34, 0x6d, 0x8c, 0x60, 0xd3, + 0x0a, 0x42, 0x79, 0x39, 0xc0, 0xdb, 0x30, 0x17, 0xc9, 0x89, 0x4a, 0xbb, 0x52, 0x73, 0x73, 0xd2, + 0x84, 0x9f, 0x32, 0xbc, 0x64, 0xae, 0xbd, 0x08, 0x47, 0x07, 0x46, 0x39, 0x01, 0xa3, 0x02, 0x45, + 0x59, 0xe4, 0x88, 0xad, 0x89, 0x69, 0xed, 0xcd, 0x99, 0x74, 0xca, 0x71, 0xcd, 0x4d, 0xb7, 0x95, + 0x71, 0xdf, 0xcf, 0xde, 0x4e, 0x66, 0x2a, 0xd7, 0x54, 0xae, 0xf6, 0x92, 0x64, 0xeb, 0x0c, 0xd7, + 0x09, 0x89, 0xe5, 0x50, 0x5f, 0x64, 0xc5, 0x64, 0x80, 0x6d, 0x43, 0x60, 0x39, 0x06, 0xdd, 0xa2, + 0x86, 0xeb, 0x98, 0x01, 0xdf, 0xcf, 0xbc, 0x9e, 0x1a, 0xc3, 0x37, 0x60, 0x9e, 0xd3, 0x77, 0xad, + 0x76, 0x94, 0x06, 0x4a, 0xcd, 0xd5, 0x7a, 0xd4, 0x83, 0xab, 0xab, 0x3d, 0xb8, 0xc4, 0x86, 0x6d, + 0x1a, 0x92, 0x7a, 0xf7, 0x7c, 0x9d, 0xad, 0xd0, 0x93, 0xc5, 0x0c, 0x4b, 0x48, 0x2c, 0x7b, 0xd3, + 0x72, 0x78, 0xe1, 0xc9, 0x44, 0x25, 0x03, 0xcc, 0x55, 0xb6, 0x5d, 0xdb, 0x76, 0x1f, 0xca, 0x73, + 0x13, 0x51, 0x6c, 0x55, 0xc7, 0x09, 0x2d, 0x9b, 0xcb, 0x8f, 0x1c, 0x21, 0x19, 0xe0, 0xab, 0x2c, + 0x3b, 0xa4, 0xbe, 0x38, 0x30, 0x82, 0x8a, 0x9d, 0xb1, 0x14, 0xb5, 0x95, 0xe4, 0x79, 0x8d, 0xdc, + 0x76, 0x41, 0x75, 0xdb, 0xde, 0xa3, 0xb0, 0x38, 0xa0, 0x37, 0xc2, 0xbb, 0x6c, 0xb4, 0x6b, 0xb9, + 0x1d, 0x56, 0x53, 0xf1, 0xd2, 0x43, 0xd2, 0x7d, 0xae, 0xbc, 0x94, 0xed, 0xca, 0x07, 0xd3, 0xae, + 0xfc, 0x5b, 0x04, 0xc5, 0x4d, 0xb7, 0x75, 0xd5, 0x09, 0xfd, 0x3d, 0x7e, 0x4b, 0x72, 0x9d, 0x90, + 0x3a, 0xd2, 0x5f, 0x24, 0xc9, 0x36, 0x21, 0xb4, 0xda, 0x74, 0x2b, 0x24, 0x6d, 0x4f, 0xd4, 0x58, + 0xfb, 0xda, 0x84, 0x78, 0x31, 0x33, 0x8c, 0x4d, 0x82, 0x90, 0x9f, 0xf8, 0xa2, 0xce, 0xbf, 0x99, + 0x0a, 0xf1, 0x84, 0xad, 0xd0, 0x17, 0xc7, 0x3d, 0x35, 0xa6, 0xba, 0x58, 0x21, 0xc2, 0x26, 0x48, + 0xad, 0x0d, 0xcf, 0xc6, 0xc5, 0xff, 0x5d, 0xea, 0xb7, 0x2d, 0x87, 0x64, 0x47, 0xef, 0x31, 0xda, + 0x7b, 0x19, 0x77, 0x4f, 0x37, 0x75, 0xe8, 0x58, 0x2d, 0x7d, 0xdf, 0x72, 0x4c, 0xf7, 0x61, 0xc6, + 0xe1, 0x99, 0x4c, 0xe0, 0x5f, 0xd2, 0x1d, 0x3a, 0x45, 0x62, 0x7c, 0xd2, 0x6f, 0xc0, 0x22, 0x8b, + 0x09, 0x5d, 0x2a, 0x7e, 0x10, 0x61, 0x47, 0x1b, 0xd6, 0x2c, 0x49, 0x78, 0xe8, 0xe9, 0x85, 0x78, + 0x13, 0x96, 0x48, 0x10, 0x58, 0x2d, 0x87, 0x9a, 0x92, 0x57, 0x6e, 0x6c, 0x5e, 0xbd, 0x4b, 0xa3, + 0x6b, 0x37, 0x9f, 0x21, 0xf6, 0x5b, 0x92, 0xda, 0x57, 0x11, 0x1c, 0x19, 0xc8, 0x24, 0x3e, 0x39, + 0x48, 0x09, 0xe3, 0x15, 0x28, 0x06, 0xc6, 0x0e, 0x35, 0x3b, 0x36, 0x95, 0xbd, 0x28, 0x49, 0xb3, + 0xdf, 0xcc, 0x4e, 0xb4, 0xfb, 0x22, 0x8d, 0xc4, 0x34, 0x3e, 0x06, 0xd0, 0x26, 0x4e, 0x87, 0xd8, + 0x1c, 0xc2, 0x0c, 0x87, 0xa0, 0x8c, 0x68, 0x2b, 0x50, 0x19, 0xe4, 0x3a, 0xa2, 0xc7, 0xf3, 0x2f, + 0x04, 0x07, 0x64, 0x50, 0x15, 0xbb, 0x5b, 0x83, 0x25, 0xc5, 0x0c, 0xb7, 0x93, 0x8d, 0xee, 0x1d, + 0x1e, 0x11, 0x30, 0xa5, 0x97, 0xe4, 0xd3, 0x4d, 0xf6, 0x6e, 0xaa, 0x4d, 0x3e, 0x76, 0xbe, 0x43, + 0x53, 0xaa, 0x1f, 0xbf, 0x02, 0xe5, 0x5b, 0xc4, 0x21, 0x2d, 0x6a, 0xc6, 0x6a, 0xc7, 0x2e, 0xf6, + 0x45, 0xb5, 0x59, 0x31, 0x71, 0x6b, 0x20, 0x2e, 0xb5, 0xac, 0xed, 0x6d, 0xd9, 0xf8, 0xf0, 0xa1, + 0xb8, 0x69, 0x39, 0xbb, 0xec, 0xfe, 0xcc, 0x34, 0x0e, 0xad, 0xd0, 0x96, 0xd6, 0x8d, 0x08, 0x7c, + 0x10, 0xf2, 0x1d, 0xdf, 0x16, 0x1e, 0xc0, 0x3e, 0x71, 0x15, 0x4a, 0x26, 0x0d, 0x0c, 0xdf, 0xf2, + 0xc4, 0xfe, 0xf3, 0xa6, 0xb1, 0x32, 0xc4, 0xf6, 0xc1, 0x32, 0x5c, 0x67, 0xc3, 0x26, 0x41, 0x20, + 0x13, 0x50, 0x3c, 0xa0, 0xbd, 0x0c, 0x8b, 0x4c, 0x66, 0xa2, 0xe6, 0x99, 0xb4, 0x9a, 0x47, 0x52, + 0xf0, 0x25, 0x3c, 0x89, 0x98, 0xc0, 0x33, 0x2c, 0xef, 0x5f, 0xf2, 0x3c, 0xc1, 0x64, 0xcc, 0x72, + 0x28, 0x3f, 0x28, 0x7f, 0x0e, 0xec, 0x95, 0x36, 0xff, 0x76, 0x1c, 0xb0, 0x7a, 0x4e, 0xa8, 0xdf, + 0xb5, 0x0c, 0x8a, 0xbf, 0x85, 0x60, 0x86, 0x89, 0xc6, 0xcf, 0x0d, 0x3b, 0x96, 0xdc, 0x5f, 0x2b, + 0xd3, 0xbb, 0x08, 0x33, 0x69, 0xda, 0xca, 0x1b, 0x7f, 0xfd, 0xc7, 0xb7, 0x73, 0xcb, 0xf8, 0x30, + 0x7f, 0x21, 0xeb, 0x9e, 0x57, 0x5f, 0xab, 0x02, 0xfc, 0x16, 0x02, 0x2c, 0xea, 0x20, 0xe5, 0x0d, + 0x01, 0x9f, 0x19, 0x06, 0x71, 0xc0, 0x5b, 0x43, 0xe5, 0x39, 0x25, 0xab, 0xd4, 0x0d, 0xd7, 0xa7, + 0x2c, 0x87, 0xf0, 0x09, 0x1c, 0xc0, 0x2a, 0x07, 0x70, 0x02, 0x6b, 0x83, 0x00, 0x34, 0x1e, 0x31, + 0x8b, 0x3e, 0x6e, 0xd0, 0x48, 0xee, 0x3b, 0x08, 0x0a, 0xf7, 0xf9, 0x1d, 0x62, 0x84, 0x91, 0xb6, + 0xa6, 0x66, 0x24, 0x2e, 0x8e, 0xa3, 0xd5, 0x8e, 0x73, 0xa4, 0xcf, 0xe1, 0xa3, 0x12, 0x69, 0x10, + 0xfa, 0x94, 0xb4, 0x53, 0x80, 0xcf, 0x21, 0xfc, 0x2e, 0x82, 0xd9, 0xa8, 0x79, 0x8c, 0x4f, 0x0e, + 0x43, 0x99, 0x6a, 0x2e, 0x57, 0xa6, 0xd7, 0x89, 0xd5, 0x4e, 0x73, 0x8c, 0xc7, 0xb5, 0x81, 0xdb, + 0xb9, 0x9e, 0xea, 0xd3, 0xbe, 0x8d, 0x20, 0x7f, 0x9d, 0x8e, 0xf4, 0xb7, 0x29, 0x82, 0xeb, 0x33, + 0xe0, 0x80, 0xad, 0xc6, 0x3f, 0x42, 0xf0, 0xec, 0x75, 0x1a, 0x0e, 0x4e, 0x8f, 0xb8, 0x36, 0x3a, + 0x67, 0x09, 0xb7, 0x3b, 0x33, 0xc6, 0xcc, 0x38, 0x2f, 0x34, 0x38, 0xb2, 0xd3, 0xf8, 0x54, 0x96, + 0x13, 0x06, 0x7b, 0x8e, 0xf1, 0x50, 0xe0, 0xf8, 0x13, 0x82, 0x83, 0xbd, 0x6f, 0x85, 0x38, 0x9d, + 0x50, 0x07, 0x3e, 0x25, 0x56, 0x6e, 0x4f, 0x1a, 0x65, 0xd3, 0x4c, 0xb5, 0x4b, 0x1c, 0xf9, 0x4b, + 0xf8, 0xc5, 0x2c, 0xe4, 0x71, 0x27, 0xae, 0xf1, 0x48, 0x7e, 0x3e, 0xe6, 0xef, 0xda, 0x1c, 0xf6, + 0x9f, 0x11, 0x1c, 0x96, 0x7c, 0x37, 0x76, 0x88, 0x1f, 0x5e, 0xa1, 0xac, 0x86, 0x0e, 0xc6, 0xd2, + 0x67, 0xc2, 0xac, 0xa1, 0xca, 0xd3, 0xae, 0x72, 0x5d, 0x3e, 0x81, 0x5f, 0xd9, 0xb7, 0x2e, 0x06, + 0x63, 0x63, 0x0a, 0xd8, 0x6f, 0x20, 0x58, 0xb8, 0x4e, 0xc3, 0x5b, 0x71, 0x37, 0xf8, 0xe4, 0x58, + 0x2f, 0x4c, 0x95, 0x95, 0xba, 0xf2, 0x9c, 0x2e, 0x7f, 0x8a, 0x5d, 0x64, 0x8d, 0x83, 0x3b, 0x85, + 0x4f, 0x66, 0x81, 0x4b, 0x3a, 0xd0, 0xef, 0x20, 0x38, 0xa2, 0x82, 0x48, 0x5e, 0xe6, 0x3e, 0xb6, + 0xbf, 0xf7, 0x2e, 0xf1, 0x6a, 0x36, 0x02, 0x5d, 0x93, 0xa3, 0x3b, 0xab, 0x0d, 0x76, 0xe0, 0x76, + 0x1f, 0x8a, 0x75, 0xb4, 0x5a, 0x43, 0xf8, 0x77, 0x08, 0x66, 0xa3, 0x66, 0xec, 0x70, 0x1b, 0xa5, + 0x5e, 0x92, 0xa6, 0x19, 0x0d, 0xc4, 0x6e, 0x57, 0xce, 0x0d, 0x36, 0xa8, 0xba, 0x5e, 0xba, 0x6a, + 0x9d, 0x5b, 0x39, 0x1d, 0xc6, 0x7e, 0x89, 0x00, 0x92, 0x86, 0x32, 0x3e, 0x9d, 0xad, 0x87, 0xd2, + 0x74, 0xae, 0x4c, 0xb7, 0xa5, 0xac, 0xd5, 0xb9, 0x3e, 0xb5, 0x4a, 0x35, 0x33, 0x86, 0x78, 0xd4, + 0x58, 0x8f, 0x9a, 0xcf, 0x3f, 0x44, 0x50, 0xe0, 0x7d, 0x3c, 0x7c, 0x62, 0x18, 0x66, 0xb5, 0xcd, + 0x37, 0x4d, 0xd3, 0xbf, 0xc0, 0xa1, 0x56, 0x9b, 0x59, 0x81, 0x78, 0x1d, 0xad, 0xe2, 0x2e, 0xcc, + 0x46, 0x9d, 0xb3, 0xe1, 0xee, 0x91, 0xea, 0xac, 0x55, 0xaa, 0x19, 0x85, 0x41, 0xe4, 0xa8, 0x22, + 0x07, 0xac, 0x8e, 0xca, 0x01, 0x33, 0x2c, 0x4c, 0xe3, 0xe3, 0x59, 0x41, 0xfc, 0xff, 0x60, 0x98, + 0x33, 0x1c, 0xdd, 0x49, 0xad, 0x3a, 0x2a, 0x0f, 0x30, 0xeb, 0x7c, 0x07, 0xc1, 0xc1, 0xde, 0xe2, + 0x1a, 0x1f, 0xed, 0x89, 0x99, 0xea, 0x5d, 0xa3, 0x92, 0xb6, 0xe2, 0xb0, 0xc2, 0x5c, 0xfb, 0x24, + 0x47, 0xb1, 0x8e, 0x2f, 0x8e, 0x3c, 0x19, 0xb7, 0x65, 0xd4, 0x61, 0x8c, 0xd6, 0x92, 0xd7, 0xb1, + 0x5f, 0x21, 0x58, 0x90, 0x7c, 0xef, 0xfa, 0x94, 0x66, 0xc3, 0x9a, 0xde, 0x41, 0x60, 0xb2, 0xb4, + 0x97, 0x39, 0xfc, 0x8f, 0xe3, 0x0b, 0x63, 0xc2, 0x97, 0xb0, 0xd7, 0x42, 0x86, 0xf4, 0x0f, 0x08, + 0x0e, 0xdd, 0x8f, 0xfc, 0xfe, 0x03, 0xc2, 0xbf, 0xc1, 0xf1, 0xbf, 0x82, 0x5f, 0xca, 0xa8, 0xf3, + 0x46, 0xa9, 0x71, 0x0e, 0xe1, 0x9f, 0x23, 0x28, 0xca, 0x57, 0x15, 0x7c, 0x6a, 0xe8, 0xc1, 0x48, + 0xbf, 0xbb, 0x4c, 0xd3, 0x99, 0x45, 0x51, 0xa3, 0x9d, 0xc8, 0x4c, 0xa7, 0x42, 0x3e, 0x73, 0xe8, + 0xb7, 0x11, 0xe0, 0xf8, 0xce, 0x1c, 0xdf, 0xa2, 0xf1, 0x0b, 0x29, 0x51, 0x43, 0x1b, 0x33, 0x95, + 0x53, 0x23, 0xe7, 0xa5, 0x53, 0xe9, 0x6a, 0x66, 0x2a, 0x75, 0x63, 0xf9, 0x5f, 0x47, 0x50, 0xba, + 0x4e, 0xe3, 0x3b, 0x48, 0x86, 0x2d, 0xd3, 0x8f, 0x42, 0x95, 0xda, 0xe8, 0x89, 0x02, 0xd1, 0x59, + 0x8e, 0xe8, 0x05, 0x9c, 0x6d, 0x2a, 0x09, 0xe0, 0x7b, 0x08, 0x16, 0xef, 0xa8, 0x2e, 0x8a, 0xcf, + 0x8e, 0x92, 0x94, 0x8a, 0xe4, 0xe3, 0xe3, 0xfa, 0x28, 0xc7, 0xb5, 0xa6, 0x8d, 0x85, 0x6b, 0x5d, + 0xbc, 0xaf, 0x7c, 0x1f, 0x45, 0x97, 0xd8, 0x9e, 0x7e, 0xf6, 0xff, 0x6a, 0xb7, 0x8c, 0xb6, 0xb8, + 0x76, 0x81, 0xe3, 0xab, 0xe3, 0xb3, 0xe3, 0xe0, 0x6b, 0x88, 0x26, 0x37, 0xfe, 0x2e, 0x82, 0x43, + 0xfc, 0xad, 0x41, 0x65, 0xdc, 0x93, 0x62, 0x86, 0xbd, 0x4c, 0x8c, 0x91, 0x62, 0x44, 0xfc, 0xd1, + 0xf6, 0x05, 0x6a, 0x5d, 0xbe, 0x23, 0x7c, 0x03, 0xc1, 0x01, 0x99, 0xd4, 0xc4, 0xee, 0xae, 0x8d, + 0x32, 0xdc, 0x7e, 0x93, 0xa0, 0x70, 0xb7, 0xd5, 0xf1, 0xdc, 0xed, 0x5d, 0x04, 0x73, 0xa2, 0x9b, + 0x9f, 0x51, 0x2a, 0x28, 0xed, 0xfe, 0x4a, 0x4f, 0x8f, 0x43, 0x34, 0x83, 0xb5, 0xcf, 0x73, 0xb1, + 0xf7, 0x70, 0x23, 0x4b, 0xac, 0xe7, 0x9a, 0x41, 0xe3, 0x91, 0xe8, 0xc4, 0x3e, 0x6e, 0xd8, 0x6e, + 0x2b, 0x78, 0x4d, 0xc3, 0x99, 0x09, 0x91, 0xcd, 0x39, 0x87, 0x70, 0x08, 0xf3, 0xcc, 0x39, 0x78, + 0xe3, 0x04, 0x57, 0x7b, 0xda, 0x2c, 0x7d, 0x3d, 0x95, 0x4a, 0xa5, 0xaf, 0x11, 0x93, 0x64, 0x40, + 0x71, 0x8d, 0xc5, 0xcf, 0x67, 0x8a, 0xe5, 0x82, 0xde, 0x42, 0x70, 0x48, 0xf5, 0xf6, 0x48, 0xfc, + 0xd8, 0xbe, 0x9e, 0x85, 0x42, 0x14, 0xd5, 0x78, 0x75, 0x2c, 0x47, 0xe2, 0x70, 0x2e, 0x5f, 0xfb, + 0xe3, 0x93, 0x63, 0xe8, 0xbd, 0x27, 0xc7, 0xd0, 0xdf, 0x9f, 0x1c, 0x43, 0xaf, 0x5d, 0x1c, 0xef, + 0x3f, 0xc2, 0x86, 0x6d, 0x51, 0x27, 0x54, 0xd9, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x45, 0x63, + 0x3b, 0x00, 0x09, 0x2d, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -5776,51 +5700,6 @@ func (m *ApplicationResourceDeleteRequest) MarshalToSizedBuffer(dAtA []byte) (in return len(dAtA) - i, nil } -func (m *ResourceActionParameters) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceActionParameters) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ResourceActionParameters) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.XXX_unrecognized != nil { - i -= len(m.XXX_unrecognized) - copy(dAtA[i:], m.XXX_unrecognized) - } - if m.Value == nil { - return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") - } else { - i -= len(*m.Value) - copy(dAtA[i:], *m.Value) - i = encodeVarintApplication(dAtA, i, uint64(len(*m.Value))) - i-- - dAtA[i] = 0x12 - } - if m.Name == nil { - return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") - } else { - i -= len(*m.Name) - copy(dAtA[i:], *m.Name) - i = encodeVarintApplication(dAtA, i, uint64(len(*m.Name))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - func (m *ResourceActionRunRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -5845,20 +5724,6 @@ func (m *ResourceActionRunRequest) MarshalToSizedBuffer(dAtA []byte) (int, error i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - if len(m.ResourceActionParameters) > 0 { - for iNdEx := len(m.ResourceActionParameters) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.ResourceActionParameters[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintApplication(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x52 - } - } if m.Project != nil { i -= len(*m.Project) copy(dAtA[i:], *m.Project) @@ -6036,18 +5901,6 @@ func (m *ApplicationPodLogsQuery) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - if m.MatchCase != nil { - i-- - if *m.MatchCase { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x88 - } if m.Project != nil { i -= len(*m.Project) copy(dAtA[i:], *m.Project) @@ -7484,26 +7337,6 @@ func (m *ApplicationResourceDeleteRequest) Size() (n int) { return n } -func (m *ResourceActionParameters) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Name != nil { - l = len(*m.Name) - n += 1 + l + sovApplication(uint64(l)) - } - if m.Value != nil { - l = len(*m.Value) - n += 1 + l + sovApplication(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - func (m *ResourceActionRunRequest) Size() (n int) { if m == nil { return 0 @@ -7546,12 +7379,6 @@ func (m *ResourceActionRunRequest) Size() (n int) { l = len(*m.Project) n += 1 + l + sovApplication(uint64(l)) } - if len(m.ResourceActionParameters) > 0 { - for _, e := range m.ResourceActionParameters { - l = e.Size() - n += 1 + l + sovApplication(uint64(l)) - } - } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -7658,9 +7485,6 @@ func (m *ApplicationPodLogsQuery) Size() (n int) { l = len(*m.Project) n += 2 + l + sovApplication(uint64(l)) } - if m.MatchCase != nil { - n += 3 - } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -12512,132 +12336,6 @@ func (m *ApplicationResourceDeleteRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *ResourceActionParameters) Unmarshal(dAtA []byte) error { - var hasFields [1]uint64 - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApplication - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceActionParameters: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceActionParameters: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApplication - } - 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 ErrInvalidLengthApplication - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthApplication - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Name = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000001) - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApplication - } - 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 ErrInvalidLengthApplication - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthApplication - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Value = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000002) - default: - iNdEx = preIndex - skippy, err := skipApplication(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthApplication - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - if hasFields[0]&uint64(0x00000001) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") - } - if hasFields[0]&uint64(0x00000002) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *ResourceActionRunRequest) Unmarshal(dAtA []byte) error { var hasFields [1]uint64 l := len(dAtA) @@ -12970,40 +12668,6 @@ func (m *ResourceActionRunRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.Project = &s iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceActionParameters", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApplication - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthApplication - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthApplication - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ResourceActionParameters = append(m.ResourceActionParameters, &ResourceActionParameters{}) - if err := m.ResourceActionParameters[len(m.ResourceActionParameters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -13727,27 +13391,6 @@ func (m *ApplicationPodLogsQuery) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.Project = &s iNdEx = postIndex - case 17: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MatchCase", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApplication - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.MatchCase = &b default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) diff --git a/pkg/apiclient/application/application.pb.gw.go b/pkg/apiclient/application/application.pb.gw.go index 1085fe040c..ed6064cadb 100644 --- a/pkg/apiclient/application/application.pb.gw.go +++ b/pkg/apiclient/application/application.pb.gw.go @@ -1621,6 +1621,10 @@ func local_request_ApplicationService_ListResourceActions_0(ctx context.Context, } +var ( + filter_ApplicationService_RunResourceAction_0 = &utilities.DoubleArray{Encoding: map[string]int{"action": 0, "name": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} +) + func request_ApplicationService_RunResourceAction_0(ctx context.Context, marshaler runtime.Marshaler, client ApplicationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq ResourceActionRunRequest var metadata runtime.ServerMetadata @@ -1629,7 +1633,7 @@ func request_ApplicationService_RunResourceAction_0(ctx context.Context, marshal if berr != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) } - if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Action); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -1651,6 +1655,13 @@ func request_ApplicationService_RunResourceAction_0(ctx context.Context, marshal return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ApplicationService_RunResourceAction_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.RunResourceAction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err @@ -1664,7 +1675,7 @@ func local_request_ApplicationService_RunResourceAction_0(ctx context.Context, m if berr != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) } - if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Action); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -1686,6 +1697,13 @@ func local_request_ApplicationService_RunResourceAction_0(ctx context.Context, m return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ApplicationService_RunResourceAction_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.RunResourceAction(ctx, &protoReq) return msg, metadata, err diff --git a/pkg/apiclient/application/forwarder_overwrite.go b/pkg/apiclient/application/forwarder_overwrite.go index 4dd166a011..4769775f96 100644 --- a/pkg/apiclient/application/forwarder_overwrite.go +++ b/pkg/apiclient/application/forwarder_overwrite.go @@ -7,62 +7,62 @@ import ( gohttp "net/http" "strings" - "github.com/argoproj/argo-cd/v3/util/kube" + "github.com/argoproj/argo-cd/v2/util/kube" - "github.com/argoproj/pkg/v2/grpc/http" + "github.com/argoproj/pkg/grpc/http" "github.com/grpc-ecosystem/grpc-gateway/runtime" - //nolint:staticcheck + // nolint:staticcheck "github.com/golang/protobuf/proto" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) // appFields is a map of fields that can be selected from an application. // The manually maintained list is required because application list response might include thousands of applications // and JSON based field handling is too slow. -var appFields = map[string]func(app *v1alpha1.Application) any{ - "metadata.name": func(app *v1alpha1.Application) any { return app.Name }, - "metadata.namespace": func(app *v1alpha1.Application) any { return app.Namespace }, - "metadata.annotations": func(app *v1alpha1.Application) any { return app.Annotations }, - "metadata.labels": func(app *v1alpha1.Application) any { return app.Labels }, - "metadata.creationTimestamp": func(app *v1alpha1.Application) any { return app.CreationTimestamp }, - "metadata.deletionTimestamp": func(app *v1alpha1.Application) any { return app.DeletionTimestamp }, - "spec": func(app *v1alpha1.Application) any { return app.Spec }, - "status.sync.status": func(app *v1alpha1.Application) any { return app.Status.Sync.Status }, - "status.health": func(app *v1alpha1.Application) any { return app.Status.Health }, - "status.summary": func(app *v1alpha1.Application) any { return app.Status.Summary }, - "status.operationState.startedAt": func(app *v1alpha1.Application) any { +var appFields = map[string]func(app *v1alpha1.Application) interface{}{ + "metadata.name": func(app *v1alpha1.Application) interface{} { return app.Name }, + "metadata.namespace": func(app *v1alpha1.Application) interface{} { return app.Namespace }, + "metadata.annotations": func(app *v1alpha1.Application) interface{} { return app.Annotations }, + "metadata.labels": func(app *v1alpha1.Application) interface{} { return app.Labels }, + "metadata.creationTimestamp": func(app *v1alpha1.Application) interface{} { return app.CreationTimestamp }, + "metadata.deletionTimestamp": func(app *v1alpha1.Application) interface{} { return app.DeletionTimestamp }, + "spec": func(app *v1alpha1.Application) interface{} { return app.Spec }, + "status.sync.status": func(app *v1alpha1.Application) interface{} { return app.Status.Sync.Status }, + "status.health": func(app *v1alpha1.Application) interface{} { return app.Status.Health }, + "status.summary": func(app *v1alpha1.Application) interface{} { return app.Status.Summary }, + "status.operationState.startedAt": func(app *v1alpha1.Application) interface{} { if app.Status.OperationState != nil { return app.Status.OperationState.StartedAt } return nil }, - "status.operationState.finishedAt": func(app *v1alpha1.Application) any { + "status.operationState.finishedAt": func(app *v1alpha1.Application) interface{} { if app.Status.OperationState != nil { return app.Status.OperationState.FinishedAt } return nil }, - "status.resources": func(app *v1alpha1.Application) any { + "status.resources": func(app *v1alpha1.Application) interface{} { if len(app.Status.Resources) > 0 { return app.Status.Resources } return nil }, - "operation.sync": func(app *v1alpha1.Application) any { + "operation.sync": func(app *v1alpha1.Application) interface{} { if app.Operation != nil { return app.Operation.Sync } return nil }, - "status.operationState.phase": func(app *v1alpha1.Application) any { + "status.operationState.phase": func(app *v1alpha1.Application) interface{} { if app.Status.OperationState != nil { return app.Status.OperationState.Phase } return nil }, - "status.operationState.operation.sync": func(app *v1alpha1.Application) any { + "status.operationState.operation.sync": func(app *v1alpha1.Application) interface{} { if app.Status.OperationState != nil { return app.Status.OperationState.SyncResult } @@ -70,11 +70,11 @@ var appFields = map[string]func(app *v1alpha1.Application) any{ }, } -func processApplicationListField(v any, fields map[string]any, exclude bool) (any, error) { +func processApplicationListField(v interface{}, fields map[string]interface{}, exclude bool) (interface{}, error) { if appList, ok := v.(*v1alpha1.ApplicationList); ok { - var items []map[string]any + var items []map[string]interface{} for _, app := range appList.Items { - converted := make(map[string]any) + converted := make(map[string]interface{}) items = append(items, converted) for field, fn := range appFields { if _, ok := fields["items."+field]; ok == exclude { @@ -92,9 +92,9 @@ func processApplicationListField(v any, fields map[string]any, exclude bool) (an item[subField] = value } else { if _, ok := item[subField]; !ok { - item[subField] = make(map[string]any) + item[subField] = make(map[string]interface{}) } - nestedMap, ok := item[subField].(map[string]any) + nestedMap, ok := item[subField].(map[string]interface{}) if !ok { return nil, fmt.Errorf("field %s is not a map", field) } @@ -103,7 +103,7 @@ func processApplicationListField(v any, fields map[string]any, exclude bool) (an } } } - return map[string]any{ + return map[string]interface{}{ "items": items, "metadata": appList.ListMeta, }, nil diff --git a/pkg/apiclient/application/forwarder_overwrite_test.go b/pkg/apiclient/application/forwarder_overwrite_test.go index 6a748d4188..370a841739 100644 --- a/pkg/apiclient/application/forwarder_overwrite_test.go +++ b/pkg/apiclient/application/forwarder_overwrite_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test" ) func TestProcessApplicationListField_SyncOperation(t *testing.T) { @@ -17,12 +17,12 @@ func TestProcessApplicationListField_SyncOperation(t *testing.T) { }}}}, } - res, err := processApplicationListField(&list, map[string]any{"items.operation.sync": true}, false) + res, err := processApplicationListField(&list, map[string]interface{}{"items.operation.sync": true}, false) require.NoError(t, err) - resMap, ok := res.(map[string]any) + resMap, ok := res.(map[string]interface{}) require.True(t, ok) - items, ok := resMap["items"].([]map[string]any) + items, ok := resMap["items"].([]map[string]interface{}) require.True(t, ok) item := test.ToMap(items[0]) @@ -38,12 +38,12 @@ func TestProcessApplicationListField_SyncOperationMissing(t *testing.T) { Items: []v1alpha1.Application{{Operation: nil}}, } - res, err := processApplicationListField(&list, map[string]any{"items.operation.sync": true}, false) + res, err := processApplicationListField(&list, map[string]interface{}{"items.operation.sync": true}, false) require.NoError(t, err) - resMap, ok := res.(map[string]any) + resMap, ok := res.(map[string]interface{}) require.True(t, ok) - items, ok := resMap["items"].([]map[string]any) + items, ok := resMap["items"].([]map[string]interface{}) require.True(t, ok) item := test.ToMap(items[0]) diff --git a/pkg/apiclient/applicationset/applicationset.pb.go b/pkg/apiclient/applicationset/applicationset.pb.go index 7ad86f0e2b..1c26125224 100644 --- a/pkg/apiclient/applicationset/applicationset.pb.go +++ b/pkg/apiclient/applicationset/applicationset.pb.go @@ -10,7 +10,7 @@ package applicationset import ( context "context" fmt "fmt" - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" @@ -499,49 +499,49 @@ func init() { } var fileDescriptor_eacb9df0ce5738fa = []byte{ - // 664 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x96, 0xcf, 0x6b, 0xd4, 0x40, - 0x14, 0xc7, 0x99, 0xb6, 0x6c, 0xb7, 0xd3, 0xa2, 0x30, 0x60, 0xbb, 0x46, 0x5d, 0x97, 0x80, 0xb5, - 0xb6, 0x76, 0x42, 0x5b, 0x4f, 0xf5, 0xe4, 0x0f, 0x28, 0x85, 0x22, 0x9a, 0x15, 0x05, 0x3d, 0xc8, - 0x34, 0xfb, 0x48, 0x63, 0xb3, 0xc9, 0x38, 0x33, 0x09, 0x94, 0xe2, 0x45, 0xf0, 0xec, 0x41, 0xf4, - 0x0f, 0xd0, 0x8b, 0x7f, 0x80, 0x77, 0x0f, 0x5e, 0x3c, 0x0a, 0xfe, 0x03, 0x52, 0xfc, 0x33, 0x3c, - 0x48, 0x26, 0xd9, 0x6d, 0x33, 0xec, 0x8f, 0x82, 0xd1, 0x5b, 0x5e, 0x66, 0xf2, 0xde, 0x67, 0xbe, - 0xef, 0xe5, 0xcb, 0xe0, 0x65, 0x09, 0x22, 0x05, 0xe1, 0x30, 0xce, 0xc3, 0xc0, 0x63, 0x2a, 0x88, - 0x23, 0x09, 0xca, 0x08, 0x29, 0x17, 0xb1, 0x8a, 0xc9, 0x99, 0xf2, 0x5b, 0xeb, 0xa2, 0x1f, 0xc7, - 0x7e, 0x08, 0x0e, 0xe3, 0x81, 0xc3, 0xa2, 0x28, 0x56, 0xf9, 0x4a, 0xbe, 0xdb, 0xda, 0xf1, 0x03, - 0xb5, 0x97, 0xec, 0x52, 0x2f, 0xee, 0x3a, 0x4c, 0xf8, 0x31, 0x17, 0xf1, 0x73, 0xfd, 0xb0, 0xea, - 0x75, 0x9c, 0x74, 0xc3, 0xe1, 0xfb, 0x7e, 0xf6, 0xa5, 0x3c, 0x59, 0xcb, 0x49, 0xd7, 0x58, 0xc8, - 0xf7, 0xd8, 0x9a, 0xe3, 0x43, 0x04, 0x82, 0x29, 0xe8, 0xe4, 0xd9, 0xec, 0x47, 0x78, 0xfe, 0xd6, - 0xf1, 0xbe, 0x36, 0xa8, 0x2d, 0x50, 0x0f, 0x12, 0x10, 0x07, 0x84, 0xe0, 0xa9, 0x88, 0x75, 0xa1, - 0x81, 0x5a, 0x68, 0x69, 0xc6, 0xd5, 0xcf, 0x64, 0x09, 0x9f, 0x65, 0x9c, 0x4b, 0x50, 0xf7, 0x58, - 0x17, 0x24, 0x67, 0x1e, 0x34, 0x26, 0xf4, 0xb2, 0xf9, 0xda, 0x3e, 0xc4, 0x0b, 0xe5, 0xbc, 0x3b, - 0x81, 0x2c, 0x12, 0x5b, 0xb8, 0x9e, 0x31, 0x83, 0xa7, 0x64, 0x03, 0xb5, 0x26, 0x97, 0x66, 0xdc, - 0x7e, 0x9c, 0xad, 0x49, 0x08, 0xc1, 0x53, 0xb1, 0x28, 0x32, 0xf7, 0xe3, 0x41, 0xc5, 0x27, 0x07, - 0x17, 0xff, 0x84, 0xcc, 0x53, 0xb9, 0x20, 0x79, 0x26, 0x2e, 0x69, 0xe0, 0xe9, 0xa2, 0x58, 0x71, - 0xb0, 0x5e, 0x48, 0x14, 0x36, 0xfa, 0xa0, 0x01, 0x66, 0xd7, 0x77, 0xe8, 0xb1, 0xe0, 0xb4, 0x27, - 0xb8, 0x7e, 0x78, 0xe6, 0x75, 0x68, 0xba, 0x41, 0xf9, 0xbe, 0x4f, 0x33, 0xc1, 0xe9, 0x89, 0xcf, - 0x69, 0x4f, 0x70, 0x6a, 0x70, 0x18, 0x35, 0xec, 0xaf, 0x08, 0x5f, 0x28, 0x6f, 0xb9, 0x23, 0x80, - 0x29, 0x70, 0xe1, 0x45, 0x02, 0x72, 0x10, 0x15, 0xfa, 0xf7, 0x54, 0x64, 0x1e, 0xd7, 0x12, 0x2e, - 0x41, 0xe4, 0x1a, 0xd4, 0xdd, 0x22, 0xca, 0xde, 0x77, 0xc4, 0x81, 0x9b, 0x44, 0x5a, 0xf9, 0xba, - 0x5b, 0x44, 0xf6, 0x53, 0xf3, 0x10, 0x77, 0x21, 0x84, 0xe3, 0x43, 0xfc, 0xdd, 0x28, 0x3d, 0x36, - 0x47, 0xe9, 0xa1, 0x00, 0xa8, 0x62, 0x46, 0xdf, 0x21, 0x7c, 0xc9, 0x1c, 0xfe, 0xfc, 0xef, 0x18, - 0xac, 0x7e, 0xfb, 0x3f, 0xa8, 0xdf, 0x06, 0x65, 0xbf, 0x41, 0xb8, 0x39, 0x8c, 0xab, 0x18, 0xe3, - 0x2e, 0x9e, 0x3b, 0xd9, 0x32, 0xfd, 0x1f, 0xcd, 0xae, 0x6f, 0x57, 0x86, 0xe5, 0x96, 0xd2, 0xaf, - 0xff, 0x9e, 0xc6, 0xe7, 0xca, 0x44, 0x6d, 0x10, 0x69, 0xe0, 0x01, 0xf9, 0x88, 0xf0, 0xe4, 0x16, - 0x28, 0xb2, 0x48, 0x0d, 0x6b, 0x1b, 0xec, 0x2a, 0x56, 0xa5, 0xca, 0xd9, 0x8b, 0xaf, 0x7e, 0xfc, - 0x7a, 0x3b, 0xd1, 0x22, 0x4d, 0xed, 0x95, 0xe9, 0x9a, 0xe1, 0xaf, 0xd2, 0x39, 0xcc, 0x46, 0xe2, - 0x25, 0x79, 0x8f, 0x70, 0xbd, 0xa7, 0x21, 0x59, 0x1d, 0x87, 0x5a, 0x9a, 0x01, 0x8b, 0x9e, 0x76, - 0x7b, 0xde, 0x1a, 0x7b, 0x45, 0x33, 0x5d, 0xb1, 0x5b, 0xc3, 0x98, 0x7a, 0x16, 0xbc, 0x89, 0x96, - 0xc9, 0x07, 0x84, 0xa7, 0x32, 0x67, 0x24, 0x57, 0x47, 0x57, 0xe9, 0xbb, 0xa7, 0x75, 0xbf, 0x4a, - 0x01, 0xb3, 0xb4, 0xf6, 0x65, 0x0d, 0x7c, 0x9e, 0x2c, 0x0c, 0x01, 0x26, 0x9f, 0x11, 0xae, 0xe5, - 0xae, 0x44, 0x56, 0x46, 0x63, 0x96, 0xbc, 0xab, 0xe2, 0x5e, 0x3b, 0x1a, 0xf3, 0x9a, 0x3d, 0x0c, - 0x73, 0xd3, 0x34, 0xb1, 0xd7, 0x08, 0xd7, 0x72, 0x1f, 0x1a, 0x87, 0x5d, 0x72, 0x2b, 0x6b, 0xcc, - 0x28, 0xf7, 0x1b, 0x5d, 0x0c, 0xdf, 0xf2, 0xb8, 0xe1, 0xfb, 0x82, 0xf0, 0x9c, 0x0b, 0x32, 0x4e, - 0x84, 0x07, 0x99, 0x75, 0x8d, 0xeb, 0x75, 0xdf, 0xde, 0xaa, 0xed, 0x75, 0x96, 0xd6, 0xbe, 0xa1, - 0x99, 0x29, 0xb9, 0x3e, 0x9a, 0xd9, 0x11, 0x05, 0xef, 0xaa, 0x12, 0x00, 0xb7, 0xb7, 0xbf, 0x1d, - 0x35, 0xd1, 0xf7, 0xa3, 0x26, 0xfa, 0x79, 0xd4, 0x44, 0x4f, 0x6e, 0x9e, 0xee, 0x02, 0xe2, 0x85, - 0x01, 0x44, 0xe6, 0x8d, 0x67, 0xb7, 0xa6, 0xaf, 0x1d, 0x1b, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, - 0xc5, 0x6a, 0x1d, 0x1e, 0x20, 0x09, 0x00, 0x00, + // 665 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x96, 0x4f, 0x6b, 0xd4, 0x4e, + 0x18, 0xc7, 0x99, 0xb6, 0x6c, 0xb7, 0xd3, 0xf2, 0xfb, 0xc1, 0x80, 0xed, 0x1a, 0x75, 0x5d, 0x02, + 0xd6, 0xda, 0xda, 0x09, 0x5d, 0x3d, 0xd5, 0x93, 0x7f, 0xa0, 0x14, 0x8a, 0x68, 0x56, 0x14, 0xf4, + 0x20, 0xd3, 0xec, 0x43, 0x1a, 0x9b, 0x4d, 0xc6, 0x99, 0x49, 0xa0, 0x14, 0x2f, 0x82, 0x67, 0x0f, + 0xa2, 0x2f, 0x40, 0x2f, 0xbe, 0x00, 0xef, 0x1e, 0xbc, 0x78, 0x14, 0x7c, 0x03, 0x52, 0x7c, 0x19, + 0x1e, 0x24, 0x93, 0xec, 0xb6, 0x19, 0xf6, 0x4f, 0xc1, 0xe8, 0x2d, 0x4f, 0x66, 0xf2, 0x3c, 0x9f, + 0xf9, 0x3e, 0x4f, 0xbe, 0x0c, 0x5e, 0x95, 0x20, 0x52, 0x10, 0x0e, 0xe3, 0x3c, 0x0c, 0x3c, 0xa6, + 0x82, 0x38, 0x92, 0xa0, 0x8c, 0x90, 0x72, 0x11, 0xab, 0x98, 0xfc, 0x57, 0x7e, 0x6b, 0x9d, 0xf7, + 0xe3, 0xd8, 0x0f, 0xc1, 0x61, 0x3c, 0x70, 0x58, 0x14, 0xc5, 0x2a, 0x5f, 0xc9, 0x77, 0x5b, 0x3b, + 0x7e, 0xa0, 0xf6, 0x92, 0x5d, 0xea, 0xc5, 0x3d, 0x87, 0x09, 0x3f, 0xe6, 0x22, 0x7e, 0xa6, 0x1f, + 0xd6, 0xbd, 0xae, 0x93, 0xb6, 0x1d, 0xbe, 0xef, 0x67, 0x5f, 0xca, 0x93, 0xb5, 0x9c, 0x74, 0x83, + 0x85, 0x7c, 0x8f, 0x6d, 0x38, 0x3e, 0x44, 0x20, 0x98, 0x82, 0x6e, 0x9e, 0xcd, 0x7e, 0x88, 0x17, + 0x6f, 0x1e, 0xef, 0xeb, 0x80, 0xda, 0x02, 0x75, 0x3f, 0x01, 0x71, 0x40, 0x08, 0x9e, 0x89, 0x58, + 0x0f, 0x1a, 0xa8, 0x85, 0x56, 0xe6, 0x5c, 0xfd, 0x4c, 0x56, 0xf0, 0xff, 0x8c, 0x73, 0x09, 0xea, + 0x2e, 0xeb, 0x81, 0xe4, 0xcc, 0x83, 0xc6, 0x94, 0x5e, 0x36, 0x5f, 0xdb, 0x87, 0x78, 0xa9, 0x9c, + 0x77, 0x27, 0x90, 0x45, 0x62, 0x0b, 0xd7, 0x33, 0x66, 0xf0, 0x94, 0x6c, 0xa0, 0xd6, 0xf4, 0xca, + 0x9c, 0x3b, 0x88, 0xb3, 0x35, 0x09, 0x21, 0x78, 0x2a, 0x16, 0x45, 0xe6, 0x41, 0x3c, 0xac, 0xf8, + 0xf4, 0xf0, 0xe2, 0x1f, 0x91, 0x79, 0x2a, 0x17, 0x24, 0xcf, 0xc4, 0x25, 0x0d, 0x3c, 0x5b, 0x14, + 0x2b, 0x0e, 0xd6, 0x0f, 0x89, 0xc2, 0x46, 0x1f, 0x34, 0xc0, 0x7c, 0x7b, 0x87, 0x1e, 0x0b, 0x4e, + 0xfb, 0x82, 0xeb, 0x87, 0xa7, 0x5e, 0x97, 0xa6, 0x6d, 0xca, 0xf7, 0x7d, 0x9a, 0x09, 0x4e, 0x4f, + 0x7c, 0x4e, 0xfb, 0x82, 0x53, 0x83, 0xc3, 0xa8, 0x61, 0x7f, 0x41, 0xf8, 0x5c, 0x79, 0xcb, 0x6d, + 0x01, 0x4c, 0x81, 0x0b, 0xcf, 0x13, 0x90, 0xc3, 0xa8, 0xd0, 0xdf, 0xa7, 0x22, 0x8b, 0xb8, 0x96, + 0x70, 0x09, 0x22, 0xd7, 0xa0, 0xee, 0x16, 0x51, 0xf6, 0xbe, 0x2b, 0x0e, 0xdc, 0x24, 0xd2, 0xca, + 0xd7, 0xdd, 0x22, 0xb2, 0x9f, 0x98, 0x87, 0xb8, 0x03, 0x21, 0x1c, 0x1f, 0xe2, 0xcf, 0x46, 0xe9, + 0x91, 0x39, 0x4a, 0x0f, 0x04, 0x40, 0x15, 0x33, 0xfa, 0x16, 0xe1, 0x0b, 0xe6, 0xf0, 0xe7, 0x7f, + 0xc7, 0x70, 0xf5, 0x3b, 0xff, 0x40, 0xfd, 0x0e, 0x28, 0xfb, 0x35, 0xc2, 0xcd, 0x51, 0x5c, 0xc5, + 0x18, 0xf7, 0xf0, 0xc2, 0xc9, 0x96, 0xe9, 0xff, 0x68, 0xbe, 0xbd, 0x5d, 0x19, 0x96, 0x5b, 0x4a, + 0xdf, 0xfe, 0x35, 0x8b, 0xcf, 0x94, 0x89, 0x3a, 0x20, 0xd2, 0xc0, 0x03, 0xf2, 0x01, 0xe1, 0xe9, + 0x2d, 0x50, 0x64, 0x99, 0x1a, 0xd6, 0x36, 0xdc, 0x55, 0xac, 0x4a, 0x95, 0xb3, 0x97, 0x5f, 0x7e, + 0xff, 0xf9, 0x66, 0xaa, 0x45, 0x9a, 0xda, 0x2b, 0xd3, 0x0d, 0xc3, 0x5f, 0xa5, 0x73, 0x98, 0x8d, + 0xc4, 0x0b, 0xf2, 0x0e, 0xe1, 0x7a, 0x5f, 0x43, 0xb2, 0x3e, 0x09, 0xb5, 0x34, 0x03, 0x16, 0x3d, + 0xed, 0xf6, 0xbc, 0x35, 0xf6, 0x9a, 0x66, 0xba, 0x64, 0xb7, 0x46, 0x31, 0xf5, 0x2d, 0x78, 0x13, + 0xad, 0x92, 0xf7, 0x08, 0xcf, 0x64, 0xce, 0x48, 0x2e, 0x8f, 0xaf, 0x32, 0x70, 0x4f, 0xeb, 0x5e, + 0x95, 0x02, 0x66, 0x69, 0xed, 0x8b, 0x1a, 0xf8, 0x2c, 0x59, 0x1a, 0x01, 0x4c, 0x3e, 0x21, 0x5c, + 0xcb, 0x5d, 0x89, 0xac, 0x8d, 0xc7, 0x2c, 0x79, 0x57, 0xc5, 0xbd, 0x76, 0x34, 0xe6, 0x15, 0x7b, + 0x14, 0xe6, 0xa6, 0x69, 0x62, 0xaf, 0x10, 0xae, 0xe5, 0x3e, 0x34, 0x09, 0xbb, 0xe4, 0x56, 0xd6, + 0x84, 0x51, 0x1e, 0x34, 0xba, 0x18, 0xbe, 0xd5, 0x49, 0xc3, 0xf7, 0x19, 0xe1, 0x05, 0x17, 0x64, + 0x9c, 0x08, 0x0f, 0x32, 0xeb, 0x9a, 0xd4, 0xeb, 0x81, 0xbd, 0x55, 0xdb, 0xeb, 0x2c, 0xad, 0x7d, + 0x5d, 0x33, 0x53, 0x72, 0x75, 0x3c, 0xb3, 0x23, 0x0a, 0xde, 0x75, 0x25, 0x00, 0x6e, 0x6d, 0x7f, + 0x3d, 0x6a, 0xa2, 0x6f, 0x47, 0x4d, 0xf4, 0xe3, 0xa8, 0x89, 0x1e, 0xdf, 0x38, 0xdd, 0x05, 0xc4, + 0x0b, 0x03, 0x88, 0xcc, 0x1b, 0xcf, 0x6e, 0x4d, 0x5f, 0x3b, 0xae, 0xfd, 0x0e, 0x00, 0x00, 0xff, + 0xff, 0x05, 0x4d, 0x64, 0x24, 0x20, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/pkg/apiclient/certificate/certificate.pb.go b/pkg/apiclient/certificate/certificate.pb.go index 96810f6a7d..e236c418e9 100644 --- a/pkg/apiclient/certificate/certificate.pb.go +++ b/pkg/apiclient/certificate/certificate.pb.go @@ -11,7 +11,7 @@ package certificate import ( context "context" fmt "fmt" - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" @@ -211,32 +211,32 @@ var fileDescriptor_387c41efc0710f00 = []byte{ // 448 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x54, 0xcf, 0x6a, 0x14, 0x31, 0x18, 0x27, 0x55, 0x4a, 0x4d, 0x05, 0x6d, 0x90, 0x52, 0x86, 0xba, 0x96, 0xa1, 0x60, 0x29, 0x98, - 0xb0, 0xdd, 0x8b, 0x78, 0x74, 0xc5, 0x53, 0x11, 0x9d, 0x0a, 0x82, 0x17, 0xc9, 0xce, 0x7e, 0xce, - 0xc6, 0xce, 0x26, 0x31, 0xf9, 0x66, 0x60, 0xf1, 0x26, 0xbe, 0x81, 0x6f, 0xa2, 0x27, 0xdf, 0x40, - 0xf1, 0x22, 0xf8, 0x02, 0xb2, 0xf8, 0x20, 0x32, 0x59, 0xd7, 0xcd, 0xc8, 0x88, 0x5e, 0x16, 0xbc, - 0x7d, 0xf9, 0x92, 0x7c, 0xbf, 0x7f, 0x21, 0xf4, 0xd0, 0x83, 0xab, 0xc1, 0x89, 0x1c, 0x1c, 0xaa, - 0xe7, 0x2a, 0x97, 0x08, 0x71, 0xcd, 0xad, 0x33, 0x68, 0xd8, 0x76, 0xd4, 0x4a, 0xf6, 0x0b, 0x63, - 0x8a, 0x12, 0x84, 0xb4, 0x4a, 0x48, 0xad, 0x0d, 0x4a, 0x54, 0x46, 0xfb, 0xc5, 0xd1, 0xe4, 0xb4, - 0x50, 0x38, 0xa9, 0x46, 0x3c, 0x37, 0x53, 0x21, 0x5d, 0x61, 0xac, 0x33, 0x2f, 0x42, 0x71, 0x2b, - 0x1f, 0x8b, 0x7a, 0x20, 0xec, 0x79, 0xd1, 0xdc, 0xf4, 0x42, 0x5a, 0x5b, 0x36, 0x03, 0x95, 0xd1, - 0xa2, 0xee, 0xcb, 0xd2, 0x4e, 0x64, 0x5f, 0x14, 0xa0, 0xc1, 0x49, 0x84, 0xf1, 0x62, 0x5a, 0xfa, - 0x86, 0xd0, 0x24, 0x03, 0x6b, 0xbc, 0x42, 0xe3, 0x66, 0xc3, 0x15, 0x8b, 0x47, 0x15, 0xb8, 0x19, - 0x3b, 0xa2, 0x57, 0x26, 0xc6, 0xe3, 0x03, 0x39, 0x85, 0x87, 0x12, 0x11, 0x9c, 0xde, 0x23, 0x07, - 0xe4, 0xe8, 0x52, 0xf6, 0x7b, 0x9b, 0x25, 0x74, 0xab, 0xd1, 0xf0, 0x78, 0x66, 0x61, 0x6f, 0x23, - 0x1c, 0xf9, 0xb5, 0x66, 0x07, 0x34, 0xe8, 0x3b, 0xab, 0x46, 0x61, 0xfb, 0x42, 0xd8, 0x8e, 0x5b, - 0xe9, 0x07, 0x42, 0xd3, 0x4e, 0x1a, 0x43, 0x07, 0x12, 0x21, 0x83, 0x97, 0x15, 0x78, 0x64, 0xaf, - 0xe8, 0xe5, 0xc8, 0x28, 0x1f, 0xb8, 0x6c, 0x9f, 0x3c, 0xe1, 0x2b, 0x4b, 0xf8, 0xd2, 0x92, 0x50, - 0x3c, 0xcb, 0xc7, 0xbc, 0x1e, 0x70, 0x7b, 0x5e, 0xf0, 0xc6, 0x12, 0x1e, 0x59, 0xc2, 0x97, 0x96, - 0xf0, 0x4e, 0xdc, 0x53, 0xe5, 0x31, 0x6b, 0x81, 0xb1, 0x5d, 0xba, 0x59, 0x59, 0x0f, 0x0e, 0x83, - 0xbe, 0xad, 0xec, 0xe7, 0x2a, 0xbd, 0x41, 0xaf, 0x77, 0x8e, 0xc8, 0xc0, 0x5b, 0xa3, 0x3d, 0x9c, - 0x7c, 0xbe, 0x48, 0x59, 0xd4, 0x3f, 0x03, 0x57, 0xab, 0x1c, 0xd8, 0x3b, 0x42, 0xaf, 0x36, 0x30, - 0xc3, 0x18, 0xe4, 0x26, 0x8f, 0x1f, 0xc7, 0x9f, 0x93, 0x49, 0xd6, 0x25, 0x3a, 0xdd, 0x7f, 0xfd, - 0xf5, 0xfb, 0xdb, 0x8d, 0x5d, 0x76, 0x2d, 0xbc, 0xbf, 0xba, 0x2f, 0x5a, 0x26, 0x7c, 0x22, 0x74, - 0x67, 0x91, 0x49, 0x74, 0x8f, 0x89, 0xbf, 0xb3, 0x6e, 0x05, 0xb9, 0x3e, 0xf6, 0xc7, 0x81, 0xfd, - 0x61, 0xda, 0xc9, 0xfe, 0x4e, 0x3b, 0xd0, 0xf7, 0x84, 0xee, 0xdc, 0x83, 0x12, 0xda, 0x5a, 0xfe, - 0x9b, 0x04, 0x8e, 0x3b, 0x35, 0xdc, 0xbd, 0xff, 0x71, 0xde, 0x23, 0x5f, 0xe6, 0x3d, 0xf2, 0x6d, - 0xde, 0x23, 0x4f, 0x6f, 0xff, 0xdb, 0x6f, 0x90, 0x97, 0x0a, 0x34, 0xc6, 0x83, 0x46, 0x9b, 0xe1, - 0x03, 0x18, 0xfc, 0x08, 0x00, 0x00, 0xff, 0xff, 0xaf, 0x4d, 0x4a, 0x41, 0xa1, 0x04, 0x00, 0x00, + 0xb0, 0xe3, 0x45, 0x3c, 0xba, 0xe2, 0xa9, 0x88, 0x4e, 0x05, 0xc1, 0x8b, 0x64, 0x67, 0x3f, 0x67, + 0x63, 0xa7, 0x49, 0x4c, 0xbe, 0x19, 0x58, 0xbc, 0x89, 0x6f, 0xe0, 0x9b, 0xe8, 0xc9, 0x37, 0x50, + 0xbc, 0x08, 0xbe, 0x80, 0x2c, 0x3e, 0x88, 0x4c, 0xd6, 0xba, 0x19, 0x19, 0xd1, 0xcb, 0x42, 0x6f, + 0x5f, 0xbe, 0x24, 0xdf, 0xef, 0x5f, 0x08, 0xdd, 0xf7, 0xe0, 0x1a, 0x70, 0xa2, 0x00, 0x87, 0xea, + 0x85, 0x2a, 0x24, 0x42, 0x5c, 0x73, 0xeb, 0x0c, 0x1a, 0xb6, 0x19, 0xb5, 0x92, 0xdd, 0xd2, 0x98, + 0xb2, 0x02, 0x21, 0xad, 0x12, 0x52, 0x6b, 0x83, 0x12, 0x95, 0xd1, 0x7e, 0x71, 0x34, 0x39, 0x2a, + 0x15, 0x4e, 0xeb, 0x31, 0x2f, 0xcc, 0xa9, 0x90, 0xae, 0x34, 0xd6, 0x99, 0x97, 0xa1, 0xb8, 0x55, + 0x4c, 0x44, 0x93, 0x09, 0x7b, 0x52, 0xb6, 0x37, 0xbd, 0x90, 0xd6, 0x56, 0xed, 0x40, 0x65, 0xb4, + 0x68, 0x86, 0xb2, 0xb2, 0x53, 0x39, 0x14, 0x25, 0x68, 0x70, 0x12, 0x61, 0xb2, 0x98, 0x96, 0xbe, + 0x25, 0x34, 0xc9, 0xc1, 0x1a, 0xaf, 0xd0, 0xb8, 0xd9, 0x68, 0xc9, 0xe2, 0x71, 0x0d, 0x6e, 0xc6, + 0x0e, 0xe8, 0x95, 0xa9, 0xf1, 0xf8, 0x50, 0x9e, 0xc2, 0x23, 0x89, 0x08, 0x4e, 0xef, 0x90, 0x3d, + 0x72, 0x70, 0x29, 0xff, 0xb3, 0xcd, 0x12, 0xba, 0xd1, 0x6a, 0x78, 0x32, 0xb3, 0xb0, 0xb3, 0x16, + 0x8e, 0xfc, 0x5e, 0xb3, 0x3d, 0x1a, 0xf4, 0x1d, 0xd7, 0xe3, 0xb0, 0x7d, 0x21, 0x6c, 0xc7, 0xad, + 0xf4, 0x23, 0xa1, 0x69, 0x2f, 0x8d, 0x91, 0x03, 0x89, 0x90, 0xc3, 0xab, 0x1a, 0x3c, 0xb2, 0xd7, + 0xf4, 0x72, 0x64, 0x94, 0x0f, 0x5c, 0x36, 0xb3, 0xa7, 0x7c, 0x69, 0x09, 0x3f, 0xb3, 0x24, 0x14, + 0xcf, 0x8b, 0x09, 0x6f, 0x32, 0x6e, 0x4f, 0x4a, 0xde, 0x5a, 0xc2, 0x23, 0x4b, 0xf8, 0x99, 0x25, + 0xbc, 0x17, 0xf7, 0x48, 0x79, 0xcc, 0x3b, 0x60, 0x6c, 0x9b, 0xae, 0xd7, 0xd6, 0x83, 0xc3, 0xa0, + 0x6f, 0x23, 0xff, 0xb5, 0x4a, 0x6f, 0xd0, 0xeb, 0xbd, 0x23, 0x72, 0xf0, 0xd6, 0x68, 0x0f, 0xd9, + 0x97, 0x8b, 0x94, 0x45, 0xfd, 0x63, 0x70, 0x8d, 0x2a, 0x80, 0xbd, 0x27, 0xf4, 0x6a, 0x0b, 0x33, + 0x8a, 0x41, 0x6e, 0xf2, 0xf8, 0x71, 0xfc, 0x3d, 0x99, 0x64, 0x55, 0xa2, 0xd3, 0xdd, 0x37, 0xdf, + 0x7e, 0xbc, 0x5b, 0xdb, 0x66, 0xd7, 0xc2, 0xfb, 0x6b, 0x86, 0xa2, 0x63, 0xc2, 0x67, 0x42, 0xb7, + 0x16, 0x99, 0x44, 0xf7, 0x98, 0xf8, 0x37, 0xeb, 0x4e, 0x90, 0xab, 0x63, 0x7f, 0x18, 0xd8, 0xef, + 0xa7, 0xbd, 0xec, 0xef, 0x76, 0x03, 0xfd, 0x40, 0xe8, 0xd6, 0x7d, 0xa8, 0xa0, 0xab, 0xe5, 0xdc, + 0x24, 0x70, 0xd8, 0xab, 0xe1, 0xde, 0x83, 0x4f, 0xf3, 0x01, 0xf9, 0x3a, 0x1f, 0x90, 0xef, 0xf3, + 0x01, 0x79, 0x76, 0xe7, 0xff, 0x7e, 0x83, 0xa2, 0x52, 0xa0, 0x31, 0x1e, 0x34, 0x5e, 0x0f, 0x1f, + 0xc0, 0xed, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x19, 0x1a, 0x3e, 0x95, 0xa1, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/pkg/apiclient/cluster/cluster.pb.go b/pkg/apiclient/cluster/cluster.pb.go index b8dcfe85e9..605be6d307 100644 --- a/pkg/apiclient/cluster/cluster.pb.go +++ b/pkg/apiclient/cluster/cluster.pb.go @@ -10,7 +10,7 @@ package cluster import ( context "context" fmt "fmt" - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" @@ -322,45 +322,45 @@ func init() { func init() { proto.RegisterFile("server/cluster/cluster.proto", fileDescriptor_a6b5ba0b5aa57b32) } var fileDescriptor_a6b5ba0b5aa57b32 = []byte{ - // 596 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x95, 0xcf, 0x6f, 0xd3, 0x30, - 0x14, 0xc7, 0xe5, 0x6e, 0x74, 0xcc, 0x03, 0x06, 0xd6, 0x40, 0x51, 0xf7, 0x43, 0x25, 0x20, 0x28, - 0x68, 0xb5, 0xd5, 0x76, 0x5c, 0xb8, 0xb1, 0x0e, 0x50, 0xa5, 0x5d, 0x08, 0xe2, 0xc2, 0x61, 0x93, - 0x97, 0x3c, 0xa5, 0x66, 0x59, 0x62, 0x62, 0x27, 0xd2, 0x84, 0xb8, 0xec, 0xc4, 0x0d, 0x21, 0xae, - 0x5c, 0xf9, 0x43, 0xb8, 0x21, 0x71, 0x41, 0xe2, 0x1f, 0x40, 0x15, 0x7f, 0x08, 0x8a, 0x93, 0xb4, - 0xb4, 0xd3, 0xaa, 0x21, 0x15, 0x4e, 0xf5, 0x7b, 0xea, 0xf3, 0xf7, 0xf3, 0xbe, 0x7e, 0x8e, 0xf1, - 0x9a, 0x82, 0x38, 0x85, 0x98, 0xb9, 0x41, 0xa2, 0xf4, 0xe8, 0x97, 0xca, 0x38, 0xd2, 0x11, 0x59, - 0x28, 0xc2, 0xda, 0x9a, 0x1f, 0x45, 0x7e, 0x00, 0x8c, 0x4b, 0xc1, 0x78, 0x18, 0x46, 0x9a, 0x6b, - 0x11, 0x85, 0x2a, 0xff, 0x5b, 0x6d, 0xd7, 0x17, 0xba, 0x9f, 0x1c, 0x50, 0x37, 0x3a, 0x62, 0x3c, - 0xf6, 0x23, 0x19, 0x47, 0xaf, 0xcc, 0xa2, 0xe9, 0x7a, 0x2c, 0xed, 0x30, 0x79, 0xe8, 0x67, 0x95, - 0x8a, 0x71, 0x29, 0x03, 0xe1, 0x9a, 0x5a, 0x96, 0xb6, 0x78, 0x20, 0xfb, 0xbc, 0xc5, 0x7c, 0x08, - 0x21, 0xe6, 0x1a, 0xbc, 0x7c, 0x37, 0xfb, 0x01, 0x5e, 0xec, 0xe6, 0xb2, 0xbd, 0x1d, 0x42, 0xf0, - 0xbc, 0x3e, 0x96, 0x60, 0xa1, 0x3a, 0x6a, 0x2c, 0x3a, 0x66, 0x4d, 0x56, 0xf0, 0x85, 0x94, 0x07, - 0x09, 0x58, 0x15, 0x93, 0xcc, 0x03, 0x7b, 0x0f, 0x5f, 0x2a, 0xca, 0x9e, 0x25, 0x10, 0x1f, 0x93, - 0x1b, 0xb8, 0x9a, 0xf7, 0x56, 0xd4, 0x16, 0x51, 0xb6, 0x63, 0xc8, 0x8f, 0xca, 0x62, 0xb3, 0x26, - 0x36, 0xae, 0x08, 0xcf, 0x9a, 0xab, 0xa3, 0xc6, 0x52, 0x9b, 0xd0, 0xd2, 0x83, 0x21, 0x85, 0x53, - 0x11, 0x9e, 0x7d, 0x0d, 0x2f, 0x17, 0x09, 0x07, 0x94, 0x8c, 0x42, 0x05, 0xf6, 0x7b, 0x84, 0x57, - 0x8a, 0x5c, 0x37, 0x06, 0xae, 0xc1, 0x81, 0xd7, 0x09, 0x28, 0x4d, 0xf6, 0x71, 0xe9, 0x9c, 0x11, - 0x5f, 0x6a, 0x3f, 0xa6, 0x23, 0x8b, 0x68, 0x69, 0x91, 0x59, 0xec, 0xbb, 0x1e, 0x4d, 0x3b, 0x54, - 0x1e, 0xfa, 0x34, 0xb3, 0x88, 0xfe, 0x61, 0x11, 0x2d, 0x2d, 0x2a, 0x49, 0x9c, 0x72, 0xd7, 0xac, - 0xb9, 0x44, 0x2a, 0x88, 0xb5, 0x69, 0xe3, 0xa2, 0x53, 0x44, 0xf6, 0x97, 0x11, 0xd1, 0x0b, 0xe9, - 0xfd, 0x4f, 0xa2, 0xdb, 0xf8, 0x72, 0x62, 0x14, 0xbd, 0x27, 0x02, 0x02, 0x4f, 0x59, 0x95, 0xfa, - 0x5c, 0x63, 0xd1, 0x19, 0x4f, 0x9e, 0xc7, 0xe8, 0xf6, 0xb7, 0x05, 0x7c, 0xa5, 0xc8, 0x3c, 0x87, - 0x38, 0x15, 0x2e, 0x90, 0x13, 0x84, 0xe7, 0x77, 0x85, 0xd2, 0xe4, 0xfa, 0x64, 0x8d, 0x39, 0xeb, - 0x5a, 0x6f, 0x26, 0xcd, 0x64, 0x0a, 0xb6, 0x75, 0xf2, 0xe3, 0xd7, 0xc7, 0x0a, 0x21, 0x57, 0xcd, - 0xac, 0xa7, 0xad, 0xf2, 0x46, 0x28, 0xf2, 0x01, 0xe1, 0x6a, 0x7e, 0xcc, 0x64, 0x7d, 0x12, 0x63, - 0xec, 0xf8, 0x6b, 0xb3, 0xf1, 0xd6, 0xbe, 0x69, 0x50, 0x56, 0xed, 0x53, 0x28, 0x0f, 0x87, 0xae, - 0xbf, 0x43, 0x78, 0xee, 0x29, 0x9c, 0xe9, 0xcb, 0x8c, 0x40, 0x6e, 0x19, 0x90, 0x75, 0xb2, 0x3a, - 0x09, 0xc2, 0xde, 0x08, 0x8f, 0x9a, 0xeb, 0xf7, 0x96, 0x7c, 0x42, 0xb8, 0x9a, 0xcf, 0xdc, 0x69, - 0x7b, 0xc6, 0x66, 0x71, 0x56, 0x54, 0x9b, 0x86, 0xea, 0x4e, 0x6d, 0x1a, 0xd5, 0xc8, 0xa9, 0x3d, - 0x5c, 0xdd, 0x81, 0x00, 0x34, 0x9c, 0xe5, 0x95, 0x35, 0x99, 0x1e, 0x5e, 0xf3, 0xa2, 0xfd, 0xfb, - 0x53, 0xdb, 0x0f, 0x31, 0x76, 0xb2, 0xcf, 0x22, 0x3c, 0x4a, 0x74, 0xff, 0xef, 0x35, 0x98, 0xd1, - 0xb8, 0x67, 0xdf, 0x9d, 0xa2, 0xc1, 0x62, 0x23, 0xd0, 0xe4, 0x99, 0xc2, 0x67, 0x84, 0x97, 0x7b, - 0x61, 0xca, 0x03, 0x91, 0x59, 0xdb, 0xe5, 0x6e, 0x1f, 0xfe, 0xf1, 0x14, 0x6c, 0x19, 0x44, 0x6a, - 0x6f, 0x4e, 0x43, 0x14, 0x43, 0xa4, 0xa6, 0x9b, 0x31, 0x6d, 0x6f, 0x7f, 0x1d, 0x6c, 0xa0, 0xef, - 0x83, 0x0d, 0xf4, 0x73, 0xb0, 0x81, 0x5e, 0x6e, 0x9d, 0xef, 0xa5, 0x70, 0x03, 0x01, 0xa1, 0x2e, - 0x05, 0x0e, 0xaa, 0xe6, 0x61, 0xe8, 0xfc, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x3f, 0x7b, 0x15, - 0xad, 0x06, 0x00, 0x00, + // 597 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x95, 0xc1, 0x6f, 0xd3, 0x3e, + 0x14, 0xc7, 0xe5, 0x6e, 0xbf, 0xee, 0x57, 0x0f, 0x18, 0x58, 0x03, 0x45, 0xdd, 0x56, 0x95, 0x80, + 0xa0, 0xa0, 0xd5, 0x56, 0xcb, 0xb8, 0x70, 0x63, 0x1d, 0xa0, 0x4a, 0xbb, 0x10, 0xc4, 0x85, 0xc3, + 0x26, 0x2f, 0x79, 0x4a, 0xcd, 0xb2, 0xc4, 0xc4, 0x4e, 0xa4, 0x09, 0x71, 0xd9, 0x89, 0x1b, 0x42, + 0x5c, 0xb9, 0xf2, 0x87, 0x70, 0x43, 0xe2, 0x82, 0xc4, 0x3f, 0x80, 0x2a, 0xfe, 0x10, 0x14, 0x27, + 0x69, 0x69, 0xa7, 0x55, 0x43, 0x2a, 0x9c, 0xea, 0xf7, 0xd4, 0xe7, 0xef, 0xe7, 0x7d, 0xfd, 0x1c, + 0xe3, 0x75, 0x05, 0x71, 0x0a, 0x31, 0x73, 0x83, 0x44, 0xe9, 0xf1, 0x2f, 0x95, 0x71, 0xa4, 0x23, + 0xb2, 0x54, 0x84, 0xf5, 0x75, 0x3f, 0x8a, 0xfc, 0x00, 0x18, 0x97, 0x82, 0xf1, 0x30, 0x8c, 0x34, + 0xd7, 0x22, 0x0a, 0x55, 0xfe, 0xb7, 0xfa, 0xae, 0x2f, 0xf4, 0x20, 0x39, 0xa0, 0x6e, 0x74, 0xc4, + 0x78, 0xec, 0x47, 0x32, 0x8e, 0x5e, 0x9a, 0x45, 0xdb, 0xf5, 0x58, 0xda, 0x65, 0xf2, 0xd0, 0xcf, + 0x2a, 0x15, 0xe3, 0x52, 0x06, 0xc2, 0x35, 0xb5, 0x2c, 0xed, 0xf0, 0x40, 0x0e, 0x78, 0x87, 0xf9, + 0x10, 0x42, 0xcc, 0x35, 0x78, 0xf9, 0x6e, 0xf6, 0x7d, 0x5c, 0xeb, 0xe5, 0xb2, 0xfd, 0x1d, 0x42, + 0xf0, 0xa2, 0x3e, 0x96, 0x60, 0xa1, 0x26, 0x6a, 0xd5, 0x1c, 0xb3, 0x26, 0xab, 0xf8, 0xbf, 0x94, + 0x07, 0x09, 0x58, 0x15, 0x93, 0xcc, 0x03, 0x7b, 0x0f, 0x5f, 0x28, 0xca, 0x9e, 0x26, 0x10, 0x1f, + 0x93, 0x6b, 0xb8, 0x9a, 0xf7, 0x56, 0xd4, 0x16, 0x51, 0xb6, 0x63, 0xc8, 0x8f, 0xca, 0x62, 0xb3, + 0x26, 0x36, 0xae, 0x08, 0xcf, 0x5a, 0x68, 0xa2, 0xd6, 0x72, 0x97, 0xd0, 0xd2, 0x83, 0x11, 0x85, + 0x53, 0x11, 0x9e, 0x7d, 0x05, 0xaf, 0x14, 0x09, 0x07, 0x94, 0x8c, 0x42, 0x05, 0xf6, 0x3b, 0x84, + 0x57, 0x8b, 0x5c, 0x2f, 0x06, 0xae, 0xc1, 0x81, 0x57, 0x09, 0x28, 0x4d, 0xf6, 0x71, 0xe9, 0x9c, + 0x11, 0x5f, 0xee, 0x3e, 0xa2, 0x63, 0x8b, 0x68, 0x69, 0x91, 0x59, 0xec, 0xbb, 0x1e, 0x4d, 0xbb, + 0x54, 0x1e, 0xfa, 0x34, 0xb3, 0x88, 0xfe, 0x66, 0x11, 0x2d, 0x2d, 0x2a, 0x49, 0x9c, 0x72, 0xd7, + 0xac, 0xb9, 0x44, 0x2a, 0x88, 0xb5, 0x69, 0xe3, 0x7f, 0xa7, 0x88, 0xec, 0xcf, 0x63, 0xa2, 0xe7, + 0xd2, 0xfb, 0x97, 0x44, 0x37, 0xf1, 0xc5, 0xc4, 0x28, 0x7a, 0x8f, 0x05, 0x04, 0x9e, 0xb2, 0x2a, + 0xcd, 0x85, 0x56, 0xcd, 0x99, 0x4c, 0x9e, 0xc7, 0xe8, 0xee, 0xd7, 0x25, 0x7c, 0xa9, 0xc8, 0x3c, + 0x83, 0x38, 0x15, 0x2e, 0x90, 0x13, 0x84, 0x17, 0x77, 0x85, 0xd2, 0xe4, 0xea, 0x74, 0x8d, 0x39, + 0xeb, 0x7a, 0x7f, 0x2e, 0xcd, 0x64, 0x0a, 0xb6, 0x75, 0xf2, 0xfd, 0xe7, 0x87, 0x0a, 0x21, 0x97, + 0xcd, 0xac, 0xa7, 0x9d, 0xf2, 0x46, 0x28, 0xf2, 0x1e, 0xe1, 0x6a, 0x7e, 0xcc, 0x64, 0x63, 0x1a, + 0x63, 0xe2, 0xf8, 0xeb, 0xf3, 0xf1, 0xd6, 0xbe, 0x6e, 0x50, 0xd6, 0xec, 0x53, 0x28, 0x0f, 0x46, + 0xae, 0xbf, 0x45, 0x78, 0xe1, 0x09, 0x9c, 0xe9, 0xcb, 0x9c, 0x40, 0x6e, 0x18, 0x90, 0x0d, 0xb2, + 0x36, 0x0d, 0xc2, 0x5e, 0x0b, 0x8f, 0x9a, 0xeb, 0xf7, 0x86, 0x7c, 0x44, 0xb8, 0x9a, 0xcf, 0xdc, + 0x69, 0x7b, 0x26, 0x66, 0x71, 0x5e, 0x54, 0x9b, 0x86, 0xea, 0x56, 0x7d, 0x16, 0xd5, 0xd8, 0xa9, + 0x3d, 0x5c, 0xdd, 0x81, 0x00, 0x34, 0x9c, 0xe5, 0x95, 0x35, 0x9d, 0x1e, 0x5d, 0xf3, 0xa2, 0xfd, + 0xbb, 0x33, 0xdb, 0x0f, 0x31, 0x76, 0xb2, 0xcf, 0x22, 0x3c, 0x4c, 0xf4, 0xe0, 0xcf, 0x35, 0x98, + 0xd1, 0xb8, 0x63, 0xdf, 0x9e, 0xa1, 0xc1, 0x62, 0x23, 0xd0, 0xe6, 0x99, 0xc2, 0x27, 0x84, 0x57, + 0xfa, 0x61, 0xca, 0x03, 0x91, 0x59, 0xdb, 0xe3, 0xee, 0x00, 0xfe, 0xf2, 0x14, 0x6c, 0x19, 0x44, + 0x6a, 0x6f, 0xce, 0x42, 0x14, 0x23, 0xa4, 0xb6, 0x9b, 0x31, 0x6d, 0x6f, 0x7f, 0x19, 0x36, 0xd0, + 0xb7, 0x61, 0x03, 0xfd, 0x18, 0x36, 0xd0, 0x8b, 0xad, 0xf3, 0xbd, 0x14, 0x6e, 0x20, 0x20, 0xd4, + 0xa5, 0xc0, 0x41, 0xd5, 0x3c, 0x0c, 0xf7, 0x7e, 0x05, 0x00, 0x00, 0xff, 0xff, 0x1c, 0x77, 0xdb, + 0xd9, 0xad, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/pkg/apiclient/cluster/mocks/ClusterServiceServer.go b/pkg/apiclient/cluster/mocks/ClusterServiceServer.go index 87971e7dc5..a219a88153 100644 --- a/pkg/apiclient/cluster/mocks/ClusterServiceServer.go +++ b/pkg/apiclient/cluster/mocks/ClusterServiceServer.go @@ -1,17 +1,232 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" + context "context" + + cluster "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" mock "github.com/stretchr/testify/mock" + + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) +// ClusterServiceServer is an autogenerated mock type for the ClusterServiceServer type +type ClusterServiceServer struct { + mock.Mock +} + +// Create provides a mock function with given fields: _a0, _a1 +func (_m *ClusterServiceServer) Create(_a0 context.Context, _a1 *cluster.ClusterCreateRequest) (*v1alpha1.Cluster, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for Create") + } + + var r0 *v1alpha1.Cluster + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterCreateRequest) (*v1alpha1.Cluster, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterCreateRequest) *v1alpha1.Cluster); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Cluster) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *cluster.ClusterCreateRequest) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Delete provides a mock function with given fields: _a0, _a1 +func (_m *ClusterServiceServer) Delete(_a0 context.Context, _a1 *cluster.ClusterQuery) (*cluster.ClusterResponse, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for Delete") + } + + var r0 *cluster.ClusterResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) (*cluster.ClusterResponse, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) *cluster.ClusterResponse); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*cluster.ClusterResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *cluster.ClusterQuery) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Get provides a mock function with given fields: _a0, _a1 +func (_m *ClusterServiceServer) Get(_a0 context.Context, _a1 *cluster.ClusterQuery) (*v1alpha1.Cluster, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for Get") + } + + var r0 *v1alpha1.Cluster + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) (*v1alpha1.Cluster, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) *v1alpha1.Cluster); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Cluster) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *cluster.ClusterQuery) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// InvalidateCache provides a mock function with given fields: _a0, _a1 +func (_m *ClusterServiceServer) InvalidateCache(_a0 context.Context, _a1 *cluster.ClusterQuery) (*v1alpha1.Cluster, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for InvalidateCache") + } + + var r0 *v1alpha1.Cluster + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) (*v1alpha1.Cluster, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) *v1alpha1.Cluster); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Cluster) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *cluster.ClusterQuery) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// List provides a mock function with given fields: _a0, _a1 +func (_m *ClusterServiceServer) List(_a0 context.Context, _a1 *cluster.ClusterQuery) (*v1alpha1.ClusterList, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for List") + } + + var r0 *v1alpha1.ClusterList + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) (*v1alpha1.ClusterList, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) *v1alpha1.ClusterList); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.ClusterList) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *cluster.ClusterQuery) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RotateAuth provides a mock function with given fields: _a0, _a1 +func (_m *ClusterServiceServer) RotateAuth(_a0 context.Context, _a1 *cluster.ClusterQuery) (*cluster.ClusterResponse, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for RotateAuth") + } + + var r0 *cluster.ClusterResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) (*cluster.ClusterResponse, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) *cluster.ClusterResponse); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*cluster.ClusterResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *cluster.ClusterQuery) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Update provides a mock function with given fields: _a0, _a1 +func (_m *ClusterServiceServer) Update(_a0 context.Context, _a1 *cluster.ClusterUpdateRequest) (*v1alpha1.Cluster, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for Update") + } + + var r0 *v1alpha1.Cluster + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterUpdateRequest) (*v1alpha1.Cluster, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *cluster.ClusterUpdateRequest) *v1alpha1.Cluster); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Cluster) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *cluster.ClusterUpdateRequest) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewClusterServiceServer creates a new instance of ClusterServiceServer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewClusterServiceServer(t interface { @@ -25,415 +240,3 @@ func NewClusterServiceServer(t interface { return mock } - -// ClusterServiceServer is an autogenerated mock type for the ClusterServiceServer type -type ClusterServiceServer struct { - mock.Mock -} - -type ClusterServiceServer_Expecter struct { - mock *mock.Mock -} - -func (_m *ClusterServiceServer) EXPECT() *ClusterServiceServer_Expecter { - return &ClusterServiceServer_Expecter{mock: &_m.Mock} -} - -// Create provides a mock function for the type ClusterServiceServer -func (_mock *ClusterServiceServer) Create(context1 context.Context, clusterCreateRequest *cluster.ClusterCreateRequest) (*v1alpha1.Cluster, error) { - ret := _mock.Called(context1, clusterCreateRequest) - - if len(ret) == 0 { - panic("no return value specified for Create") - } - - var r0 *v1alpha1.Cluster - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterCreateRequest) (*v1alpha1.Cluster, error)); ok { - return returnFunc(context1, clusterCreateRequest) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterCreateRequest) *v1alpha1.Cluster); ok { - r0 = returnFunc(context1, clusterCreateRequest) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Cluster) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *cluster.ClusterCreateRequest) error); ok { - r1 = returnFunc(context1, clusterCreateRequest) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ClusterServiceServer_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' -type ClusterServiceServer_Create_Call struct { - *mock.Call -} - -// Create is a helper method to define mock.On call -// - context1 -// - clusterCreateRequest -func (_e *ClusterServiceServer_Expecter) Create(context1 interface{}, clusterCreateRequest interface{}) *ClusterServiceServer_Create_Call { - return &ClusterServiceServer_Create_Call{Call: _e.mock.On("Create", context1, clusterCreateRequest)} -} - -func (_c *ClusterServiceServer_Create_Call) Run(run func(context1 context.Context, clusterCreateRequest *cluster.ClusterCreateRequest)) *ClusterServiceServer_Create_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*cluster.ClusterCreateRequest)) - }) - return _c -} - -func (_c *ClusterServiceServer_Create_Call) Return(cluster1 *v1alpha1.Cluster, err error) *ClusterServiceServer_Create_Call { - _c.Call.Return(cluster1, err) - return _c -} - -func (_c *ClusterServiceServer_Create_Call) RunAndReturn(run func(context1 context.Context, clusterCreateRequest *cluster.ClusterCreateRequest) (*v1alpha1.Cluster, error)) *ClusterServiceServer_Create_Call { - _c.Call.Return(run) - return _c -} - -// Delete provides a mock function for the type ClusterServiceServer -func (_mock *ClusterServiceServer) Delete(context1 context.Context, clusterQuery *cluster.ClusterQuery) (*cluster.ClusterResponse, error) { - ret := _mock.Called(context1, clusterQuery) - - if len(ret) == 0 { - panic("no return value specified for Delete") - } - - var r0 *cluster.ClusterResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) (*cluster.ClusterResponse, error)); ok { - return returnFunc(context1, clusterQuery) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) *cluster.ClusterResponse); ok { - r0 = returnFunc(context1, clusterQuery) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*cluster.ClusterResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *cluster.ClusterQuery) error); ok { - r1 = returnFunc(context1, clusterQuery) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ClusterServiceServer_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' -type ClusterServiceServer_Delete_Call struct { - *mock.Call -} - -// Delete is a helper method to define mock.On call -// - context1 -// - clusterQuery -func (_e *ClusterServiceServer_Expecter) Delete(context1 interface{}, clusterQuery interface{}) *ClusterServiceServer_Delete_Call { - return &ClusterServiceServer_Delete_Call{Call: _e.mock.On("Delete", context1, clusterQuery)} -} - -func (_c *ClusterServiceServer_Delete_Call) Run(run func(context1 context.Context, clusterQuery *cluster.ClusterQuery)) *ClusterServiceServer_Delete_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*cluster.ClusterQuery)) - }) - return _c -} - -func (_c *ClusterServiceServer_Delete_Call) Return(clusterResponse *cluster.ClusterResponse, err error) *ClusterServiceServer_Delete_Call { - _c.Call.Return(clusterResponse, err) - return _c -} - -func (_c *ClusterServiceServer_Delete_Call) RunAndReturn(run func(context1 context.Context, clusterQuery *cluster.ClusterQuery) (*cluster.ClusterResponse, error)) *ClusterServiceServer_Delete_Call { - _c.Call.Return(run) - return _c -} - -// Get provides a mock function for the type ClusterServiceServer -func (_mock *ClusterServiceServer) Get(context1 context.Context, clusterQuery *cluster.ClusterQuery) (*v1alpha1.Cluster, error) { - ret := _mock.Called(context1, clusterQuery) - - if len(ret) == 0 { - panic("no return value specified for Get") - } - - var r0 *v1alpha1.Cluster - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) (*v1alpha1.Cluster, error)); ok { - return returnFunc(context1, clusterQuery) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) *v1alpha1.Cluster); ok { - r0 = returnFunc(context1, clusterQuery) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Cluster) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *cluster.ClusterQuery) error); ok { - r1 = returnFunc(context1, clusterQuery) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ClusterServiceServer_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' -type ClusterServiceServer_Get_Call struct { - *mock.Call -} - -// Get is a helper method to define mock.On call -// - context1 -// - clusterQuery -func (_e *ClusterServiceServer_Expecter) Get(context1 interface{}, clusterQuery interface{}) *ClusterServiceServer_Get_Call { - return &ClusterServiceServer_Get_Call{Call: _e.mock.On("Get", context1, clusterQuery)} -} - -func (_c *ClusterServiceServer_Get_Call) Run(run func(context1 context.Context, clusterQuery *cluster.ClusterQuery)) *ClusterServiceServer_Get_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*cluster.ClusterQuery)) - }) - return _c -} - -func (_c *ClusterServiceServer_Get_Call) Return(cluster1 *v1alpha1.Cluster, err error) *ClusterServiceServer_Get_Call { - _c.Call.Return(cluster1, err) - return _c -} - -func (_c *ClusterServiceServer_Get_Call) RunAndReturn(run func(context1 context.Context, clusterQuery *cluster.ClusterQuery) (*v1alpha1.Cluster, error)) *ClusterServiceServer_Get_Call { - _c.Call.Return(run) - return _c -} - -// InvalidateCache provides a mock function for the type ClusterServiceServer -func (_mock *ClusterServiceServer) InvalidateCache(context1 context.Context, clusterQuery *cluster.ClusterQuery) (*v1alpha1.Cluster, error) { - ret := _mock.Called(context1, clusterQuery) - - if len(ret) == 0 { - panic("no return value specified for InvalidateCache") - } - - var r0 *v1alpha1.Cluster - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) (*v1alpha1.Cluster, error)); ok { - return returnFunc(context1, clusterQuery) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) *v1alpha1.Cluster); ok { - r0 = returnFunc(context1, clusterQuery) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Cluster) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *cluster.ClusterQuery) error); ok { - r1 = returnFunc(context1, clusterQuery) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ClusterServiceServer_InvalidateCache_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'InvalidateCache' -type ClusterServiceServer_InvalidateCache_Call struct { - *mock.Call -} - -// InvalidateCache is a helper method to define mock.On call -// - context1 -// - clusterQuery -func (_e *ClusterServiceServer_Expecter) InvalidateCache(context1 interface{}, clusterQuery interface{}) *ClusterServiceServer_InvalidateCache_Call { - return &ClusterServiceServer_InvalidateCache_Call{Call: _e.mock.On("InvalidateCache", context1, clusterQuery)} -} - -func (_c *ClusterServiceServer_InvalidateCache_Call) Run(run func(context1 context.Context, clusterQuery *cluster.ClusterQuery)) *ClusterServiceServer_InvalidateCache_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*cluster.ClusterQuery)) - }) - return _c -} - -func (_c *ClusterServiceServer_InvalidateCache_Call) Return(cluster1 *v1alpha1.Cluster, err error) *ClusterServiceServer_InvalidateCache_Call { - _c.Call.Return(cluster1, err) - return _c -} - -func (_c *ClusterServiceServer_InvalidateCache_Call) RunAndReturn(run func(context1 context.Context, clusterQuery *cluster.ClusterQuery) (*v1alpha1.Cluster, error)) *ClusterServiceServer_InvalidateCache_Call { - _c.Call.Return(run) - return _c -} - -// List provides a mock function for the type ClusterServiceServer -func (_mock *ClusterServiceServer) List(context1 context.Context, clusterQuery *cluster.ClusterQuery) (*v1alpha1.ClusterList, error) { - ret := _mock.Called(context1, clusterQuery) - - if len(ret) == 0 { - panic("no return value specified for List") - } - - var r0 *v1alpha1.ClusterList - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) (*v1alpha1.ClusterList, error)); ok { - return returnFunc(context1, clusterQuery) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) *v1alpha1.ClusterList); ok { - r0 = returnFunc(context1, clusterQuery) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.ClusterList) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *cluster.ClusterQuery) error); ok { - r1 = returnFunc(context1, clusterQuery) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ClusterServiceServer_List_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'List' -type ClusterServiceServer_List_Call struct { - *mock.Call -} - -// List is a helper method to define mock.On call -// - context1 -// - clusterQuery -func (_e *ClusterServiceServer_Expecter) List(context1 interface{}, clusterQuery interface{}) *ClusterServiceServer_List_Call { - return &ClusterServiceServer_List_Call{Call: _e.mock.On("List", context1, clusterQuery)} -} - -func (_c *ClusterServiceServer_List_Call) Run(run func(context1 context.Context, clusterQuery *cluster.ClusterQuery)) *ClusterServiceServer_List_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*cluster.ClusterQuery)) - }) - return _c -} - -func (_c *ClusterServiceServer_List_Call) Return(clusterList *v1alpha1.ClusterList, err error) *ClusterServiceServer_List_Call { - _c.Call.Return(clusterList, err) - return _c -} - -func (_c *ClusterServiceServer_List_Call) RunAndReturn(run func(context1 context.Context, clusterQuery *cluster.ClusterQuery) (*v1alpha1.ClusterList, error)) *ClusterServiceServer_List_Call { - _c.Call.Return(run) - return _c -} - -// RotateAuth provides a mock function for the type ClusterServiceServer -func (_mock *ClusterServiceServer) RotateAuth(context1 context.Context, clusterQuery *cluster.ClusterQuery) (*cluster.ClusterResponse, error) { - ret := _mock.Called(context1, clusterQuery) - - if len(ret) == 0 { - panic("no return value specified for RotateAuth") - } - - var r0 *cluster.ClusterResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) (*cluster.ClusterResponse, error)); ok { - return returnFunc(context1, clusterQuery) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterQuery) *cluster.ClusterResponse); ok { - r0 = returnFunc(context1, clusterQuery) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*cluster.ClusterResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *cluster.ClusterQuery) error); ok { - r1 = returnFunc(context1, clusterQuery) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ClusterServiceServer_RotateAuth_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RotateAuth' -type ClusterServiceServer_RotateAuth_Call struct { - *mock.Call -} - -// RotateAuth is a helper method to define mock.On call -// - context1 -// - clusterQuery -func (_e *ClusterServiceServer_Expecter) RotateAuth(context1 interface{}, clusterQuery interface{}) *ClusterServiceServer_RotateAuth_Call { - return &ClusterServiceServer_RotateAuth_Call{Call: _e.mock.On("RotateAuth", context1, clusterQuery)} -} - -func (_c *ClusterServiceServer_RotateAuth_Call) Run(run func(context1 context.Context, clusterQuery *cluster.ClusterQuery)) *ClusterServiceServer_RotateAuth_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*cluster.ClusterQuery)) - }) - return _c -} - -func (_c *ClusterServiceServer_RotateAuth_Call) Return(clusterResponse *cluster.ClusterResponse, err error) *ClusterServiceServer_RotateAuth_Call { - _c.Call.Return(clusterResponse, err) - return _c -} - -func (_c *ClusterServiceServer_RotateAuth_Call) RunAndReturn(run func(context1 context.Context, clusterQuery *cluster.ClusterQuery) (*cluster.ClusterResponse, error)) *ClusterServiceServer_RotateAuth_Call { - _c.Call.Return(run) - return _c -} - -// Update provides a mock function for the type ClusterServiceServer -func (_mock *ClusterServiceServer) Update(context1 context.Context, clusterUpdateRequest *cluster.ClusterUpdateRequest) (*v1alpha1.Cluster, error) { - ret := _mock.Called(context1, clusterUpdateRequest) - - if len(ret) == 0 { - panic("no return value specified for Update") - } - - var r0 *v1alpha1.Cluster - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterUpdateRequest) (*v1alpha1.Cluster, error)); ok { - return returnFunc(context1, clusterUpdateRequest) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *cluster.ClusterUpdateRequest) *v1alpha1.Cluster); ok { - r0 = returnFunc(context1, clusterUpdateRequest) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Cluster) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *cluster.ClusterUpdateRequest) error); ok { - r1 = returnFunc(context1, clusterUpdateRequest) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ClusterServiceServer_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update' -type ClusterServiceServer_Update_Call struct { - *mock.Call -} - -// Update is a helper method to define mock.On call -// - context1 -// - clusterUpdateRequest -func (_e *ClusterServiceServer_Expecter) Update(context1 interface{}, clusterUpdateRequest interface{}) *ClusterServiceServer_Update_Call { - return &ClusterServiceServer_Update_Call{Call: _e.mock.On("Update", context1, clusterUpdateRequest)} -} - -func (_c *ClusterServiceServer_Update_Call) Run(run func(context1 context.Context, clusterUpdateRequest *cluster.ClusterUpdateRequest)) *ClusterServiceServer_Update_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*cluster.ClusterUpdateRequest)) - }) - return _c -} - -func (_c *ClusterServiceServer_Update_Call) Return(cluster1 *v1alpha1.Cluster, err error) *ClusterServiceServer_Update_Call { - _c.Call.Return(cluster1, err) - return _c -} - -func (_c *ClusterServiceServer_Update_Call) RunAndReturn(run func(context1 context.Context, clusterUpdateRequest *cluster.ClusterUpdateRequest) (*v1alpha1.Cluster, error)) *ClusterServiceServer_Update_Call { - _c.Call.Return(run) - return _c -} diff --git a/pkg/apiclient/gpgkey/gpgkey.pb.go b/pkg/apiclient/gpgkey/gpgkey.pb.go index 4300c4b23d..4e461a464e 100644 --- a/pkg/apiclient/gpgkey/gpgkey.pb.go +++ b/pkg/apiclient/gpgkey/gpgkey.pb.go @@ -10,7 +10,7 @@ package gpgkey import ( context "context" fmt "fmt" - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" @@ -250,7 +250,7 @@ var fileDescriptor_8ba55a5eb76dc6fd = []byte{ // 487 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x41, 0x8b, 0xd3, 0x40, 0x14, 0xc7, 0x99, 0xee, 0xda, 0xb5, 0x23, 0x22, 0x8e, 0xb2, 0x1b, 0xb3, 0xa5, 0x96, 0xe8, 0xa1, - 0x28, 0xce, 0xd0, 0xed, 0xcd, 0x9b, 0xba, 0x10, 0x64, 0x7b, 0xa8, 0xf1, 0xe6, 0x41, 0x49, 0x93, + 0x28, 0xce, 0xd0, 0xee, 0xcd, 0x9b, 0xba, 0x10, 0x64, 0x7b, 0xa8, 0xf1, 0xe6, 0x41, 0x49, 0x93, 0x47, 0x76, 0x9a, 0x98, 0x19, 0x67, 0x26, 0x91, 0x20, 0x5e, 0xbc, 0x2b, 0x88, 0x9f, 0x40, 0xf0, 0xc3, 0x78, 0x14, 0xfc, 0x02, 0x52, 0xfc, 0x20, 0xd2, 0x49, 0xea, 0x6e, 0x4b, 0x59, 0x3d, 0xf4, 0x94, 0x79, 0x99, 0x79, 0xef, 0xff, 0x9b, 0xf7, 0xfe, 0x83, 0x5d, 0x0d, 0xaa, 0x04, 0xc5, 0x12, @@ -262,23 +262,23 @@ var fileDescriptor_8ba55a5eb76dc6fd = []byte{ 0x8f, 0x6f, 0xf8, 0x79, 0x31, 0xf1, 0x27, 0xc5, 0x34, 0xe3, 0xd1, 0x09, 0x54, 0xcf, 0x0a, 0x50, 0x15, 0xb9, 0x89, 0x2f, 0xa5, 0x50, 0x3d, 0x3d, 0x76, 0x50, 0x1f, 0x0d, 0x3a, 0x41, 0x1d, 0x78, 0x5f, 0x11, 0x3e, 0x5c, 0x3d, 0xfd, 0x44, 0x41, 0x68, 0x20, 0x80, 0x37, 0x05, 0x68, 0x43, 0x66, - 0xb8, 0x23, 0xed, 0x4e, 0x0a, 0x95, 0xcd, 0xbc, 0x72, 0x34, 0xa6, 0x67, 0xb8, 0x74, 0x89, 0x6b, - 0x17, 0xaf, 0xa2, 0x98, 0x96, 0x23, 0x2a, 0xd3, 0x84, 0x2e, 0x70, 0xe9, 0x39, 0x5c, 0xba, 0xc4, - 0xa5, 0xab, 0x6a, 0xc1, 0x59, 0x79, 0xb2, 0x8f, 0xdb, 0x85, 0xd4, 0xa0, 0x8c, 0xd3, 0xea, 0xa3, - 0xc1, 0xe5, 0xa0, 0x89, 0xbc, 0x6f, 0x08, 0x77, 0x37, 0x33, 0x6a, 0x29, 0x72, 0x0d, 0x64, 0x86, - 0xf7, 0x22, 0xfb, 0x27, 0x6e, 0x10, 0x27, 0xdb, 0x44, 0x1c, 0x73, 0x6d, 0x82, 0xa5, 0x00, 0x71, - 0xf0, 0x9e, 0x4e, 0xb9, 0x94, 0x10, 0x3b, 0xad, 0xfe, 0xce, 0xa0, 0x13, 0x2c, 0x43, 0xcf, 0xc1, - 0xfb, 0x6b, 0x77, 0x6b, 0xf8, 0x8e, 0x3e, 0xee, 0xe2, 0xab, 0xfe, 0xc4, 0x3f, 0x81, 0xea, 0x39, - 0xa8, 0x92, 0x47, 0x40, 0x3e, 0x21, 0xbc, 0xbb, 0xa8, 0x4b, 0x0e, 0x69, 0xe3, 0x97, 0x0d, 0x23, - 0x73, 0xb7, 0x7e, 0x0d, 0xef, 0xe0, 0xc3, 0xcf, 0xdf, 0x5f, 0x5a, 0xd7, 0xc9, 0x35, 0xeb, 0xc4, - 0x72, 0xd8, 0xb8, 0x55, 0x93, 0xcf, 0x08, 0xef, 0xf8, 0xf0, 0x0f, 0x9e, 0xad, 0x4e, 0xde, 0xbb, - 0x6d, 0x59, 0x6e, 0x91, 0x83, 0x35, 0x16, 0xf6, 0xce, 0x5a, 0xf3, 0x3d, 0x79, 0x8b, 0xdb, 0xf5, - 0xa0, 0xc9, 0x9d, 0xcd, 0x54, 0x2b, 0x56, 0x75, 0xef, 0x5e, 0x7c, 0xa8, 0x9e, 0x85, 0xe7, 0x59, - 0xd5, 0xae, 0xb7, 0xde, 0x81, 0x87, 0xe7, 0x8c, 0xf8, 0x12, 0xb7, 0x8f, 0x21, 0x03, 0x03, 0x17, - 0xb7, 0xa3, 0xb7, 0x79, 0xf3, 0xaf, 0x54, 0xd3, 0xec, 0x7b, 0xeb, 0x52, 0x8f, 0x1f, 0x7d, 0x9f, - 0xf7, 0xd0, 0x8f, 0x79, 0x0f, 0xfd, 0x9a, 0xf7, 0xd0, 0x8b, 0xd1, 0xff, 0xbd, 0xfe, 0x28, 0xe3, - 0x90, 0x9b, 0xa6, 0xc6, 0xb4, 0x6d, 0xdf, 0xfa, 0xe8, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x44, - 0x30, 0xc0, 0xc7, 0x7d, 0x04, 0x00, 0x00, + 0xb8, 0x23, 0xed, 0x4e, 0x0a, 0x95, 0xcd, 0xbc, 0x32, 0x1a, 0xd3, 0x33, 0x5c, 0xba, 0xc4, 0xb5, + 0x8b, 0x57, 0x51, 0x4c, 0xcb, 0x11, 0x95, 0x69, 0x42, 0x17, 0xb8, 0xf4, 0x1c, 0x2e, 0x5d, 0xe2, + 0xd2, 0x55, 0xb5, 0xe0, 0xac, 0x3c, 0xd9, 0xc7, 0xed, 0x42, 0x6a, 0x50, 0xc6, 0x69, 0xf5, 0xd1, + 0xe0, 0x72, 0xd0, 0x44, 0xde, 0x37, 0x84, 0xbb, 0x9b, 0x19, 0xb5, 0x14, 0xb9, 0x06, 0x32, 0xc3, + 0x7b, 0x91, 0xfd, 0x13, 0x37, 0x88, 0x93, 0x6d, 0x22, 0x8e, 0xb9, 0x36, 0xc1, 0x52, 0x80, 0x38, + 0x78, 0x4f, 0xa7, 0x5c, 0x4a, 0x88, 0x9d, 0x56, 0x7f, 0x67, 0xd0, 0x09, 0x96, 0xa1, 0xe7, 0xe0, + 0xfd, 0xb5, 0xbb, 0x35, 0x7c, 0xa3, 0x8f, 0xbb, 0xf8, 0xaa, 0x3f, 0xf1, 0x4f, 0xa0, 0x7a, 0x0e, + 0xaa, 0xe4, 0x11, 0x90, 0x4f, 0x08, 0xef, 0x2e, 0xea, 0x92, 0x43, 0xda, 0xf8, 0x65, 0xc3, 0xc8, + 0xdc, 0xad, 0x5f, 0xc3, 0x3b, 0xf8, 0xf0, 0xf3, 0xf7, 0x97, 0xd6, 0x75, 0x72, 0xcd, 0x3a, 0xb1, + 0x1c, 0x36, 0x6e, 0xd5, 0xe4, 0x33, 0xc2, 0x3b, 0x3e, 0xfc, 0x83, 0x67, 0xab, 0x93, 0xf7, 0x6e, + 0x5b, 0x96, 0x5b, 0xe4, 0x60, 0x8d, 0x85, 0xbd, 0xb3, 0xd6, 0x7c, 0x4f, 0xde, 0xe2, 0x76, 0x3d, + 0x68, 0x72, 0x67, 0x33, 0xd5, 0x8a, 0x55, 0xdd, 0xbb, 0x17, 0x1f, 0xaa, 0x67, 0xe1, 0x79, 0x56, + 0xb5, 0xeb, 0xad, 0x77, 0xe0, 0xe1, 0x39, 0x23, 0xbe, 0xc4, 0xed, 0x63, 0xc8, 0xc0, 0xc0, 0xc5, + 0xed, 0xe8, 0x6d, 0xde, 0xfc, 0x2b, 0xd5, 0x34, 0xfb, 0xde, 0xba, 0xd4, 0xe3, 0x47, 0xdf, 0xe7, + 0x3d, 0xf4, 0x63, 0xde, 0x43, 0xbf, 0xe6, 0x3d, 0xf4, 0xe2, 0xe8, 0xff, 0x5e, 0x7f, 0x94, 0x71, + 0xc8, 0x4d, 0x53, 0x63, 0xda, 0xb6, 0x6f, 0xfd, 0xe8, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, + 0x72, 0x6b, 0xb1, 0x7d, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/pkg/apiclient/grpcproxy.go b/pkg/apiclient/grpcproxy.go index 9cfe4b8fa0..b426db178a 100644 --- a/pkg/apiclient/grpcproxy.go +++ b/pkg/apiclient/grpcproxy.go @@ -18,10 +18,10 @@ import ( "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" - "github.com/argoproj/argo-cd/v3/common" - argocderrors "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/rand" + "github.com/argoproj/argo-cd/v2/common" + argocderrors "github.com/argoproj/argo-cd/v2/util/errors" + argoio "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/rand" ) const ( @@ -31,11 +31,11 @@ const ( type noopCodec struct{} -func (noopCodec) Marshal(v any) ([]byte, error) { +func (noopCodec) Marshal(v interface{}) ([]byte, error) { return v.([]byte), nil } -func (noopCodec) Unmarshal(data []byte, v any) error { +func (noopCodec) Unmarshal(data []byte, v interface{}) error { pointer := v.(*[]byte) *pointer = data return nil @@ -118,10 +118,10 @@ func (c *client) startGRPCProxy() (*grpc.Server, net.Listener, error) { MinTime: common.GetGRPCKeepAliveEnforcementMinimum(), }, ), - grpc.UnknownServiceHandler(func(_ any, stream grpc.ServerStream) error { + grpc.UnknownServiceHandler(func(srv interface{}, stream grpc.ServerStream) error { fullMethodName, ok := grpc.MethodFromServerStream(stream) if !ok { - return errors.New("unable to get method name from stream context") + return fmt.Errorf("Unable to get method name from stream context.") } msg := make([]byte, 0) err := stream.RecvMsg(&msg) @@ -144,9 +144,9 @@ func (c *client) startGRPCProxy() (*grpc.Server, net.Listener, error) { go func() { <-stream.Context().Done() - utilio.Close(resp.Body) + argoio.Close(resp.Body) }() - defer utilio.Close(resp.Body) + defer argoio.Close(resp.Body) c.httpClient.CloseIdleConnections() for { @@ -169,8 +169,9 @@ func (c *client) startGRPCProxy() (*grpc.Server, net.Listener, error) { return err } else if read < length { return io.ErrUnexpectedEOF + } else { + return nil } - return nil } if err := stream.SendMsg(data); err != nil { @@ -199,7 +200,7 @@ func (c *client) useGRPCProxy() (net.Addr, io.Closer, error) { } c.proxyUsersCount = c.proxyUsersCount + 1 - return c.proxyListener.Addr(), utilio.NewCloser(func() error { + return c.proxyListener.Addr(), argoio.NewCloser(func() error { c.proxyMutex.Lock() defer c.proxyMutex.Unlock() c.proxyUsersCount = c.proxyUsersCount - 1 diff --git a/pkg/apiclient/notification/notification.pb.go b/pkg/apiclient/notification/notification.pb.go index 4ff95ab540..bfea046701 100644 --- a/pkg/apiclient/notification/notification.pb.go +++ b/pkg/apiclient/notification/notification.pb.go @@ -448,31 +448,31 @@ func init() { } var fileDescriptor_e1dead44d55a8ff4 = []byte{ - // 370 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x31, 0x4e, 0xc3, 0x30, - 0x14, 0x86, 0x95, 0x02, 0x02, 0xdc, 0xb2, 0xb8, 0xb4, 0x2a, 0x15, 0x84, 0x36, 0x43, 0xa9, 0x04, - 0xd4, 0xa2, 0x4c, 0x20, 0x26, 0x16, 0x16, 0xc4, 0x50, 0x3a, 0xb1, 0x85, 0x60, 0x8c, 0xa1, 0x89, - 0x83, 0xed, 0x46, 0xcc, 0x5c, 0x81, 0x4b, 0x31, 0x22, 0x71, 0x01, 0x54, 0x71, 0x0b, 0x16, 0x14, - 0xd7, 0x96, 0xe2, 0xc8, 0x15, 0x6c, 0xce, 0x7b, 0x9f, 0xdf, 0xa7, 0xf7, 0x3b, 0xa0, 0x27, 0x30, - 0xcf, 0x30, 0x47, 0x09, 0x93, 0xf4, 0x9e, 0x46, 0xa1, 0xa4, 0x2c, 0xb1, 0x3e, 0x06, 0x29, 0x67, - 0x92, 0xc1, 0x5a, 0xb1, 0xd6, 0xde, 0x26, 0x8c, 0x91, 0x09, 0x46, 0x61, 0x4a, 0x51, 0x98, 0x24, - 0x4c, 0xaa, 0xb2, 0x98, 0xb3, 0xc1, 0x0e, 0x58, 0x1d, 0x73, 0x4a, 0x08, 0xe6, 0x10, 0x82, 0xe5, - 0x24, 0x8c, 0x71, 0xcb, 0xeb, 0x54, 0xfa, 0xeb, 0x23, 0x75, 0x0e, 0x4e, 0x41, 0x55, 0xb7, 0x2f, - 0xa9, 0x90, 0x70, 0x1f, 0xac, 0x50, 0x89, 0x63, 0xd1, 0xf2, 0x3a, 0x4b, 0xfd, 0xea, 0xb0, 0x31, - 0xb0, 0xec, 0x9a, 0x1c, 0xcd, 0x99, 0xa0, 0x01, 0xea, 0xba, 0x22, 0xf2, 0xcb, 0x23, 0xfc, 0x3c, - 0xc5, 0x42, 0xe6, 0xc6, 0x6b, 0xcc, 0x33, 0x1a, 0xe1, 0x45, 0x46, 0xdd, 0xfe, 0x87, 0x51, 0x93, - 0x05, 0xa3, 0xae, 0x58, 0x46, 0x1f, 0xac, 0x8d, 0x71, 0x9c, 0x4e, 0x42, 0xe9, 0x56, 0x9e, 0x81, - 0x9a, 0xe9, 0x2b, 0xe7, 0x81, 0xed, 0x6c, 0x96, 0xb6, 0xd4, 0xa8, 0x91, 0x36, 0xc1, 0xa6, 0x29, - 0x15, 0xad, 0xc3, 0x9f, 0x0a, 0xa8, 0x5f, 0x15, 0x2e, 0x9a, 0xa5, 0x25, 0xa8, 0xe5, 0x98, 0x89, - 0x06, 0x76, 0x9d, 0x21, 0x16, 0x47, 0xb5, 0xb7, 0x9c, 0x48, 0x4e, 0x04, 0xbd, 0xd7, 0xcf, 0xef, - 0xb7, 0x4a, 0x07, 0xfa, 0xea, 0x7d, 0xb3, 0x23, 0xeb, 0x7f, 0x10, 0x48, 0x1a, 0x8b, 0xb6, 0x9a, - 0x78, 0xca, 0x56, 0x47, 0x6c, 0x65, 0x6b, 0xe1, 0x55, 0xfe, 0xb2, 0x0a, 0x63, 0x79, 0x01, 0x1b, - 0x6a, 0x57, 0x93, 0x0f, 0x0c, 0xdc, 0x59, 0x5a, 0xde, 0xb6, 0x9b, 0x51, 0xe2, 0x3d, 0x25, 0xee, - 0xc2, 0xdd, 0x05, 0xeb, 0x9a, 0x79, 0xe7, 0x17, 0xef, 0x33, 0xdf, 0xfb, 0x98, 0xf9, 0xde, 0xd7, - 0xcc, 0xf7, 0x6e, 0x4e, 0x08, 0x95, 0x0f, 0xd3, 0xdb, 0x41, 0xc4, 0x62, 0x14, 0x72, 0xc2, 0x52, - 0xce, 0x1e, 0xd5, 0xe1, 0x30, 0xba, 0x43, 0xd9, 0x31, 0x4a, 0x9f, 0x48, 0x3e, 0x30, 0x9a, 0x50, - 0x9c, 0x48, 0x6b, 0xe6, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb0, 0xe4, 0x3d, 0x23, 0x75, 0x03, - 0x00, 0x00, + // 371 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xb1, 0x4e, 0xf3, 0x30, + 0x10, 0xc7, 0x95, 0x7e, 0x1f, 0x02, 0xdc, 0xb2, 0xb8, 0xb4, 0x2a, 0x15, 0x84, 0x36, 0x43, 0xa9, + 0x04, 0xd4, 0xa2, 0x1b, 0x88, 0x89, 0x85, 0x05, 0x31, 0x94, 0x4e, 0x6c, 0x21, 0x18, 0x63, 0x68, + 0xe2, 0x60, 0x5f, 0x23, 0x66, 0x5e, 0x81, 0x97, 0x62, 0x44, 0xe2, 0x05, 0x50, 0xc5, 0x5b, 0xb0, + 0xa0, 0xb8, 0xb6, 0x14, 0x57, 0xa9, 0x60, 0x73, 0xee, 0x7e, 0xbe, 0x9f, 0xee, 0xef, 0xa0, 0x9e, + 0xa2, 0x32, 0xa3, 0x92, 0x24, 0x02, 0xf8, 0x1d, 0x8f, 0x42, 0xe0, 0x22, 0x71, 0x3e, 0x06, 0xa9, + 0x14, 0x20, 0x70, 0xad, 0x58, 0x6b, 0x6f, 0x33, 0x21, 0xd8, 0x84, 0x92, 0x30, 0xe5, 0x24, 0x4c, + 0x12, 0x01, 0xba, 0xac, 0xe6, 0x6c, 0xb0, 0x83, 0x56, 0xc7, 0x92, 0x33, 0x46, 0x25, 0xc6, 0xe8, + 0x7f, 0x12, 0xc6, 0xb4, 0xe5, 0x75, 0x2a, 0xfd, 0xf5, 0x91, 0x3e, 0x07, 0x27, 0xa8, 0x6a, 0xda, + 0x17, 0x5c, 0x01, 0xde, 0x47, 0x2b, 0x1c, 0x68, 0xac, 0x5a, 0x5e, 0xe7, 0x5f, 0xbf, 0x3a, 0x6c, + 0x0c, 0x1c, 0xbb, 0x21, 0x47, 0x73, 0x26, 0x68, 0xa0, 0xba, 0xa9, 0xa8, 0xfc, 0xf2, 0x88, 0x3e, + 0x4d, 0xa9, 0x82, 0xdc, 0x78, 0x45, 0x65, 0xc6, 0x23, 0xba, 0xcc, 0x68, 0xda, 0x7f, 0x30, 0x1a, + 0xb2, 0x60, 0x34, 0x15, 0xc7, 0xe8, 0xa3, 0xb5, 0x31, 0x8d, 0xd3, 0x49, 0x08, 0xe5, 0xca, 0x53, + 0x54, 0xb3, 0x7d, 0xed, 0x3c, 0x70, 0x9d, 0xcd, 0x85, 0x2d, 0x0d, 0x6a, 0xa5, 0x4d, 0xb4, 0x69, + 0x4b, 0x45, 0xeb, 0xf0, 0xbb, 0x82, 0xea, 0x97, 0x85, 0x8b, 0x76, 0x69, 0x40, 0xb5, 0x1c, 0xb3, + 0xd1, 0xe0, 0x6e, 0x69, 0x88, 0xc5, 0x51, 0xed, 0xad, 0x52, 0x24, 0x27, 0x82, 0xde, 0xcb, 0xc7, + 0xd7, 0x6b, 0xa5, 0x83, 0x7d, 0xfd, 0xbe, 0xd9, 0x91, 0xf3, 0x3f, 0x28, 0x02, 0xd6, 0x62, 0xac, + 0x36, 0x9e, 0x45, 0x6b, 0x49, 0x6c, 0x8b, 0xd6, 0xc2, 0xab, 0xfc, 0x66, 0x55, 0xd6, 0xf2, 0x8c, + 0x36, 0xf4, 0xae, 0x36, 0x1f, 0x1c, 0x94, 0x67, 0xe9, 0x78, 0xdb, 0xe5, 0x8c, 0x16, 0xef, 0x69, + 0x71, 0x17, 0xef, 0x2e, 0x59, 0xd7, 0xce, 0x3b, 0x3b, 0x7f, 0x9b, 0xf9, 0xde, 0xfb, 0xcc, 0xf7, + 0x3e, 0x67, 0xbe, 0x77, 0x7d, 0xcc, 0x38, 0xdc, 0x4f, 0x6f, 0x06, 0x91, 0x88, 0x49, 0x28, 0x99, + 0x48, 0xa5, 0x78, 0xd0, 0x87, 0xc3, 0xe8, 0x96, 0x64, 0x43, 0x92, 0x3e, 0xb2, 0x7c, 0x60, 0x34, + 0xe1, 0x34, 0x01, 0x67, 0xe6, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xad, 0x19, 0x88, 0x22, 0x75, + 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/pkg/apiclient/project/forwarder_overwrite.go b/pkg/apiclient/project/forwarder_overwrite.go index c8f857f99a..697f95efca 100644 --- a/pkg/apiclient/project/forwarder_overwrite.go +++ b/pkg/apiclient/project/forwarder_overwrite.go @@ -1,7 +1,7 @@ package project import ( - "github.com/argoproj/pkg/v2/grpc/http" + "github.com/argoproj/pkg/grpc/http" ) func init() { diff --git a/pkg/apiclient/project/project.pb.go b/pkg/apiclient/project/project.pb.go index 9d89bd971c..2a89c8c2a0 100644 --- a/pkg/apiclient/project/project.pb.go +++ b/pkg/apiclient/project/project.pb.go @@ -10,8 +10,8 @@ package project import ( context "context" fmt "fmt" - application "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + application "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" @@ -705,7 +705,7 @@ var fileDescriptor_5f0a51496972c9e2 = []byte{ // 1007 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x6f, 0xe3, 0x44, 0x14, 0x96, 0x93, 0x36, 0xbb, 0x7d, 0x2d, 0xa5, 0xcc, 0xee, 0x76, 0xdd, 0xd0, 0x1f, 0x61, 0xd0, - 0x56, 0x51, 0xa1, 0xb6, 0xda, 0x80, 0xb4, 0x82, 0x13, 0xdb, 0xad, 0x02, 0x52, 0x0f, 0xe0, 0x82, + 0x56, 0x51, 0xa1, 0xb6, 0x9a, 0x82, 0xb4, 0x82, 0x13, 0xdb, 0xad, 0x02, 0x52, 0x0f, 0xe0, 0x82, 0x40, 0x1c, 0x40, 0x8e, 0xfd, 0x94, 0x9d, 0x8d, 0x63, 0x1b, 0xcf, 0x24, 0xdb, 0x10, 0xf5, 0x82, 0x04, 0x48, 0x1c, 0x38, 0xc0, 0x89, 0x0b, 0x47, 0xfe, 0x0f, 0x6e, 0x1c, 0x91, 0xf8, 0x07, 0x50, 0xc5, 0x1f, 0x82, 0x66, 0x3c, 0x76, 0xe2, 0xa4, 0xe6, 0x87, 0x1a, 0x38, 0x65, 0x3c, 0x7e, 0xfe, @@ -718,54 +718,54 @@ var fileDescriptor_5f0a51496972c9e2 = []byte{ 0xed, 0xc6, 0x71, 0xc0, 0x3c, 0x85, 0x6f, 0x0f, 0x8f, 0xdc, 0x20, 0x7e, 0xe2, 0xce, 0xa3, 0x9d, 0xfc, 0x0d, 0x9a, 0xce, 0x6a, 0x1a, 0x6b, 0x6a, 0x9c, 0x82, 0xd0, 0xef, 0x0c, 0xb8, 0xfb, 0x6e, 0x9a, 0xe0, 0x49, 0x82, 0xae, 0x40, 0x07, 0x3f, 0x1b, 0x20, 0x17, 0xa4, 0x03, 0x59, 0xe2, 0xa6, - 0xd1, 0x30, 0x9a, 0xab, 0xc7, 0x6f, 0x5b, 0x13, 0x3e, 0x2b, 0xe3, 0x53, 0x83, 0x4f, 0x3d, 0xdf, - 0x1a, 0xb6, 0xac, 0xb8, 0xd7, 0xb5, 0xa4, 0x7a, 0x6b, 0x9a, 0x25, 0x53, 0x6f, 0xbd, 0x15, 0xc7, - 0x9a, 0xc7, 0xc9, 0x80, 0xc9, 0x26, 0xd4, 0x06, 0x31, 0xc7, 0x44, 0x98, 0x95, 0x86, 0xd1, 0xbc, - 0xed, 0xe8, 0x27, 0xda, 0x83, 0x2d, 0x1d, 0xfb, 0x7e, 0xd4, 0xc3, 0xf0, 0x31, 0x06, 0x38, 0x11, - 0x66, 0x16, 0x85, 0xad, 0x4c, 0xe0, 0x08, 0x2c, 0x25, 0x51, 0x80, 0x0a, 0x6c, 0xc5, 0x51, 0x63, - 0xb2, 0x01, 0x55, 0xe6, 0x0a, 0xb3, 0xda, 0x30, 0x9a, 0x55, 0x47, 0x0e, 0xc9, 0x3a, 0x54, 0x98, - 0x6f, 0x2e, 0xa9, 0x98, 0x0a, 0xf3, 0xe9, 0x0f, 0x46, 0x91, 0xad, 0x58, 0x86, 0x72, 0xb6, 0x06, - 0xac, 0xfa, 0xc8, 0xbd, 0x84, 0xc5, 0x32, 0x51, 0x4d, 0x3a, 0x3d, 0x95, 0xeb, 0xa9, 0x4e, 0xe9, - 0xd9, 0x86, 0x15, 0xbc, 0x88, 0x59, 0x82, 0xfc, 0x9d, 0x50, 0x89, 0xa8, 0x3a, 0x93, 0x09, 0xad, - 0x6d, 0x39, 0xd7, 0xf6, 0x6a, 0xbe, 0x38, 0x4a, 0x9a, 0x83, 0x3c, 0x8e, 0x42, 0x8e, 0xe4, 0x2e, - 0x2c, 0x0b, 0x39, 0xa1, 0x35, 0xa5, 0x0f, 0x94, 0xc2, 0x9a, 0x8e, 0x7e, 0x6f, 0x80, 0xc9, 0x48, - 0xf2, 0x87, 0x6e, 0x1f, 0x75, 0x90, 0x1a, 0xd3, 0xcf, 0x73, 0xc4, 0x0f, 0x62, 0xff, 0xff, 0x5d, - 0x6e, 0xfa, 0x3c, 0x3c, 0x77, 0xda, 0x8f, 0xc5, 0x28, 0x4b, 0x83, 0xee, 0xc3, 0xc6, 0xf9, 0x28, - 0xf4, 0x3e, 0x64, 0xa1, 0x1f, 0x3d, 0xe3, 0xe5, 0xa2, 0x47, 0x70, 0x67, 0x2a, 0x2e, 0xaf, 0x42, - 0x07, 0x6e, 0x3d, 0x4b, 0xa7, 0x4c, 0xa3, 0x51, 0xbd, 0xb9, 0xe6, 0x09, 0x87, 0x93, 0x01, 0xd3, - 0x0b, 0xd8, 0x6c, 0x07, 0x51, 0xc7, 0x0d, 0x74, 0x36, 0x13, 0xf6, 0x4f, 0x60, 0x99, 0x09, 0xec, - 0x2f, 0x88, 0x7b, 0xaa, 0x5e, 0x29, 0x2c, 0xfd, 0xb9, 0x0a, 0xe6, 0x63, 0x14, 0x2e, 0x0b, 0xd0, - 0x9f, 0x23, 0x8f, 0x61, 0xbd, 0x5b, 0x90, 0xb5, 0x70, 0x15, 0x33, 0xf8, 0xd3, 0x0d, 0x52, 0xf9, - 0xaf, 0xfc, 0x20, 0x80, 0xb5, 0x04, 0xe3, 0x88, 0x33, 0x11, 0x25, 0x0c, 0xb9, 0x59, 0x5d, 0x44, - 0x4e, 0x4e, 0x86, 0x38, 0x72, 0x0a, 0xe8, 0xc4, 0x85, 0xdb, 0x5e, 0x30, 0xe0, 0x02, 0x13, 0x6e, - 0x2e, 0x29, 0xa6, 0xd3, 0x9b, 0x31, 0x9d, 0xa4, 0x68, 0x4e, 0x0e, 0x4b, 0x0f, 0xe1, 0xfe, 0x19, - 0xe3, 0x42, 0x27, 0x7a, 0xc6, 0xc2, 0x1e, 0xcf, 0x36, 0xdc, 0x35, 0x7d, 0x7e, 0xfc, 0xe3, 0x1a, - 0xac, 0xeb, 0xd8, 0x73, 0x4c, 0x86, 0xcc, 0x43, 0xf2, 0x8d, 0x01, 0xab, 0xa9, 0x23, 0x29, 0x07, - 0x20, 0xd4, 0xca, 0x4e, 0xa7, 0x52, 0xcf, 0xaa, 0xef, 0x5c, 0x1b, 0x93, 0xef, 0xba, 0x87, 0x5f, - 0xfc, 0xf6, 0xc7, 0xf7, 0x95, 0x63, 0x7a, 0xa8, 0xce, 0xaa, 0xe1, 0x51, 0x76, 0xde, 0x71, 0x7b, - 0xac, 0x47, 0x97, 0xb6, 0xf4, 0x2a, 0x6e, 0x8f, 0xe5, 0xcf, 0xa5, 0xad, 0xdc, 0xe5, 0x0d, 0xe3, - 0x80, 0x7c, 0x65, 0xc0, 0x6a, 0x6a, 0xc6, 0x7f, 0x25, 0xa6, 0x60, 0xd7, 0xf5, 0xcd, 0x3c, 0xa6, - 0xb8, 0xf7, 0xdf, 0x54, 0x2a, 0x5e, 0x3f, 0x68, 0xfd, 0x2b, 0x15, 0xf6, 0x98, 0xb9, 0xe2, 0x92, - 0x7c, 0x6b, 0x40, 0x2d, 0xcd, 0x99, 0xcc, 0x25, 0x5b, 0xac, 0xc5, 0xc2, 0xba, 0x94, 0xbe, 0xa8, - 0x04, 0xdf, 0xa3, 0x1b, 0xb3, 0x82, 0x65, 0x65, 0xbe, 0x34, 0x60, 0x49, 0xae, 0x34, 0xb9, 0x37, - 0x2b, 0x47, 0xb9, 0x5a, 0xfd, 0x6c, 0x51, 0x32, 0x24, 0x09, 0x35, 0x95, 0x14, 0x42, 0xe6, 0xa4, - 0x90, 0x0b, 0x20, 0x6d, 0x14, 0x33, 0xb6, 0x51, 0x26, 0xea, 0xa5, 0x7c, 0xba, 0xcc, 0x67, 0x68, - 0x53, 0x31, 0x51, 0xd2, 0x98, 0x5f, 0x25, 0xd9, 0xb1, 0x97, 0xb6, 0xaf, 0xbf, 0x24, 0x5f, 0x1b, - 0x50, 0x6d, 0x63, 0x29, 0xd7, 0xe2, 0xd6, 0x61, 0x4f, 0x49, 0xda, 0x22, 0xf7, 0x4b, 0x24, 0x91, - 0x31, 0xbc, 0xd0, 0x46, 0x51, 0x74, 0xed, 0x32, 0x59, 0x7b, 0xf9, 0xf4, 0xf5, 0x2e, 0x4f, 0x2d, - 0xc5, 0xd6, 0x24, 0xfb, 0x65, 0x05, 0x48, 0x6d, 0x32, 0x5f, 0x80, 0x9f, 0x0c, 0xa8, 0xa5, 0x27, - 0xeb, 0x7c, 0x67, 0x16, 0x4e, 0xdc, 0x05, 0x56, 0xa4, 0xa5, 0x34, 0x1e, 0xd6, 0x9b, 0xa5, 0x5b, - 0xc9, 0xea, 0xa3, 0x70, 0x7d, 0x57, 0xb8, 0x96, 0x12, 0x2d, 0x3b, 0xf6, 0x23, 0xa8, 0xa5, 0x1b, - 0xb5, 0xac, 0x34, 0x65, 0x1b, 0x57, 0xd7, 0xff, 0xa0, 0xb4, 0xfe, 0x4f, 0x01, 0x64, 0x97, 0x9e, - 0x0e, 0x31, 0x2c, 0x2f, 0xfc, 0x8e, 0x95, 0xde, 0x97, 0x65, 0x86, 0x96, 0xbc, 0x2f, 0x5b, 0xc3, - 0x23, 0x4b, 0x7d, 0xa2, 0x3a, 0x7c, 0x5f, 0x91, 0x34, 0xc8, 0x6e, 0x59, 0xd9, 0x31, 0x45, 0x1f, - 0xc3, 0x9d, 0x36, 0x8a, 0xa9, 0xcb, 0xc1, 0xb9, 0x90, 0xa5, 0xdf, 0xca, 0x49, 0x67, 0xef, 0x17, - 0xf5, 0xed, 0xeb, 0x5e, 0xe5, 0xc9, 0xbd, 0xa2, 0x78, 0x1f, 0x90, 0x97, 0xcb, 0x78, 0xf9, 0x28, - 0xf4, 0xf4, 0xdd, 0x80, 0xc4, 0xb0, 0x22, 0xc5, 0x2a, 0x5b, 0x27, 0x8d, 0x1c, 0xb7, 0xc4, 0xf1, - 0xeb, 0xf5, 0xc2, 0x42, 0xea, 0x57, 0x9a, 0xf7, 0x81, 0xe2, 0xdd, 0x23, 0x3b, 0x65, 0xbc, 0x81, - 0x0c, 0x7f, 0xf4, 0xe8, 0x97, 0xab, 0x5d, 0xe3, 0xd7, 0xab, 0x5d, 0xe3, 0xf7, 0xab, 0x5d, 0xe3, - 0xe3, 0xd7, 0xfe, 0xd9, 0xdf, 0x09, 0x2f, 0x60, 0x18, 0xe6, 0xff, 0x6a, 0x3a, 0x35, 0x75, 0xf1, - 0x6f, 0xfd, 0x19, 0x00, 0x00, 0xff, 0xff, 0xae, 0xc9, 0xe8, 0xa8, 0xf6, 0x0c, 0x00, 0x00, + 0xd1, 0x30, 0x9a, 0xab, 0xad, 0xb7, 0xad, 0x09, 0x9f, 0x95, 0xf1, 0xa9, 0xc1, 0xa7, 0x9e, 0x6f, + 0x0d, 0x5b, 0x56, 0xdc, 0xeb, 0x5a, 0x52, 0xbd, 0x35, 0xcd, 0x92, 0xa9, 0xb7, 0xde, 0x8a, 0x63, + 0xcd, 0xe3, 0x64, 0xc0, 0x64, 0x13, 0x6a, 0x83, 0x98, 0x63, 0x22, 0xcc, 0x4a, 0xc3, 0x68, 0xde, + 0x76, 0xf4, 0x13, 0xed, 0xc1, 0x96, 0x8e, 0x7d, 0x3f, 0xea, 0x61, 0xf8, 0x18, 0x03, 0x9c, 0x08, + 0x33, 0x8b, 0xc2, 0x56, 0x26, 0x70, 0x04, 0x96, 0x92, 0x28, 0x40, 0x05, 0xb6, 0xe2, 0xa8, 0x31, + 0xd9, 0x80, 0x2a, 0x73, 0x85, 0x59, 0x6d, 0x18, 0xcd, 0xaa, 0x23, 0x87, 0x64, 0x1d, 0x2a, 0xcc, + 0x37, 0x97, 0x54, 0x4c, 0x85, 0xf9, 0xf4, 0x07, 0xa3, 0xc8, 0x56, 0x2c, 0x43, 0x39, 0x5b, 0x03, + 0x56, 0x7d, 0xe4, 0x5e, 0xc2, 0x62, 0x99, 0xa8, 0x26, 0x9d, 0x9e, 0xca, 0xf5, 0x54, 0xa7, 0xf4, + 0x6c, 0xc3, 0x0a, 0x5e, 0xc4, 0x2c, 0x41, 0xfe, 0x4e, 0xa8, 0x44, 0x54, 0x9d, 0xc9, 0x84, 0xd6, + 0xb6, 0x9c, 0x6b, 0x7b, 0x35, 0x5f, 0x1c, 0x25, 0xcd, 0x41, 0x1e, 0x47, 0x21, 0x47, 0x72, 0x17, + 0x96, 0x85, 0x9c, 0xd0, 0x9a, 0xd2, 0x07, 0x4a, 0x61, 0x4d, 0x47, 0xbf, 0x37, 0xc0, 0x64, 0x24, + 0xf9, 0x43, 0xb7, 0x8f, 0x3a, 0x48, 0x8d, 0xe9, 0xe7, 0x39, 0xe2, 0x07, 0xb1, 0xff, 0xff, 0x2e, + 0x37, 0x7d, 0x1e, 0x9e, 0x3b, 0xed, 0xc7, 0x62, 0x94, 0xa5, 0x41, 0xf7, 0x61, 0xe3, 0x7c, 0x14, + 0x7a, 0x1f, 0xb2, 0xd0, 0x8f, 0x9e, 0xf1, 0x72, 0xd1, 0x23, 0xb8, 0x33, 0x15, 0x97, 0x57, 0xa1, + 0x03, 0xb7, 0x9e, 0xa5, 0x53, 0xa6, 0xd1, 0xa8, 0xde, 0x5c, 0xf3, 0x84, 0xc3, 0xc9, 0x80, 0xe9, + 0x05, 0x6c, 0xb6, 0x83, 0xa8, 0xe3, 0x06, 0x3a, 0x9b, 0x09, 0xfb, 0x27, 0xb0, 0xcc, 0x04, 0xf6, + 0x17, 0xc4, 0x3d, 0x55, 0xaf, 0x14, 0x96, 0xfe, 0x5c, 0x05, 0xf3, 0x31, 0x0a, 0x97, 0x05, 0xe8, + 0xcf, 0x91, 0xc7, 0xb0, 0xde, 0x2d, 0xc8, 0x5a, 0xb8, 0x8a, 0x19, 0xfc, 0xe9, 0x06, 0xa9, 0xfc, + 0x57, 0x7e, 0x10, 0xc0, 0x5a, 0x82, 0x71, 0xc4, 0x99, 0x88, 0x12, 0x86, 0xdc, 0xac, 0x2e, 0x22, + 0x27, 0x27, 0x43, 0x1c, 0x39, 0x05, 0x74, 0xe2, 0xc2, 0x6d, 0x2f, 0x18, 0x70, 0x81, 0x09, 0x37, + 0x97, 0x14, 0xd3, 0xe9, 0xcd, 0x98, 0x4e, 0x52, 0x34, 0x27, 0x87, 0xa5, 0x87, 0x70, 0xff, 0x8c, + 0x71, 0xa1, 0x13, 0x3d, 0x63, 0x61, 0x8f, 0x67, 0x1b, 0xee, 0x9a, 0x3e, 0x6f, 0xfd, 0xb8, 0x06, + 0xeb, 0x3a, 0xf6, 0x1c, 0x93, 0x21, 0xf3, 0x90, 0x7c, 0x63, 0xc0, 0x6a, 0xea, 0x48, 0xca, 0x01, + 0x08, 0xb5, 0xb2, 0xd3, 0xa9, 0xd4, 0xb3, 0xea, 0x3b, 0xd7, 0xc6, 0xe4, 0xbb, 0xee, 0xe1, 0x17, + 0xbf, 0xfd, 0xf1, 0x7d, 0xa5, 0x45, 0x0f, 0xd5, 0x59, 0x35, 0x3c, 0xca, 0xce, 0x3b, 0x6e, 0x8f, + 0xf5, 0xe8, 0xd2, 0x96, 0x5e, 0xc5, 0xed, 0xb1, 0xfc, 0xb9, 0xb4, 0x95, 0xbb, 0xbc, 0x61, 0x1c, + 0x90, 0xaf, 0x0c, 0x58, 0x4d, 0xcd, 0xf8, 0xaf, 0xc4, 0x14, 0xec, 0xba, 0xbe, 0x99, 0xc7, 0x14, + 0xf7, 0xfe, 0x9b, 0x4a, 0xc5, 0xeb, 0x07, 0xc7, 0xff, 0x4a, 0x85, 0x3d, 0x66, 0xae, 0xb8, 0x24, + 0xdf, 0x1a, 0x50, 0x4b, 0x73, 0x26, 0x73, 0xc9, 0x16, 0x6b, 0xb1, 0xb0, 0x2e, 0xa5, 0x2f, 0x2a, + 0xc1, 0xf7, 0xe8, 0xc6, 0xac, 0x60, 0x59, 0x99, 0x2f, 0x0d, 0x58, 0x92, 0x2b, 0x4d, 0xee, 0xcd, + 0xca, 0x51, 0xae, 0x56, 0x3f, 0x5b, 0x94, 0x0c, 0x49, 0x42, 0x4d, 0x25, 0x85, 0x90, 0x39, 0x29, + 0xe4, 0x02, 0x48, 0x1b, 0xc5, 0x8c, 0x6d, 0x94, 0x89, 0x7a, 0x29, 0x9f, 0x2e, 0xf3, 0x19, 0xda, + 0x54, 0x4c, 0x94, 0x34, 0xe6, 0x57, 0x49, 0x76, 0xec, 0xa5, 0xed, 0xeb, 0x2f, 0xc9, 0xd7, 0x06, + 0x54, 0xdb, 0x58, 0xca, 0xb5, 0xb8, 0x75, 0xd8, 0x53, 0x92, 0xb6, 0xc8, 0xfd, 0x12, 0x49, 0x64, + 0x0c, 0x2f, 0xb4, 0x51, 0x14, 0x5d, 0xbb, 0x4c, 0xd6, 0x5e, 0x3e, 0x7d, 0xbd, 0xcb, 0x53, 0x4b, + 0xb1, 0x35, 0xc9, 0x7e, 0x59, 0x01, 0x52, 0x9b, 0xcc, 0x17, 0xe0, 0x27, 0x03, 0x6a, 0xe9, 0xc9, + 0x3a, 0xdf, 0x99, 0x85, 0x13, 0x77, 0x81, 0x15, 0x39, 0x56, 0x1a, 0x0f, 0xeb, 0xcd, 0xd2, 0xad, + 0x64, 0xf5, 0x51, 0xb8, 0xbe, 0x2b, 0x5c, 0x4b, 0x89, 0x96, 0x1d, 0xfb, 0x11, 0xd4, 0xd2, 0x8d, + 0x5a, 0x56, 0x9a, 0xb2, 0x8d, 0xab, 0xeb, 0x7f, 0x50, 0x5a, 0xff, 0xa7, 0x00, 0xb2, 0x4b, 0x4f, + 0x87, 0x18, 0x96, 0x17, 0x7e, 0xc7, 0x4a, 0xef, 0xcb, 0x32, 0x43, 0x4b, 0xde, 0x97, 0xad, 0xe1, + 0x91, 0xa5, 0x3e, 0x51, 0x1d, 0xbe, 0xaf, 0x48, 0x1a, 0x64, 0xb7, 0xac, 0xec, 0x98, 0xa2, 0x8f, + 0xe1, 0x4e, 0x1b, 0xc5, 0xd4, 0xe5, 0xe0, 0x5c, 0xc8, 0xd2, 0x6f, 0xe5, 0xa4, 0xb3, 0xf7, 0x8b, + 0xfa, 0xf6, 0x75, 0xaf, 0xf2, 0xe4, 0x5e, 0x51, 0xbc, 0x0f, 0xc8, 0xcb, 0x65, 0xbc, 0x7c, 0x14, + 0x7a, 0xfa, 0x6e, 0x40, 0x62, 0x58, 0x91, 0x62, 0x95, 0xad, 0x93, 0x46, 0x8e, 0x5b, 0xe2, 0xf8, + 0xf5, 0x7a, 0x61, 0x21, 0xf5, 0x2b, 0xcd, 0xfb, 0x40, 0xf1, 0xee, 0x91, 0x9d, 0x32, 0xde, 0x40, + 0x86, 0x3f, 0x7a, 0xf4, 0xcb, 0xd5, 0xae, 0xf1, 0xeb, 0xd5, 0xae, 0xf1, 0xfb, 0xd5, 0xae, 0xf1, + 0xf1, 0x6b, 0xff, 0xec, 0xef, 0x84, 0x17, 0x30, 0x0c, 0xf3, 0x7f, 0x35, 0x9d, 0x9a, 0xba, 0xf8, + 0x1f, 0xff, 0x19, 0x00, 0x00, 0xff, 0xff, 0x28, 0x9d, 0xea, 0xa8, 0xf6, 0x0c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/pkg/apiclient/repocreds/repocreds.pb.go b/pkg/apiclient/repocreds/repocreds.pb.go index 41ff23d403..6a856e869f 100644 --- a/pkg/apiclient/repocreds/repocreds.pb.go +++ b/pkg/apiclient/repocreds/repocreds.pb.go @@ -10,7 +10,7 @@ package repocreds import ( context "context" fmt "fmt" - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" @@ -285,43 +285,43 @@ func init() { func init() { proto.RegisterFile("server/repocreds/repocreds.proto", fileDescriptor_b0b5fce4710a8821) } var fileDescriptor_b0b5fce4710a8821 = []byte{ - // 571 bytes of a gzipped FileDescriptorProto + // 570 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x95, 0x41, 0x6b, 0xd4, 0x40, - 0x14, 0xc7, 0x99, 0x8a, 0xc5, 0x8e, 0x20, 0x6d, 0x0a, 0x6d, 0x37, 0x6d, 0xb7, 0x31, 0x62, 0x29, - 0x4b, 0x3b, 0x61, 0x77, 0xc1, 0x83, 0x47, 0x5b, 0xf0, 0x60, 0x2f, 0xae, 0x88, 0x20, 0x88, 0x4c, - 0xb3, 0x8f, 0x74, 0x6c, 0xcc, 0x8c, 0x33, 0x93, 0x94, 0x22, 0x22, 0x78, 0xf4, 0xe2, 0xc1, 0xbb, - 0x77, 0xf1, 0xae, 0x77, 0x4f, 0x1e, 0x85, 0x7e, 0x01, 0x59, 0xfc, 0x20, 0x32, 0x93, 0xcd, 0x66, - 0x97, 0x66, 0x65, 0x17, 0xd6, 0x7a, 0x7b, 0x49, 0x5e, 0xde, 0xfb, 0xfd, 0xff, 0xf3, 0x66, 0x06, + 0x14, 0xc7, 0x99, 0x8a, 0xc5, 0x8e, 0x20, 0x6d, 0x0a, 0x6d, 0x37, 0xdb, 0x6e, 0x63, 0xc4, 0x52, + 0x96, 0x76, 0xc2, 0xae, 0xe0, 0xc1, 0xa3, 0x2d, 0x78, 0xb0, 0x17, 0x57, 0x44, 0x10, 0x44, 0xa6, + 0xd9, 0x47, 0x3a, 0x36, 0x66, 0xc6, 0x99, 0x49, 0x4a, 0x11, 0x11, 0x3c, 0x7a, 0xf1, 0xe0, 0xdd, + 0xbb, 0x78, 0xd7, 0xbb, 0x27, 0x8f, 0x42, 0xbf, 0x80, 0x2c, 0x7e, 0x10, 0x99, 0xc9, 0x66, 0xb3, + 0x4b, 0xb3, 0xb2, 0x0b, 0x6b, 0x7b, 0x7b, 0x49, 0x5e, 0xde, 0xfb, 0xfd, 0xff, 0xf3, 0x66, 0x06, 0x7b, 0x0a, 0x64, 0x06, 0x32, 0x90, 0x20, 0x78, 0x28, 0xa1, 0xab, 0xca, 0x88, 0x08, 0xc9, 0x35, - 0x77, 0x16, 0x06, 0x2f, 0xdc, 0x8d, 0x88, 0xf3, 0x28, 0x86, 0x80, 0x0a, 0x16, 0xd0, 0x24, 0xe1, - 0x9a, 0x6a, 0xc6, 0x93, 0x7e, 0xa2, 0x7b, 0x18, 0x31, 0x7d, 0x9c, 0x1e, 0x91, 0x90, 0xbf, 0x0c, - 0xa8, 0x8c, 0xb8, 0x90, 0xfc, 0x85, 0x0d, 0xf6, 0xc2, 0x6e, 0x90, 0xb5, 0x03, 0x71, 0x12, 0x99, - 0x3f, 0x55, 0x40, 0x85, 0x88, 0x59, 0x68, 0xff, 0x0d, 0xb2, 0x26, 0x8d, 0xc5, 0x31, 0x6d, 0x06, - 0x11, 0x24, 0x20, 0xa9, 0x86, 0x6e, 0x5e, 0xcd, 0xf7, 0xf1, 0x8d, 0x0e, 0x08, 0xbe, 0x6f, 0x1a, - 0x3f, 0x4c, 0x41, 0x9e, 0x39, 0x8b, 0xf8, 0x4a, 0x2a, 0xe3, 0x35, 0xe4, 0xa1, 0x9d, 0x85, 0x8e, - 0x09, 0xfd, 0x06, 0x5e, 0x19, 0xe4, 0x1c, 0x40, 0x0c, 0x1a, 0x3a, 0xf0, 0x2a, 0x05, 0xa5, 0x2b, - 0x72, 0x97, 0xf1, 0xd2, 0x20, 0xb7, 0x03, 0x4a, 0xf0, 0x44, 0x81, 0xff, 0x01, 0x0d, 0x55, 0xd8, - 0x97, 0x40, 0xcb, 0x0a, 0xcf, 0xf0, 0x55, 0x2b, 0xda, 0xd6, 0xb8, 0xde, 0xba, 0x4f, 0x4a, 0x75, - 0xa4, 0x50, 0x67, 0x83, 0xe7, 0x61, 0x97, 0x64, 0x6d, 0x22, 0x4e, 0x22, 0x62, 0xd4, 0x91, 0x21, + 0x77, 0x16, 0x06, 0x2f, 0xdc, 0xf5, 0x88, 0xf3, 0x28, 0x86, 0x80, 0x0a, 0x16, 0xd0, 0x24, 0xe1, + 0x9a, 0x6a, 0xc6, 0x93, 0x7e, 0xa2, 0x7b, 0x10, 0x31, 0x7d, 0x94, 0x1e, 0x92, 0x90, 0xbf, 0x0a, + 0xa8, 0x8c, 0xb8, 0x90, 0xfc, 0xa5, 0x0d, 0x76, 0xc3, 0x6e, 0x90, 0xb5, 0x03, 0x71, 0x1c, 0x99, + 0x3f, 0x55, 0x40, 0x85, 0x88, 0x59, 0x68, 0xff, 0x0d, 0xb2, 0x16, 0x8d, 0xc5, 0x11, 0x6d, 0x05, + 0x11, 0x24, 0x20, 0xa9, 0x86, 0x6e, 0x5e, 0xcd, 0xf7, 0xf1, 0x8d, 0x0e, 0x08, 0xbe, 0x67, 0x1a, + 0x3f, 0x4a, 0x41, 0x9e, 0x3a, 0x8b, 0xf8, 0x4a, 0x2a, 0xe3, 0x35, 0xe4, 0xa1, 0xed, 0x85, 0x8e, + 0x09, 0xfd, 0x26, 0x5e, 0x19, 0xe4, 0xec, 0x43, 0x0c, 0x1a, 0x3a, 0xf0, 0x3a, 0x05, 0xa5, 0x2b, + 0x72, 0x97, 0xf1, 0xd2, 0x20, 0xb7, 0x03, 0x4a, 0xf0, 0x44, 0x81, 0xff, 0x11, 0x0d, 0x55, 0xd8, + 0x93, 0x40, 0xcb, 0x0a, 0xcf, 0xf1, 0x55, 0x2b, 0xda, 0xd6, 0xb8, 0xde, 0x7e, 0x40, 0x4a, 0x75, + 0xa4, 0x50, 0x67, 0x83, 0x17, 0x61, 0x97, 0x64, 0x6d, 0x22, 0x8e, 0x23, 0x62, 0xd4, 0x91, 0x21, 0x75, 0xa4, 0x50, 0x47, 0xca, 0xd6, 0x79, 0x55, 0x67, 0x05, 0xcf, 0xa7, 0x42, 0x81, 0xd4, 0x6b, - 0x73, 0x1e, 0xda, 0xb9, 0xd6, 0xe9, 0x3f, 0xf9, 0xa7, 0x43, 0x40, 0x8f, 0x45, 0xf7, 0xd2, 0x80, - 0x5a, 0xe7, 0x18, 0x2f, 0x0e, 0x5e, 0x3e, 0x02, 0x99, 0xb1, 0x10, 0x9c, 0x4f, 0x08, 0xd7, 0x0e, - 0x99, 0xd2, 0xe6, 0x83, 0x62, 0x9a, 0xcb, 0x33, 0xf3, 0x19, 0x12, 0xcd, 0x68, 0xac, 0x9c, 0x1a, - 0x29, 0x67, 0x65, 0x74, 0xad, 0xdc, 0x07, 0x33, 0xa2, 0x33, 0xcd, 0xfd, 0xda, 0xbb, 0xf3, 0xdf, - 0x1f, 0xe7, 0x96, 0x9d, 0x25, 0x3b, 0x78, 0x59, 0xb3, 0x1c, 0x51, 0xe7, 0x33, 0xc2, 0x75, 0x93, - 0xf3, 0x44, 0x32, 0xe3, 0xd4, 0xff, 0xa4, 0xdc, 0xb2, 0x94, 0x35, 0x67, 0xb5, 0xa0, 0x3c, 0x35, - 0x4c, 0x7b, 0x25, 0xeb, 0x17, 0x84, 0xd7, 0x8b, 0x19, 0xab, 0x02, 0xbd, 0x59, 0x05, 0x3a, 0x32, - 0x94, 0xee, 0xac, 0x16, 0xdd, 0xf7, 0x2c, 0xac, 0xeb, 0x5f, 0xb4, 0xf4, 0x6e, 0x7f, 0x40, 0xbf, - 0x22, 0xec, 0xe5, 0xcd, 0xff, 0xe2, 0xed, 0x65, 0x22, 0x6f, 0x5b, 0x64, 0xcf, 0x1f, 0xe7, 0x6f, - 0x01, 0xfe, 0x0d, 0xe1, 0xf5, 0x62, 0xe7, 0x4c, 0xcc, 0x3c, 0xb2, 0xd5, 0x66, 0xc7, 0xbc, 0x6b, - 0x99, 0xb7, 0xdd, 0xcd, 0x0b, 0x36, 0x07, 0xaf, 0x73, 0x82, 0x54, 0xc6, 0x6f, 0x0a, 0xf2, 0xef, - 0x08, 0x7b, 0x39, 0xc8, 0xb4, 0x96, 0xff, 0x23, 0xfc, 0x96, 0xc5, 0xdf, 0x75, 0x6f, 0x8d, 0xb1, - 0xbc, 0x4a, 0xc4, 0x5b, 0xbc, 0x5e, 0x1c, 0xc5, 0x13, 0xe3, 0x8f, 0x9c, 0xdd, 0xee, 0x46, 0x55, - 0xca, 0xe0, 0xc8, 0xee, 0x6f, 0xb3, 0xc6, 0x6a, 0x85, 0xa5, 0x86, 0xc3, 0x79, 0x8f, 0xb0, 0x97, - 0x17, 0x9c, 0xd6, 0xc5, 0x69, 0x30, 0x6e, 0x5b, 0x8c, 0xad, 0xc6, 0xe6, 0x58, 0x6b, 0x0c, 0xcc, - 0xbd, 0x83, 0x1f, 0xbd, 0x3a, 0xfa, 0xd9, 0xab, 0xa3, 0x5f, 0xbd, 0x3a, 0x7a, 0x7a, 0x67, 0xb2, - 0x1b, 0x32, 0x8c, 0x19, 0x24, 0xba, 0x14, 0x76, 0x34, 0x6f, 0xaf, 0xc4, 0xf6, 0x9f, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x25, 0xb3, 0xca, 0x8a, 0xad, 0x07, 0x00, 0x00, + 0x73, 0x1e, 0xda, 0xbe, 0xd6, 0xe9, 0x3f, 0xf9, 0x27, 0x43, 0x40, 0x4f, 0x44, 0xf7, 0xc2, 0x80, + 0xda, 0x67, 0x18, 0x2f, 0x0e, 0x5e, 0x3e, 0x06, 0x99, 0xb1, 0x10, 0x9c, 0xcf, 0x08, 0xd7, 0x0e, + 0x98, 0xd2, 0xe6, 0x83, 0x62, 0x9a, 0xcb, 0x53, 0xf3, 0x19, 0x12, 0xcd, 0x68, 0xac, 0x9c, 0x1a, + 0x29, 0x67, 0x65, 0x74, 0xad, 0xdc, 0x87, 0x33, 0xa2, 0x33, 0xcd, 0xfd, 0xda, 0xfb, 0xb3, 0x3f, + 0x9f, 0xe6, 0x96, 0x9d, 0x25, 0x3b, 0x78, 0x59, 0xab, 0x1c, 0x51, 0xe7, 0x0b, 0xc2, 0x0d, 0x93, + 0xf3, 0x54, 0x32, 0xe3, 0xd4, 0x65, 0x52, 0x6e, 0x5a, 0xca, 0x9a, 0xb3, 0x5a, 0x50, 0x9e, 0x18, + 0xa6, 0xdd, 0x92, 0xf5, 0x2b, 0xc2, 0xf5, 0x62, 0xc6, 0xaa, 0x40, 0x6f, 0x56, 0x81, 0x8e, 0x0c, + 0xa5, 0x3b, 0xab, 0x45, 0xf7, 0x3d, 0x0b, 0xeb, 0xfa, 0xe7, 0x2d, 0xbd, 0xd7, 0x1f, 0xd0, 0x6f, + 0x08, 0x7b, 0x79, 0xf3, 0x7f, 0x78, 0x7b, 0x91, 0xc8, 0x5b, 0x16, 0xd9, 0xf3, 0xc7, 0xf9, 0x5b, + 0x80, 0x7f, 0x47, 0xb8, 0x5e, 0xec, 0x9c, 0x89, 0x99, 0x47, 0xb6, 0xda, 0xec, 0x98, 0x77, 0x2c, + 0xf3, 0x96, 0xbb, 0x71, 0xce, 0xe6, 0xe0, 0x4d, 0x4e, 0x90, 0xca, 0xf8, 0x6d, 0x41, 0xfe, 0x03, + 0x61, 0x2f, 0x07, 0x99, 0xd6, 0xf2, 0xff, 0x84, 0xdf, 0xb6, 0xf8, 0x3b, 0xee, 0xad, 0x31, 0x96, + 0x57, 0x89, 0x78, 0x87, 0xeb, 0xc5, 0x51, 0x3c, 0x31, 0xfe, 0xc8, 0xd9, 0xed, 0xae, 0x57, 0xa5, + 0x0c, 0x8e, 0xec, 0xfe, 0x36, 0x6b, 0xae, 0x56, 0x58, 0x6a, 0x38, 0x9c, 0x0f, 0x08, 0x7b, 0x79, + 0xc1, 0x69, 0x5d, 0x9c, 0x06, 0xe3, 0xb6, 0xc5, 0xd8, 0x6c, 0x6e, 0x8c, 0xb5, 0xc6, 0xc0, 0xdc, + 0xdf, 0xff, 0xd9, 0x6b, 0xa0, 0x5f, 0xbd, 0x06, 0xfa, 0xdd, 0x6b, 0xa0, 0x67, 0x77, 0x27, 0xbb, + 0x21, 0xc3, 0x98, 0x41, 0xa2, 0x4b, 0x61, 0x87, 0xf3, 0xf6, 0x4a, 0xbc, 0xf3, 0x37, 0x00, 0x00, + 0xff, 0xff, 0xe4, 0x00, 0xe9, 0x59, 0xad, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/pkg/apiclient/repository/repository.pb.go b/pkg/apiclient/repository/repository.pb.go index e9e8951a6e..feb1003e45 100644 --- a/pkg/apiclient/repository/repository.pb.go +++ b/pkg/apiclient/repository/repository.pb.go @@ -10,8 +10,8 @@ package repository import ( context "context" fmt "fmt" - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - apiclient "github.com/argoproj/argo-cd/v3/reposerver/apiclient" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + apiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" @@ -395,11 +395,7 @@ type RepoAccessQuery struct { // Google Cloud Platform service account key GcpServiceAccountKey string `protobuf:"bytes,18,opt,name=gcpServiceAccountKey,proto3" json:"gcpServiceAccountKey,omitempty"` // Whether to force HTTP basic auth - ForceHttpBasicAuth bool `protobuf:"varint,19,opt,name=forceHttpBasicAuth,proto3" json:"forceHttpBasicAuth,omitempty"` - // Whether to use azure workload identity for authentication - UseAzureWorkloadIdentity bool `protobuf:"varint,20,opt,name=useAzureWorkloadIdentity,proto3" json:"useAzureWorkloadIdentity,omitempty"` - // BearerToken contains the bearer token used for Git auth at the repo server - BearerToken string `protobuf:"bytes,21,opt,name=bearerToken,proto3" json:"bearerToken,omitempty"` + ForceHttpBasicAuth bool `protobuf:"varint,19,opt,name=forceHttpBasicAuth,proto3" json:"forceHttpBasicAuth,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -564,20 +560,6 @@ func (m *RepoAccessQuery) GetForceHttpBasicAuth() bool { return false } -func (m *RepoAccessQuery) GetUseAzureWorkloadIdentity() bool { - if m != nil { - return m.UseAzureWorkloadIdentity - } - return false -} - -func (m *RepoAccessQuery) GetBearerToken() string { - if m != nil { - return m.BearerToken - } - return "" -} - type RepoResponse struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -748,92 +730,89 @@ func init() { } var fileDescriptor_8d38260443475705 = []byte{ - // 1349 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x98, 0xcf, 0x6f, 0x1c, 0x35, - 0x14, 0xc7, 0x35, 0x49, 0xb3, 0x4d, 0x5e, 0x9a, 0x76, 0xeb, 0x24, 0x65, 0xd8, 0xa6, 0x69, 0x98, - 0x96, 0x2a, 0x8d, 0xda, 0xd9, 0x66, 0x0b, 0xa2, 0x2a, 0x02, 0x69, 0x9b, 0x54, 0x6d, 0x44, 0x44, - 0xcb, 0x94, 0x52, 0x09, 0x81, 0x90, 0x33, 0xfb, 0xb2, 0x3b, 0xcd, 0x64, 0xc6, 0xb5, 0xbd, 0xdb, - 0x2e, 0x55, 0x2f, 0x1c, 0x10, 0x12, 0x5c, 0x10, 0x02, 0x71, 0x02, 0x0e, 0x48, 0x48, 0x70, 0xe7, - 0x6f, 0xe0, 0x88, 0xc4, 0x3f, 0x80, 0x2a, 0xfe, 0x08, 0x6e, 0x20, 0xdb, 0xb3, 0x33, 0xb3, 0xc9, - 0xfe, 0x48, 0xd5, 0x34, 0x37, 0xfb, 0xd9, 0xf3, 0xde, 0xc7, 0x5f, 0xbf, 0x67, 0x7b, 0x17, 0x1c, - 0x81, 0xbc, 0x85, 0xbc, 0xcc, 0x91, 0xc5, 0x22, 0x90, 0x31, 0x6f, 0xe7, 0x9a, 0x2e, 0xe3, 0xb1, - 0x8c, 0x09, 0x64, 0x96, 0xd2, 0x5c, 0x3d, 0x8e, 0xeb, 0x21, 0x96, 0x29, 0x0b, 0xca, 0x34, 0x8a, - 0x62, 0x49, 0x65, 0x10, 0x47, 0xc2, 0xcc, 0x2c, 0xad, 0xd7, 0x03, 0xd9, 0x68, 0x6e, 0xb8, 0x7e, - 0xbc, 0x5d, 0xa6, 0xbc, 0x1e, 0x33, 0x1e, 0xdf, 0xd7, 0x8d, 0x8b, 0x7e, 0xad, 0xdc, 0xba, 0x5c, - 0x66, 0x5b, 0x75, 0xf5, 0xa5, 0x28, 0x53, 0xc6, 0xc2, 0xc0, 0xd7, 0xdf, 0x96, 0x5b, 0xcb, 0x34, - 0x64, 0x0d, 0xba, 0x5c, 0xae, 0x63, 0x84, 0x9c, 0x4a, 0xac, 0x25, 0xde, 0xae, 0x0f, 0xf1, 0xa6, - 0xb1, 0x86, 0xe2, 0x3b, 0x6d, 0x98, 0xf2, 0x90, 0xc5, 0x55, 0xc6, 0xc4, 0x7b, 0x4d, 0xe4, 0x6d, - 0x42, 0xe0, 0x90, 0x9a, 0x64, 0x5b, 0x0b, 0xd6, 0xe2, 0x84, 0xa7, 0xdb, 0xa4, 0x04, 0xe3, 0x1c, - 0x5b, 0x81, 0x08, 0xe2, 0xc8, 0x1e, 0xd1, 0xf6, 0xb4, 0x4f, 0x6c, 0x38, 0x4c, 0x19, 0x7b, 0x97, - 0x6e, 0xa3, 0x3d, 0xaa, 0x87, 0x3a, 0x5d, 0x32, 0x0f, 0x40, 0x19, 0xbb, 0xcd, 0xe3, 0xfb, 0xe8, - 0x4b, 0xfb, 0x90, 0x1e, 0xcc, 0x59, 0x9c, 0x65, 0x38, 0x5c, 0x65, 0x6c, 0x2d, 0xda, 0x8c, 0x55, - 0x50, 0xd9, 0x66, 0xd8, 0x09, 0xaa, 0xda, 0xca, 0xc6, 0xa8, 0x6c, 0x24, 0x01, 0x75, 0xdb, 0xf9, - 0xd7, 0x82, 0xe9, 0x04, 0x77, 0x15, 0x25, 0x0d, 0xc2, 0x04, 0xba, 0x0e, 0x05, 0x11, 0x37, 0xb9, - 0x6f, 0x3c, 0x4c, 0x56, 0x6e, 0xb9, 0x99, 0x3a, 0x6e, 0x47, 0x1d, 0xdd, 0xf8, 0xc4, 0xaf, 0xb9, - 0xad, 0xcb, 0x2e, 0xdb, 0xaa, 0xbb, 0x4a, 0x6b, 0x37, 0xa7, 0xb5, 0xdb, 0xd1, 0xda, 0xad, 0x66, - 0xc6, 0x3b, 0xda, 0xad, 0x97, 0xb8, 0xcf, 0xaf, 0x76, 0x64, 0xd0, 0x6a, 0x47, 0x77, 0xae, 0x96, - 0x2c, 0xc0, 0xa4, 0xf1, 0xb1, 0x16, 0xd5, 0xf0, 0x91, 0x96, 0x63, 0xcc, 0xcb, 0x9b, 0xc8, 0x1c, - 0x4c, 0xb4, 0x90, 0x2b, 0x51, 0xd7, 0x6a, 0xf6, 0x98, 0x1e, 0xcf, 0x0c, 0xce, 0x5b, 0x50, 0xec, - 0x6c, 0x94, 0x87, 0x82, 0xc5, 0x91, 0x40, 0x72, 0x1e, 0xc6, 0x02, 0x89, 0xdb, 0xc2, 0xb6, 0x16, - 0x46, 0x17, 0x27, 0x2b, 0xd3, 0x6e, 0x6e, 0x7b, 0x13, 0x69, 0x3d, 0x33, 0xc3, 0xf1, 0x61, 0x42, - 0x7d, 0xde, 0x7f, 0x8f, 0x1d, 0x38, 0xb2, 0x19, 0xab, 0xa5, 0xe2, 0x26, 0x47, 0x61, 0x64, 0x1f, - 0xf7, 0xba, 0x6c, 0xc3, 0xd6, 0xe8, 0xfc, 0x37, 0x06, 0xc7, 0x34, 0xa4, 0xef, 0xa3, 0x18, 0x9c, - 0x4f, 0x4d, 0x81, 0x3c, 0xca, 0x64, 0x4c, 0xfb, 0x6a, 0x8c, 0x51, 0x21, 0x1e, 0xc6, 0xbc, 0x96, - 0x44, 0x48, 0xfb, 0xe4, 0x2c, 0x4c, 0x09, 0xd1, 0xb8, 0xcd, 0x83, 0x16, 0x95, 0xf8, 0x0e, 0xb6, - 0x93, 0xa4, 0xea, 0x36, 0x2a, 0x0f, 0x41, 0x24, 0xd0, 0x6f, 0x72, 0xd4, 0x32, 0x8e, 0x7b, 0x69, - 0x9f, 0x5c, 0x80, 0xe3, 0x32, 0x14, 0x2b, 0x61, 0x80, 0x91, 0x5c, 0x41, 0x2e, 0x57, 0xa9, 0xa4, - 0x76, 0x41, 0x7b, 0xd9, 0x3d, 0x40, 0x96, 0xa0, 0xd8, 0x65, 0x54, 0x21, 0x0f, 0xeb, 0xc9, 0xbb, - 0xec, 0x69, 0x0a, 0x4f, 0x74, 0xa7, 0xb0, 0x5e, 0x23, 0x18, 0x9b, 0x5e, 0xdf, 0x1c, 0x4c, 0x60, - 0x44, 0x37, 0x42, 0xbc, 0xe5, 0x07, 0xf6, 0xa4, 0xc6, 0xcb, 0x0c, 0xe4, 0x12, 0x4c, 0x9b, 0xcc, - 0xad, 0x2a, 0x55, 0xd3, 0x75, 0x1e, 0xd1, 0x0e, 0x7a, 0x0d, 0xa9, 0xbc, 0x4a, 0xcd, 0x6b, 0xab, - 0xf6, 0xd4, 0x82, 0xb5, 0x38, 0xea, 0xe5, 0x4d, 0xe4, 0x0a, 0xbc, 0x94, 0x75, 0x23, 0x21, 0x69, - 0x18, 0xea, 0xd4, 0x5e, 0x5b, 0xb5, 0x8f, 0xea, 0xd9, 0xfd, 0x86, 0xc9, 0xdb, 0x50, 0x4a, 0x87, - 0xae, 0x47, 0x12, 0x39, 0xe3, 0x81, 0xc0, 0x6b, 0x54, 0xe0, 0x5d, 0x1e, 0xda, 0xc7, 0x34, 0xd4, - 0x80, 0x19, 0x64, 0x06, 0xc6, 0x18, 0x8f, 0x1f, 0xb5, 0xed, 0xa2, 0x9e, 0x6a, 0x3a, 0xaa, 0x86, - 0x58, 0x92, 0x42, 0xc7, 0x4d, 0x0d, 0x25, 0x5d, 0x52, 0x81, 0x99, 0xba, 0xcf, 0xee, 0x20, 0x6f, - 0x05, 0x3e, 0x56, 0x7d, 0x3f, 0x6e, 0x46, 0x5a, 0x73, 0xa2, 0xa7, 0xf5, 0x1c, 0x23, 0x2e, 0x10, - 0x9d, 0xa3, 0x37, 0xa5, 0x64, 0xd7, 0xa8, 0x08, 0xfc, 0x6a, 0x53, 0x36, 0xec, 0x69, 0x2d, 0x6c, - 0x8f, 0x11, 0x72, 0x15, 0xec, 0xa6, 0xc0, 0xea, 0xa7, 0x4d, 0x8e, 0xf7, 0x62, 0xbe, 0x15, 0xc6, - 0xb4, 0xb6, 0x56, 0xc3, 0x48, 0x06, 0xb2, 0x6d, 0xcf, 0xe8, 0xaf, 0xfa, 0x8e, 0x2b, 0xad, 0x37, - 0x90, 0x72, 0xe4, 0xef, 0xc7, 0x5b, 0x18, 0xd9, 0xb3, 0x1a, 0x2b, 0x6f, 0x72, 0x8e, 0xc2, 0x11, - 0x55, 0x00, 0x9d, 0x0a, 0x75, 0x7e, 0xb1, 0xe0, 0xb8, 0x32, 0xac, 0x70, 0xa4, 0x12, 0x3d, 0x7c, - 0xd0, 0x44, 0x21, 0xc9, 0x47, 0xb9, 0x9a, 0x98, 0xac, 0xdc, 0x7c, 0xbe, 0xc3, 0xca, 0x4b, 0x6b, - 0x3e, 0xa9, 0xae, 0x13, 0x50, 0x68, 0x32, 0x81, 0x5c, 0x26, 0x35, 0x9c, 0xf4, 0x54, 0xe6, 0xf9, - 0x1c, 0x6b, 0xe2, 0x56, 0x14, 0xb6, 0x75, 0x69, 0x8d, 0x7b, 0x99, 0xc1, 0x79, 0x60, 0x40, 0xef, - 0xb2, 0xda, 0x41, 0x81, 0x56, 0x7e, 0x38, 0x61, 0x62, 0x1a, 0x63, 0xb2, 0xb5, 0xe4, 0x2b, 0x0b, - 0x0e, 0xad, 0x07, 0x42, 0x92, 0xd9, 0xfc, 0x71, 0x96, 0x1e, 0x5e, 0xa5, 0xf5, 0xfd, 0xa2, 0x50, - 0x41, 0x9c, 0xd3, 0x9f, 0xfd, 0xf5, 0xcf, 0x37, 0x23, 0x27, 0xc8, 0x8c, 0xbe, 0xb4, 0x5b, 0xcb, - 0xd9, 0x0d, 0x19, 0xa0, 0xf8, 0x62, 0xc4, 0x22, 0x5f, 0x5a, 0x30, 0x7a, 0x03, 0xfb, 0xd2, 0xec, - 0x9b, 0x26, 0xce, 0x19, 0x4d, 0x72, 0x8a, 0x9c, 0xec, 0x45, 0x52, 0x7e, 0xac, 0x7a, 0x4f, 0xc8, - 0x77, 0x16, 0x8c, 0xdf, 0x40, 0x79, 0x8f, 0x07, 0x12, 0x5f, 0x3c, 0xd2, 0x79, 0x8d, 0x74, 0x86, - 0xbc, 0xd2, 0x41, 0x7a, 0xa8, 0xe2, 0x5e, 0xec, 0x05, 0xf6, 0xad, 0x05, 0x45, 0x25, 0xa8, 0x97, - 0x1b, 0x3b, 0x98, 0x1d, 0x9c, 0x1b, 0xb4, 0x83, 0xe4, 0x27, 0x0b, 0x66, 0xd5, 0x34, 0xad, 0xd8, - 0xc1, 0xc3, 0x39, 0x1a, 0x6e, 0x8e, 0x94, 0xfa, 0x2b, 0x48, 0x3e, 0x86, 0x71, 0xa3, 0xdc, 0x66, - 0x5f, 0xa8, 0x62, 0xb7, 0x79, 0x53, 0x38, 0x8b, 0xda, 0xb1, 0x43, 0x16, 0x06, 0x64, 0x4b, 0x99, - 0x2b, 0x97, 0xdb, 0xc6, 0xbd, 0x7a, 0x38, 0x90, 0x97, 0x77, 0xba, 0x4f, 0xdf, 0x7d, 0xa5, 0xb9, - 0x5e, 0x43, 0xe9, 0x39, 0xb6, 0xa7, 0x70, 0x54, 0x85, 0xf8, 0xda, 0x82, 0xa9, 0x1b, 0x28, 0xb3, - 0x17, 0x1a, 0x39, 0xdd, 0xc3, 0x73, 0xfe, 0xf5, 0x56, 0x72, 0xfa, 0x4f, 0x48, 0x01, 0xde, 0xd4, - 0x00, 0xaf, 0x3b, 0x97, 0x7a, 0x03, 0x98, 0x77, 0x94, 0xf6, 0x73, 0xd7, 0x5b, 0xd7, 0x28, 0x35, - 0xe3, 0xe1, 0xaa, 0xb5, 0x44, 0x5a, 0x1a, 0xe9, 0x26, 0x86, 0xdb, 0x2b, 0x0d, 0xca, 0x65, 0x5f, - 0x99, 0xe7, 0xf3, 0xe6, 0x6c, 0x7a, 0x0a, 0xe1, 0x6a, 0x88, 0x45, 0x72, 0x6e, 0x90, 0x0a, 0x0d, - 0x0c, 0xb7, 0x7d, 0x13, 0xe6, 0x7b, 0x0b, 0x0a, 0xe6, 0xe4, 0x27, 0xa7, 0x76, 0x46, 0xec, 0xba, - 0x11, 0xf6, 0xb1, 0x66, 0x5f, 0x35, 0x19, 0xe7, 0xf4, 0x2c, 0x87, 0xab, 0xfa, 0xe0, 0x55, 0xc7, - 0xda, 0x8f, 0x16, 0x14, 0x3b, 0x08, 0x9d, 0x6f, 0x0f, 0x0e, 0xd2, 0x19, 0x0e, 0x49, 0x7e, 0xb5, - 0x60, 0xd6, 0xc4, 0xef, 0xae, 0xdd, 0x03, 0xc4, 0x4c, 0xb2, 0xde, 0x19, 0x50, 0xbd, 0x09, 0xec, - 0xcf, 0x16, 0x14, 0xcc, 0xd5, 0xb9, 0x9b, 0xae, 0xeb, 0x4a, 0xdd, 0x47, 0xba, 0x65, 0x93, 0x8d, - 0xa5, 0x01, 0x35, 0xa9, 0x51, 0x9e, 0x64, 0xbb, 0xfe, 0x9b, 0x05, 0xc5, 0x0e, 0x4e, 0x7f, 0x39, - 0x5f, 0x14, 0xb0, 0xfb, 0x6c, 0xc0, 0xe4, 0x77, 0x0b, 0x66, 0x0d, 0xcb, 0xd0, 0x0c, 0x78, 0x51, - 0xc8, 0xaf, 0x69, 0x64, 0xb7, 0x74, 0x6e, 0xd8, 0x0d, 0xd8, 0x05, 0x4e, 0xa1, 0xb0, 0x8a, 0x21, - 0xf6, 0xbf, 0xa2, 0xed, 0x9d, 0xe6, 0xf4, 0x88, 0x39, 0x67, 0x5e, 0x01, 0x4b, 0x83, 0x5e, 0x01, - 0x6a, 0x27, 0x1b, 0x50, 0x34, 0x21, 0x72, 0xaa, 0x3c, 0x73, 0xb0, 0x33, 0x7b, 0x08, 0x46, 0x04, - 0xcc, 0x9a, 0x48, 0x3b, 0x37, 0xe1, 0x99, 0xc3, 0x25, 0xcf, 0x89, 0xa5, 0x3d, 0x3c, 0x27, 0x1e, - 0xc3, 0xd1, 0x0f, 0x68, 0x18, 0xa8, 0x4d, 0x35, 0x3f, 0x26, 0xc9, 0xc9, 0x5d, 0x97, 0x44, 0xf6, - 0x23, 0x73, 0x40, 0xcc, 0x8a, 0x8e, 0x79, 0xc1, 0x39, 0x3b, 0xe8, 0xc8, 0x6e, 0x25, 0xa1, 0x92, - 0xed, 0xfb, 0xdc, 0x82, 0xe9, 0x4e, 0x74, 0xbd, 0xe8, 0xe7, 0x43, 0xb8, 0xa2, 0x11, 0x2a, 0xce, - 0xd2, 0xd0, 0x65, 0xef, 0x00, 0xb9, 0x76, 0xfd, 0x8f, 0xa7, 0xf3, 0xd6, 0x9f, 0x4f, 0xe7, 0xad, - 0xbf, 0x9f, 0xce, 0x5b, 0x1f, 0xbe, 0xb1, 0xb7, 0xff, 0x8f, 0x7c, 0xfd, 0xb3, 0x34, 0xf7, 0x4f, - 0xcf, 0x46, 0x41, 0xff, 0xd5, 0x73, 0xf9, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb8, 0x97, 0xe0, - 0xc3, 0xcf, 0x12, 0x00, 0x00, + // 1304 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x98, 0xdd, 0x6e, 0x1b, 0x45, + 0x14, 0xc7, 0xb5, 0x49, 0xe3, 0x26, 0x27, 0x4d, 0xeb, 0x4e, 0x9a, 0xb2, 0xb8, 0x69, 0x1a, 0xb6, + 0xa5, 0x4a, 0xa3, 0x76, 0xdd, 0x18, 0x10, 0x55, 0x11, 0x48, 0x6e, 0x52, 0xb5, 0x11, 0x11, 0x2d, + 0x5b, 0x15, 0x24, 0x04, 0x42, 0xd3, 0xf5, 0x89, 0xbd, 0xed, 0x7a, 0x77, 0x3a, 0x33, 0x76, 0x6b, + 0x55, 0xbd, 0xe1, 0x02, 0x21, 0xc1, 0x0d, 0x42, 0x20, 0xae, 0xf8, 0x90, 0x90, 0x90, 0xe0, 0x9e, + 0x67, 0xe0, 0x12, 0x89, 0x17, 0x40, 0x15, 0x0f, 0xc1, 0x25, 0x9a, 0x99, 0xf5, 0xee, 0xda, 0xf1, + 0x47, 0xaa, 0x26, 0xb9, 0x9b, 0x39, 0x67, 0xf6, 0x9c, 0xdf, 0xfc, 0xe7, 0xcc, 0x87, 0x0d, 0x8e, + 0x40, 0xde, 0x46, 0x5e, 0xe6, 0xc8, 0x62, 0x11, 0xc8, 0x98, 0x77, 0x72, 0x4d, 0x97, 0xf1, 0x58, + 0xc6, 0x04, 0x32, 0x4b, 0x69, 0xb1, 0x1e, 0xc7, 0xf5, 0x10, 0xcb, 0x94, 0x05, 0x65, 0x1a, 0x45, + 0xb1, 0xa4, 0x32, 0x88, 0x23, 0x61, 0x46, 0x96, 0xb6, 0xea, 0x81, 0x6c, 0xb4, 0xee, 0xb9, 0x7e, + 0xdc, 0x2c, 0x53, 0x5e, 0x8f, 0x19, 0x8f, 0xef, 0xeb, 0xc6, 0x25, 0xbf, 0x56, 0x6e, 0x57, 0xca, + 0xec, 0x41, 0x5d, 0x7d, 0x29, 0xca, 0x94, 0xb1, 0x30, 0xf0, 0xf5, 0xb7, 0xe5, 0xf6, 0x1a, 0x0d, + 0x59, 0x83, 0xae, 0x95, 0xeb, 0x18, 0x21, 0xa7, 0x12, 0x6b, 0x49, 0xb4, 0xeb, 0x63, 0xa2, 0x69, + 0xac, 0xb1, 0xf8, 0x4e, 0x07, 0xe6, 0x3c, 0x64, 0x71, 0x95, 0x31, 0xf1, 0x7e, 0x0b, 0x79, 0x87, + 0x10, 0x38, 0xa4, 0x06, 0xd9, 0xd6, 0xb2, 0xb5, 0x32, 0xe3, 0xe9, 0x36, 0x29, 0xc1, 0x34, 0xc7, + 0x76, 0x20, 0x82, 0x38, 0xb2, 0x27, 0xb4, 0x3d, 0xed, 0x13, 0x1b, 0x0e, 0x53, 0xc6, 0xde, 0xa3, + 0x4d, 0xb4, 0x27, 0xb5, 0xab, 0xdb, 0x25, 0x4b, 0x00, 0x94, 0xb1, 0xdb, 0x3c, 0xbe, 0x8f, 0xbe, + 0xb4, 0x0f, 0x69, 0x67, 0xce, 0xe2, 0xac, 0xc1, 0xe1, 0x2a, 0x63, 0x9b, 0xd1, 0x76, 0xac, 0x92, + 0xca, 0x0e, 0xc3, 0x6e, 0x52, 0xd5, 0x56, 0x36, 0x46, 0x65, 0x23, 0x49, 0xa8, 0xdb, 0xce, 0x7f, + 0x16, 0xcc, 0x27, 0xb8, 0x1b, 0x28, 0x69, 0x10, 0x26, 0xd0, 0x75, 0x28, 0x88, 0xb8, 0xc5, 0x7d, + 0x13, 0x61, 0xb6, 0x72, 0xcb, 0xcd, 0xd4, 0x71, 0xbb, 0xea, 0xe8, 0xc6, 0xa7, 0x7e, 0xcd, 0x6d, + 0x57, 0x5c, 0xf6, 0xa0, 0xee, 0x2a, 0xad, 0xdd, 0x9c, 0xd6, 0x6e, 0x57, 0x6b, 0xb7, 0x9a, 0x19, + 0xef, 0xe8, 0xb0, 0x5e, 0x12, 0x3e, 0x3f, 0xdb, 0x89, 0x51, 0xb3, 0x9d, 0xec, 0x9f, 0x2d, 0x59, + 0x86, 0x59, 0x13, 0x63, 0x33, 0xaa, 0xe1, 0x63, 0x2d, 0xc7, 0x94, 0x97, 0x37, 0x91, 0x45, 0x98, + 0x69, 0x23, 0x57, 0xa2, 0x6e, 0xd6, 0xec, 0x29, 0xed, 0xcf, 0x0c, 0xce, 0xdb, 0x50, 0xec, 0x2e, + 0x94, 0x87, 0x82, 0xc5, 0x91, 0x40, 0x72, 0x01, 0xa6, 0x02, 0x89, 0x4d, 0x61, 0x5b, 0xcb, 0x93, + 0x2b, 0xb3, 0x95, 0x79, 0x37, 0xb7, 0xbc, 0x89, 0xb4, 0x9e, 0x19, 0xe1, 0xf8, 0x30, 0xa3, 0x3e, + 0x1f, 0xbe, 0xc6, 0x0e, 0x1c, 0xd9, 0x8e, 0xd5, 0x54, 0x71, 0x9b, 0xa3, 0x30, 0xb2, 0x4f, 0x7b, + 0x3d, 0xb6, 0x71, 0x73, 0x74, 0x7e, 0x9e, 0x82, 0x63, 0x1a, 0xd2, 0xf7, 0x51, 0x8c, 0xae, 0xa7, + 0x96, 0x40, 0x1e, 0x65, 0x32, 0xa6, 0x7d, 0xe5, 0x63, 0x54, 0x88, 0x47, 0x31, 0xaf, 0x25, 0x19, + 0xd2, 0x3e, 0x39, 0x07, 0x73, 0x42, 0x34, 0x6e, 0xf3, 0xa0, 0x4d, 0x25, 0xbe, 0x8b, 0x9d, 0xa4, + 0xa8, 0x7a, 0x8d, 0x2a, 0x42, 0x10, 0x09, 0xf4, 0x5b, 0x1c, 0xb5, 0x8c, 0xd3, 0x5e, 0xda, 0x27, + 0x17, 0xe1, 0xb8, 0x0c, 0xc5, 0x7a, 0x18, 0x60, 0x24, 0xd7, 0x91, 0xcb, 0x0d, 0x2a, 0xa9, 0x5d, + 0xd0, 0x51, 0x76, 0x3a, 0xc8, 0x2a, 0x14, 0x7b, 0x8c, 0x2a, 0xe5, 0x61, 0x3d, 0x78, 0x87, 0x3d, + 0x2d, 0xe1, 0x99, 0xde, 0x12, 0xd6, 0x73, 0x04, 0x63, 0xd3, 0xf3, 0x5b, 0x84, 0x19, 0x8c, 0xe8, + 0xbd, 0x10, 0x6f, 0xf9, 0x81, 0x3d, 0xab, 0xf1, 0x32, 0x03, 0xb9, 0x0c, 0xf3, 0xa6, 0x72, 0xab, + 0x4a, 0xd5, 0x74, 0x9e, 0x47, 0x74, 0x80, 0x41, 0x2e, 0x55, 0x57, 0xa9, 0x79, 0x73, 0xc3, 0x9e, + 0x5b, 0xb6, 0x56, 0x26, 0xbd, 0xbc, 0x89, 0x5c, 0x81, 0x97, 0xb2, 0x6e, 0x24, 0x24, 0x0d, 0x43, + 0x5d, 0xda, 0x9b, 0x1b, 0xf6, 0x51, 0x3d, 0x7a, 0x98, 0x9b, 0xbc, 0x03, 0xa5, 0xd4, 0x75, 0x3d, + 0x92, 0xc8, 0x19, 0x0f, 0x04, 0x5e, 0xa3, 0x02, 0xef, 0xf2, 0xd0, 0x3e, 0xa6, 0xa1, 0x46, 0x8c, + 0x20, 0x27, 0x60, 0x8a, 0xf1, 0xf8, 0x71, 0xc7, 0x2e, 0xea, 0xa1, 0xa6, 0xa3, 0xf6, 0x10, 0x4b, + 0x4a, 0xe8, 0xb8, 0xd9, 0x43, 0x49, 0x97, 0x54, 0xe0, 0x44, 0xdd, 0x67, 0x77, 0x90, 0xb7, 0x03, + 0x1f, 0xab, 0xbe, 0x1f, 0xb7, 0x22, 0xad, 0x39, 0xd1, 0xc3, 0x06, 0xfa, 0x88, 0x0b, 0x44, 0xd7, + 0xe8, 0x4d, 0x29, 0xd9, 0x35, 0x2a, 0x02, 0xbf, 0xda, 0x92, 0x0d, 0x7b, 0x5e, 0x0b, 0x3b, 0xc0, + 0xe3, 0x1c, 0x85, 0x23, 0xaa, 0x44, 0xbb, 0x7b, 0xc8, 0xf9, 0xd5, 0x82, 0xe3, 0xca, 0xb0, 0xce, + 0x91, 0x4a, 0xf4, 0xf0, 0x61, 0x0b, 0x85, 0x24, 0x1f, 0xe7, 0xaa, 0x76, 0xb6, 0x72, 0xf3, 0xc5, + 0x8e, 0x13, 0x2f, 0xdd, 0x95, 0x49, 0xfd, 0x9f, 0x84, 0x42, 0x8b, 0x09, 0xe4, 0x32, 0xd9, 0x65, + 0x49, 0x4f, 0xd5, 0x86, 0xcf, 0xb1, 0x26, 0x6e, 0x45, 0x61, 0x47, 0x17, 0xff, 0xb4, 0x97, 0x19, + 0x9c, 0x87, 0x06, 0xf4, 0x2e, 0xab, 0x1d, 0x14, 0x68, 0xe5, 0x87, 0x93, 0x26, 0xa7, 0x31, 0x26, + 0xe2, 0x93, 0xaf, 0x2c, 0x38, 0xb4, 0x15, 0x08, 0x49, 0x16, 0xf2, 0x07, 0x4e, 0x7a, 0xbc, 0x94, + 0xb6, 0xf6, 0x8a, 0x42, 0x25, 0x71, 0xce, 0x7c, 0xf6, 0xf7, 0xbf, 0xdf, 0x4c, 0x9c, 0x24, 0x27, + 0xf4, 0xb5, 0xda, 0x5e, 0xcb, 0xee, 0xb0, 0x00, 0xc5, 0x17, 0x13, 0x16, 0xf9, 0xd2, 0x82, 0xc9, + 0x1b, 0x38, 0x94, 0x66, 0xcf, 0x34, 0x71, 0xce, 0x6a, 0x92, 0xd3, 0xe4, 0xd4, 0x20, 0x92, 0xf2, + 0x13, 0xd5, 0x7b, 0x4a, 0xbe, 0xb3, 0x60, 0xfa, 0x06, 0xca, 0x0f, 0x79, 0x20, 0x71, 0xff, 0x91, + 0x2e, 0x68, 0xa4, 0xb3, 0xe4, 0x95, 0x2e, 0xd2, 0x23, 0x95, 0xf7, 0xd2, 0x20, 0xb0, 0x6f, 0x2d, + 0x28, 0x2a, 0x41, 0xbd, 0x9c, 0xef, 0x60, 0x56, 0x70, 0x71, 0xd4, 0x0a, 0x92, 0x9f, 0x2c, 0x58, + 0x50, 0xc3, 0xb4, 0x62, 0x07, 0x0f, 0xe7, 0x68, 0xb8, 0x45, 0x52, 0x1a, 0xae, 0x20, 0xf9, 0x04, + 0xa6, 0x8d, 0x72, 0xdb, 0x43, 0xa1, 0x8a, 0xbd, 0xe6, 0x6d, 0xe1, 0xac, 0xe8, 0xc0, 0x0e, 0x59, + 0x1e, 0x51, 0x2d, 0x65, 0xae, 0x42, 0x36, 0x4d, 0x78, 0x75, 0xb5, 0x93, 0x97, 0xfb, 0xc3, 0xa7, + 0x2f, 0xb3, 0xd2, 0xe2, 0x20, 0x57, 0x7a, 0x8e, 0xed, 0x2a, 0x1d, 0x55, 0x29, 0xbe, 0xb6, 0x60, + 0xee, 0x06, 0xca, 0xec, 0x0d, 0x45, 0xce, 0x0c, 0x88, 0x9c, 0x7f, 0x5f, 0x95, 0x9c, 0xe1, 0x03, + 0x52, 0x80, 0xb7, 0x34, 0xc0, 0x1b, 0xce, 0xe5, 0xc1, 0x00, 0xe6, 0xa5, 0xa3, 0xe3, 0xdc, 0xf5, + 0xb6, 0x34, 0x4a, 0xcd, 0x44, 0xb8, 0x6a, 0xad, 0x92, 0xb6, 0x46, 0xba, 0x89, 0x61, 0x73, 0xbd, + 0x41, 0xb9, 0x1c, 0x2a, 0xf3, 0x52, 0xde, 0x9c, 0x0d, 0x4f, 0x21, 0x5c, 0x0d, 0xb1, 0x42, 0xce, + 0x8f, 0x52, 0xa1, 0x81, 0x61, 0xd3, 0x37, 0x69, 0xbe, 0xb7, 0xa0, 0x60, 0x4e, 0x7e, 0x72, 0xba, + 0x3f, 0x63, 0xcf, 0x8d, 0xb0, 0x87, 0x7b, 0xf6, 0x55, 0x53, 0x71, 0xce, 0xc0, 0xed, 0x70, 0x55, + 0x1f, 0xbc, 0xea, 0x58, 0xfb, 0xd1, 0x82, 0x62, 0x17, 0xa1, 0xfb, 0xed, 0xc1, 0x41, 0x3a, 0xe3, + 0x21, 0xc9, 0x6f, 0x16, 0x2c, 0x98, 0xfc, 0xbd, 0x7b, 0xf7, 0x00, 0x31, 0x93, 0xaa, 0x77, 0x46, + 0xec, 0xde, 0x04, 0xf6, 0x17, 0x0b, 0x0a, 0xe6, 0xea, 0xdc, 0x49, 0xd7, 0x73, 0xa5, 0xee, 0x21, + 0xdd, 0x9a, 0xa9, 0xc6, 0xd2, 0x88, 0x3d, 0xa9, 0x51, 0x9e, 0x66, 0xab, 0xfe, 0xbb, 0x05, 0xc5, + 0x2e, 0xce, 0x70, 0x39, 0xf7, 0x0b, 0xd8, 0x7d, 0x3e, 0x60, 0xf2, 0x87, 0x05, 0x0b, 0x86, 0x65, + 0x6c, 0x05, 0xec, 0x17, 0xf2, 0xeb, 0x1a, 0xd9, 0x2d, 0x9d, 0x1f, 0x77, 0x03, 0xf6, 0x80, 0x53, + 0x28, 0x6c, 0x60, 0x88, 0xc3, 0xaf, 0x68, 0xbb, 0xdf, 0x9c, 0x1e, 0x31, 0xe7, 0xcd, 0x2b, 0x60, + 0x75, 0xd4, 0x2b, 0x40, 0xad, 0x64, 0x03, 0x8a, 0x26, 0x45, 0x4e, 0x95, 0xe7, 0x4e, 0x76, 0x76, + 0x17, 0xc9, 0x88, 0x80, 0x05, 0x93, 0xa9, 0x7f, 0x11, 0x9e, 0x3b, 0x5d, 0xf2, 0x9c, 0x58, 0xdd, + 0xc5, 0x73, 0xe2, 0x09, 0x1c, 0xfd, 0x80, 0x86, 0x81, 0x5a, 0x54, 0xf3, 0x73, 0x8f, 0x9c, 0xda, + 0x71, 0x49, 0x64, 0x3f, 0x03, 0x47, 0xe4, 0xac, 0xe8, 0x9c, 0x17, 0x9d, 0x73, 0xa3, 0x8e, 0xec, + 0x76, 0x92, 0x2a, 0x59, 0xbe, 0xcf, 0x2d, 0x98, 0xef, 0x66, 0xd7, 0x93, 0x7e, 0x31, 0x84, 0x2b, + 0x1a, 0xa1, 0xe2, 0xac, 0x8e, 0x9d, 0x76, 0x1f, 0xc8, 0xb5, 0xeb, 0x7f, 0x3e, 0x5b, 0xb2, 0xfe, + 0x7a, 0xb6, 0x64, 0xfd, 0xf3, 0x6c, 0xc9, 0xfa, 0xe8, 0xcd, 0xdd, 0xfd, 0xc3, 0xe3, 0xeb, 0x1f, + 0x8e, 0xb9, 0xff, 0x62, 0xee, 0x15, 0xf4, 0x9f, 0x31, 0xaf, 0xfd, 0x1f, 0x00, 0x00, 0xff, 0xff, + 0x85, 0x4e, 0xc2, 0x40, 0x71, 0x12, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1917,27 +1896,6 @@ func (m *RepoAccessQuery) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - if len(m.BearerToken) > 0 { - i -= len(m.BearerToken) - copy(dAtA[i:], m.BearerToken) - i = encodeVarintRepository(dAtA, i, uint64(len(m.BearerToken))) - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xaa - } - if m.UseAzureWorkloadIdentity { - i-- - if m.UseAzureWorkloadIdentity { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xa0 - } if m.ForceHttpBasicAuth { i-- if m.ForceHttpBasicAuth { @@ -2408,13 +2366,6 @@ func (m *RepoAccessQuery) Size() (n int) { if m.ForceHttpBasicAuth { n += 3 } - if m.UseAzureWorkloadIdentity { - n += 3 - } - l = len(m.BearerToken) - if l > 0 { - n += 2 + l + sovRepository(uint64(l)) - } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -3723,58 +3674,6 @@ func (m *RepoAccessQuery) Unmarshal(dAtA []byte) error { } } m.ForceHttpBasicAuth = bool(v != 0) - case 20: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field UseAzureWorkloadIdentity", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRepository - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.UseAzureWorkloadIdentity = bool(v != 0) - case 21: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BearerToken", 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.BearerToken = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) diff --git a/pkg/apiclient/session/mocks/SessionServiceClient.go b/pkg/apiclient/session/mocks/SessionServiceClient.go index 6ebaaaf010..216f8956ef 100644 --- a/pkg/apiclient/session/mocks/SessionServiceClient.go +++ b/pkg/apiclient/session/mocks/SessionServiceClient.go @@ -1,17 +1,133 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" + context "context" + + grpc "google.golang.org/grpc" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" mock "github.com/stretchr/testify/mock" - "google.golang.org/grpc" + + session "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" ) +// SessionServiceClient is an autogenerated mock type for the SessionServiceClient type +type SessionServiceClient struct { + mock.Mock +} + +// Create provides a mock function with given fields: ctx, in, opts +func (_m *SessionServiceClient) Create(ctx context.Context, in *session.SessionCreateRequest, opts ...grpc.CallOption) (*session.SessionResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for Create") + } + + var r0 *session.SessionResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *session.SessionCreateRequest, ...grpc.CallOption) (*session.SessionResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *session.SessionCreateRequest, ...grpc.CallOption) *session.SessionResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*session.SessionResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *session.SessionCreateRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Delete provides a mock function with given fields: ctx, in, opts +func (_m *SessionServiceClient) Delete(ctx context.Context, in *session.SessionDeleteRequest, opts ...grpc.CallOption) (*session.SessionResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for Delete") + } + + var r0 *session.SessionResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *session.SessionDeleteRequest, ...grpc.CallOption) (*session.SessionResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *session.SessionDeleteRequest, ...grpc.CallOption) *session.SessionResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*session.SessionResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *session.SessionDeleteRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetUserInfo provides a mock function with given fields: ctx, in, opts +func (_m *SessionServiceClient) GetUserInfo(ctx context.Context, in *session.GetUserInfoRequest, opts ...grpc.CallOption) (*session.GetUserInfoResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetUserInfo") + } + + var r0 *session.GetUserInfoResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *session.GetUserInfoRequest, ...grpc.CallOption) (*session.GetUserInfoResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *session.GetUserInfoRequest, ...grpc.CallOption) *session.GetUserInfoResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*session.GetUserInfoResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *session.GetUserInfoRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewSessionServiceClient creates a new instance of SessionServiceClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewSessionServiceClient(t interface { @@ -25,235 +141,3 @@ func NewSessionServiceClient(t interface { return mock } - -// SessionServiceClient is an autogenerated mock type for the SessionServiceClient type -type SessionServiceClient struct { - mock.Mock -} - -type SessionServiceClient_Expecter struct { - mock *mock.Mock -} - -func (_m *SessionServiceClient) EXPECT() *SessionServiceClient_Expecter { - return &SessionServiceClient_Expecter{mock: &_m.Mock} -} - -// Create provides a mock function for the type SessionServiceClient -func (_mock *SessionServiceClient) Create(ctx context.Context, in *session.SessionCreateRequest, opts ...grpc.CallOption) (*session.SessionResponse, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for Create") - } - - var r0 *session.SessionResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *session.SessionCreateRequest, ...grpc.CallOption) (*session.SessionResponse, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *session.SessionCreateRequest, ...grpc.CallOption) *session.SessionResponse); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*session.SessionResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *session.SessionCreateRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// SessionServiceClient_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' -type SessionServiceClient_Create_Call struct { - *mock.Call -} - -// Create is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *SessionServiceClient_Expecter) Create(ctx interface{}, in interface{}, opts ...interface{}) *SessionServiceClient_Create_Call { - return &SessionServiceClient_Create_Call{Call: _e.mock.On("Create", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *SessionServiceClient_Create_Call) Run(run func(ctx context.Context, in *session.SessionCreateRequest, opts ...grpc.CallOption)) *SessionServiceClient_Create_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*session.SessionCreateRequest), variadicArgs...) - }) - return _c -} - -func (_c *SessionServiceClient_Create_Call) Return(sessionResponse *session.SessionResponse, err error) *SessionServiceClient_Create_Call { - _c.Call.Return(sessionResponse, err) - return _c -} - -func (_c *SessionServiceClient_Create_Call) RunAndReturn(run func(ctx context.Context, in *session.SessionCreateRequest, opts ...grpc.CallOption) (*session.SessionResponse, error)) *SessionServiceClient_Create_Call { - _c.Call.Return(run) - return _c -} - -// Delete provides a mock function for the type SessionServiceClient -func (_mock *SessionServiceClient) Delete(ctx context.Context, in *session.SessionDeleteRequest, opts ...grpc.CallOption) (*session.SessionResponse, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for Delete") - } - - var r0 *session.SessionResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *session.SessionDeleteRequest, ...grpc.CallOption) (*session.SessionResponse, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *session.SessionDeleteRequest, ...grpc.CallOption) *session.SessionResponse); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*session.SessionResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *session.SessionDeleteRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// SessionServiceClient_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' -type SessionServiceClient_Delete_Call struct { - *mock.Call -} - -// Delete is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *SessionServiceClient_Expecter) Delete(ctx interface{}, in interface{}, opts ...interface{}) *SessionServiceClient_Delete_Call { - return &SessionServiceClient_Delete_Call{Call: _e.mock.On("Delete", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *SessionServiceClient_Delete_Call) Run(run func(ctx context.Context, in *session.SessionDeleteRequest, opts ...grpc.CallOption)) *SessionServiceClient_Delete_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*session.SessionDeleteRequest), variadicArgs...) - }) - return _c -} - -func (_c *SessionServiceClient_Delete_Call) Return(sessionResponse *session.SessionResponse, err error) *SessionServiceClient_Delete_Call { - _c.Call.Return(sessionResponse, err) - return _c -} - -func (_c *SessionServiceClient_Delete_Call) RunAndReturn(run func(ctx context.Context, in *session.SessionDeleteRequest, opts ...grpc.CallOption) (*session.SessionResponse, error)) *SessionServiceClient_Delete_Call { - _c.Call.Return(run) - return _c -} - -// GetUserInfo provides a mock function for the type SessionServiceClient -func (_mock *SessionServiceClient) GetUserInfo(ctx context.Context, in *session.GetUserInfoRequest, opts ...grpc.CallOption) (*session.GetUserInfoResponse, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GetUserInfo") - } - - var r0 *session.GetUserInfoResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *session.GetUserInfoRequest, ...grpc.CallOption) (*session.GetUserInfoResponse, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *session.GetUserInfoRequest, ...grpc.CallOption) *session.GetUserInfoResponse); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*session.GetUserInfoResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *session.GetUserInfoRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// SessionServiceClient_GetUserInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetUserInfo' -type SessionServiceClient_GetUserInfo_Call struct { - *mock.Call -} - -// GetUserInfo is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *SessionServiceClient_Expecter) GetUserInfo(ctx interface{}, in interface{}, opts ...interface{}) *SessionServiceClient_GetUserInfo_Call { - return &SessionServiceClient_GetUserInfo_Call{Call: _e.mock.On("GetUserInfo", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *SessionServiceClient_GetUserInfo_Call) Run(run func(ctx context.Context, in *session.GetUserInfoRequest, opts ...grpc.CallOption)) *SessionServiceClient_GetUserInfo_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*session.GetUserInfoRequest), variadicArgs...) - }) - return _c -} - -func (_c *SessionServiceClient_GetUserInfo_Call) Return(getUserInfoResponse *session.GetUserInfoResponse, err error) *SessionServiceClient_GetUserInfo_Call { - _c.Call.Return(getUserInfoResponse, err) - return _c -} - -func (_c *SessionServiceClient_GetUserInfo_Call) RunAndReturn(run func(ctx context.Context, in *session.GetUserInfoRequest, opts ...grpc.CallOption) (*session.GetUserInfoResponse, error)) *SessionServiceClient_GetUserInfo_Call { - _c.Call.Return(run) - return _c -} diff --git a/pkg/apiclient/session/mocks/SessionServiceServer.go b/pkg/apiclient/session/mocks/SessionServiceServer.go index fe8486703f..e5e815b2b7 100644 --- a/pkg/apiclient/session/mocks/SessionServiceServer.go +++ b/pkg/apiclient/session/mocks/SessionServiceServer.go @@ -1,16 +1,109 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" + context "context" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" + session "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" mock "github.com/stretchr/testify/mock" ) +// SessionServiceServer is an autogenerated mock type for the SessionServiceServer type +type SessionServiceServer struct { + mock.Mock +} + +// Create provides a mock function with given fields: _a0, _a1 +func (_m *SessionServiceServer) Create(_a0 context.Context, _a1 *session.SessionCreateRequest) (*session.SessionResponse, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for Create") + } + + var r0 *session.SessionResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *session.SessionCreateRequest) (*session.SessionResponse, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *session.SessionCreateRequest) *session.SessionResponse); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*session.SessionResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *session.SessionCreateRequest) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Delete provides a mock function with given fields: _a0, _a1 +func (_m *SessionServiceServer) Delete(_a0 context.Context, _a1 *session.SessionDeleteRequest) (*session.SessionResponse, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for Delete") + } + + var r0 *session.SessionResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *session.SessionDeleteRequest) (*session.SessionResponse, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *session.SessionDeleteRequest) *session.SessionResponse); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*session.SessionResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *session.SessionDeleteRequest) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetUserInfo provides a mock function with given fields: _a0, _a1 +func (_m *SessionServiceServer) GetUserInfo(_a0 context.Context, _a1 *session.GetUserInfoRequest) (*session.GetUserInfoResponse, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetUserInfo") + } + + var r0 *session.GetUserInfoResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *session.GetUserInfoRequest) (*session.GetUserInfoResponse, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *session.GetUserInfoRequest) *session.GetUserInfoResponse); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*session.GetUserInfoResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *session.GetUserInfoRequest) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewSessionServiceServer creates a new instance of SessionServiceServer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewSessionServiceServer(t interface { @@ -24,187 +117,3 @@ func NewSessionServiceServer(t interface { return mock } - -// SessionServiceServer is an autogenerated mock type for the SessionServiceServer type -type SessionServiceServer struct { - mock.Mock -} - -type SessionServiceServer_Expecter struct { - mock *mock.Mock -} - -func (_m *SessionServiceServer) EXPECT() *SessionServiceServer_Expecter { - return &SessionServiceServer_Expecter{mock: &_m.Mock} -} - -// Create provides a mock function for the type SessionServiceServer -func (_mock *SessionServiceServer) Create(context1 context.Context, sessionCreateRequest *session.SessionCreateRequest) (*session.SessionResponse, error) { - ret := _mock.Called(context1, sessionCreateRequest) - - if len(ret) == 0 { - panic("no return value specified for Create") - } - - var r0 *session.SessionResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *session.SessionCreateRequest) (*session.SessionResponse, error)); ok { - return returnFunc(context1, sessionCreateRequest) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *session.SessionCreateRequest) *session.SessionResponse); ok { - r0 = returnFunc(context1, sessionCreateRequest) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*session.SessionResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *session.SessionCreateRequest) error); ok { - r1 = returnFunc(context1, sessionCreateRequest) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// SessionServiceServer_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' -type SessionServiceServer_Create_Call struct { - *mock.Call -} - -// Create is a helper method to define mock.On call -// - context1 -// - sessionCreateRequest -func (_e *SessionServiceServer_Expecter) Create(context1 interface{}, sessionCreateRequest interface{}) *SessionServiceServer_Create_Call { - return &SessionServiceServer_Create_Call{Call: _e.mock.On("Create", context1, sessionCreateRequest)} -} - -func (_c *SessionServiceServer_Create_Call) Run(run func(context1 context.Context, sessionCreateRequest *session.SessionCreateRequest)) *SessionServiceServer_Create_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*session.SessionCreateRequest)) - }) - return _c -} - -func (_c *SessionServiceServer_Create_Call) Return(sessionResponse *session.SessionResponse, err error) *SessionServiceServer_Create_Call { - _c.Call.Return(sessionResponse, err) - return _c -} - -func (_c *SessionServiceServer_Create_Call) RunAndReturn(run func(context1 context.Context, sessionCreateRequest *session.SessionCreateRequest) (*session.SessionResponse, error)) *SessionServiceServer_Create_Call { - _c.Call.Return(run) - return _c -} - -// Delete provides a mock function for the type SessionServiceServer -func (_mock *SessionServiceServer) Delete(context1 context.Context, sessionDeleteRequest *session.SessionDeleteRequest) (*session.SessionResponse, error) { - ret := _mock.Called(context1, sessionDeleteRequest) - - if len(ret) == 0 { - panic("no return value specified for Delete") - } - - var r0 *session.SessionResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *session.SessionDeleteRequest) (*session.SessionResponse, error)); ok { - return returnFunc(context1, sessionDeleteRequest) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *session.SessionDeleteRequest) *session.SessionResponse); ok { - r0 = returnFunc(context1, sessionDeleteRequest) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*session.SessionResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *session.SessionDeleteRequest) error); ok { - r1 = returnFunc(context1, sessionDeleteRequest) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// SessionServiceServer_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' -type SessionServiceServer_Delete_Call struct { - *mock.Call -} - -// Delete is a helper method to define mock.On call -// - context1 -// - sessionDeleteRequest -func (_e *SessionServiceServer_Expecter) Delete(context1 interface{}, sessionDeleteRequest interface{}) *SessionServiceServer_Delete_Call { - return &SessionServiceServer_Delete_Call{Call: _e.mock.On("Delete", context1, sessionDeleteRequest)} -} - -func (_c *SessionServiceServer_Delete_Call) Run(run func(context1 context.Context, sessionDeleteRequest *session.SessionDeleteRequest)) *SessionServiceServer_Delete_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*session.SessionDeleteRequest)) - }) - return _c -} - -func (_c *SessionServiceServer_Delete_Call) Return(sessionResponse *session.SessionResponse, err error) *SessionServiceServer_Delete_Call { - _c.Call.Return(sessionResponse, err) - return _c -} - -func (_c *SessionServiceServer_Delete_Call) RunAndReturn(run func(context1 context.Context, sessionDeleteRequest *session.SessionDeleteRequest) (*session.SessionResponse, error)) *SessionServiceServer_Delete_Call { - _c.Call.Return(run) - return _c -} - -// GetUserInfo provides a mock function for the type SessionServiceServer -func (_mock *SessionServiceServer) GetUserInfo(context1 context.Context, getUserInfoRequest *session.GetUserInfoRequest) (*session.GetUserInfoResponse, error) { - ret := _mock.Called(context1, getUserInfoRequest) - - if len(ret) == 0 { - panic("no return value specified for GetUserInfo") - } - - var r0 *session.GetUserInfoResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *session.GetUserInfoRequest) (*session.GetUserInfoResponse, error)); ok { - return returnFunc(context1, getUserInfoRequest) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *session.GetUserInfoRequest) *session.GetUserInfoResponse); ok { - r0 = returnFunc(context1, getUserInfoRequest) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*session.GetUserInfoResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *session.GetUserInfoRequest) error); ok { - r1 = returnFunc(context1, getUserInfoRequest) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// SessionServiceServer_GetUserInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetUserInfo' -type SessionServiceServer_GetUserInfo_Call struct { - *mock.Call -} - -// GetUserInfo is a helper method to define mock.On call -// - context1 -// - getUserInfoRequest -func (_e *SessionServiceServer_Expecter) GetUserInfo(context1 interface{}, getUserInfoRequest interface{}) *SessionServiceServer_GetUserInfo_Call { - return &SessionServiceServer_GetUserInfo_Call{Call: _e.mock.On("GetUserInfo", context1, getUserInfoRequest)} -} - -func (_c *SessionServiceServer_GetUserInfo_Call) Run(run func(context1 context.Context, getUserInfoRequest *session.GetUserInfoRequest)) *SessionServiceServer_GetUserInfo_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*session.GetUserInfoRequest)) - }) - return _c -} - -func (_c *SessionServiceServer_GetUserInfo_Call) Return(getUserInfoResponse *session.GetUserInfoResponse, err error) *SessionServiceServer_GetUserInfo_Call { - _c.Call.Return(getUserInfoResponse, err) - return _c -} - -func (_c *SessionServiceServer_GetUserInfo_Call) RunAndReturn(run func(context1 context.Context, getUserInfoRequest *session.GetUserInfoRequest) (*session.GetUserInfoResponse, error)) *SessionServiceServer_GetUserInfo_Call { - _c.Call.Return(run) - return _c -} diff --git a/pkg/apiclient/session/session.pb.go b/pkg/apiclient/session/session.pb.go index b7e4671937..29cf296296 100644 --- a/pkg/apiclient/session/session.pb.go +++ b/pkg/apiclient/session/session.pb.go @@ -309,7 +309,7 @@ var fileDescriptor_87870a51a62685ed = []byte{ // 404 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0x41, 0x8e, 0xd3, 0x30, 0x18, 0x85, 0x95, 0x14, 0x42, 0xc7, 0x48, 0x0c, 0x98, 0x68, 0x88, 0x42, 0xa9, 0xaa, 0x6c, 0x18, - 0x8d, 0x44, 0x23, 0x18, 0x56, 0x2c, 0x0b, 0x12, 0xea, 0x36, 0x15, 0x9b, 0x4a, 0x2c, 0xd2, 0xe4, + 0x8d, 0x44, 0x23, 0x06, 0x56, 0x2c, 0x0b, 0x12, 0xea, 0x36, 0x15, 0x9b, 0x4a, 0x2c, 0xd2, 0xe4, 0xc7, 0xb8, 0x4d, 0xfd, 0x07, 0xdb, 0x49, 0xf7, 0x5c, 0x81, 0xc3, 0x70, 0x05, 0x96, 0x48, 0x5c, 0x00, 0x55, 0x1c, 0x04, 0x25, 0x4e, 0x42, 0x9b, 0x56, 0xac, 0xe2, 0xe7, 0xdf, 0xf9, 0xde, 0xb3, 0x9e, 0xc9, 0x48, 0x81, 0x2c, 0x41, 0x86, 0x0a, 0x94, 0xe2, 0x28, 0xda, 0xef, 0x34, 0x97, 0xa8, @@ -322,16 +322,16 @@ var fileDescriptor_87870a51a62685ed = []byte{ 0x5c, 0x42, 0xdf, 0x83, 0xfe, 0xa0, 0x40, 0xce, 0xc5, 0x27, 0x6c, 0x7f, 0xdf, 0x91, 0xc7, 0x47, 0xbb, 0x0d, 0xc2, 0x27, 0xc3, 0x0c, 0x19, 0x83, 0x74, 0x6e, 0x28, 0xc3, 0xa8, 0xd3, 0x47, 0xf7, 0xb2, 0x7b, 0xf7, 0x7a, 0x48, 0x06, 0x5c, 0xa9, 0x26, 0x79, 0xb5, 0xa4, 0x57, 0xc4, 0x61, 0x12, - 0x8b, 0x5c, 0x79, 0x77, 0x26, 0x83, 0xeb, 0x8b, 0xa8, 0x51, 0xaf, 0xbe, 0xdb, 0xe4, 0x41, 0x13, - 0x7c, 0x01, 0xb2, 0xe4, 0x09, 0xd0, 0x35, 0xb9, 0x7f, 0x90, 0x85, 0x3e, 0x9d, 0xb6, 0x75, 0x9c, - 0xe6, 0xf6, 0x47, 0xe7, 0x87, 0x26, 0x7e, 0x30, 0xf9, 0xfa, 0xeb, 0xcf, 0x37, 0xdb, 0xa7, 0x5e, - 0x5d, 0x59, 0xf9, 0xb2, 0x2b, 0xb8, 0x0a, 0xca, 0x2b, 0xf8, 0x47, 0xe2, 0x98, 0xb6, 0xe8, 0xb3, - 0x8e, 0x74, 0xae, 0x45, 0xdf, 0xeb, 0x8f, 0x3b, 0x13, 0xbf, 0x36, 0x71, 0x83, 0xcb, 0x9e, 0xc9, - 0x1b, 0xeb, 0x86, 0x2e, 0x89, 0x63, 0x6a, 0x3a, 0xc5, 0x1f, 0xd5, 0xf7, 0x1f, 0xfc, 0x93, 0x1a, - 0xff, 0xe8, 0xa6, 0x8f, 0x9f, 0xcd, 0x7e, 0xec, 0xc7, 0xd6, 0xcf, 0xfd, 0xd8, 0xfa, 0xbd, 0x1f, - 0x5b, 0xcb, 0xd7, 0x8c, 0xeb, 0xcf, 0xc5, 0x6a, 0x9a, 0xe0, 0x36, 0x8c, 0x25, 0xc3, 0x5c, 0xe2, - 0xba, 0x5e, 0xbc, 0x48, 0xd2, 0xb0, 0xbc, 0x0d, 0xf3, 0x0d, 0xab, 0x00, 0x49, 0xc6, 0x41, 0xe8, - 0x96, 0xb1, 0x72, 0xea, 0xa7, 0x7b, 0xfb, 0x37, 0x00, 0x00, 0xff, 0xff, 0x0b, 0x96, 0x29, 0xbd, + 0x8b, 0x5c, 0x79, 0x77, 0x26, 0x83, 0xeb, 0x8b, 0xa8, 0x51, 0xb7, 0xdf, 0x6d, 0xf2, 0xa0, 0x09, + 0xbe, 0x00, 0x59, 0xf2, 0x04, 0xe8, 0x9a, 0xdc, 0x3f, 0xc8, 0x42, 0x9f, 0x4e, 0xdb, 0x3a, 0x4e, + 0x73, 0xfb, 0xa3, 0xf3, 0x43, 0x13, 0x3f, 0x98, 0x7c, 0xfd, 0xf5, 0xe7, 0x9b, 0xed, 0x53, 0xaf, + 0xae, 0xac, 0x7c, 0xd9, 0x15, 0x5c, 0x05, 0xe5, 0x15, 0xfc, 0x23, 0x71, 0x4c, 0x5b, 0xf4, 0x59, + 0x47, 0x3a, 0xd7, 0xa2, 0xef, 0xf5, 0xc7, 0x9d, 0x89, 0x5f, 0x9b, 0xb8, 0xc1, 0x65, 0xcf, 0xe4, + 0x8d, 0x75, 0x43, 0x97, 0xc4, 0x31, 0x35, 0x9d, 0xe2, 0x8f, 0xea, 0xfb, 0x0f, 0xfe, 0x49, 0x8d, + 0x7f, 0x74, 0xd3, 0xc7, 0xcf, 0x66, 0x3f, 0xf6, 0x63, 0xeb, 0xe7, 0x7e, 0x6c, 0xfd, 0xde, 0x8f, + 0xad, 0xe5, 0x6b, 0xc6, 0xf5, 0xe7, 0x62, 0x35, 0x4d, 0x70, 0x1b, 0xc6, 0x92, 0x61, 0x2e, 0x71, + 0x5d, 0x2f, 0x5e, 0x24, 0x69, 0x58, 0xde, 0x86, 0xf9, 0x86, 0x55, 0x80, 0x24, 0xe3, 0x20, 0x74, + 0xcb, 0x58, 0x39, 0xf5, 0xd3, 0x7d, 0xf5, 0x37, 0x00, 0x00, 0xff, 0xff, 0xda, 0x7e, 0xce, 0xb3, 0x01, 0x03, 0x00, 0x00, } diff --git a/pkg/apiclient/settings/settings.pb.go b/pkg/apiclient/settings/settings.pb.go index 084e3f9891..71bff2ca9e 100644 --- a/pkg/apiclient/settings/settings.pb.go +++ b/pkg/apiclient/settings/settings.pb.go @@ -10,8 +10,8 @@ package settings import ( context "context" fmt "fmt" - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - oidc "github.com/argoproj/argo-cd/v3/server/settings/oidc" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + oidc "github.com/argoproj/argo-cd/v2/server/settings/oidc" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" @@ -772,88 +772,88 @@ func init() { func init() { proto.RegisterFile("server/settings/settings.proto", fileDescriptor_a480d494da040caa) } var fileDescriptor_a480d494da040caa = []byte{ - // 1291 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xcf, 0x6f, 0x1b, 0xc5, - 0x17, 0xd7, 0xd6, 0x69, 0x62, 0xbf, 0x34, 0x71, 0x32, 0x4d, 0xd3, 0xad, 0xbf, 0xfd, 0x26, 0xc6, - 0x87, 0xca, 0x20, 0x58, 0x37, 0x89, 0x10, 0xa8, 0xa2, 0x82, 0xd8, 0xae, 0x5a, 0x53, 0xb7, 0x0d, - 0xd3, 0xa6, 0x07, 0x2e, 0xd5, 0x64, 0x77, 0x58, 0x2f, 0x59, 0xcf, 0xac, 0x66, 0x66, 0x4d, 0xdd, - 0x23, 0x7f, 0x00, 0x17, 0xf8, 0x6b, 0xb8, 0x23, 0x38, 0x22, 0x71, 0x8f, 0x90, 0xc5, 0x1f, 0xc1, - 0x11, 0xcd, 0xec, 0x8f, 0x6c, 0xd6, 0x4e, 0x41, 0xea, 0x6d, 0xe6, 0xf3, 0x79, 0xbf, 0xe6, 0xcd, - 0x7b, 0x33, 0x0f, 0x76, 0x24, 0x15, 0x13, 0x2a, 0x3a, 0x92, 0x2a, 0x15, 0x30, 0x5f, 0xe6, 0x0b, - 0x27, 0x12, 0x5c, 0x71, 0xb4, 0xe2, 0x86, 0xb1, 0x54, 0x54, 0x34, 0xb6, 0x7c, 0xee, 0x73, 0x83, - 0x75, 0xf4, 0x2a, 0xa1, 0x1b, 0xb7, 0x7d, 0xce, 0xfd, 0x90, 0x76, 0x48, 0x14, 0x74, 0x08, 0x63, - 0x5c, 0x11, 0x15, 0x70, 0x96, 0x2a, 0x37, 0x86, 0x7e, 0xa0, 0x46, 0xf1, 0x89, 0xe3, 0xf2, 0x71, - 0x87, 0x08, 0xa3, 0xfe, 0xad, 0x59, 0x7c, 0xe4, 0x7a, 0x9d, 0xc9, 0x41, 0x27, 0x3a, 0xf5, 0xb5, - 0xa6, 0xec, 0x90, 0x28, 0x0a, 0x03, 0xd7, 0xe8, 0x76, 0x26, 0x7b, 0x24, 0x8c, 0x46, 0x64, 0xaf, - 0xe3, 0x53, 0x46, 0x05, 0x51, 0xd4, 0x4b, 0xad, 0x7d, 0xf1, 0x2f, 0xd6, 0xca, 0x27, 0xe1, 0x81, - 0xe7, 0x76, 0xdc, 0x90, 0x04, 0xe3, 0x34, 0x9e, 0x56, 0x1d, 0xd6, 0x9e, 0xa7, 0xec, 0x57, 0x31, - 0x15, 0xd3, 0xd6, 0xdf, 0xd7, 0xa0, 0x9a, 0x21, 0xe8, 0x16, 0x54, 0x62, 0x11, 0xda, 0x56, 0xd3, - 0x6a, 0xd7, 0xba, 0x2b, 0xb3, 0xb3, 0xdd, 0xca, 0x31, 0x1e, 0x62, 0x8d, 0xa1, 0xbb, 0x50, 0xf3, - 0xe8, 0xeb, 0x1e, 0x67, 0xdf, 0x04, 0xbe, 0x7d, 0xa5, 0x69, 0xb5, 0x57, 0xf7, 0x91, 0x93, 0x66, - 0xc6, 0xe9, 0x67, 0x0c, 0x3e, 0x17, 0x42, 0x3d, 0x00, 0xed, 0x3f, 0x55, 0xa9, 0x18, 0x95, 0xeb, - 0xb9, 0xca, 0xb3, 0x41, 0xbf, 0x97, 0x50, 0xdd, 0xf5, 0xd9, 0xd9, 0x2e, 0x9c, 0xef, 0x71, 0x41, - 0x0d, 0x35, 0x61, 0x95, 0x44, 0xd1, 0x90, 0x9c, 0xd0, 0xf0, 0x31, 0x9d, 0xda, 0x4b, 0x3a, 0x32, - 0x5c, 0x84, 0xd0, 0x4b, 0xd8, 0x14, 0x54, 0xf2, 0x58, 0xb8, 0xf4, 0xd9, 0x84, 0x0a, 0x11, 0x78, - 0x54, 0xda, 0x57, 0x9b, 0x95, 0xf6, 0xea, 0x7e, 0x3b, 0xf7, 0x96, 0x9d, 0xd0, 0xc1, 0x65, 0xd1, - 0x07, 0x4c, 0x89, 0x29, 0x9e, 0x37, 0x81, 0x1c, 0x40, 0x52, 0x11, 0x15, 0xcb, 0x2e, 0xf1, 0x7c, - 0xfa, 0x80, 0x91, 0x93, 0x90, 0x7a, 0xf6, 0x72, 0xd3, 0x6a, 0x57, 0xf1, 0x02, 0x06, 0x3d, 0x82, - 0x7a, 0x52, 0x09, 0x87, 0x8c, 0x84, 0x53, 0x15, 0xb8, 0xd2, 0x5e, 0x31, 0x67, 0xde, 0xc9, 0xa3, - 0x78, 0x78, 0x91, 0x4f, 0x8f, 0x5b, 0x56, 0x43, 0x6f, 0x60, 0xe3, 0x34, 0x96, 0x8a, 0x8f, 0x83, - 0x37, 0xf4, 0x59, 0x64, 0xaa, 0xc9, 0xae, 0x1a, 0x53, 0x4f, 0x9d, 0xf3, 0x02, 0x70, 0xb2, 0x02, - 0x30, 0x8b, 0x57, 0xae, 0xe7, 0x4c, 0x0e, 0x9c, 0xe8, 0xd4, 0x77, 0x74, 0x39, 0x39, 0x85, 0x72, - 0x72, 0xb2, 0x72, 0x72, 0x1e, 0x97, 0xac, 0xe2, 0x39, 0x3f, 0xe8, 0x3d, 0x58, 0x1a, 0xd1, 0x30, - 0xb2, 0x6b, 0xc6, 0xdf, 0x5a, 0x1e, 0xfa, 0x23, 0x1a, 0x46, 0xd8, 0x50, 0xe8, 0x7d, 0x58, 0x89, - 0xc2, 0xd8, 0x0f, 0x98, 0xb4, 0xc1, 0xa4, 0xb9, 0x9e, 0x4b, 0x1d, 0x19, 0x1c, 0x67, 0xbc, 0xce, - 0x61, 0x2c, 0xa9, 0x18, 0x72, 0xbd, 0xeb, 0x07, 0x32, 0xc9, 0xe1, 0x6a, 0x92, 0xc3, 0x79, 0x06, - 0xfd, 0x60, 0xc1, 0x4d, 0xd7, 0x64, 0xe5, 0x09, 0x61, 0xc4, 0xa7, 0x63, 0xca, 0xd4, 0x51, 0xea, - 0xeb, 0x9a, 0xf1, 0xf5, 0xe2, 0xdd, 0x32, 0xd0, 0x5b, 0x68, 0x1c, 0x5f, 0xe6, 0x14, 0x7d, 0x08, - 0x9b, 0x79, 0x8a, 0x5e, 0x52, 0x21, 0xcd, 0x5d, 0xac, 0x35, 0x2b, 0xed, 0x1a, 0x9e, 0x27, 0x50, - 0x03, 0xaa, 0x71, 0xd0, 0x93, 0xf2, 0x18, 0x0f, 0xed, 0x75, 0x53, 0xa9, 0xf9, 0x1e, 0xb5, 0xa1, - 0x1e, 0x07, 0x5d, 0xc2, 0x18, 0x15, 0x3d, 0xce, 0x14, 0x65, 0xca, 0xae, 0x1b, 0x91, 0x32, 0xac, - 0x4b, 0x3e, 0x83, 0xb4, 0xa1, 0x8d, 0xa4, 0xe4, 0x0b, 0x90, 0xb6, 0x15, 0x11, 0x29, 0xbf, 0xe3, - 0xc2, 0x3b, 0x22, 0x4a, 0x51, 0xc1, 0xec, 0xcd, 0xc4, 0x56, 0x09, 0x46, 0x77, 0x60, 0x5d, 0x09, - 0xe2, 0x9e, 0x06, 0xcc, 0x7f, 0x42, 0xd5, 0x88, 0x7b, 0x36, 0x32, 0x82, 0x25, 0x54, 0x9f, 0x33, - 0x73, 0x70, 0x44, 0xc5, 0x98, 0x30, 0x1d, 0xdf, 0x75, 0x73, 0x4f, 0xf3, 0x04, 0xfa, 0x00, 0x36, - 0x72, 0x90, 0xcb, 0x40, 0xa7, 0xd8, 0xde, 0x32, 0x76, 0xe7, 0xf0, 0x52, 0x1b, 0x61, 0xce, 0xd5, - 0xb1, 0x08, 0xed, 0x1b, 0x46, 0x7a, 0x01, 0xa3, 0x4f, 0x4f, 0x5f, 0x53, 0x37, 0xeb, 0xb7, 0x6d, - 0x13, 0x43, 0x11, 0x42, 0x77, 0xe1, 0xba, 0xcb, 0x99, 0x12, 0x3c, 0x0c, 0xa9, 0x78, 0x4a, 0xc6, - 0x54, 0x46, 0xc4, 0xa5, 0xf6, 0x4d, 0x63, 0x72, 0x11, 0x85, 0x3e, 0x83, 0x5b, 0x24, 0x8a, 0xe4, - 0x80, 0x1d, 0xb2, 0x69, 0x8e, 0x66, 0x1e, 0x6c, 0xe3, 0xe1, 0x72, 0x01, 0xb4, 0x0f, 0x5b, 0xc1, - 0x38, 0xa2, 0x42, 0x72, 0x66, 0xaa, 0x29, 0x53, 0xbc, 0x65, 0x14, 0x17, 0x72, 0x3a, 0xef, 0x01, - 0x93, 0x8a, 0x84, 0xa1, 0x81, 0x07, 0x7d, 0xbb, 0x91, 0xe4, 0xfd, 0x22, 0x8a, 0xee, 0xc1, 0x3a, - 0xf1, 0x3c, 0x93, 0x29, 0x12, 0x1e, 0x8b, 0x50, 0xda, 0xff, 0xd3, 0xc5, 0xd5, 0x45, 0xb3, 0xb3, - 0xdd, 0xf5, 0xc3, 0x73, 0x06, 0x0f, 0x25, 0x2e, 0x49, 0xea, 0x2a, 0x18, 0x4d, 0x3d, 0x41, 0x14, - 0x17, 0x59, 0x48, 0xb7, 0x4d, 0x48, 0x65, 0xb8, 0xf1, 0x93, 0x05, 0xdb, 0x8b, 0x1f, 0x3e, 0xb4, - 0x01, 0x95, 0x53, 0x3a, 0x4d, 0x5e, 0x7c, 0xac, 0x97, 0xc8, 0x83, 0xab, 0x13, 0x12, 0xc6, 0x34, - 0x7d, 0xe4, 0xdf, 0xf1, 0xc9, 0x29, 0xbb, 0xc5, 0x89, 0xf1, 0x7b, 0x57, 0x3e, 0xb5, 0x5a, 0xaf, - 0xe0, 0xc6, 0xc2, 0x17, 0x11, 0xed, 0x00, 0x64, 0xf5, 0x39, 0xe8, 0xa7, 0xb1, 0x15, 0x10, 0x9d, - 0x5d, 0xc2, 0x38, 0x9b, 0xea, 0xe6, 0x3b, 0x96, 0x54, 0x48, 0x13, 0x6b, 0x15, 0x97, 0xd0, 0x56, - 0x1f, 0x6e, 0x66, 0x0f, 0x7f, 0xda, 0xd0, 0x98, 0xca, 0x88, 0x33, 0x49, 0x8b, 0x8f, 0x98, 0xf5, - 0xf6, 0x47, 0xac, 0xf5, 0xb3, 0x05, 0x4b, 0xfa, 0xf9, 0x43, 0x36, 0xac, 0xb8, 0x23, 0x62, 0xea, - 0x37, 0x89, 0x29, 0xdb, 0xea, 0xc6, 0xd7, 0xcb, 0x17, 0xf4, 0xb5, 0x32, 0xa1, 0xd4, 0x70, 0xbe, - 0x47, 0xf7, 0x01, 0x4e, 0x02, 0x46, 0xc4, 0xd4, 0x5c, 0x6f, 0xc5, 0x38, 0xfb, 0xff, 0x85, 0x77, - 0xd5, 0xe9, 0xe6, 0x7c, 0xf2, 0x1b, 0x15, 0x14, 0x1a, 0xf7, 0xa1, 0x5e, 0xa2, 0x17, 0xdc, 0xd9, - 0x56, 0xf1, 0xce, 0x6a, 0xc5, 0x1c, 0xdf, 0x86, 0xe5, 0xe4, 0x3c, 0x08, 0xc1, 0x12, 0x23, 0x63, - 0x9a, 0xaa, 0x99, 0x75, 0xeb, 0x73, 0xa8, 0xe5, 0x5f, 0x37, 0xda, 0x07, 0x70, 0x39, 0x63, 0xd4, - 0x55, 0x5c, 0x64, 0x59, 0x39, 0xff, 0xe2, 0x7b, 0x19, 0x85, 0x0b, 0x52, 0xad, 0x03, 0xa8, 0xe5, - 0xc4, 0x22, 0x0f, 0x1a, 0x53, 0xd3, 0x28, 0x0b, 0xcc, 0xac, 0x5b, 0xbf, 0x54, 0xa0, 0xf0, 0xdd, - 0x2f, 0x54, 0xdb, 0x86, 0xe5, 0x40, 0xca, 0x98, 0x8a, 0x54, 0x31, 0xdd, 0xa1, 0x36, 0x54, 0xdd, - 0x30, 0xa0, 0x4c, 0x0d, 0xfa, 0x66, 0xa2, 0xa8, 0x75, 0xaf, 0xcd, 0xce, 0x76, 0xab, 0xbd, 0x14, - 0xc3, 0x39, 0x8b, 0xf6, 0x60, 0xd5, 0x0d, 0x83, 0x8c, 0x48, 0x06, 0x87, 0x6e, 0x7d, 0x76, 0xb6, - 0xbb, 0xda, 0x1b, 0x0e, 0x72, 0xf9, 0xa2, 0x8c, 0x76, 0x2a, 0x5d, 0x1e, 0xa5, 0xe3, 0x43, 0x0d, - 0xa7, 0x3b, 0xf4, 0x0a, 0xd6, 0x02, 0xef, 0x05, 0x3f, 0xa5, 0xac, 0x67, 0x46, 0x29, 0x7b, 0xd9, - 0xe4, 0xe6, 0xce, 0x82, 0x59, 0xc6, 0x19, 0x14, 0x05, 0xcd, 0x75, 0x75, 0x37, 0x67, 0x67, 0xbb, - 0x6b, 0x83, 0x7e, 0x01, 0xc7, 0x17, 0xed, 0xa1, 0x7b, 0x60, 0x53, 0xd3, 0xaa, 0x47, 0x8f, 0x7b, - 0x0f, 0x0e, 0x63, 0x35, 0xa2, 0x4c, 0xa5, 0x9d, 0x64, 0x66, 0x88, 0x2a, 0xbe, 0x94, 0x6f, 0x4c, - 0x01, 0xcd, 0xfb, 0x5c, 0x50, 0x22, 0x4f, 0x2e, 0xb6, 0xf5, 0x27, 0x6f, 0x6d, 0xeb, 0x64, 0x8e, - 0x74, 0xf2, 0x41, 0x58, 0x0f, 0x64, 0x8e, 0xb1, 0x5f, 0xa8, 0xad, 0xfd, 0x5f, 0x2d, 0xa8, 0x67, - 0xfd, 0xf5, 0x9c, 0x8a, 0x49, 0xe0, 0x52, 0xf4, 0x25, 0x54, 0x1e, 0x52, 0x85, 0xb6, 0xe7, 0x26, - 0x2f, 0x33, 0x6d, 0x36, 0x36, 0xe7, 0xf0, 0x96, 0xfd, 0xfd, 0x1f, 0x7f, 0xfd, 0x78, 0x05, 0xa1, - 0x0d, 0x33, 0x41, 0x4f, 0xf6, 0xf2, 0xe9, 0x15, 0x8d, 0x00, 0x1e, 0xd2, 0xfc, 0x2b, 0xbe, 0xcc, - 0x64, 0x73, 0x0e, 0x2f, 0xf5, 0x7a, 0xab, 0x69, 0x3c, 0x34, 0x90, 0x5d, 0xf6, 0xd0, 0x49, 0x5b, - 0xbc, 0xdb, 0xfb, 0x6d, 0xb6, 0x63, 0xfd, 0x3e, 0xdb, 0xb1, 0xfe, 0x9c, 0xed, 0x58, 0x5f, 0x7f, - 0xfc, 0xdf, 0x66, 0xf6, 0xa4, 0xd4, 0x72, 0x63, 0x27, 0xcb, 0x66, 0xc2, 0x3e, 0xf8, 0x27, 0x00, - 0x00, 0xff, 0xff, 0xb3, 0xaf, 0x63, 0xe2, 0x50, 0x0c, 0x00, 0x00, + // 1293 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xcd, 0x6e, 0x1b, 0xb7, + 0x16, 0xc6, 0x44, 0x8e, 0x2d, 0x1d, 0xc7, 0x96, 0xcd, 0x38, 0xce, 0x44, 0x37, 0xd7, 0xd6, 0xd5, + 0x22, 0xd0, 0xbd, 0xb8, 0x1d, 0xc5, 0x0a, 0x8a, 0x16, 0x41, 0x83, 0xd6, 0x92, 0x82, 0x44, 0x8d, + 0x92, 0xb8, 0x4c, 0x9c, 0x45, 0x37, 0x01, 0x3d, 0xc3, 0x8e, 0xa6, 0x1e, 0x91, 0x03, 0x92, 0xa3, + 0x46, 0x59, 0xf6, 0x01, 0xba, 0x69, 0x9f, 0xa6, 0xfb, 0xa2, 0x5d, 0x16, 0xe8, 0xde, 0x28, 0x84, + 0x3e, 0x44, 0x97, 0x05, 0x39, 0x3f, 0x1e, 0x8f, 0xe4, 0xb4, 0x40, 0x76, 0xe4, 0xf7, 0x9d, 0x3f, + 0x1e, 0x9e, 0x43, 0x1e, 0xd8, 0x93, 0x54, 0x4c, 0xa9, 0xe8, 0x48, 0xaa, 0x54, 0xc0, 0x7c, 0x99, + 0x2f, 0x9c, 0x48, 0x70, 0xc5, 0xd1, 0x9a, 0x1b, 0xc6, 0x52, 0x51, 0xd1, 0xd8, 0xf1, 0xb9, 0xcf, + 0x0d, 0xd6, 0xd1, 0xab, 0x84, 0x6e, 0xdc, 0xf6, 0x39, 0xf7, 0x43, 0xda, 0x21, 0x51, 0xd0, 0x21, + 0x8c, 0x71, 0x45, 0x54, 0xc0, 0x59, 0xaa, 0xdc, 0x18, 0xf9, 0x81, 0x1a, 0xc7, 0x27, 0x8e, 0xcb, + 0x27, 0x1d, 0x22, 0x8c, 0xfa, 0xd7, 0x66, 0xf1, 0x81, 0xeb, 0x75, 0xa6, 0xdd, 0x4e, 0x74, 0xea, + 0x6b, 0x4d, 0xd9, 0x21, 0x51, 0x14, 0x06, 0xae, 0xd1, 0xed, 0x4c, 0x0f, 0x48, 0x18, 0x8d, 0xc9, + 0x41, 0xc7, 0xa7, 0x8c, 0x0a, 0xa2, 0xa8, 0x97, 0x5a, 0xfb, 0xec, 0x6f, 0xac, 0x95, 0x4f, 0xc2, + 0x03, 0xcf, 0xed, 0xb8, 0x21, 0x09, 0x26, 0x69, 0x3c, 0xad, 0x3a, 0x6c, 0xbc, 0x48, 0xd9, 0x2f, + 0x62, 0x2a, 0x66, 0xad, 0x3f, 0xaf, 0x41, 0x35, 0x43, 0xd0, 0x2d, 0xa8, 0xc4, 0x22, 0xb4, 0xad, + 0xa6, 0xd5, 0xae, 0xf5, 0xd6, 0xe6, 0x67, 0xfb, 0x95, 0x63, 0x3c, 0xc2, 0x1a, 0x43, 0x77, 0xa1, + 0xe6, 0xd1, 0x37, 0x7d, 0xce, 0xbe, 0x0a, 0x7c, 0xfb, 0x4a, 0xd3, 0x6a, 0xaf, 0x77, 0x91, 0x93, + 0x66, 0xc6, 0x19, 0x64, 0x0c, 0x3e, 0x17, 0x42, 0x7d, 0x00, 0xed, 0x3f, 0x55, 0xa9, 0x18, 0x95, + 0xeb, 0xb9, 0xca, 0xf3, 0xe1, 0xa0, 0x9f, 0x50, 0xbd, 0xcd, 0xf9, 0xd9, 0x3e, 0x9c, 0xef, 0x71, + 0x41, 0x0d, 0x35, 0x61, 0x9d, 0x44, 0xd1, 0x88, 0x9c, 0xd0, 0xf0, 0x09, 0x9d, 0xd9, 0x2b, 0x3a, + 0x32, 0x5c, 0x84, 0xd0, 0x2b, 0xd8, 0x16, 0x54, 0xf2, 0x58, 0xb8, 0xf4, 0xf9, 0x94, 0x0a, 0x11, + 0x78, 0x54, 0xda, 0x57, 0x9b, 0x95, 0xf6, 0x7a, 0xb7, 0x9d, 0x7b, 0xcb, 0x4e, 0xe8, 0xe0, 0xb2, + 0xe8, 0x43, 0xa6, 0xc4, 0x0c, 0x2f, 0x9a, 0x40, 0x0e, 0x20, 0xa9, 0x88, 0x8a, 0x65, 0x8f, 0x78, + 0x3e, 0x7d, 0xc8, 0xc8, 0x49, 0x48, 0x3d, 0x7b, 0xb5, 0x69, 0xb5, 0xab, 0x78, 0x09, 0x83, 0x1e, + 0x43, 0x3d, 0xa9, 0x84, 0x43, 0x46, 0xc2, 0x99, 0x0a, 0x5c, 0x69, 0xaf, 0x99, 0x33, 0xef, 0xe5, + 0x51, 0x3c, 0xba, 0xc8, 0xa7, 0xc7, 0x2d, 0xab, 0xa1, 0xb7, 0xb0, 0x75, 0x1a, 0x4b, 0xc5, 0x27, + 0xc1, 0x5b, 0xfa, 0x3c, 0x32, 0xd5, 0x64, 0x57, 0x8d, 0xa9, 0x67, 0xce, 0x79, 0x01, 0x38, 0x59, + 0x01, 0x98, 0xc5, 0x6b, 0xd7, 0x73, 0xa6, 0x5d, 0x27, 0x3a, 0xf5, 0x1d, 0x5d, 0x4e, 0x4e, 0xa1, + 0x9c, 0x9c, 0xac, 0x9c, 0x9c, 0x27, 0x25, 0xab, 0x78, 0xc1, 0x0f, 0xfa, 0x0f, 0xac, 0x8c, 0x69, + 0x18, 0xd9, 0x35, 0xe3, 0x6f, 0x23, 0x0f, 0xfd, 0x31, 0x0d, 0x23, 0x6c, 0x28, 0xf4, 0x5f, 0x58, + 0x8b, 0xc2, 0xd8, 0x0f, 0x98, 0xb4, 0xc1, 0xa4, 0xb9, 0x9e, 0x4b, 0x1d, 0x19, 0x1c, 0x67, 0xbc, + 0xce, 0x61, 0x2c, 0xa9, 0x18, 0x71, 0xbd, 0x1b, 0x04, 0x32, 0xc9, 0xe1, 0x7a, 0x92, 0xc3, 0x45, + 0x06, 0x7d, 0x67, 0xc1, 0x4d, 0xd7, 0x64, 0xe5, 0x29, 0x61, 0xc4, 0xa7, 0x13, 0xca, 0xd4, 0x51, + 0xea, 0xeb, 0x9a, 0xf1, 0xf5, 0xf2, 0xfd, 0x32, 0xd0, 0x5f, 0x6a, 0x1c, 0x5f, 0xe6, 0x14, 0xfd, + 0x1f, 0xb6, 0xf3, 0x14, 0xbd, 0xa2, 0x42, 0x9a, 0xbb, 0xd8, 0x68, 0x56, 0xda, 0x35, 0xbc, 0x48, + 0xa0, 0x06, 0x54, 0xe3, 0xa0, 0x2f, 0xe5, 0x31, 0x1e, 0xd9, 0x9b, 0xa6, 0x52, 0xf3, 0x3d, 0x6a, + 0x43, 0x3d, 0x0e, 0x7a, 0x84, 0x31, 0x2a, 0xfa, 0x9c, 0x29, 0xca, 0x94, 0x5d, 0x37, 0x22, 0x65, + 0x58, 0x97, 0x7c, 0x06, 0x69, 0x43, 0x5b, 0x49, 0xc9, 0x17, 0x20, 0x6d, 0x2b, 0x22, 0x52, 0x7e, + 0xc3, 0x85, 0x77, 0x44, 0x94, 0xa2, 0x82, 0xd9, 0xdb, 0x89, 0xad, 0x12, 0x8c, 0xee, 0xc0, 0xa6, + 0x12, 0xc4, 0x3d, 0x0d, 0x98, 0xff, 0x94, 0xaa, 0x31, 0xf7, 0x6c, 0x64, 0x04, 0x4b, 0xa8, 0x3e, + 0x67, 0xe6, 0xe0, 0x88, 0x8a, 0x09, 0x61, 0x3a, 0xbe, 0xeb, 0xe6, 0x9e, 0x16, 0x09, 0xf4, 0x3f, + 0xd8, 0xca, 0x41, 0x2e, 0x03, 0x9d, 0x62, 0x7b, 0xc7, 0xd8, 0x5d, 0xc0, 0x4b, 0x6d, 0x84, 0x39, + 0x57, 0xc7, 0x22, 0xb4, 0x6f, 0x18, 0xe9, 0x25, 0x8c, 0x3e, 0x3d, 0x7d, 0x43, 0xdd, 0xac, 0xdf, + 0x76, 0x4d, 0x0c, 0x45, 0x08, 0xdd, 0x85, 0xeb, 0x2e, 0x67, 0x4a, 0xf0, 0x30, 0xa4, 0xe2, 0x19, + 0x99, 0x50, 0x19, 0x11, 0x97, 0xda, 0x37, 0x8d, 0xc9, 0x65, 0x14, 0xfa, 0x04, 0x6e, 0x91, 0x28, + 0x92, 0x43, 0x76, 0xc8, 0x66, 0x39, 0x9a, 0x79, 0xb0, 0x8d, 0x87, 0xcb, 0x05, 0x50, 0x17, 0x76, + 0x82, 0x49, 0x44, 0x85, 0xe4, 0xcc, 0x54, 0x53, 0xa6, 0x78, 0xcb, 0x28, 0x2e, 0xe5, 0x74, 0xde, + 0x03, 0x26, 0x15, 0x09, 0x43, 0x03, 0x0f, 0x07, 0x76, 0x23, 0xc9, 0xfb, 0x45, 0x14, 0xdd, 0x87, + 0x4d, 0xe2, 0x79, 0x26, 0x53, 0x24, 0x3c, 0x16, 0xa1, 0xb4, 0xff, 0xa5, 0x8b, 0xab, 0x87, 0xe6, + 0x67, 0xfb, 0x9b, 0x87, 0xe7, 0x0c, 0x1e, 0x49, 0x5c, 0x92, 0xd4, 0x55, 0x30, 0x9e, 0x79, 0x82, + 0x28, 0x2e, 0xb2, 0x90, 0x6e, 0x9b, 0x90, 0xca, 0x70, 0xe3, 0x07, 0x0b, 0x76, 0x97, 0x3f, 0x7c, + 0x68, 0x0b, 0x2a, 0xa7, 0x74, 0x96, 0xbc, 0xf8, 0x58, 0x2f, 0x91, 0x07, 0x57, 0xa7, 0x24, 0x8c, + 0x69, 0xfa, 0xc8, 0xbf, 0xe7, 0x93, 0x53, 0x76, 0x8b, 0x13, 0xe3, 0xf7, 0xaf, 0x7c, 0x6c, 0xb5, + 0x5e, 0xc3, 0x8d, 0xa5, 0x2f, 0x22, 0xda, 0x03, 0xc8, 0xea, 0x73, 0x38, 0x48, 0x63, 0x2b, 0x20, + 0x3a, 0xbb, 0x84, 0x71, 0x36, 0xd3, 0xcd, 0x77, 0x2c, 0xa9, 0x90, 0x26, 0xd6, 0x2a, 0x2e, 0xa1, + 0xad, 0x01, 0xdc, 0xcc, 0x1e, 0xfe, 0xb4, 0xa1, 0x31, 0x95, 0x11, 0x67, 0x92, 0x16, 0x1f, 0x31, + 0xeb, 0xdd, 0x8f, 0x58, 0xeb, 0x47, 0x0b, 0x56, 0xf4, 0xf3, 0x87, 0x6c, 0x58, 0x73, 0xc7, 0xc4, + 0xd4, 0x6f, 0x12, 0x53, 0xb6, 0xd5, 0x8d, 0xaf, 0x97, 0x2f, 0xe9, 0x1b, 0x65, 0x42, 0xa9, 0xe1, + 0x7c, 0x8f, 0x1e, 0x00, 0x9c, 0x04, 0x8c, 0x88, 0x99, 0xb9, 0xde, 0x8a, 0x71, 0xf6, 0xef, 0x0b, + 0xef, 0xaa, 0xd3, 0xcb, 0xf9, 0xe4, 0x37, 0x2a, 0x28, 0x34, 0x1e, 0x40, 0xbd, 0x44, 0x2f, 0xb9, + 0xb3, 0x9d, 0xe2, 0x9d, 0xd5, 0x8a, 0x39, 0xbe, 0x0d, 0xab, 0xc9, 0x79, 0x10, 0x82, 0x15, 0x46, + 0x26, 0x34, 0x55, 0x33, 0xeb, 0xd6, 0xa7, 0x50, 0xcb, 0xbf, 0x6e, 0xd4, 0x05, 0x70, 0x39, 0x63, + 0xd4, 0x55, 0x5c, 0x64, 0x59, 0x39, 0xff, 0xe2, 0xfb, 0x19, 0x85, 0x0b, 0x52, 0xad, 0x7b, 0x50, + 0xcb, 0x89, 0x65, 0x1e, 0x34, 0xa6, 0x66, 0x51, 0x16, 0x98, 0x59, 0xb7, 0x7e, 0xaa, 0x40, 0xe1, + 0xbb, 0x5f, 0xaa, 0xb6, 0x0b, 0xab, 0x81, 0x94, 0x31, 0x15, 0xa9, 0x62, 0xba, 0x43, 0x6d, 0xa8, + 0xba, 0x61, 0x40, 0x99, 0x1a, 0x0e, 0xcc, 0x44, 0x51, 0xeb, 0x5d, 0x9b, 0x9f, 0xed, 0x57, 0xfb, + 0x29, 0x86, 0x73, 0x16, 0x1d, 0xc0, 0xba, 0x1b, 0x06, 0x19, 0x91, 0x0c, 0x0e, 0xbd, 0xfa, 0xfc, + 0x6c, 0x7f, 0xbd, 0x3f, 0x1a, 0xe6, 0xf2, 0x45, 0x19, 0xed, 0x54, 0xba, 0x3c, 0x4a, 0xc7, 0x87, + 0x1a, 0x4e, 0x77, 0xe8, 0x35, 0x6c, 0x04, 0xde, 0x4b, 0x7e, 0x4a, 0x59, 0xdf, 0x8c, 0x52, 0xf6, + 0xaa, 0xc9, 0xcd, 0x9d, 0x25, 0xb3, 0x8c, 0x33, 0x2c, 0x0a, 0x9a, 0xeb, 0xea, 0x6d, 0xcf, 0xcf, + 0xf6, 0x37, 0x86, 0x83, 0x02, 0x8e, 0x2f, 0xda, 0x43, 0xf7, 0xc1, 0xa6, 0xa6, 0x55, 0x8f, 0x9e, + 0xf4, 0x1f, 0x1e, 0xc6, 0x6a, 0x4c, 0x99, 0x4a, 0x3b, 0xc9, 0xcc, 0x10, 0x55, 0x7c, 0x29, 0xdf, + 0x98, 0x01, 0x5a, 0xf4, 0xb9, 0xa4, 0x44, 0x9e, 0x5e, 0x6c, 0xeb, 0x8f, 0xde, 0xd9, 0xd6, 0xc9, + 0x1c, 0xe9, 0xe4, 0x83, 0xb0, 0x1e, 0xc8, 0x1c, 0x63, 0xbf, 0x50, 0x5b, 0xdd, 0x9f, 0x2d, 0xa8, + 0x67, 0xfd, 0xf5, 0x82, 0x8a, 0x69, 0xe0, 0x52, 0xf4, 0x39, 0x54, 0x1e, 0x51, 0x85, 0x76, 0x17, + 0x26, 0x2f, 0x33, 0x6d, 0x36, 0xb6, 0x17, 0xf0, 0x96, 0xfd, 0xed, 0x6f, 0x7f, 0x7c, 0x7f, 0x05, + 0xa1, 0x2d, 0x33, 0x41, 0x4f, 0x0f, 0xf2, 0xe9, 0x15, 0x8d, 0x01, 0x1e, 0xd1, 0xfc, 0x2b, 0xbe, + 0xcc, 0x64, 0x73, 0x01, 0x2f, 0xf5, 0x7a, 0xab, 0x69, 0x3c, 0x34, 0x90, 0x5d, 0xf6, 0xd0, 0x49, + 0x5b, 0xbc, 0xd7, 0xff, 0x65, 0xbe, 0x67, 0xfd, 0x3a, 0xdf, 0xb3, 0x7e, 0x9f, 0xef, 0x59, 0x5f, + 0x7e, 0xf8, 0xcf, 0x66, 0xf6, 0xa4, 0xd4, 0x72, 0x63, 0x27, 0xab, 0x66, 0xc2, 0xbe, 0xf7, 0x57, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x57, 0xdb, 0xcf, 0xcf, 0x50, 0x0c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/pkg/apiclient/version/version.pb.go b/pkg/apiclient/version/version.pb.go index fcede900bb..0b58bf4a6c 100644 --- a/pkg/apiclient/version/version.pb.go +++ b/pkg/apiclient/version/version.pb.go @@ -186,7 +186,7 @@ var fileDescriptor_8be80977d07a4107 = []byte{ // 415 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x92, 0xd1, 0x6a, 0x14, 0x31, 0x18, 0x85, 0x99, 0x56, 0x77, 0xdb, 0x74, 0x5d, 0x24, 0x48, 0x0d, 0xeb, 0xb2, 0x94, 0xbd, 0x10, - 0x11, 0x9c, 0x01, 0xeb, 0x13, 0x6c, 0x2d, 0x55, 0x8b, 0x50, 0xac, 0x78, 0xe1, 0x5d, 0x66, 0xfa, + 0x11, 0x9c, 0x81, 0xea, 0x13, 0x6c, 0x2d, 0x55, 0x8b, 0x50, 0xac, 0x78, 0xe1, 0x5d, 0x66, 0xfa, 0xef, 0x18, 0x9d, 0xe4, 0x1f, 0x32, 0xff, 0x2c, 0xea, 0xa5, 0xaf, 0xe0, 0xfb, 0x78, 0xed, 0xa5, 0xe0, 0x0b, 0xc8, 0xe2, 0x83, 0x48, 0x92, 0xc9, 0xe8, 0xd8, 0xab, 0xcd, 0x39, 0xe7, 0xdb, 0x43, 0x98, 0x13, 0x36, 0x6f, 0xc0, 0x6e, 0xc0, 0x66, 0x1b, 0xb0, 0x8d, 0x42, 0x13, 0x7f, 0xd3, 0xda, @@ -203,13 +203,13 @@ var fileDescriptor_8be80977d07a4107 = []byte{ 0x1d, 0x3c, 0x83, 0x4a, 0x47, 0xec, 0xc0, 0x63, 0xff, 0x5a, 0xfc, 0x3e, 0x9b, 0x9e, 0xb7, 0x39, 0x14, 0x54, 0x45, 0x68, 0xe2, 0xa1, 0xff, 0x5c, 0xc7, 0xbd, 0x68, 0xd0, 0x18, 0xa0, 0xc8, 0xdd, 0x0a, 0xdc, 0xd0, 0x75, 0xdc, 0xe9, 0x47, 0xb2, 0xd2, 0x7f, 0xdf, 0xe7, 0x66, 0x8d, 0x62, 0x1a, - 0xb8, 0xa1, 0xfb, 0x38, 0xef, 0xf7, 0xbb, 0x04, 0xbb, 0x51, 0x05, 0xf0, 0x8b, 0x7e, 0x3f, 0x7e, - 0x98, 0x86, 0xed, 0xd3, 0xb8, 0x7d, 0x7a, 0xea, 0xb6, 0x9f, 0xdd, 0x4d, 0xe3, 0x4b, 0x1a, 0x6e, - 0xbf, 0xbc, 0xf3, 0xe5, 0xe7, 0xef, 0xaf, 0x3b, 0x53, 0x3e, 0xf1, 0x6f, 0xa9, 0x83, 0x56, 0xab, - 0xef, 0xdb, 0x45, 0xf2, 0x63, 0xbb, 0x48, 0x7e, 0x6d, 0x17, 0xc9, 0xdb, 0x27, 0xa5, 0xa2, 0x77, - 0x6d, 0x9e, 0x16, 0xa8, 0x33, 0x69, 0x4b, 0xac, 0x2d, 0xbe, 0xf7, 0x87, 0x47, 0xc5, 0x55, 0xb6, - 0x39, 0xce, 0xea, 0x0f, 0xa5, 0xfb, 0x77, 0x51, 0x29, 0x30, 0x14, 0x3b, 0xf2, 0x91, 0xbf, 0xc2, - 0xf1, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0xc9, 0x27, 0xdf, 0xd3, 0x02, 0x00, 0x00, + 0xb8, 0xa1, 0x7b, 0x9c, 0xf7, 0xfb, 0x5d, 0x82, 0xdd, 0xa8, 0x02, 0xf8, 0x45, 0xbf, 0x1f, 0x3f, + 0x4c, 0xc3, 0xf6, 0x69, 0xdc, 0x3e, 0x3d, 0x75, 0xdb, 0xcf, 0xee, 0xa6, 0xf1, 0x25, 0x0d, 0xb7, + 0x5f, 0xde, 0xf9, 0xf2, 0xf3, 0xf7, 0xd7, 0x9d, 0x29, 0x9f, 0xf8, 0xb7, 0xd4, 0x41, 0xab, 0xd5, + 0xf7, 0xed, 0x22, 0xf9, 0xb1, 0x5d, 0x24, 0xbf, 0xb6, 0x8b, 0xe4, 0xed, 0x93, 0x52, 0xd1, 0xbb, + 0x36, 0x4f, 0x0b, 0xd4, 0x99, 0xb4, 0x25, 0xd6, 0x16, 0xdf, 0xfb, 0xc3, 0xa3, 0xe2, 0x2a, 0xdb, + 0x1c, 0x67, 0xf5, 0x87, 0xd2, 0xfd, 0xbb, 0xa8, 0x14, 0x18, 0x8a, 0x1d, 0xf9, 0xc8, 0x5f, 0xe1, + 0xf1, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd2, 0x21, 0xc0, 0xd1, 0xd3, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/pkg/apis/application/v1alpha1/app_project_types.go b/pkg/apis/application/v1alpha1/app_project_types.go index 097b2600ee..436e578548 100644 --- a/pkg/apis/application/v1alpha1/app_project_types.go +++ b/pkg/apis/application/v1alpha1/app_project_types.go @@ -14,8 +14,8 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - "github.com/argoproj/argo-cd/v3/util/git" - "github.com/argoproj/argo-cd/v3/util/glob" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/glob" ) const ( @@ -74,19 +74,19 @@ type AppProjectStatus struct { } // GetRoleByName returns the role in a project by the name with its index -func (proj *AppProject) GetRoleByName(name string) (*ProjectRole, int, error) { - for i, role := range proj.Spec.Roles { +func (p *AppProject) GetRoleByName(name string) (*ProjectRole, int, error) { + for i, role := range p.Spec.Roles { if name == role.Name { return &role, i, nil } } - return nil, -1, fmt.Errorf("role '%s' does not exist in project '%s'", name, proj.Name) + return nil, -1, fmt.Errorf("role '%s' does not exist in project '%s'", name, p.Name) } // GetJWTTokenFromSpec looks up the index of a JWTToken in a project by id (new token), if not then by the issue at time (old token) -func (proj *AppProject) GetJWTTokenFromSpec(roleName string, issuedAt int64, id string) (*JWTToken, int, error) { +func (p *AppProject) GetJWTTokenFromSpec(roleName string, issuedAt int64, id string) (*JWTToken, int, error) { // This is for backward compatibility. In the oder version, JWTTokens are stored under spec.role - role, _, err := proj.GetRoleByName(roleName) + role, _, err := p.GetRoleByName(roleName) if err != nil { return nil, -1, err } @@ -107,14 +107,14 @@ func (proj *AppProject) GetJWTTokenFromSpec(roleName string, issuedAt int64, id } } - return nil, -1, fmt.Errorf("JWT token for role '%s' issued at '%d' does not exist in project '%s'", role.Name, issuedAt, proj.Name) + return nil, -1, fmt.Errorf("JWT token for role '%s' issued at '%d' does not exist in project '%s'", role.Name, issuedAt, p.Name) } // GetJWTToken looks up the index of a JWTToken in a project by id (new token), if not then by the issue at time (old token) -func (proj *AppProject) GetJWTToken(roleName string, issuedAt int64, id string) (*JWTToken, int, error) { +func (p *AppProject) GetJWTToken(roleName string, issuedAt int64, id string) (*JWTToken, int, error) { // This is for newer version, JWTTokens are stored under status if id != "" { - for i, token := range proj.Status.JWTTokensByRole[roleName].Items { + for i, token := range p.Status.JWTTokensByRole[roleName].Items { if id == token.ID { return &token, i, nil } @@ -122,44 +122,45 @@ func (proj *AppProject) GetJWTToken(roleName string, issuedAt int64, id string) } if issuedAt != -1 { - for i, token := range proj.Status.JWTTokensByRole[roleName].Items { + for i, token := range p.Status.JWTTokensByRole[roleName].Items { if issuedAt == token.IssuedAt { return &token, i, nil } } } - return nil, -1, fmt.Errorf("JWT token for role '%s' issued at '%d' does not exist in project '%s'", roleName, issuedAt, proj.Name) + return nil, -1, fmt.Errorf("JWT token for role '%s' issued at '%d' does not exist in project '%s'", roleName, issuedAt, p.Name) } // RemoveJWTToken removes the specified JWT from an AppProject -func (proj AppProject) RemoveJWTToken(roleIndex int, issuedAt int64, id string) error { - roleName := proj.Spec.Roles[roleIndex].Name +func (p AppProject) RemoveJWTToken(roleIndex int, issuedAt int64, id string) error { + roleName := p.Spec.Roles[roleIndex].Name // For backward compatibility - _, jwtTokenIndex, err1 := proj.GetJWTTokenFromSpec(roleName, issuedAt, id) + _, jwtTokenIndex, err1 := p.GetJWTTokenFromSpec(roleName, issuedAt, id) if err1 == nil { - proj.Spec.Roles[roleIndex].JWTTokens[jwtTokenIndex] = proj.Spec.Roles[roleIndex].JWTTokens[len(proj.Spec.Roles[roleIndex].JWTTokens)-1] - proj.Spec.Roles[roleIndex].JWTTokens = proj.Spec.Roles[roleIndex].JWTTokens[:len(proj.Spec.Roles[roleIndex].JWTTokens)-1] + p.Spec.Roles[roleIndex].JWTTokens[jwtTokenIndex] = p.Spec.Roles[roleIndex].JWTTokens[len(p.Spec.Roles[roleIndex].JWTTokens)-1] + p.Spec.Roles[roleIndex].JWTTokens = p.Spec.Roles[roleIndex].JWTTokens[:len(p.Spec.Roles[roleIndex].JWTTokens)-1] } // New location for storing JWTToken - _, jwtTokenIndex, err2 := proj.GetJWTToken(roleName, issuedAt, id) + _, jwtTokenIndex, err2 := p.GetJWTToken(roleName, issuedAt, id) if err2 == nil { - proj.Status.JWTTokensByRole[roleName].Items[jwtTokenIndex] = proj.Status.JWTTokensByRole[roleName].Items[len(proj.Status.JWTTokensByRole[roleName].Items)-1] - proj.Status.JWTTokensByRole[roleName] = JWTTokens{Items: proj.Status.JWTTokensByRole[roleName].Items[:len(proj.Status.JWTTokensByRole[roleName].Items)-1]} + p.Status.JWTTokensByRole[roleName].Items[jwtTokenIndex] = p.Status.JWTTokensByRole[roleName].Items[len(p.Status.JWTTokensByRole[roleName].Items)-1] + p.Status.JWTTokensByRole[roleName] = JWTTokens{Items: p.Status.JWTTokensByRole[roleName].Items[:len(p.Status.JWTTokensByRole[roleName].Items)-1]} } if err1 == nil || err2 == nil { // If we find this token from either places, we can say there are no error return nil + } else { + // If we could not locate this taken from either places, we can return any of the errors + return err2 } - // If we could not locate this taken from either places, we can return any of the errors - return err2 } // TODO: document this method -func (proj *AppProject) ValidateJWTTokenID(roleName string, id string) error { - role, _, err := proj.GetRoleByName(roleName) +func (p *AppProject) ValidateJWTTokenID(roleName string, id string) error { + role, _, err := p.GetRoleByName(roleName) if err != nil { return err } @@ -174,9 +175,9 @@ func (proj *AppProject) ValidateJWTTokenID(roleName string, id string) error { return nil } -func (proj *AppProject) ValidateProject() error { +func (p *AppProject) ValidateProject() error { destKeys := make(map[string]bool) - for _, dest := range proj.Spec.Destinations { + for _, dest := range p.Spec.Destinations { if dest.Name == "!*" { return status.Errorf(codes.InvalidArgument, "name has an invalid format, '!*'") } @@ -201,7 +202,7 @@ func (proj *AppProject) ValidateProject() error { } srcNamespaces := make(map[string]bool) - for _, ns := range proj.Spec.SourceNamespaces { + for _, ns := range p.Spec.SourceNamespaces { if _, ok := srcNamespaces[ns]; ok { return status.Errorf(codes.InvalidArgument, "source namespace '%s' already added", ns) } @@ -209,7 +210,7 @@ func (proj *AppProject) ValidateProject() error { } srcRepos := make(map[string]bool) - for _, src := range proj.Spec.SourceRepos { + for _, src := range p.Spec.SourceRepos { if src == "!*" { return status.Errorf(codes.InvalidArgument, "source repository has an invalid format, '!*'") } @@ -221,7 +222,7 @@ func (proj *AppProject) ValidateProject() error { } roleNames := make(map[string]bool) - for _, role := range proj.Spec.Roles { + for _, role := range p.Spec.Roles { if _, ok := roleNames[role.Name]; ok { return status.Errorf(codes.AlreadyExists, "role '%s' already exists", role.Name) } @@ -233,7 +234,7 @@ func (proj *AppProject) ValidateProject() error { if _, ok := existingPolicies[policy]; ok { return status.Errorf(codes.AlreadyExists, "policy '%s' already exists for role '%s'", policy, role.Name) } - if err := validatePolicy(proj.Name, role.Name, policy); err != nil { + if err := validatePolicy(p.Name, role.Name, policy); err != nil { return err } existingPolicies[policy] = true @@ -251,9 +252,9 @@ func (proj *AppProject) ValidateProject() error { roleNames[role.Name] = true } - if proj.Spec.SyncWindows.HasWindows() { + if p.Spec.SyncWindows.HasWindows() { existingWindows := make(map[string]bool) - for _, window := range proj.Spec.SyncWindows { + for _, window := range p.Spec.SyncWindows { if window == nil { continue } @@ -272,7 +273,7 @@ func (proj *AppProject) ValidateProject() error { } destServiceAccts := make(map[string]bool) - for _, destServiceAcct := range proj.Spec.DestinationServiceAccounts { + for _, destServiceAcct := range p.Spec.DestinationServiceAccounts { if strings.Contains(destServiceAcct.Server, "!") { return status.Errorf(codes.InvalidArgument, "server has an invalid format, '%s'", destServiceAcct.Server) } @@ -307,8 +308,8 @@ func (proj *AppProject) ValidateProject() error { } // AddGroupToRole adds an OIDC group to a role -func (proj *AppProject) AddGroupToRole(roleName, group string) (bool, error) { - role, roleIndex, err := proj.GetRoleByName(roleName) +func (p *AppProject) AddGroupToRole(roleName, group string) (bool, error) { + role, roleIndex, err := p.GetRoleByName(roleName) if err != nil { return false, err } @@ -318,20 +319,20 @@ func (proj *AppProject) AddGroupToRole(roleName, group string) (bool, error) { } } role.Groups = append(role.Groups, group) - proj.Spec.Roles[roleIndex] = *role + p.Spec.Roles[roleIndex] = *role return true, nil } // RemoveGroupFromRole removes an OIDC group from a role -func (proj *AppProject) RemoveGroupFromRole(roleName, group string) (bool, error) { - role, roleIndex, err := proj.GetRoleByName(roleName) +func (p *AppProject) RemoveGroupFromRole(roleName, group string) (bool, error) { + role, roleIndex, err := p.GetRoleByName(roleName) if err != nil { return false, err } for i, roleGroup := range role.Groups { if group == roleGroup { role.Groups = append(role.Groups[:i], role.Groups[i+1:]...) - proj.Spec.Roles[roleIndex] = *role + p.Spec.Roles[roleIndex] = *role return true, nil } } @@ -339,17 +340,17 @@ func (proj *AppProject) RemoveGroupFromRole(roleName, group string) (bool, error } // NormalizePolicies normalizes the policies in the project -func (proj *AppProject) NormalizePolicies() { - for i, role := range proj.Spec.Roles { +func (p *AppProject) NormalizePolicies() { + for i, role := range p.Spec.Roles { var normalizedPolicies []string for _, policy := range role.Policies { - normalizedPolicies = append(normalizedPolicies, proj.normalizePolicy(policy)) + normalizedPolicies = append(normalizedPolicies, p.normalizePolicy(policy)) } - proj.Spec.Roles[i].Policies = normalizedPolicies + p.Spec.Roles[i].Policies = normalizedPolicies } } -func (proj *AppProject) normalizePolicy(policy string) string { +func (p *AppProject) normalizePolicy(policy string) string { policyComponents := strings.Split(policy, ",") normalizedPolicy := "" for _, component := range policyComponents { @@ -366,11 +367,11 @@ func (proj *AppProject) normalizePolicy(policy string) string { func (proj *AppProject) ProjectPoliciesString() string { var policies []string for _, role := range proj.Spec.Roles { - projectPolicy := fmt.Sprintf("p, proj:%s:%s, projects, get, %s, allow", proj.Name, role.Name, proj.Name) + projectPolicy := fmt.Sprintf("p, proj:%s:%s, projects, get, %s, allow", proj.ObjectMeta.Name, role.Name, proj.ObjectMeta.Name) policies = append(policies, projectPolicy) policies = append(policies, role.Policies...) for _, groupName := range role.Groups { - policies = append(policies, fmt.Sprintf("g, %s, proj:%s:%s", groupName, proj.Name, role.Name)) + policies = append(policies, fmt.Sprintf("g, %s, proj:%s:%s", groupName, proj.ObjectMeta.Name, role.Name)) } } return strings.Join(policies, "\n") @@ -399,16 +400,16 @@ func (proj AppProject) IsGroupKindPermitted(gk schema.GroupKind, namespaced bool } // IsLiveResourcePermitted returns whether a live resource found in the cluster is permitted by an AppProject -func (proj AppProject) IsLiveResourcePermitted(un *unstructured.Unstructured, destCluster *Cluster, projectClusters func(project string) ([]*Cluster, error)) (bool, error) { - return proj.IsResourcePermitted(un.GroupVersionKind().GroupKind(), un.GetNamespace(), destCluster, projectClusters) +func (proj AppProject) IsLiveResourcePermitted(un *unstructured.Unstructured, server string, name string, projectClusters func(project string) ([]*Cluster, error)) (bool, error) { + return proj.IsResourcePermitted(un.GroupVersionKind().GroupKind(), un.GetNamespace(), ApplicationDestination{Server: server, Name: name}, projectClusters) } -func (proj AppProject) IsResourcePermitted(groupKind schema.GroupKind, namespace string, destCluster *Cluster, projectClusters func(project string) ([]*Cluster, error)) (bool, error) { +func (proj AppProject) IsResourcePermitted(groupKind schema.GroupKind, namespace string, dest ApplicationDestination, projectClusters func(project string) ([]*Cluster, error)) (bool, error) { if !proj.IsGroupKindPermitted(groupKind, namespace != "") { return false, nil } if namespace != "" { - return proj.IsDestinationPermitted(destCluster, namespace, projectClusters) + return proj.IsDestinationPermitted(ApplicationDestination{Server: dest.Server, Name: dest.Name, Namespace: namespace}, projectClusters) } return true, nil } @@ -460,11 +461,7 @@ func (proj AppProject) IsSourcePermitted(src ApplicationSource) bool { } // IsDestinationPermitted validates if the provided application's destination is one of the allowed destinations for the project -func (proj AppProject) IsDestinationPermitted(destCluster *Cluster, destNamespace string, projectClusters func(project string) ([]*Cluster, error)) (bool, error) { - if destCluster == nil { - return false, nil - } - dst := ApplicationDestination{Server: destCluster.Server, Name: destCluster.Name, Namespace: destNamespace} +func (proj AppProject) IsDestinationPermitted(dst ApplicationDestination, projectClusters func(project string) ([]*Cluster, error)) (bool, error) { destinationMatched := proj.isDestinationMatched(dst) if destinationMatched && proj.Spec.PermitOnlyProjectScopedClusters { clusters, err := projectClusters(proj.Name) @@ -493,12 +490,11 @@ func (proj AppProject) isDestinationMatched(dst ApplicationDestination) bool { dstNamespaceMatched := globMatch(item.Namespace, dst.Namespace, true) matched := (dstServerMatched || dstNameMatched) && dstNamespaceMatched - switch { - case matched: + if matched { anyDestinationMatched = true - case (!dstNameMatched && isDenyPattern(item.Name)) || (!dstServerMatched && isDenyPattern(item.Server)) && dstNamespaceMatched: + } else if (!dstNameMatched && isDenyPattern(item.Name)) || (!dstServerMatched && isDenyPattern(item.Server)) && dstNamespaceMatched { return false - case !dstNamespaceMatched && isDenyPattern(item.Namespace) && dstServerMatched: + } else if !dstNamespaceMatched && isDenyPattern(item.Namespace) && dstServerMatched { return false } } @@ -601,10 +597,10 @@ func jwtTokensCombine(tokens1 []JWTToken, tokens2 []JWTToken) []JWTToken { // Applications in the installation namespace are always permitted. Also, at // application creation time, its namespace may yet be empty to indicate that // the application will be created in the controller's namespace. -func (proj AppProject) IsAppNamespacePermitted(app *Application, controllerNs string) bool { +func (p AppProject) IsAppNamespacePermitted(app *Application, controllerNs string) bool { if app.Namespace == "" || app.Namespace == controllerNs { return true } - return glob.MatchStringInList(proj.Spec.SourceNamespaces, app.Namespace, glob.REGEXP) + return glob.MatchStringInList(p.Spec.SourceNamespaces, app.Namespace, glob.REGEXP) } diff --git a/pkg/apis/application/v1alpha1/applicationset_types.go b/pkg/apis/application/v1alpha1/applicationset_types.go index 1bd56992cc..16f9eeecd5 100644 --- a/pkg/apis/application/v1alpha1/applicationset_types.go +++ b/pkg/apis/application/v1alpha1/applicationset_types.go @@ -21,8 +21,8 @@ import ( "fmt" "sort" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/security" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/security" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -69,8 +69,6 @@ type ApplicationSetSpec struct { PreservedFields *ApplicationPreservedFields `json:"preservedFields,omitempty" protobuf:"bytes,6,opt,name=preservedFields"` GoTemplateOptions []string `json:"goTemplateOptions,omitempty" protobuf:"bytes,7,opt,name=goTemplateOptions"` // ApplyNestedSelectors enables selectors defined within the generators of two level-nested matrix or merge generators - // Deprecated: This field is ignored, and the behavior is always enabled. The field will be removed in a future - // version of the ApplicationSet CRD. ApplyNestedSelectors bool `json:"applyNestedSelectors,omitempty" protobuf:"bytes,8,name=applyNestedSelectors"` IgnoreApplicationDifferences ApplicationSetIgnoreDifferences `json:"ignoreApplicationDifferences,omitempty" protobuf:"bytes,9,name=ignoreApplicationDifferences"` TemplatePatch *string `json:"templatePatch,omitempty" protobuf:"bytes,10,name=templatePatch"` @@ -421,8 +419,7 @@ type GitDirectoryGeneratorItem struct { } type GitFileGeneratorItem struct { - Path string `json:"path" protobuf:"bytes,1,name=path"` - Exclude bool `json:"exclude,omitempty" protobuf:"bytes,2,name=exclude"` + Path string `json:"path" protobuf:"bytes,1,name=path"` } // SCMProviderGenerator defines a generator that scrapes a SCMaaS API to find candidate repos. @@ -449,17 +446,16 @@ type SCMProviderGenerator struct { // If you add a new SCM provider, update CustomApiUrl below. } -func (g *SCMProviderGenerator) CustomApiUrl() string { //nolint:revive //FIXME(var-naming) - switch { - case g.Github != nil: +func (g *SCMProviderGenerator) CustomApiUrl() string { + if g.Github != nil { return g.Github.API - case g.Gitlab != nil: + } else if g.Gitlab != nil { return g.Gitlab.API - case g.Gitea != nil: + } else if g.Gitea != nil { return g.Gitea.API - case g.BitbucketServer != nil: + } else if g.BitbucketServer != nil { return g.BitbucketServer.API - case g.AzureDevOps != nil: + } else if g.AzureDevOps != nil { return g.AzureDevOps.API } return "" @@ -613,12 +609,10 @@ type PullRequestGenerator struct { Bitbucket *PullRequestGeneratorBitbucket `json:"bitbucket,omitempty" protobuf:"bytes,8,opt,name=bitbucket"` // Additional provider to use and config for it. AzureDevOps *PullRequestGeneratorAzureDevOps `json:"azuredevops,omitempty" protobuf:"bytes,9,opt,name=azuredevops"` - // Values contains key/value pairs which are passed directly as parameters to the template - Values map[string]string `json:"values,omitempty" protobuf:"bytes,10,name=values"` // If you add a new SCM provider, update CustomApiUrl below. } -func (p *PullRequestGenerator) CustomApiUrl() string { //nolint:revive //FIXME(var-naming) +func (p *PullRequestGenerator) CustomApiUrl() string { if p.Github != nil { return p.Github.API } @@ -652,8 +646,6 @@ type PullRequestGeneratorGitea struct { TokenRef *SecretRef `json:"tokenRef,omitempty" protobuf:"bytes,4,opt,name=tokenRef"` // Allow insecure tls, for self-signed certificates; default: false. Insecure bool `json:"insecure,omitempty" protobuf:"varint,5,opt,name=insecure"` - // Labels is used to filter the PRs that you want to target - Labels []string `json:"labels,omitempty" protobuf:"bytes,6,rep,name=labels"` } // PullRequestGeneratorAzureDevOps defines connection info specific to AzureDevOps. @@ -698,8 +690,7 @@ type PullRequestGeneratorGitLab struct { TokenRef *SecretRef `json:"tokenRef,omitempty" protobuf:"bytes,3,opt,name=tokenRef"` // Labels is used to filter the MRs that you want to target Labels []string `json:"labels,omitempty" protobuf:"bytes,4,rep,name=labels"` - // PullRequestState is an additional MRs filter to get only those with a certain state. Default: "" (all states). - // Valid values: opened, closed, merged, locked". + // PullRequestState is an additional MRs filter to get only those with a certain state. Default: "" (all states) PullRequestState string `json:"pullRequestState,omitempty" protobuf:"bytes,5,rep,name=pullRequestState"` // Skips validating the SCM provider's TLS certificate - useful for self-signed certificates.; default: false Insecure bool `json:"insecure,omitempty" protobuf:"varint,6,opt,name=insecure"` @@ -917,7 +908,7 @@ func (a *ApplicationSet) RefreshRequired() bool { // If the applicationset has a pre-existing condition of a type that is not in the evaluated list, // it will be preserved. If the applicationset has a pre-existing condition of a type, status, reason that // is in the evaluated list, but not in the incoming conditions list, it will be removed. -func (status *ApplicationSetStatus) SetConditions(conditions []ApplicationSetCondition, _ map[ApplicationSetConditionType]bool) { +func (status *ApplicationSetStatus) SetConditions(conditions []ApplicationSetCondition, evaluatedTypes map[ApplicationSetConditionType]bool) { applicationSetConditions := make([]ApplicationSetCondition, 0) now := metav1.Now() for i := range conditions { @@ -969,6 +960,7 @@ func (status *ApplicationSetStatus) SetApplicationStatus(newStatus ApplicationSe func (a *ApplicationSet) QualifiedName() string { if a.Namespace == "" { return a.Name + } else { + return a.Namespace + "/" + a.Name } - return a.Namespace + "/" + a.Name } diff --git a/pkg/apis/application/v1alpha1/applicationset_types_test.go b/pkg/apis/application/v1alpha1/applicationset_types_test.go index f72e19b3ea..cb61167b2e 100644 --- a/pkg/apis/application/v1alpha1/applicationset_types_test.go +++ b/pkg/apis/application/v1alpha1/applicationset_types_test.go @@ -123,8 +123,8 @@ func TestApplicationSetSetConditions(t *testing.T) { validate: func(t *testing.T, a *ApplicationSet) { t.Helper() // SetConditions should add timestamps for new conditions. - assert.True(t, a.Status.Conditions[0].LastTransitionTime.After(fiveMinsAgo.Time)) - assert.True(t, a.Status.Conditions[1].LastTransitionTime.After(fiveMinsAgo.Time)) + assert.True(t, a.Status.Conditions[0].LastTransitionTime.Time.After(fiveMinsAgo.Time)) + assert.True(t, a.Status.Conditions[1].LastTransitionTime.Time.After(fiveMinsAgo.Time)) }, }, { name: "condition cleared", @@ -165,7 +165,7 @@ func TestApplicationSetSetConditions(t *testing.T) { func assertAppSetConditions(t *testing.T, expected []ApplicationSetCondition, actual []ApplicationSetCondition) { t.Helper() - assert.Len(t, actual, len(expected)) + assert.Equal(t, len(expected), len(actual)) for i := range expected { assert.Equal(t, expected[i].Type, actual[i].Type) assert.Equal(t, expected[i].Message, actual[i].Message) diff --git a/pkg/apis/application/v1alpha1/cluster_constants.go b/pkg/apis/application/v1alpha1/cluster_constants.go index 877b8df05c..d9fc0052de 100644 --- a/pkg/apis/application/v1alpha1/cluster_constants.go +++ b/pkg/apis/application/v1alpha1/cluster_constants.go @@ -4,7 +4,7 @@ import ( "math" "time" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/util/env" ) const ( diff --git a/pkg/apis/application/v1alpha1/generated.pb.go b/pkg/apis/application/v1alpha1/generated.pb.go index d3cbc56f20..bdb2368203 100644 --- a/pkg/apis/application/v1alpha1/generated.pb.go +++ b/pkg/apis/application/v1alpha1/generated.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto +// source: github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto package v1alpha1 @@ -42,7 +42,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package func (m *AWSAuthConfig) Reset() { *m = AWSAuthConfig{} } func (*AWSAuthConfig) ProtoMessage() {} func (*AWSAuthConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{0} + return fileDescriptor_030104ce3b95bcac, []int{0} } func (m *AWSAuthConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -67,38 +67,10 @@ func (m *AWSAuthConfig) XXX_DiscardUnknown() { var xxx_messageInfo_AWSAuthConfig proto.InternalMessageInfo -func (m *AppHealthStatus) Reset() { *m = AppHealthStatus{} } -func (*AppHealthStatus) ProtoMessage() {} -func (*AppHealthStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{1} -} -func (m *AppHealthStatus) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AppHealthStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *AppHealthStatus) XXX_Merge(src proto.Message) { - xxx_messageInfo_AppHealthStatus.Merge(m, src) -} -func (m *AppHealthStatus) XXX_Size() int { - return m.Size() -} -func (m *AppHealthStatus) XXX_DiscardUnknown() { - xxx_messageInfo_AppHealthStatus.DiscardUnknown(m) -} - -var xxx_messageInfo_AppHealthStatus proto.InternalMessageInfo - func (m *AppProject) Reset() { *m = AppProject{} } func (*AppProject) ProtoMessage() {} func (*AppProject) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{2} + return fileDescriptor_030104ce3b95bcac, []int{1} } func (m *AppProject) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -126,7 +98,7 @@ var xxx_messageInfo_AppProject proto.InternalMessageInfo func (m *AppProjectList) Reset() { *m = AppProjectList{} } func (*AppProjectList) ProtoMessage() {} func (*AppProjectList) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{3} + return fileDescriptor_030104ce3b95bcac, []int{2} } func (m *AppProjectList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -154,7 +126,7 @@ var xxx_messageInfo_AppProjectList proto.InternalMessageInfo func (m *AppProjectSpec) Reset() { *m = AppProjectSpec{} } func (*AppProjectSpec) ProtoMessage() {} func (*AppProjectSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{4} + return fileDescriptor_030104ce3b95bcac, []int{3} } func (m *AppProjectSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -182,7 +154,7 @@ var xxx_messageInfo_AppProjectSpec proto.InternalMessageInfo func (m *AppProjectStatus) Reset() { *m = AppProjectStatus{} } func (*AppProjectStatus) ProtoMessage() {} func (*AppProjectStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{5} + return fileDescriptor_030104ce3b95bcac, []int{4} } func (m *AppProjectStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -210,7 +182,7 @@ var xxx_messageInfo_AppProjectStatus proto.InternalMessageInfo func (m *Application) Reset() { *m = Application{} } func (*Application) ProtoMessage() {} func (*Application) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{6} + return fileDescriptor_030104ce3b95bcac, []int{5} } func (m *Application) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -238,7 +210,7 @@ var xxx_messageInfo_Application proto.InternalMessageInfo func (m *ApplicationCondition) Reset() { *m = ApplicationCondition{} } func (*ApplicationCondition) ProtoMessage() {} func (*ApplicationCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{7} + return fileDescriptor_030104ce3b95bcac, []int{6} } func (m *ApplicationCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -266,7 +238,7 @@ var xxx_messageInfo_ApplicationCondition proto.InternalMessageInfo func (m *ApplicationDestination) Reset() { *m = ApplicationDestination{} } func (*ApplicationDestination) ProtoMessage() {} func (*ApplicationDestination) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{8} + return fileDescriptor_030104ce3b95bcac, []int{7} } func (m *ApplicationDestination) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -294,7 +266,7 @@ var xxx_messageInfo_ApplicationDestination proto.InternalMessageInfo func (m *ApplicationDestinationServiceAccount) Reset() { *m = ApplicationDestinationServiceAccount{} } func (*ApplicationDestinationServiceAccount) ProtoMessage() {} func (*ApplicationDestinationServiceAccount) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{9} + return fileDescriptor_030104ce3b95bcac, []int{8} } func (m *ApplicationDestinationServiceAccount) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -322,7 +294,7 @@ var xxx_messageInfo_ApplicationDestinationServiceAccount proto.InternalMessageIn func (m *ApplicationList) Reset() { *m = ApplicationList{} } func (*ApplicationList) ProtoMessage() {} func (*ApplicationList) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{10} + return fileDescriptor_030104ce3b95bcac, []int{9} } func (m *ApplicationList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -350,7 +322,7 @@ var xxx_messageInfo_ApplicationList proto.InternalMessageInfo func (m *ApplicationMatchExpression) Reset() { *m = ApplicationMatchExpression{} } func (*ApplicationMatchExpression) ProtoMessage() {} func (*ApplicationMatchExpression) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{11} + return fileDescriptor_030104ce3b95bcac, []int{10} } func (m *ApplicationMatchExpression) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -378,7 +350,7 @@ var xxx_messageInfo_ApplicationMatchExpression proto.InternalMessageInfo func (m *ApplicationPreservedFields) Reset() { *m = ApplicationPreservedFields{} } func (*ApplicationPreservedFields) ProtoMessage() {} func (*ApplicationPreservedFields) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{12} + return fileDescriptor_030104ce3b95bcac, []int{11} } func (m *ApplicationPreservedFields) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -406,7 +378,7 @@ var xxx_messageInfo_ApplicationPreservedFields proto.InternalMessageInfo func (m *ApplicationSet) Reset() { *m = ApplicationSet{} } func (*ApplicationSet) ProtoMessage() {} func (*ApplicationSet) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{13} + return fileDescriptor_030104ce3b95bcac, []int{12} } func (m *ApplicationSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -434,7 +406,7 @@ var xxx_messageInfo_ApplicationSet proto.InternalMessageInfo func (m *ApplicationSetApplicationStatus) Reset() { *m = ApplicationSetApplicationStatus{} } func (*ApplicationSetApplicationStatus) ProtoMessage() {} func (*ApplicationSetApplicationStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{14} + return fileDescriptor_030104ce3b95bcac, []int{13} } func (m *ApplicationSetApplicationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -462,7 +434,7 @@ var xxx_messageInfo_ApplicationSetApplicationStatus proto.InternalMessageInfo func (m *ApplicationSetCondition) Reset() { *m = ApplicationSetCondition{} } func (*ApplicationSetCondition) ProtoMessage() {} func (*ApplicationSetCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{15} + return fileDescriptor_030104ce3b95bcac, []int{14} } func (m *ApplicationSetCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -490,7 +462,7 @@ var xxx_messageInfo_ApplicationSetCondition proto.InternalMessageInfo func (m *ApplicationSetGenerator) Reset() { *m = ApplicationSetGenerator{} } func (*ApplicationSetGenerator) ProtoMessage() {} func (*ApplicationSetGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{16} + return fileDescriptor_030104ce3b95bcac, []int{15} } func (m *ApplicationSetGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -518,7 +490,7 @@ var xxx_messageInfo_ApplicationSetGenerator proto.InternalMessageInfo func (m *ApplicationSetList) Reset() { *m = ApplicationSetList{} } func (*ApplicationSetList) ProtoMessage() {} func (*ApplicationSetList) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{17} + return fileDescriptor_030104ce3b95bcac, []int{16} } func (m *ApplicationSetList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -546,7 +518,7 @@ var xxx_messageInfo_ApplicationSetList proto.InternalMessageInfo func (m *ApplicationSetNestedGenerator) Reset() { *m = ApplicationSetNestedGenerator{} } func (*ApplicationSetNestedGenerator) ProtoMessage() {} func (*ApplicationSetNestedGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{18} + return fileDescriptor_030104ce3b95bcac, []int{17} } func (m *ApplicationSetNestedGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -576,7 +548,7 @@ func (m *ApplicationSetResourceIgnoreDifferences) Reset() { } func (*ApplicationSetResourceIgnoreDifferences) ProtoMessage() {} func (*ApplicationSetResourceIgnoreDifferences) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{19} + return fileDescriptor_030104ce3b95bcac, []int{18} } func (m *ApplicationSetResourceIgnoreDifferences) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -604,7 +576,7 @@ var xxx_messageInfo_ApplicationSetResourceIgnoreDifferences proto.InternalMessag func (m *ApplicationSetRolloutStep) Reset() { *m = ApplicationSetRolloutStep{} } func (*ApplicationSetRolloutStep) ProtoMessage() {} func (*ApplicationSetRolloutStep) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{20} + return fileDescriptor_030104ce3b95bcac, []int{19} } func (m *ApplicationSetRolloutStep) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -632,7 +604,7 @@ var xxx_messageInfo_ApplicationSetRolloutStep proto.InternalMessageInfo func (m *ApplicationSetRolloutStrategy) Reset() { *m = ApplicationSetRolloutStrategy{} } func (*ApplicationSetRolloutStrategy) ProtoMessage() {} func (*ApplicationSetRolloutStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{21} + return fileDescriptor_030104ce3b95bcac, []int{20} } func (m *ApplicationSetRolloutStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -660,7 +632,7 @@ var xxx_messageInfo_ApplicationSetRolloutStrategy proto.InternalMessageInfo func (m *ApplicationSetSpec) Reset() { *m = ApplicationSetSpec{} } func (*ApplicationSetSpec) ProtoMessage() {} func (*ApplicationSetSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{22} + return fileDescriptor_030104ce3b95bcac, []int{21} } func (m *ApplicationSetSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -688,7 +660,7 @@ var xxx_messageInfo_ApplicationSetSpec proto.InternalMessageInfo func (m *ApplicationSetStatus) Reset() { *m = ApplicationSetStatus{} } func (*ApplicationSetStatus) ProtoMessage() {} func (*ApplicationSetStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{23} + return fileDescriptor_030104ce3b95bcac, []int{22} } func (m *ApplicationSetStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -716,7 +688,7 @@ var xxx_messageInfo_ApplicationSetStatus proto.InternalMessageInfo func (m *ApplicationSetStrategy) Reset() { *m = ApplicationSetStrategy{} } func (*ApplicationSetStrategy) ProtoMessage() {} func (*ApplicationSetStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{24} + return fileDescriptor_030104ce3b95bcac, []int{23} } func (m *ApplicationSetStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -744,7 +716,7 @@ var xxx_messageInfo_ApplicationSetStrategy proto.InternalMessageInfo func (m *ApplicationSetSyncPolicy) Reset() { *m = ApplicationSetSyncPolicy{} } func (*ApplicationSetSyncPolicy) ProtoMessage() {} func (*ApplicationSetSyncPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{25} + return fileDescriptor_030104ce3b95bcac, []int{24} } func (m *ApplicationSetSyncPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -772,7 +744,7 @@ var xxx_messageInfo_ApplicationSetSyncPolicy proto.InternalMessageInfo func (m *ApplicationSetTemplate) Reset() { *m = ApplicationSetTemplate{} } func (*ApplicationSetTemplate) ProtoMessage() {} func (*ApplicationSetTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{26} + return fileDescriptor_030104ce3b95bcac, []int{25} } func (m *ApplicationSetTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -800,7 +772,7 @@ var xxx_messageInfo_ApplicationSetTemplate proto.InternalMessageInfo func (m *ApplicationSetTemplateMeta) Reset() { *m = ApplicationSetTemplateMeta{} } func (*ApplicationSetTemplateMeta) ProtoMessage() {} func (*ApplicationSetTemplateMeta) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{27} + return fileDescriptor_030104ce3b95bcac, []int{26} } func (m *ApplicationSetTemplateMeta) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -828,7 +800,7 @@ var xxx_messageInfo_ApplicationSetTemplateMeta proto.InternalMessageInfo func (m *ApplicationSetTerminalGenerator) Reset() { *m = ApplicationSetTerminalGenerator{} } func (*ApplicationSetTerminalGenerator) ProtoMessage() {} func (*ApplicationSetTerminalGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{28} + return fileDescriptor_030104ce3b95bcac, []int{27} } func (m *ApplicationSetTerminalGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -856,7 +828,7 @@ var xxx_messageInfo_ApplicationSetTerminalGenerator proto.InternalMessageInfo func (m *ApplicationSetTree) Reset() { *m = ApplicationSetTree{} } func (*ApplicationSetTree) ProtoMessage() {} func (*ApplicationSetTree) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{29} + return fileDescriptor_030104ce3b95bcac, []int{28} } func (m *ApplicationSetTree) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -884,7 +856,7 @@ var xxx_messageInfo_ApplicationSetTree proto.InternalMessageInfo func (m *ApplicationSource) Reset() { *m = ApplicationSource{} } func (*ApplicationSource) ProtoMessage() {} func (*ApplicationSource) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{30} + return fileDescriptor_030104ce3b95bcac, []int{29} } func (m *ApplicationSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -912,7 +884,7 @@ var xxx_messageInfo_ApplicationSource proto.InternalMessageInfo func (m *ApplicationSourceDirectory) Reset() { *m = ApplicationSourceDirectory{} } func (*ApplicationSourceDirectory) ProtoMessage() {} func (*ApplicationSourceDirectory) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{31} + return fileDescriptor_030104ce3b95bcac, []int{30} } func (m *ApplicationSourceDirectory) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -940,7 +912,7 @@ var xxx_messageInfo_ApplicationSourceDirectory proto.InternalMessageInfo func (m *ApplicationSourceHelm) Reset() { *m = ApplicationSourceHelm{} } func (*ApplicationSourceHelm) ProtoMessage() {} func (*ApplicationSourceHelm) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{32} + return fileDescriptor_030104ce3b95bcac, []int{31} } func (m *ApplicationSourceHelm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -968,7 +940,7 @@ var xxx_messageInfo_ApplicationSourceHelm proto.InternalMessageInfo func (m *ApplicationSourceJsonnet) Reset() { *m = ApplicationSourceJsonnet{} } func (*ApplicationSourceJsonnet) ProtoMessage() {} func (*ApplicationSourceJsonnet) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{33} + return fileDescriptor_030104ce3b95bcac, []int{32} } func (m *ApplicationSourceJsonnet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -996,7 +968,7 @@ var xxx_messageInfo_ApplicationSourceJsonnet proto.InternalMessageInfo func (m *ApplicationSourceKustomize) Reset() { *m = ApplicationSourceKustomize{} } func (*ApplicationSourceKustomize) ProtoMessage() {} func (*ApplicationSourceKustomize) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{34} + return fileDescriptor_030104ce3b95bcac, []int{33} } func (m *ApplicationSourceKustomize) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1024,7 +996,7 @@ var xxx_messageInfo_ApplicationSourceKustomize proto.InternalMessageInfo func (m *ApplicationSourcePlugin) Reset() { *m = ApplicationSourcePlugin{} } func (*ApplicationSourcePlugin) ProtoMessage() {} func (*ApplicationSourcePlugin) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{35} + return fileDescriptor_030104ce3b95bcac, []int{34} } func (m *ApplicationSourcePlugin) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1052,7 +1024,7 @@ var xxx_messageInfo_ApplicationSourcePlugin proto.InternalMessageInfo func (m *ApplicationSourcePluginParameter) Reset() { *m = ApplicationSourcePluginParameter{} } func (*ApplicationSourcePluginParameter) ProtoMessage() {} func (*ApplicationSourcePluginParameter) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{36} + return fileDescriptor_030104ce3b95bcac, []int{35} } func (m *ApplicationSourcePluginParameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1080,7 +1052,7 @@ var xxx_messageInfo_ApplicationSourcePluginParameter proto.InternalMessageInfo func (m *ApplicationSpec) Reset() { *m = ApplicationSpec{} } func (*ApplicationSpec) ProtoMessage() {} func (*ApplicationSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{37} + return fileDescriptor_030104ce3b95bcac, []int{36} } func (m *ApplicationSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1108,7 +1080,7 @@ var xxx_messageInfo_ApplicationSpec proto.InternalMessageInfo func (m *ApplicationStatus) Reset() { *m = ApplicationStatus{} } func (*ApplicationStatus) ProtoMessage() {} func (*ApplicationStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{38} + return fileDescriptor_030104ce3b95bcac, []int{37} } func (m *ApplicationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1136,7 +1108,7 @@ var xxx_messageInfo_ApplicationStatus proto.InternalMessageInfo func (m *ApplicationSummary) Reset() { *m = ApplicationSummary{} } func (*ApplicationSummary) ProtoMessage() {} func (*ApplicationSummary) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{39} + return fileDescriptor_030104ce3b95bcac, []int{38} } func (m *ApplicationSummary) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1164,7 +1136,7 @@ var xxx_messageInfo_ApplicationSummary proto.InternalMessageInfo func (m *ApplicationTree) Reset() { *m = ApplicationTree{} } func (*ApplicationTree) ProtoMessage() {} func (*ApplicationTree) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{40} + return fileDescriptor_030104ce3b95bcac, []int{39} } func (m *ApplicationTree) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1192,7 +1164,7 @@ var xxx_messageInfo_ApplicationTree proto.InternalMessageInfo func (m *ApplicationWatchEvent) Reset() { *m = ApplicationWatchEvent{} } func (*ApplicationWatchEvent) ProtoMessage() {} func (*ApplicationWatchEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{41} + return fileDescriptor_030104ce3b95bcac, []int{40} } func (m *ApplicationWatchEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1220,7 +1192,7 @@ var xxx_messageInfo_ApplicationWatchEvent proto.InternalMessageInfo func (m *Backoff) Reset() { *m = Backoff{} } func (*Backoff) ProtoMessage() {} func (*Backoff) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{42} + return fileDescriptor_030104ce3b95bcac, []int{41} } func (m *Backoff) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1248,7 +1220,7 @@ var xxx_messageInfo_Backoff proto.InternalMessageInfo func (m *BasicAuthBitbucketServer) Reset() { *m = BasicAuthBitbucketServer{} } func (*BasicAuthBitbucketServer) ProtoMessage() {} func (*BasicAuthBitbucketServer) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{43} + return fileDescriptor_030104ce3b95bcac, []int{42} } func (m *BasicAuthBitbucketServer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1276,7 +1248,7 @@ var xxx_messageInfo_BasicAuthBitbucketServer proto.InternalMessageInfo func (m *BearerTokenBitbucket) Reset() { *m = BearerTokenBitbucket{} } func (*BearerTokenBitbucket) ProtoMessage() {} func (*BearerTokenBitbucket) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{44} + return fileDescriptor_030104ce3b95bcac, []int{43} } func (m *BearerTokenBitbucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1304,7 +1276,7 @@ var xxx_messageInfo_BearerTokenBitbucket proto.InternalMessageInfo func (m *BearerTokenBitbucketCloud) Reset() { *m = BearerTokenBitbucketCloud{} } func (*BearerTokenBitbucketCloud) ProtoMessage() {} func (*BearerTokenBitbucketCloud) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{45} + return fileDescriptor_030104ce3b95bcac, []int{44} } func (m *BearerTokenBitbucketCloud) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1332,7 +1304,7 @@ var xxx_messageInfo_BearerTokenBitbucketCloud proto.InternalMessageInfo func (m *ChartDetails) Reset() { *m = ChartDetails{} } func (*ChartDetails) ProtoMessage() {} func (*ChartDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{46} + return fileDescriptor_030104ce3b95bcac, []int{45} } func (m *ChartDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1360,7 +1332,7 @@ var xxx_messageInfo_ChartDetails proto.InternalMessageInfo func (m *Cluster) Reset() { *m = Cluster{} } func (*Cluster) ProtoMessage() {} func (*Cluster) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{47} + return fileDescriptor_030104ce3b95bcac, []int{46} } func (m *Cluster) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1388,7 +1360,7 @@ var xxx_messageInfo_Cluster proto.InternalMessageInfo func (m *ClusterCacheInfo) Reset() { *m = ClusterCacheInfo{} } func (*ClusterCacheInfo) ProtoMessage() {} func (*ClusterCacheInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{48} + return fileDescriptor_030104ce3b95bcac, []int{47} } func (m *ClusterCacheInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1416,7 +1388,7 @@ var xxx_messageInfo_ClusterCacheInfo proto.InternalMessageInfo func (m *ClusterConfig) Reset() { *m = ClusterConfig{} } func (*ClusterConfig) ProtoMessage() {} func (*ClusterConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{49} + return fileDescriptor_030104ce3b95bcac, []int{48} } func (m *ClusterConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1444,7 +1416,7 @@ var xxx_messageInfo_ClusterConfig proto.InternalMessageInfo func (m *ClusterGenerator) Reset() { *m = ClusterGenerator{} } func (*ClusterGenerator) ProtoMessage() {} func (*ClusterGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{50} + return fileDescriptor_030104ce3b95bcac, []int{49} } func (m *ClusterGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1472,7 +1444,7 @@ var xxx_messageInfo_ClusterGenerator proto.InternalMessageInfo func (m *ClusterInfo) Reset() { *m = ClusterInfo{} } func (*ClusterInfo) ProtoMessage() {} func (*ClusterInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{51} + return fileDescriptor_030104ce3b95bcac, []int{50} } func (m *ClusterInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1500,7 +1472,7 @@ var xxx_messageInfo_ClusterInfo proto.InternalMessageInfo func (m *ClusterList) Reset() { *m = ClusterList{} } func (*ClusterList) ProtoMessage() {} func (*ClusterList) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{52} + return fileDescriptor_030104ce3b95bcac, []int{51} } func (m *ClusterList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1528,7 +1500,7 @@ var xxx_messageInfo_ClusterList proto.InternalMessageInfo func (m *Command) Reset() { *m = Command{} } func (*Command) ProtoMessage() {} func (*Command) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{53} + return fileDescriptor_030104ce3b95bcac, []int{52} } func (m *Command) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1556,7 +1528,7 @@ var xxx_messageInfo_Command proto.InternalMessageInfo func (m *ComparedTo) Reset() { *m = ComparedTo{} } func (*ComparedTo) ProtoMessage() {} func (*ComparedTo) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{54} + return fileDescriptor_030104ce3b95bcac, []int{53} } func (m *ComparedTo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1584,7 +1556,7 @@ var xxx_messageInfo_ComparedTo proto.InternalMessageInfo func (m *ComponentParameter) Reset() { *m = ComponentParameter{} } func (*ComponentParameter) ProtoMessage() {} func (*ComponentParameter) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{55} + return fileDescriptor_030104ce3b95bcac, []int{54} } func (m *ComponentParameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1612,7 +1584,7 @@ var xxx_messageInfo_ComponentParameter proto.InternalMessageInfo func (m *ConfigManagementPlugin) Reset() { *m = ConfigManagementPlugin{} } func (*ConfigManagementPlugin) ProtoMessage() {} func (*ConfigManagementPlugin) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{56} + return fileDescriptor_030104ce3b95bcac, []int{55} } func (m *ConfigManagementPlugin) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1640,7 +1612,7 @@ var xxx_messageInfo_ConfigManagementPlugin proto.InternalMessageInfo func (m *ConfigMapKeyRef) Reset() { *m = ConfigMapKeyRef{} } func (*ConfigMapKeyRef) ProtoMessage() {} func (*ConfigMapKeyRef) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{57} + return fileDescriptor_030104ce3b95bcac, []int{56} } func (m *ConfigMapKeyRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1668,7 +1640,7 @@ var xxx_messageInfo_ConfigMapKeyRef proto.InternalMessageInfo func (m *ConnectionState) Reset() { *m = ConnectionState{} } func (*ConnectionState) ProtoMessage() {} func (*ConnectionState) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{58} + return fileDescriptor_030104ce3b95bcac, []int{57} } func (m *ConnectionState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1696,7 +1668,7 @@ var xxx_messageInfo_ConnectionState proto.InternalMessageInfo func (m *DrySource) Reset() { *m = DrySource{} } func (*DrySource) ProtoMessage() {} func (*DrySource) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{59} + return fileDescriptor_030104ce3b95bcac, []int{58} } func (m *DrySource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1724,7 +1696,7 @@ var xxx_messageInfo_DrySource proto.InternalMessageInfo func (m *DuckTypeGenerator) Reset() { *m = DuckTypeGenerator{} } func (*DuckTypeGenerator) ProtoMessage() {} func (*DuckTypeGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{60} + return fileDescriptor_030104ce3b95bcac, []int{59} } func (m *DuckTypeGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1752,7 +1724,7 @@ var xxx_messageInfo_DuckTypeGenerator proto.InternalMessageInfo func (m *EnvEntry) Reset() { *m = EnvEntry{} } func (*EnvEntry) ProtoMessage() {} func (*EnvEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{61} + return fileDescriptor_030104ce3b95bcac, []int{60} } func (m *EnvEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1780,7 +1752,7 @@ var xxx_messageInfo_EnvEntry proto.InternalMessageInfo func (m *ErrApplicationNotAllowedToUseProject) Reset() { *m = ErrApplicationNotAllowedToUseProject{} } func (*ErrApplicationNotAllowedToUseProject) ProtoMessage() {} func (*ErrApplicationNotAllowedToUseProject) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{62} + return fileDescriptor_030104ce3b95bcac, []int{61} } func (m *ErrApplicationNotAllowedToUseProject) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1808,7 +1780,7 @@ var xxx_messageInfo_ErrApplicationNotAllowedToUseProject proto.InternalMessageIn func (m *ExecProviderConfig) Reset() { *m = ExecProviderConfig{} } func (*ExecProviderConfig) ProtoMessage() {} func (*ExecProviderConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{63} + return fileDescriptor_030104ce3b95bcac, []int{62} } func (m *ExecProviderConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1836,7 +1808,7 @@ var xxx_messageInfo_ExecProviderConfig proto.InternalMessageInfo func (m *GitDirectoryGeneratorItem) Reset() { *m = GitDirectoryGeneratorItem{} } func (*GitDirectoryGeneratorItem) ProtoMessage() {} func (*GitDirectoryGeneratorItem) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{64} + return fileDescriptor_030104ce3b95bcac, []int{63} } func (m *GitDirectoryGeneratorItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1864,7 +1836,7 @@ var xxx_messageInfo_GitDirectoryGeneratorItem proto.InternalMessageInfo func (m *GitFileGeneratorItem) Reset() { *m = GitFileGeneratorItem{} } func (*GitFileGeneratorItem) ProtoMessage() {} func (*GitFileGeneratorItem) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{65} + return fileDescriptor_030104ce3b95bcac, []int{64} } func (m *GitFileGeneratorItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1892,7 +1864,7 @@ var xxx_messageInfo_GitFileGeneratorItem proto.InternalMessageInfo func (m *GitGenerator) Reset() { *m = GitGenerator{} } func (*GitGenerator) ProtoMessage() {} func (*GitGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{66} + return fileDescriptor_030104ce3b95bcac, []int{65} } func (m *GitGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1920,7 +1892,7 @@ var xxx_messageInfo_GitGenerator proto.InternalMessageInfo func (m *GnuPGPublicKey) Reset() { *m = GnuPGPublicKey{} } func (*GnuPGPublicKey) ProtoMessage() {} func (*GnuPGPublicKey) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{67} + return fileDescriptor_030104ce3b95bcac, []int{66} } func (m *GnuPGPublicKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1948,7 +1920,7 @@ var xxx_messageInfo_GnuPGPublicKey proto.InternalMessageInfo func (m *GnuPGPublicKeyList) Reset() { *m = GnuPGPublicKeyList{} } func (*GnuPGPublicKeyList) ProtoMessage() {} func (*GnuPGPublicKeyList) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{68} + return fileDescriptor_030104ce3b95bcac, []int{67} } func (m *GnuPGPublicKeyList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1976,7 +1948,7 @@ var xxx_messageInfo_GnuPGPublicKeyList proto.InternalMessageInfo func (m *HealthStatus) Reset() { *m = HealthStatus{} } func (*HealthStatus) ProtoMessage() {} func (*HealthStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{69} + return fileDescriptor_030104ce3b95bcac, []int{68} } func (m *HealthStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2004,7 +1976,7 @@ var xxx_messageInfo_HealthStatus proto.InternalMessageInfo func (m *HelmFileParameter) Reset() { *m = HelmFileParameter{} } func (*HelmFileParameter) ProtoMessage() {} func (*HelmFileParameter) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{70} + return fileDescriptor_030104ce3b95bcac, []int{69} } func (m *HelmFileParameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2032,7 +2004,7 @@ var xxx_messageInfo_HelmFileParameter proto.InternalMessageInfo func (m *HelmOptions) Reset() { *m = HelmOptions{} } func (*HelmOptions) ProtoMessage() {} func (*HelmOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{71} + return fileDescriptor_030104ce3b95bcac, []int{70} } func (m *HelmOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2060,7 +2032,7 @@ var xxx_messageInfo_HelmOptions proto.InternalMessageInfo func (m *HelmParameter) Reset() { *m = HelmParameter{} } func (*HelmParameter) ProtoMessage() {} func (*HelmParameter) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{72} + return fileDescriptor_030104ce3b95bcac, []int{71} } func (m *HelmParameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2088,7 +2060,7 @@ var xxx_messageInfo_HelmParameter proto.InternalMessageInfo func (m *HostInfo) Reset() { *m = HostInfo{} } func (*HostInfo) ProtoMessage() {} func (*HostInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{73} + return fileDescriptor_030104ce3b95bcac, []int{72} } func (m *HostInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2116,7 +2088,7 @@ var xxx_messageInfo_HostInfo proto.InternalMessageInfo func (m *HostResourceInfo) Reset() { *m = HostResourceInfo{} } func (*HostResourceInfo) ProtoMessage() {} func (*HostResourceInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{74} + return fileDescriptor_030104ce3b95bcac, []int{73} } func (m *HostResourceInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2144,7 +2116,7 @@ var xxx_messageInfo_HostResourceInfo proto.InternalMessageInfo func (m *HydrateOperation) Reset() { *m = HydrateOperation{} } func (*HydrateOperation) ProtoMessage() {} func (*HydrateOperation) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{75} + return fileDescriptor_030104ce3b95bcac, []int{74} } func (m *HydrateOperation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2172,7 +2144,7 @@ var xxx_messageInfo_HydrateOperation proto.InternalMessageInfo func (m *HydrateTo) Reset() { *m = HydrateTo{} } func (*HydrateTo) ProtoMessage() {} func (*HydrateTo) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{76} + return fileDescriptor_030104ce3b95bcac, []int{75} } func (m *HydrateTo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2200,7 +2172,7 @@ var xxx_messageInfo_HydrateTo proto.InternalMessageInfo func (m *Info) Reset() { *m = Info{} } func (*Info) ProtoMessage() {} func (*Info) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{77} + return fileDescriptor_030104ce3b95bcac, []int{76} } func (m *Info) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2228,7 +2200,7 @@ var xxx_messageInfo_Info proto.InternalMessageInfo func (m *InfoItem) Reset() { *m = InfoItem{} } func (*InfoItem) ProtoMessage() {} func (*InfoItem) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{78} + return fileDescriptor_030104ce3b95bcac, []int{77} } func (m *InfoItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2256,7 +2228,7 @@ var xxx_messageInfo_InfoItem proto.InternalMessageInfo func (m *JWTToken) Reset() { *m = JWTToken{} } func (*JWTToken) ProtoMessage() {} func (*JWTToken) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{79} + return fileDescriptor_030104ce3b95bcac, []int{78} } func (m *JWTToken) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2284,7 +2256,7 @@ var xxx_messageInfo_JWTToken proto.InternalMessageInfo func (m *JWTTokens) Reset() { *m = JWTTokens{} } func (*JWTTokens) ProtoMessage() {} func (*JWTTokens) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{80} + return fileDescriptor_030104ce3b95bcac, []int{79} } func (m *JWTTokens) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2312,7 +2284,7 @@ var xxx_messageInfo_JWTTokens proto.InternalMessageInfo func (m *JsonnetVar) Reset() { *m = JsonnetVar{} } func (*JsonnetVar) ProtoMessage() {} func (*JsonnetVar) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{81} + return fileDescriptor_030104ce3b95bcac, []int{80} } func (m *JsonnetVar) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2340,7 +2312,7 @@ var xxx_messageInfo_JsonnetVar proto.InternalMessageInfo func (m *KnownTypeField) Reset() { *m = KnownTypeField{} } func (*KnownTypeField) ProtoMessage() {} func (*KnownTypeField) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{82} + return fileDescriptor_030104ce3b95bcac, []int{81} } func (m *KnownTypeField) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2368,7 +2340,7 @@ var xxx_messageInfo_KnownTypeField proto.InternalMessageInfo func (m *KustomizeGvk) Reset() { *m = KustomizeGvk{} } func (*KustomizeGvk) ProtoMessage() {} func (*KustomizeGvk) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{83} + return fileDescriptor_030104ce3b95bcac, []int{82} } func (m *KustomizeGvk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2396,7 +2368,7 @@ var xxx_messageInfo_KustomizeGvk proto.InternalMessageInfo func (m *KustomizeOptions) Reset() { *m = KustomizeOptions{} } func (*KustomizeOptions) ProtoMessage() {} func (*KustomizeOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{84} + return fileDescriptor_030104ce3b95bcac, []int{83} } func (m *KustomizeOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2424,7 +2396,7 @@ var xxx_messageInfo_KustomizeOptions proto.InternalMessageInfo func (m *KustomizePatch) Reset() { *m = KustomizePatch{} } func (*KustomizePatch) ProtoMessage() {} func (*KustomizePatch) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{85} + return fileDescriptor_030104ce3b95bcac, []int{84} } func (m *KustomizePatch) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2452,7 +2424,7 @@ var xxx_messageInfo_KustomizePatch proto.InternalMessageInfo func (m *KustomizeReplica) Reset() { *m = KustomizeReplica{} } func (*KustomizeReplica) ProtoMessage() {} func (*KustomizeReplica) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{86} + return fileDescriptor_030104ce3b95bcac, []int{85} } func (m *KustomizeReplica) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2480,7 +2452,7 @@ var xxx_messageInfo_KustomizeReplica proto.InternalMessageInfo func (m *KustomizeResId) Reset() { *m = KustomizeResId{} } func (*KustomizeResId) ProtoMessage() {} func (*KustomizeResId) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{87} + return fileDescriptor_030104ce3b95bcac, []int{86} } func (m *KustomizeResId) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2508,7 +2480,7 @@ var xxx_messageInfo_KustomizeResId proto.InternalMessageInfo func (m *KustomizeSelector) Reset() { *m = KustomizeSelector{} } func (*KustomizeSelector) ProtoMessage() {} func (*KustomizeSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{88} + return fileDescriptor_030104ce3b95bcac, []int{87} } func (m *KustomizeSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2536,7 +2508,7 @@ var xxx_messageInfo_KustomizeSelector proto.InternalMessageInfo func (m *ListGenerator) Reset() { *m = ListGenerator{} } func (*ListGenerator) ProtoMessage() {} func (*ListGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{89} + return fileDescriptor_030104ce3b95bcac, []int{88} } func (m *ListGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2564,7 +2536,7 @@ var xxx_messageInfo_ListGenerator proto.InternalMessageInfo func (m *ManagedNamespaceMetadata) Reset() { *m = ManagedNamespaceMetadata{} } func (*ManagedNamespaceMetadata) ProtoMessage() {} func (*ManagedNamespaceMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{90} + return fileDescriptor_030104ce3b95bcac, []int{89} } func (m *ManagedNamespaceMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2592,7 +2564,7 @@ var xxx_messageInfo_ManagedNamespaceMetadata proto.InternalMessageInfo func (m *MatrixGenerator) Reset() { *m = MatrixGenerator{} } func (*MatrixGenerator) ProtoMessage() {} func (*MatrixGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{91} + return fileDescriptor_030104ce3b95bcac, []int{90} } func (m *MatrixGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2620,7 +2592,7 @@ var xxx_messageInfo_MatrixGenerator proto.InternalMessageInfo func (m *MergeGenerator) Reset() { *m = MergeGenerator{} } func (*MergeGenerator) ProtoMessage() {} func (*MergeGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{92} + return fileDescriptor_030104ce3b95bcac, []int{91} } func (m *MergeGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2648,7 +2620,7 @@ var xxx_messageInfo_MergeGenerator proto.InternalMessageInfo func (m *NestedMatrixGenerator) Reset() { *m = NestedMatrixGenerator{} } func (*NestedMatrixGenerator) ProtoMessage() {} func (*NestedMatrixGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{93} + return fileDescriptor_030104ce3b95bcac, []int{92} } func (m *NestedMatrixGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2676,7 +2648,7 @@ var xxx_messageInfo_NestedMatrixGenerator proto.InternalMessageInfo func (m *NestedMergeGenerator) Reset() { *m = NestedMergeGenerator{} } func (*NestedMergeGenerator) ProtoMessage() {} func (*NestedMergeGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{94} + return fileDescriptor_030104ce3b95bcac, []int{93} } func (m *NestedMergeGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2704,7 +2676,7 @@ var xxx_messageInfo_NestedMergeGenerator proto.InternalMessageInfo func (m *Operation) Reset() { *m = Operation{} } func (*Operation) ProtoMessage() {} func (*Operation) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{95} + return fileDescriptor_030104ce3b95bcac, []int{94} } func (m *Operation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2732,7 +2704,7 @@ var xxx_messageInfo_Operation proto.InternalMessageInfo func (m *OperationInitiator) Reset() { *m = OperationInitiator{} } func (*OperationInitiator) ProtoMessage() {} func (*OperationInitiator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{96} + return fileDescriptor_030104ce3b95bcac, []int{95} } func (m *OperationInitiator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2760,7 +2732,7 @@ var xxx_messageInfo_OperationInitiator proto.InternalMessageInfo func (m *OperationState) Reset() { *m = OperationState{} } func (*OperationState) ProtoMessage() {} func (*OperationState) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{97} + return fileDescriptor_030104ce3b95bcac, []int{96} } func (m *OperationState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2788,7 +2760,7 @@ var xxx_messageInfo_OperationState proto.InternalMessageInfo func (m *OptionalArray) Reset() { *m = OptionalArray{} } func (*OptionalArray) ProtoMessage() {} func (*OptionalArray) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{98} + return fileDescriptor_030104ce3b95bcac, []int{97} } func (m *OptionalArray) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2816,7 +2788,7 @@ var xxx_messageInfo_OptionalArray proto.InternalMessageInfo func (m *OptionalMap) Reset() { *m = OptionalMap{} } func (*OptionalMap) ProtoMessage() {} func (*OptionalMap) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{99} + return fileDescriptor_030104ce3b95bcac, []int{98} } func (m *OptionalMap) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2844,7 +2816,7 @@ var xxx_messageInfo_OptionalMap proto.InternalMessageInfo func (m *OrphanedResourceKey) Reset() { *m = OrphanedResourceKey{} } func (*OrphanedResourceKey) ProtoMessage() {} func (*OrphanedResourceKey) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{100} + return fileDescriptor_030104ce3b95bcac, []int{99} } func (m *OrphanedResourceKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2872,7 +2844,7 @@ var xxx_messageInfo_OrphanedResourceKey proto.InternalMessageInfo func (m *OrphanedResourcesMonitorSettings) Reset() { *m = OrphanedResourcesMonitorSettings{} } func (*OrphanedResourcesMonitorSettings) ProtoMessage() {} func (*OrphanedResourcesMonitorSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{101} + return fileDescriptor_030104ce3b95bcac, []int{100} } func (m *OrphanedResourcesMonitorSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2900,7 +2872,7 @@ var xxx_messageInfo_OrphanedResourcesMonitorSettings proto.InternalMessageInfo func (m *OverrideIgnoreDiff) Reset() { *m = OverrideIgnoreDiff{} } func (*OverrideIgnoreDiff) ProtoMessage() {} func (*OverrideIgnoreDiff) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{102} + return fileDescriptor_030104ce3b95bcac, []int{101} } func (m *OverrideIgnoreDiff) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2928,7 +2900,7 @@ var xxx_messageInfo_OverrideIgnoreDiff proto.InternalMessageInfo func (m *PluginConfigMapRef) Reset() { *m = PluginConfigMapRef{} } func (*PluginConfigMapRef) ProtoMessage() {} func (*PluginConfigMapRef) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{103} + return fileDescriptor_030104ce3b95bcac, []int{102} } func (m *PluginConfigMapRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2956,7 +2928,7 @@ var xxx_messageInfo_PluginConfigMapRef proto.InternalMessageInfo func (m *PluginGenerator) Reset() { *m = PluginGenerator{} } func (*PluginGenerator) ProtoMessage() {} func (*PluginGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{104} + return fileDescriptor_030104ce3b95bcac, []int{103} } func (m *PluginGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2984,7 +2956,7 @@ var xxx_messageInfo_PluginGenerator proto.InternalMessageInfo func (m *PluginInput) Reset() { *m = PluginInput{} } func (*PluginInput) ProtoMessage() {} func (*PluginInput) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{105} + return fileDescriptor_030104ce3b95bcac, []int{104} } func (m *PluginInput) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3012,7 +2984,7 @@ var xxx_messageInfo_PluginInput proto.InternalMessageInfo func (m *ProjectRole) Reset() { *m = ProjectRole{} } func (*ProjectRole) ProtoMessage() {} func (*ProjectRole) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{106} + return fileDescriptor_030104ce3b95bcac, []int{105} } func (m *ProjectRole) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3040,7 +3012,7 @@ var xxx_messageInfo_ProjectRole proto.InternalMessageInfo func (m *PullRequestGenerator) Reset() { *m = PullRequestGenerator{} } func (*PullRequestGenerator) ProtoMessage() {} func (*PullRequestGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{107} + return fileDescriptor_030104ce3b95bcac, []int{106} } func (m *PullRequestGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3068,7 +3040,7 @@ var xxx_messageInfo_PullRequestGenerator proto.InternalMessageInfo func (m *PullRequestGeneratorAzureDevOps) Reset() { *m = PullRequestGeneratorAzureDevOps{} } func (*PullRequestGeneratorAzureDevOps) ProtoMessage() {} func (*PullRequestGeneratorAzureDevOps) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{108} + return fileDescriptor_030104ce3b95bcac, []int{107} } func (m *PullRequestGeneratorAzureDevOps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3096,7 +3068,7 @@ var xxx_messageInfo_PullRequestGeneratorAzureDevOps proto.InternalMessageInfo func (m *PullRequestGeneratorBitbucket) Reset() { *m = PullRequestGeneratorBitbucket{} } func (*PullRequestGeneratorBitbucket) ProtoMessage() {} func (*PullRequestGeneratorBitbucket) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{109} + return fileDescriptor_030104ce3b95bcac, []int{108} } func (m *PullRequestGeneratorBitbucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3124,7 +3096,7 @@ var xxx_messageInfo_PullRequestGeneratorBitbucket proto.InternalMessageInfo func (m *PullRequestGeneratorBitbucketServer) Reset() { *m = PullRequestGeneratorBitbucketServer{} } func (*PullRequestGeneratorBitbucketServer) ProtoMessage() {} func (*PullRequestGeneratorBitbucketServer) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{110} + return fileDescriptor_030104ce3b95bcac, []int{109} } func (m *PullRequestGeneratorBitbucketServer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3152,7 +3124,7 @@ var xxx_messageInfo_PullRequestGeneratorBitbucketServer proto.InternalMessageInf func (m *PullRequestGeneratorFilter) Reset() { *m = PullRequestGeneratorFilter{} } func (*PullRequestGeneratorFilter) ProtoMessage() {} func (*PullRequestGeneratorFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{111} + return fileDescriptor_030104ce3b95bcac, []int{110} } func (m *PullRequestGeneratorFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3180,7 +3152,7 @@ var xxx_messageInfo_PullRequestGeneratorFilter proto.InternalMessageInfo func (m *PullRequestGeneratorGitLab) Reset() { *m = PullRequestGeneratorGitLab{} } func (*PullRequestGeneratorGitLab) ProtoMessage() {} func (*PullRequestGeneratorGitLab) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{112} + return fileDescriptor_030104ce3b95bcac, []int{111} } func (m *PullRequestGeneratorGitLab) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3208,7 +3180,7 @@ var xxx_messageInfo_PullRequestGeneratorGitLab proto.InternalMessageInfo func (m *PullRequestGeneratorGitea) Reset() { *m = PullRequestGeneratorGitea{} } func (*PullRequestGeneratorGitea) ProtoMessage() {} func (*PullRequestGeneratorGitea) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{113} + return fileDescriptor_030104ce3b95bcac, []int{112} } func (m *PullRequestGeneratorGitea) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3236,7 +3208,7 @@ var xxx_messageInfo_PullRequestGeneratorGitea proto.InternalMessageInfo func (m *PullRequestGeneratorGithub) Reset() { *m = PullRequestGeneratorGithub{} } func (*PullRequestGeneratorGithub) ProtoMessage() {} func (*PullRequestGeneratorGithub) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{114} + return fileDescriptor_030104ce3b95bcac, []int{113} } func (m *PullRequestGeneratorGithub) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3264,7 +3236,7 @@ var xxx_messageInfo_PullRequestGeneratorGithub proto.InternalMessageInfo func (m *RefTarget) Reset() { *m = RefTarget{} } func (*RefTarget) ProtoMessage() {} func (*RefTarget) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{115} + return fileDescriptor_030104ce3b95bcac, []int{114} } func (m *RefTarget) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3292,7 +3264,7 @@ var xxx_messageInfo_RefTarget proto.InternalMessageInfo func (m *RepoCreds) Reset() { *m = RepoCreds{} } func (*RepoCreds) ProtoMessage() {} func (*RepoCreds) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{116} + return fileDescriptor_030104ce3b95bcac, []int{115} } func (m *RepoCreds) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3320,7 +3292,7 @@ var xxx_messageInfo_RepoCreds proto.InternalMessageInfo func (m *RepoCredsList) Reset() { *m = RepoCredsList{} } func (*RepoCredsList) ProtoMessage() {} func (*RepoCredsList) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{117} + return fileDescriptor_030104ce3b95bcac, []int{116} } func (m *RepoCredsList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3348,7 +3320,7 @@ var xxx_messageInfo_RepoCredsList proto.InternalMessageInfo func (m *Repository) Reset() { *m = Repository{} } func (*Repository) ProtoMessage() {} func (*Repository) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{118} + return fileDescriptor_030104ce3b95bcac, []int{117} } func (m *Repository) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3376,7 +3348,7 @@ var xxx_messageInfo_Repository proto.InternalMessageInfo func (m *RepositoryCertificate) Reset() { *m = RepositoryCertificate{} } func (*RepositoryCertificate) ProtoMessage() {} func (*RepositoryCertificate) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{119} + return fileDescriptor_030104ce3b95bcac, []int{118} } func (m *RepositoryCertificate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3404,7 +3376,7 @@ var xxx_messageInfo_RepositoryCertificate proto.InternalMessageInfo func (m *RepositoryCertificateList) Reset() { *m = RepositoryCertificateList{} } func (*RepositoryCertificateList) ProtoMessage() {} func (*RepositoryCertificateList) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{120} + return fileDescriptor_030104ce3b95bcac, []int{119} } func (m *RepositoryCertificateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3432,7 +3404,7 @@ var xxx_messageInfo_RepositoryCertificateList proto.InternalMessageInfo func (m *RepositoryList) Reset() { *m = RepositoryList{} } func (*RepositoryList) ProtoMessage() {} func (*RepositoryList) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{121} + return fileDescriptor_030104ce3b95bcac, []int{120} } func (m *RepositoryList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3460,7 +3432,7 @@ var xxx_messageInfo_RepositoryList proto.InternalMessageInfo func (m *ResourceAction) Reset() { *m = ResourceAction{} } func (*ResourceAction) ProtoMessage() {} func (*ResourceAction) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{122} + return fileDescriptor_030104ce3b95bcac, []int{121} } func (m *ResourceAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3488,7 +3460,7 @@ var xxx_messageInfo_ResourceAction proto.InternalMessageInfo func (m *ResourceActionDefinition) Reset() { *m = ResourceActionDefinition{} } func (*ResourceActionDefinition) ProtoMessage() {} func (*ResourceActionDefinition) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{123} + return fileDescriptor_030104ce3b95bcac, []int{122} } func (m *ResourceActionDefinition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3516,7 +3488,7 @@ var xxx_messageInfo_ResourceActionDefinition proto.InternalMessageInfo func (m *ResourceActionParam) Reset() { *m = ResourceActionParam{} } func (*ResourceActionParam) ProtoMessage() {} func (*ResourceActionParam) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{124} + return fileDescriptor_030104ce3b95bcac, []int{123} } func (m *ResourceActionParam) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3544,7 +3516,7 @@ var xxx_messageInfo_ResourceActionParam proto.InternalMessageInfo func (m *ResourceActions) Reset() { *m = ResourceActions{} } func (*ResourceActions) ProtoMessage() {} func (*ResourceActions) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{125} + return fileDescriptor_030104ce3b95bcac, []int{124} } func (m *ResourceActions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3572,7 +3544,7 @@ var xxx_messageInfo_ResourceActions proto.InternalMessageInfo func (m *ResourceDiff) Reset() { *m = ResourceDiff{} } func (*ResourceDiff) ProtoMessage() {} func (*ResourceDiff) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{126} + return fileDescriptor_030104ce3b95bcac, []int{125} } func (m *ResourceDiff) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3600,7 +3572,7 @@ var xxx_messageInfo_ResourceDiff proto.InternalMessageInfo func (m *ResourceIgnoreDifferences) Reset() { *m = ResourceIgnoreDifferences{} } func (*ResourceIgnoreDifferences) ProtoMessage() {} func (*ResourceIgnoreDifferences) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{127} + return fileDescriptor_030104ce3b95bcac, []int{126} } func (m *ResourceIgnoreDifferences) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3628,7 +3600,7 @@ var xxx_messageInfo_ResourceIgnoreDifferences proto.InternalMessageInfo func (m *ResourceNetworkingInfo) Reset() { *m = ResourceNetworkingInfo{} } func (*ResourceNetworkingInfo) ProtoMessage() {} func (*ResourceNetworkingInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{128} + return fileDescriptor_030104ce3b95bcac, []int{127} } func (m *ResourceNetworkingInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3656,7 +3628,7 @@ var xxx_messageInfo_ResourceNetworkingInfo proto.InternalMessageInfo func (m *ResourceNode) Reset() { *m = ResourceNode{} } func (*ResourceNode) ProtoMessage() {} func (*ResourceNode) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{129} + return fileDescriptor_030104ce3b95bcac, []int{128} } func (m *ResourceNode) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3684,7 +3656,7 @@ var xxx_messageInfo_ResourceNode proto.InternalMessageInfo func (m *ResourceOverride) Reset() { *m = ResourceOverride{} } func (*ResourceOverride) ProtoMessage() {} func (*ResourceOverride) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{130} + return fileDescriptor_030104ce3b95bcac, []int{129} } func (m *ResourceOverride) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3712,7 +3684,7 @@ var xxx_messageInfo_ResourceOverride proto.InternalMessageInfo func (m *ResourceRef) Reset() { *m = ResourceRef{} } func (*ResourceRef) ProtoMessage() {} func (*ResourceRef) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{131} + return fileDescriptor_030104ce3b95bcac, []int{130} } func (m *ResourceRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3740,7 +3712,7 @@ var xxx_messageInfo_ResourceRef proto.InternalMessageInfo func (m *ResourceResult) Reset() { *m = ResourceResult{} } func (*ResourceResult) ProtoMessage() {} func (*ResourceResult) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{132} + return fileDescriptor_030104ce3b95bcac, []int{131} } func (m *ResourceResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3768,7 +3740,7 @@ var xxx_messageInfo_ResourceResult proto.InternalMessageInfo func (m *ResourceStatus) Reset() { *m = ResourceStatus{} } func (*ResourceStatus) ProtoMessage() {} func (*ResourceStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{133} + return fileDescriptor_030104ce3b95bcac, []int{132} } func (m *ResourceStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3796,7 +3768,7 @@ var xxx_messageInfo_ResourceStatus proto.InternalMessageInfo func (m *RetryStrategy) Reset() { *m = RetryStrategy{} } func (*RetryStrategy) ProtoMessage() {} func (*RetryStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{134} + return fileDescriptor_030104ce3b95bcac, []int{133} } func (m *RetryStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3824,7 +3796,7 @@ var xxx_messageInfo_RetryStrategy proto.InternalMessageInfo func (m *RevisionHistory) Reset() { *m = RevisionHistory{} } func (*RevisionHistory) ProtoMessage() {} func (*RevisionHistory) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{135} + return fileDescriptor_030104ce3b95bcac, []int{134} } func (m *RevisionHistory) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3852,7 +3824,7 @@ var xxx_messageInfo_RevisionHistory proto.InternalMessageInfo func (m *RevisionMetadata) Reset() { *m = RevisionMetadata{} } func (*RevisionMetadata) ProtoMessage() {} func (*RevisionMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{136} + return fileDescriptor_030104ce3b95bcac, []int{135} } func (m *RevisionMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3880,7 +3852,7 @@ var xxx_messageInfo_RevisionMetadata proto.InternalMessageInfo func (m *SCMProviderGenerator) Reset() { *m = SCMProviderGenerator{} } func (*SCMProviderGenerator) ProtoMessage() {} func (*SCMProviderGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{137} + return fileDescriptor_030104ce3b95bcac, []int{136} } func (m *SCMProviderGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3908,7 +3880,7 @@ var xxx_messageInfo_SCMProviderGenerator proto.InternalMessageInfo func (m *SCMProviderGeneratorAWSCodeCommit) Reset() { *m = SCMProviderGeneratorAWSCodeCommit{} } func (*SCMProviderGeneratorAWSCodeCommit) ProtoMessage() {} func (*SCMProviderGeneratorAWSCodeCommit) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{138} + return fileDescriptor_030104ce3b95bcac, []int{137} } func (m *SCMProviderGeneratorAWSCodeCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3936,7 +3908,7 @@ var xxx_messageInfo_SCMProviderGeneratorAWSCodeCommit proto.InternalMessageInfo func (m *SCMProviderGeneratorAzureDevOps) Reset() { *m = SCMProviderGeneratorAzureDevOps{} } func (*SCMProviderGeneratorAzureDevOps) ProtoMessage() {} func (*SCMProviderGeneratorAzureDevOps) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{139} + return fileDescriptor_030104ce3b95bcac, []int{138} } func (m *SCMProviderGeneratorAzureDevOps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3964,7 +3936,7 @@ var xxx_messageInfo_SCMProviderGeneratorAzureDevOps proto.InternalMessageInfo func (m *SCMProviderGeneratorBitbucket) Reset() { *m = SCMProviderGeneratorBitbucket{} } func (*SCMProviderGeneratorBitbucket) ProtoMessage() {} func (*SCMProviderGeneratorBitbucket) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{140} + return fileDescriptor_030104ce3b95bcac, []int{139} } func (m *SCMProviderGeneratorBitbucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3992,7 +3964,7 @@ var xxx_messageInfo_SCMProviderGeneratorBitbucket proto.InternalMessageInfo func (m *SCMProviderGeneratorBitbucketServer) Reset() { *m = SCMProviderGeneratorBitbucketServer{} } func (*SCMProviderGeneratorBitbucketServer) ProtoMessage() {} func (*SCMProviderGeneratorBitbucketServer) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{141} + return fileDescriptor_030104ce3b95bcac, []int{140} } func (m *SCMProviderGeneratorBitbucketServer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4020,7 +3992,7 @@ var xxx_messageInfo_SCMProviderGeneratorBitbucketServer proto.InternalMessageInf func (m *SCMProviderGeneratorFilter) Reset() { *m = SCMProviderGeneratorFilter{} } func (*SCMProviderGeneratorFilter) ProtoMessage() {} func (*SCMProviderGeneratorFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{142} + return fileDescriptor_030104ce3b95bcac, []int{141} } func (m *SCMProviderGeneratorFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4048,7 +4020,7 @@ var xxx_messageInfo_SCMProviderGeneratorFilter proto.InternalMessageInfo func (m *SCMProviderGeneratorGitea) Reset() { *m = SCMProviderGeneratorGitea{} } func (*SCMProviderGeneratorGitea) ProtoMessage() {} func (*SCMProviderGeneratorGitea) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{143} + return fileDescriptor_030104ce3b95bcac, []int{142} } func (m *SCMProviderGeneratorGitea) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4076,7 +4048,7 @@ var xxx_messageInfo_SCMProviderGeneratorGitea proto.InternalMessageInfo func (m *SCMProviderGeneratorGithub) Reset() { *m = SCMProviderGeneratorGithub{} } func (*SCMProviderGeneratorGithub) ProtoMessage() {} func (*SCMProviderGeneratorGithub) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{144} + return fileDescriptor_030104ce3b95bcac, []int{143} } func (m *SCMProviderGeneratorGithub) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4104,7 +4076,7 @@ var xxx_messageInfo_SCMProviderGeneratorGithub proto.InternalMessageInfo func (m *SCMProviderGeneratorGitlab) Reset() { *m = SCMProviderGeneratorGitlab{} } func (*SCMProviderGeneratorGitlab) ProtoMessage() {} func (*SCMProviderGeneratorGitlab) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{145} + return fileDescriptor_030104ce3b95bcac, []int{144} } func (m *SCMProviderGeneratorGitlab) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4132,7 +4104,7 @@ var xxx_messageInfo_SCMProviderGeneratorGitlab proto.InternalMessageInfo func (m *SecretRef) Reset() { *m = SecretRef{} } func (*SecretRef) ProtoMessage() {} func (*SecretRef) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{146} + return fileDescriptor_030104ce3b95bcac, []int{145} } func (m *SecretRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4160,7 +4132,7 @@ var xxx_messageInfo_SecretRef proto.InternalMessageInfo func (m *SignatureKey) Reset() { *m = SignatureKey{} } func (*SignatureKey) ProtoMessage() {} func (*SignatureKey) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{147} + return fileDescriptor_030104ce3b95bcac, []int{146} } func (m *SignatureKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4188,7 +4160,7 @@ var xxx_messageInfo_SignatureKey proto.InternalMessageInfo func (m *SourceHydrator) Reset() { *m = SourceHydrator{} } func (*SourceHydrator) ProtoMessage() {} func (*SourceHydrator) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{148} + return fileDescriptor_030104ce3b95bcac, []int{147} } func (m *SourceHydrator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4216,7 +4188,7 @@ var xxx_messageInfo_SourceHydrator proto.InternalMessageInfo func (m *SourceHydratorStatus) Reset() { *m = SourceHydratorStatus{} } func (*SourceHydratorStatus) ProtoMessage() {} func (*SourceHydratorStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{149} + return fileDescriptor_030104ce3b95bcac, []int{148} } func (m *SourceHydratorStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4244,7 +4216,7 @@ var xxx_messageInfo_SourceHydratorStatus proto.InternalMessageInfo func (m *SuccessfulHydrateOperation) Reset() { *m = SuccessfulHydrateOperation{} } func (*SuccessfulHydrateOperation) ProtoMessage() {} func (*SuccessfulHydrateOperation) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{150} + return fileDescriptor_030104ce3b95bcac, []int{149} } func (m *SuccessfulHydrateOperation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4272,7 +4244,7 @@ var xxx_messageInfo_SuccessfulHydrateOperation proto.InternalMessageInfo func (m *SyncOperation) Reset() { *m = SyncOperation{} } func (*SyncOperation) ProtoMessage() {} func (*SyncOperation) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{151} + return fileDescriptor_030104ce3b95bcac, []int{150} } func (m *SyncOperation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4300,7 +4272,7 @@ var xxx_messageInfo_SyncOperation proto.InternalMessageInfo func (m *SyncOperationResource) Reset() { *m = SyncOperationResource{} } func (*SyncOperationResource) ProtoMessage() {} func (*SyncOperationResource) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{152} + return fileDescriptor_030104ce3b95bcac, []int{151} } func (m *SyncOperationResource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4328,7 +4300,7 @@ var xxx_messageInfo_SyncOperationResource proto.InternalMessageInfo func (m *SyncOperationResult) Reset() { *m = SyncOperationResult{} } func (*SyncOperationResult) ProtoMessage() {} func (*SyncOperationResult) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{153} + return fileDescriptor_030104ce3b95bcac, []int{152} } func (m *SyncOperationResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4356,7 +4328,7 @@ var xxx_messageInfo_SyncOperationResult proto.InternalMessageInfo func (m *SyncPolicy) Reset() { *m = SyncPolicy{} } func (*SyncPolicy) ProtoMessage() {} func (*SyncPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{154} + return fileDescriptor_030104ce3b95bcac, []int{153} } func (m *SyncPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4384,7 +4356,7 @@ var xxx_messageInfo_SyncPolicy proto.InternalMessageInfo func (m *SyncPolicyAutomated) Reset() { *m = SyncPolicyAutomated{} } func (*SyncPolicyAutomated) ProtoMessage() {} func (*SyncPolicyAutomated) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{155} + return fileDescriptor_030104ce3b95bcac, []int{154} } func (m *SyncPolicyAutomated) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4412,7 +4384,7 @@ var xxx_messageInfo_SyncPolicyAutomated proto.InternalMessageInfo func (m *SyncSource) Reset() { *m = SyncSource{} } func (*SyncSource) ProtoMessage() {} func (*SyncSource) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{156} + return fileDescriptor_030104ce3b95bcac, []int{155} } func (m *SyncSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4440,7 +4412,7 @@ var xxx_messageInfo_SyncSource proto.InternalMessageInfo func (m *SyncStatus) Reset() { *m = SyncStatus{} } func (*SyncStatus) ProtoMessage() {} func (*SyncStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{157} + return fileDescriptor_030104ce3b95bcac, []int{156} } func (m *SyncStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4468,7 +4440,7 @@ var xxx_messageInfo_SyncStatus proto.InternalMessageInfo func (m *SyncStrategy) Reset() { *m = SyncStrategy{} } func (*SyncStrategy) ProtoMessage() {} func (*SyncStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{158} + return fileDescriptor_030104ce3b95bcac, []int{157} } func (m *SyncStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4496,7 +4468,7 @@ var xxx_messageInfo_SyncStrategy proto.InternalMessageInfo func (m *SyncStrategyApply) Reset() { *m = SyncStrategyApply{} } func (*SyncStrategyApply) ProtoMessage() {} func (*SyncStrategyApply) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{159} + return fileDescriptor_030104ce3b95bcac, []int{158} } func (m *SyncStrategyApply) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4524,7 +4496,7 @@ var xxx_messageInfo_SyncStrategyApply proto.InternalMessageInfo func (m *SyncStrategyHook) Reset() { *m = SyncStrategyHook{} } func (*SyncStrategyHook) ProtoMessage() {} func (*SyncStrategyHook) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{160} + return fileDescriptor_030104ce3b95bcac, []int{159} } func (m *SyncStrategyHook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4552,7 +4524,7 @@ var xxx_messageInfo_SyncStrategyHook proto.InternalMessageInfo func (m *SyncWindow) Reset() { *m = SyncWindow{} } func (*SyncWindow) ProtoMessage() {} func (*SyncWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{161} + return fileDescriptor_030104ce3b95bcac, []int{160} } func (m *SyncWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4580,7 +4552,7 @@ var xxx_messageInfo_SyncWindow proto.InternalMessageInfo func (m *TLSClientConfig) Reset() { *m = TLSClientConfig{} } func (*TLSClientConfig) ProtoMessage() {} func (*TLSClientConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{162} + return fileDescriptor_030104ce3b95bcac, []int{161} } func (m *TLSClientConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4608,7 +4580,7 @@ var xxx_messageInfo_TLSClientConfig proto.InternalMessageInfo func (m *TagFilter) Reset() { *m = TagFilter{} } func (*TagFilter) ProtoMessage() {} func (*TagFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_c078c3c476799f44, []int{163} + return fileDescriptor_030104ce3b95bcac, []int{162} } func (m *TagFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4634,951 +4606,939 @@ func (m *TagFilter) XXX_DiscardUnknown() { var xxx_messageInfo_TagFilter proto.InternalMessageInfo func init() { - proto.RegisterType((*AWSAuthConfig)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AWSAuthConfig") - proto.RegisterType((*AppHealthStatus)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppHealthStatus") - proto.RegisterType((*AppProject)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProject") - proto.RegisterType((*AppProjectList)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProjectList") - proto.RegisterType((*AppProjectSpec)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProjectSpec") - proto.RegisterType((*AppProjectStatus)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProjectStatus") - proto.RegisterMapType((map[string]JWTTokens)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProjectStatus.JwtTokensByRoleEntry") - proto.RegisterType((*Application)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Application") - proto.RegisterType((*ApplicationCondition)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationCondition") - proto.RegisterType((*ApplicationDestination)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationDestination") - proto.RegisterType((*ApplicationDestinationServiceAccount)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationDestinationServiceAccount") - proto.RegisterType((*ApplicationList)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationList") - proto.RegisterType((*ApplicationMatchExpression)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationMatchExpression") - proto.RegisterType((*ApplicationPreservedFields)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationPreservedFields") - proto.RegisterType((*ApplicationSet)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSet") - proto.RegisterType((*ApplicationSetApplicationStatus)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetApplicationStatus") - proto.RegisterType((*ApplicationSetCondition)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetCondition") - proto.RegisterType((*ApplicationSetGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetGenerator") - proto.RegisterType((*ApplicationSetList)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetList") - proto.RegisterType((*ApplicationSetNestedGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetNestedGenerator") - proto.RegisterType((*ApplicationSetResourceIgnoreDifferences)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetResourceIgnoreDifferences") - proto.RegisterType((*ApplicationSetRolloutStep)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetRolloutStep") - proto.RegisterType((*ApplicationSetRolloutStrategy)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetRolloutStrategy") - proto.RegisterType((*ApplicationSetSpec)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetSpec") - proto.RegisterType((*ApplicationSetStatus)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetStatus") - proto.RegisterType((*ApplicationSetStrategy)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetStrategy") - proto.RegisterType((*ApplicationSetSyncPolicy)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetSyncPolicy") - proto.RegisterType((*ApplicationSetTemplate)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetTemplate") - proto.RegisterType((*ApplicationSetTemplateMeta)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetTemplateMeta") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetTemplateMeta.AnnotationsEntry") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetTemplateMeta.LabelsEntry") - proto.RegisterType((*ApplicationSetTerminalGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetTerminalGenerator") - proto.RegisterType((*ApplicationSetTree)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetTree") - proto.RegisterType((*ApplicationSource)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSource") - proto.RegisterType((*ApplicationSourceDirectory)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSourceDirectory") - proto.RegisterType((*ApplicationSourceHelm)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSourceHelm") - proto.RegisterType((*ApplicationSourceJsonnet)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSourceJsonnet") - proto.RegisterType((*ApplicationSourceKustomize)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSourceKustomize") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSourceKustomize.CommonAnnotationsEntry") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSourceKustomize.CommonLabelsEntry") - proto.RegisterType((*ApplicationSourcePlugin)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSourcePlugin") - proto.RegisterType((*ApplicationSourcePluginParameter)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSourcePluginParameter") - proto.RegisterType((*ApplicationSpec)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSpec") - proto.RegisterType((*ApplicationStatus)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationStatus") - proto.RegisterType((*ApplicationSummary)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSummary") - proto.RegisterType((*ApplicationTree)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationTree") - proto.RegisterType((*ApplicationWatchEvent)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationWatchEvent") - proto.RegisterType((*Backoff)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Backoff") - proto.RegisterType((*BasicAuthBitbucketServer)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.BasicAuthBitbucketServer") - proto.RegisterType((*BearerTokenBitbucket)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.BearerTokenBitbucket") - proto.RegisterType((*BearerTokenBitbucketCloud)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.BearerTokenBitbucketCloud") - proto.RegisterType((*ChartDetails)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ChartDetails") - proto.RegisterType((*Cluster)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Cluster") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Cluster.AnnotationsEntry") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Cluster.LabelsEntry") - proto.RegisterType((*ClusterCacheInfo)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ClusterCacheInfo") - proto.RegisterType((*ClusterConfig)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ClusterConfig") - proto.RegisterType((*ClusterGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ClusterGenerator") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ClusterGenerator.ValuesEntry") - proto.RegisterType((*ClusterInfo)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ClusterInfo") - proto.RegisterType((*ClusterList)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ClusterList") - proto.RegisterType((*Command)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Command") - proto.RegisterType((*ComparedTo)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ComparedTo") - proto.RegisterType((*ComponentParameter)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ComponentParameter") - proto.RegisterType((*ConfigManagementPlugin)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ConfigManagementPlugin") - proto.RegisterType((*ConfigMapKeyRef)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ConfigMapKeyRef") - proto.RegisterType((*ConnectionState)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ConnectionState") - proto.RegisterType((*DrySource)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.DrySource") - proto.RegisterType((*DuckTypeGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.DuckTypeGenerator") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.DuckTypeGenerator.ValuesEntry") - proto.RegisterType((*EnvEntry)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.EnvEntry") - proto.RegisterType((*ErrApplicationNotAllowedToUseProject)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ErrApplicationNotAllowedToUseProject") - proto.RegisterType((*ExecProviderConfig)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ExecProviderConfig") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ExecProviderConfig.EnvEntry") - proto.RegisterType((*GitDirectoryGeneratorItem)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.GitDirectoryGeneratorItem") - proto.RegisterType((*GitFileGeneratorItem)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.GitFileGeneratorItem") - proto.RegisterType((*GitGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.GitGenerator") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.GitGenerator.ValuesEntry") - proto.RegisterType((*GnuPGPublicKey)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.GnuPGPublicKey") - proto.RegisterType((*GnuPGPublicKeyList)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.GnuPGPublicKeyList") - proto.RegisterType((*HealthStatus)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.HealthStatus") - proto.RegisterType((*HelmFileParameter)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.HelmFileParameter") - proto.RegisterType((*HelmOptions)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.HelmOptions") - proto.RegisterType((*HelmParameter)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.HelmParameter") - proto.RegisterType((*HostInfo)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.HostInfo") - proto.RegisterType((*HostResourceInfo)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.HostResourceInfo") - proto.RegisterType((*HydrateOperation)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.HydrateOperation") - proto.RegisterType((*HydrateTo)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.HydrateTo") - proto.RegisterType((*Info)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Info") - proto.RegisterType((*InfoItem)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.InfoItem") - proto.RegisterType((*JWTToken)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.JWTToken") - proto.RegisterType((*JWTTokens)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.JWTTokens") - proto.RegisterType((*JsonnetVar)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.JsonnetVar") - proto.RegisterType((*KnownTypeField)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.KnownTypeField") - proto.RegisterType((*KustomizeGvk)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.KustomizeGvk") - proto.RegisterType((*KustomizeOptions)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.KustomizeOptions") - proto.RegisterType((*KustomizePatch)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.KustomizePatch") - proto.RegisterMapType((map[string]bool)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.KustomizePatch.OptionsEntry") - proto.RegisterType((*KustomizeReplica)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.KustomizeReplica") - proto.RegisterType((*KustomizeResId)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.KustomizeResId") - proto.RegisterType((*KustomizeSelector)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.KustomizeSelector") - proto.RegisterType((*ListGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ListGenerator") - proto.RegisterType((*ManagedNamespaceMetadata)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ManagedNamespaceMetadata") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ManagedNamespaceMetadata.AnnotationsEntry") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ManagedNamespaceMetadata.LabelsEntry") - proto.RegisterType((*MatrixGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.MatrixGenerator") - proto.RegisterType((*MergeGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.MergeGenerator") - proto.RegisterType((*NestedMatrixGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.NestedMatrixGenerator") - proto.RegisterType((*NestedMergeGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.NestedMergeGenerator") - proto.RegisterType((*Operation)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Operation") - proto.RegisterType((*OperationInitiator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.OperationInitiator") - proto.RegisterType((*OperationState)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.OperationState") - proto.RegisterType((*OptionalArray)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.OptionalArray") - proto.RegisterType((*OptionalMap)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.OptionalMap") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.OptionalMap.MapEntry") - proto.RegisterType((*OrphanedResourceKey)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.OrphanedResourceKey") - proto.RegisterType((*OrphanedResourcesMonitorSettings)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.OrphanedResourcesMonitorSettings") - proto.RegisterType((*OverrideIgnoreDiff)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.OverrideIgnoreDiff") - proto.RegisterType((*PluginConfigMapRef)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PluginConfigMapRef") - proto.RegisterType((*PluginGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PluginGenerator") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PluginGenerator.ValuesEntry") - proto.RegisterType((*PluginInput)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PluginInput") - proto.RegisterMapType((PluginParameters)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PluginInput.ParametersEntry") - proto.RegisterType((*ProjectRole)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ProjectRole") - proto.RegisterType((*PullRequestGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PullRequestGenerator") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PullRequestGenerator.ValuesEntry") - proto.RegisterType((*PullRequestGeneratorAzureDevOps)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PullRequestGeneratorAzureDevOps") - proto.RegisterType((*PullRequestGeneratorBitbucket)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PullRequestGeneratorBitbucket") - proto.RegisterType((*PullRequestGeneratorBitbucketServer)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PullRequestGeneratorBitbucketServer") - proto.RegisterType((*PullRequestGeneratorFilter)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PullRequestGeneratorFilter") - proto.RegisterType((*PullRequestGeneratorGitLab)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PullRequestGeneratorGitLab") - proto.RegisterType((*PullRequestGeneratorGitea)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PullRequestGeneratorGitea") - proto.RegisterType((*PullRequestGeneratorGithub)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.PullRequestGeneratorGithub") - proto.RegisterType((*RefTarget)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RefTarget") - proto.RegisterType((*RepoCreds)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepoCreds") - proto.RegisterType((*RepoCredsList)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepoCredsList") - proto.RegisterType((*Repository)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository") - proto.RegisterType((*RepositoryCertificate)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepositoryCertificate") - proto.RegisterType((*RepositoryCertificateList)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepositoryCertificateList") - proto.RegisterType((*RepositoryList)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepositoryList") - proto.RegisterType((*ResourceAction)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceAction") - proto.RegisterType((*ResourceActionDefinition)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceActionDefinition") - proto.RegisterType((*ResourceActionParam)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceActionParam") - proto.RegisterType((*ResourceActions)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceActions") - proto.RegisterType((*ResourceDiff)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceDiff") - proto.RegisterType((*ResourceIgnoreDifferences)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceIgnoreDifferences") - proto.RegisterType((*ResourceNetworkingInfo)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceNetworkingInfo") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceNetworkingInfo.LabelsEntry") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceNetworkingInfo.TargetLabelsEntry") - proto.RegisterType((*ResourceNode)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceNode") - proto.RegisterType((*ResourceOverride)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceOverride") - proto.RegisterType((*ResourceRef)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceRef") - proto.RegisterType((*ResourceResult)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceResult") - proto.RegisterType((*ResourceStatus)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceStatus") - proto.RegisterType((*RetryStrategy)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RetryStrategy") - proto.RegisterType((*RevisionHistory)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RevisionHistory") - proto.RegisterType((*RevisionMetadata)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RevisionMetadata") - proto.RegisterType((*SCMProviderGenerator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SCMProviderGenerator") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SCMProviderGenerator.ValuesEntry") - proto.RegisterType((*SCMProviderGeneratorAWSCodeCommit)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SCMProviderGeneratorAWSCodeCommit") - proto.RegisterType((*SCMProviderGeneratorAzureDevOps)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SCMProviderGeneratorAzureDevOps") - proto.RegisterType((*SCMProviderGeneratorBitbucket)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SCMProviderGeneratorBitbucket") - proto.RegisterType((*SCMProviderGeneratorBitbucketServer)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SCMProviderGeneratorBitbucketServer") - proto.RegisterType((*SCMProviderGeneratorFilter)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SCMProviderGeneratorFilter") - proto.RegisterType((*SCMProviderGeneratorGitea)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SCMProviderGeneratorGitea") - proto.RegisterType((*SCMProviderGeneratorGithub)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SCMProviderGeneratorGithub") - proto.RegisterType((*SCMProviderGeneratorGitlab)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SCMProviderGeneratorGitlab") - proto.RegisterType((*SecretRef)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SecretRef") - proto.RegisterType((*SignatureKey)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SignatureKey") - proto.RegisterType((*SourceHydrator)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SourceHydrator") - proto.RegisterType((*SourceHydratorStatus)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SourceHydratorStatus") - proto.RegisterType((*SuccessfulHydrateOperation)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SuccessfulHydrateOperation") - proto.RegisterType((*SyncOperation)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncOperation") - proto.RegisterType((*SyncOperationResource)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncOperationResource") - proto.RegisterType((*SyncOperationResult)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncOperationResult") - proto.RegisterType((*SyncPolicy)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncPolicy") - proto.RegisterType((*SyncPolicyAutomated)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncPolicyAutomated") - proto.RegisterType((*SyncSource)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncSource") - proto.RegisterType((*SyncStatus)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncStatus") - proto.RegisterType((*SyncStrategy)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncStrategy") - proto.RegisterType((*SyncStrategyApply)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncStrategyApply") - proto.RegisterType((*SyncStrategyHook)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncStrategyHook") - proto.RegisterType((*SyncWindow)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncWindow") - proto.RegisterType((*TLSClientConfig)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.TLSClientConfig") - proto.RegisterType((*TagFilter)(nil), "github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.TagFilter") + proto.RegisterType((*AWSAuthConfig)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AWSAuthConfig") + proto.RegisterType((*AppProject)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProject") + proto.RegisterType((*AppProjectList)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProjectList") + proto.RegisterType((*AppProjectSpec)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProjectSpec") + proto.RegisterType((*AppProjectStatus)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProjectStatus") + proto.RegisterMapType((map[string]JWTTokens)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProjectStatus.JwtTokensByRoleEntry") + proto.RegisterType((*Application)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application") + proto.RegisterType((*ApplicationCondition)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationCondition") + proto.RegisterType((*ApplicationDestination)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationDestination") + proto.RegisterType((*ApplicationDestinationServiceAccount)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationDestinationServiceAccount") + proto.RegisterType((*ApplicationList)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationList") + proto.RegisterType((*ApplicationMatchExpression)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationMatchExpression") + proto.RegisterType((*ApplicationPreservedFields)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationPreservedFields") + proto.RegisterType((*ApplicationSet)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSet") + proto.RegisterType((*ApplicationSetApplicationStatus)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetApplicationStatus") + proto.RegisterType((*ApplicationSetCondition)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetCondition") + proto.RegisterType((*ApplicationSetGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetGenerator") + proto.RegisterType((*ApplicationSetList)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetList") + proto.RegisterType((*ApplicationSetNestedGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetNestedGenerator") + proto.RegisterType((*ApplicationSetResourceIgnoreDifferences)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetResourceIgnoreDifferences") + proto.RegisterType((*ApplicationSetRolloutStep)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetRolloutStep") + proto.RegisterType((*ApplicationSetRolloutStrategy)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetRolloutStrategy") + proto.RegisterType((*ApplicationSetSpec)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetSpec") + proto.RegisterType((*ApplicationSetStatus)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetStatus") + proto.RegisterType((*ApplicationSetStrategy)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetStrategy") + proto.RegisterType((*ApplicationSetSyncPolicy)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetSyncPolicy") + proto.RegisterType((*ApplicationSetTemplate)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetTemplate") + proto.RegisterType((*ApplicationSetTemplateMeta)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetTemplateMeta") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetTemplateMeta.AnnotationsEntry") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetTemplateMeta.LabelsEntry") + proto.RegisterType((*ApplicationSetTerminalGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetTerminalGenerator") + proto.RegisterType((*ApplicationSetTree)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetTree") + proto.RegisterType((*ApplicationSource)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSource") + proto.RegisterType((*ApplicationSourceDirectory)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSourceDirectory") + proto.RegisterType((*ApplicationSourceHelm)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSourceHelm") + proto.RegisterType((*ApplicationSourceJsonnet)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSourceJsonnet") + proto.RegisterType((*ApplicationSourceKustomize)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSourceKustomize") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSourceKustomize.CommonAnnotationsEntry") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSourceKustomize.CommonLabelsEntry") + proto.RegisterType((*ApplicationSourcePlugin)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSourcePlugin") + proto.RegisterType((*ApplicationSourcePluginParameter)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSourcePluginParameter") + proto.RegisterType((*ApplicationSpec)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSpec") + proto.RegisterType((*ApplicationStatus)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationStatus") + proto.RegisterType((*ApplicationSummary)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSummary") + proto.RegisterType((*ApplicationTree)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationTree") + proto.RegisterType((*ApplicationWatchEvent)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationWatchEvent") + proto.RegisterType((*Backoff)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Backoff") + proto.RegisterType((*BasicAuthBitbucketServer)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.BasicAuthBitbucketServer") + proto.RegisterType((*BearerTokenBitbucket)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.BearerTokenBitbucket") + proto.RegisterType((*BearerTokenBitbucketCloud)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.BearerTokenBitbucketCloud") + proto.RegisterType((*ChartDetails)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ChartDetails") + proto.RegisterType((*Cluster)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Cluster") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Cluster.AnnotationsEntry") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Cluster.LabelsEntry") + proto.RegisterType((*ClusterCacheInfo)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ClusterCacheInfo") + proto.RegisterType((*ClusterConfig)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ClusterConfig") + proto.RegisterType((*ClusterGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ClusterGenerator") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ClusterGenerator.ValuesEntry") + proto.RegisterType((*ClusterInfo)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ClusterInfo") + proto.RegisterType((*ClusterList)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ClusterList") + proto.RegisterType((*Command)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Command") + proto.RegisterType((*ComparedTo)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ComparedTo") + proto.RegisterType((*ComponentParameter)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ComponentParameter") + proto.RegisterType((*ConfigManagementPlugin)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ConfigManagementPlugin") + proto.RegisterType((*ConfigMapKeyRef)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ConfigMapKeyRef") + proto.RegisterType((*ConnectionState)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ConnectionState") + proto.RegisterType((*DrySource)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.DrySource") + proto.RegisterType((*DuckTypeGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.DuckTypeGenerator") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.DuckTypeGenerator.ValuesEntry") + proto.RegisterType((*EnvEntry)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.EnvEntry") + proto.RegisterType((*ErrApplicationNotAllowedToUseProject)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ErrApplicationNotAllowedToUseProject") + proto.RegisterType((*ExecProviderConfig)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ExecProviderConfig") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ExecProviderConfig.EnvEntry") + proto.RegisterType((*GitDirectoryGeneratorItem)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.GitDirectoryGeneratorItem") + proto.RegisterType((*GitFileGeneratorItem)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.GitFileGeneratorItem") + proto.RegisterType((*GitGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.GitGenerator") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.GitGenerator.ValuesEntry") + proto.RegisterType((*GnuPGPublicKey)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.GnuPGPublicKey") + proto.RegisterType((*GnuPGPublicKeyList)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.GnuPGPublicKeyList") + proto.RegisterType((*HealthStatus)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HealthStatus") + proto.RegisterType((*HelmFileParameter)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmFileParameter") + proto.RegisterType((*HelmOptions)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmOptions") + proto.RegisterType((*HelmParameter)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmParameter") + proto.RegisterType((*HostInfo)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HostInfo") + proto.RegisterType((*HostResourceInfo)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HostResourceInfo") + proto.RegisterType((*HydrateOperation)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HydrateOperation") + proto.RegisterType((*HydrateTo)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HydrateTo") + proto.RegisterType((*Info)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Info") + proto.RegisterType((*InfoItem)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.InfoItem") + proto.RegisterType((*JWTToken)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.JWTToken") + proto.RegisterType((*JWTTokens)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.JWTTokens") + proto.RegisterType((*JsonnetVar)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.JsonnetVar") + proto.RegisterType((*KnownTypeField)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.KnownTypeField") + proto.RegisterType((*KustomizeGvk)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.KustomizeGvk") + proto.RegisterType((*KustomizeOptions)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.KustomizeOptions") + proto.RegisterType((*KustomizePatch)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.KustomizePatch") + proto.RegisterMapType((map[string]bool)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.KustomizePatch.OptionsEntry") + proto.RegisterType((*KustomizeReplica)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.KustomizeReplica") + proto.RegisterType((*KustomizeResId)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.KustomizeResId") + proto.RegisterType((*KustomizeSelector)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.KustomizeSelector") + proto.RegisterType((*ListGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ListGenerator") + proto.RegisterType((*ManagedNamespaceMetadata)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ManagedNamespaceMetadata") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ManagedNamespaceMetadata.AnnotationsEntry") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ManagedNamespaceMetadata.LabelsEntry") + proto.RegisterType((*MatrixGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.MatrixGenerator") + proto.RegisterType((*MergeGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.MergeGenerator") + proto.RegisterType((*NestedMatrixGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.NestedMatrixGenerator") + proto.RegisterType((*NestedMergeGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.NestedMergeGenerator") + proto.RegisterType((*Operation)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Operation") + proto.RegisterType((*OperationInitiator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.OperationInitiator") + proto.RegisterType((*OperationState)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.OperationState") + proto.RegisterType((*OptionalArray)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.OptionalArray") + proto.RegisterType((*OptionalMap)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.OptionalMap") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.OptionalMap.MapEntry") + proto.RegisterType((*OrphanedResourceKey)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.OrphanedResourceKey") + proto.RegisterType((*OrphanedResourcesMonitorSettings)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.OrphanedResourcesMonitorSettings") + proto.RegisterType((*OverrideIgnoreDiff)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.OverrideIgnoreDiff") + proto.RegisterType((*PluginConfigMapRef)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PluginConfigMapRef") + proto.RegisterType((*PluginGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PluginGenerator") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PluginGenerator.ValuesEntry") + proto.RegisterType((*PluginInput)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PluginInput") + proto.RegisterMapType((PluginParameters)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PluginInput.ParametersEntry") + proto.RegisterType((*ProjectRole)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ProjectRole") + proto.RegisterType((*PullRequestGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PullRequestGenerator") + proto.RegisterType((*PullRequestGeneratorAzureDevOps)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PullRequestGeneratorAzureDevOps") + proto.RegisterType((*PullRequestGeneratorBitbucket)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PullRequestGeneratorBitbucket") + proto.RegisterType((*PullRequestGeneratorBitbucketServer)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PullRequestGeneratorBitbucketServer") + proto.RegisterType((*PullRequestGeneratorFilter)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PullRequestGeneratorFilter") + proto.RegisterType((*PullRequestGeneratorGitLab)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PullRequestGeneratorGitLab") + proto.RegisterType((*PullRequestGeneratorGitea)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PullRequestGeneratorGitea") + proto.RegisterType((*PullRequestGeneratorGithub)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PullRequestGeneratorGithub") + proto.RegisterType((*RefTarget)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RefTarget") + proto.RegisterType((*RepoCreds)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds") + proto.RegisterType((*RepoCredsList)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCredsList") + proto.RegisterType((*Repository)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository") + proto.RegisterType((*RepositoryCertificate)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepositoryCertificate") + proto.RegisterType((*RepositoryCertificateList)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepositoryCertificateList") + proto.RegisterType((*RepositoryList)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepositoryList") + proto.RegisterType((*ResourceAction)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceAction") + proto.RegisterType((*ResourceActionDefinition)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceActionDefinition") + proto.RegisterType((*ResourceActionParam)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceActionParam") + proto.RegisterType((*ResourceActions)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceActions") + proto.RegisterType((*ResourceDiff)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceDiff") + proto.RegisterType((*ResourceIgnoreDifferences)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceIgnoreDifferences") + proto.RegisterType((*ResourceNetworkingInfo)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceNetworkingInfo") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceNetworkingInfo.LabelsEntry") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceNetworkingInfo.TargetLabelsEntry") + proto.RegisterType((*ResourceNode)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceNode") + proto.RegisterType((*ResourceOverride)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceOverride") + proto.RegisterType((*ResourceRef)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceRef") + proto.RegisterType((*ResourceResult)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceResult") + proto.RegisterType((*ResourceStatus)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceStatus") + proto.RegisterType((*RetryStrategy)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RetryStrategy") + proto.RegisterType((*RevisionHistory)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RevisionHistory") + proto.RegisterType((*RevisionMetadata)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RevisionMetadata") + proto.RegisterType((*SCMProviderGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SCMProviderGenerator") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SCMProviderGenerator.ValuesEntry") + proto.RegisterType((*SCMProviderGeneratorAWSCodeCommit)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SCMProviderGeneratorAWSCodeCommit") + proto.RegisterType((*SCMProviderGeneratorAzureDevOps)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SCMProviderGeneratorAzureDevOps") + proto.RegisterType((*SCMProviderGeneratorBitbucket)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SCMProviderGeneratorBitbucket") + proto.RegisterType((*SCMProviderGeneratorBitbucketServer)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SCMProviderGeneratorBitbucketServer") + proto.RegisterType((*SCMProviderGeneratorFilter)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SCMProviderGeneratorFilter") + proto.RegisterType((*SCMProviderGeneratorGitea)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SCMProviderGeneratorGitea") + proto.RegisterType((*SCMProviderGeneratorGithub)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SCMProviderGeneratorGithub") + proto.RegisterType((*SCMProviderGeneratorGitlab)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SCMProviderGeneratorGitlab") + proto.RegisterType((*SecretRef)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SecretRef") + proto.RegisterType((*SignatureKey)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SignatureKey") + proto.RegisterType((*SourceHydrator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SourceHydrator") + proto.RegisterType((*SourceHydratorStatus)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SourceHydratorStatus") + proto.RegisterType((*SuccessfulHydrateOperation)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SuccessfulHydrateOperation") + proto.RegisterType((*SyncOperation)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncOperation") + proto.RegisterType((*SyncOperationResource)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncOperationResource") + proto.RegisterType((*SyncOperationResult)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncOperationResult") + proto.RegisterType((*SyncPolicy)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncPolicy") + proto.RegisterType((*SyncPolicyAutomated)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncPolicyAutomated") + proto.RegisterType((*SyncSource)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncSource") + proto.RegisterType((*SyncStatus)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncStatus") + proto.RegisterType((*SyncStrategy)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncStrategy") + proto.RegisterType((*SyncStrategyApply)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncStrategyApply") + proto.RegisterType((*SyncStrategyHook)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncStrategyHook") + proto.RegisterType((*SyncWindow)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncWindow") + proto.RegisterType((*TLSClientConfig)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.TLSClientConfig") + proto.RegisterType((*TagFilter)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.TagFilter") } func init() { - proto.RegisterFile("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto", fileDescriptor_c078c3c476799f44) + proto.RegisterFile("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto", fileDescriptor_030104ce3b95bcac) } -var fileDescriptor_c078c3c476799f44 = []byte{ - // 12026 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6b, 0x70, 0x24, 0xc9, - 0x71, 0x18, 0xcc, 0x9e, 0xc1, 0x00, 0x33, 0x89, 0xd7, 0x6e, 0xed, 0xee, 0x1d, 0x76, 0xef, 0x81, - 0x55, 0x1f, 0x75, 0x3c, 0x7d, 0xbc, 0x03, 0x74, 0x2f, 0xea, 0x3e, 0x1e, 0x1f, 0xc2, 0x63, 0x1f, - 0xd8, 0x05, 0x16, 0xb8, 0x1a, 0xec, 0x2e, 0x79, 0xe4, 0xf1, 0xd8, 0x98, 0x29, 0x0c, 0x7a, 0xd1, - 0xd3, 0x3d, 0xd7, 0xdd, 0x83, 0xc5, 0x9c, 0x48, 0x8a, 0x14, 0x49, 0x89, 0x12, 0x9f, 0x26, 0x15, - 0xd6, 0xd1, 0x36, 0x69, 0xca, 0x92, 0x5f, 0xe1, 0x60, 0x88, 0xb6, 0x7e, 0x58, 0x0e, 0x49, 0xa1, - 0x90, 0x64, 0x33, 0x68, 0xcb, 0x0e, 0xc9, 0x0c, 0x86, 0x28, 0x5b, 0x12, 0x4c, 0xae, 0xed, 0xa0, - 0xc2, 0x11, 0x52, 0x84, 0x65, 0xff, 0x70, 0xac, 0x1d, 0x0e, 0x47, 0xbd, 0xab, 0x7b, 0x7a, 0x80, - 0xc1, 0xa2, 0x81, 0x5d, 0x92, 0xf7, 0x6f, 0xa6, 0x32, 0xbb, 0x32, 0xbb, 0xba, 0x2a, 0x33, 0x2b, - 0x2b, 0x33, 0x0b, 0x16, 0x1b, 0x6e, 0xbc, 0xd1, 0x5e, 0x9b, 0xaa, 0x05, 0xcd, 0x69, 0x27, 0x6c, - 0x04, 0xad, 0x30, 0xb8, 0xc1, 0x7e, 0x3c, 0x51, 0xab, 0x4f, 0x6f, 0x3d, 0x3d, 0xdd, 0xda, 0x6c, - 0x4c, 0x3b, 0x2d, 0x37, 0x9a, 0x76, 0x5a, 0x2d, 0xcf, 0xad, 0x39, 0xb1, 0x1b, 0xf8, 0xd3, 0x5b, - 0x4f, 0x3a, 0x5e, 0x6b, 0xc3, 0x79, 0x72, 0xba, 0x41, 0x7c, 0x12, 0x3a, 0x31, 0xa9, 0x4f, 0xb5, - 0xc2, 0x20, 0x0e, 0xd0, 0xdb, 0x74, 0x6f, 0x53, 0xb2, 0x37, 0xf6, 0xe3, 0xe5, 0x5a, 0x7d, 0x6a, - 0xeb, 0xe9, 0xa9, 0xd6, 0x66, 0x63, 0x8a, 0xf6, 0x36, 0x65, 0xf4, 0x36, 0x25, 0x7b, 0x3b, 0xf3, - 0x84, 0xc1, 0x4b, 0x23, 0x68, 0x04, 0xd3, 0xac, 0xd3, 0xb5, 0xf6, 0x3a, 0xfb, 0xc7, 0xfe, 0xb0, - 0x5f, 0x9c, 0xd8, 0x19, 0x7b, 0xf3, 0xb9, 0x68, 0xca, 0x0d, 0x28, 0x7b, 0xd3, 0xb5, 0x20, 0x24, - 0xd3, 0x5b, 0x5d, 0x0c, 0x9d, 0xb9, 0xa8, 0x71, 0xc8, 0x76, 0x4c, 0xfc, 0xc8, 0x0d, 0xfc, 0xe8, - 0x09, 0xca, 0x02, 0x09, 0xb7, 0x48, 0x68, 0xbe, 0x9e, 0x81, 0x90, 0xd5, 0xd3, 0x33, 0xba, 0xa7, - 0xa6, 0x53, 0xdb, 0x70, 0x7d, 0x12, 0x76, 0xf4, 0xe3, 0x4d, 0x12, 0x3b, 0x59, 0x4f, 0x4d, 0xf7, - 0x7a, 0x2a, 0x6c, 0xfb, 0xb1, 0xdb, 0x24, 0x5d, 0x0f, 0xbc, 0x65, 0xaf, 0x07, 0xa2, 0xda, 0x06, - 0x69, 0x3a, 0x5d, 0xcf, 0x3d, 0xdd, 0xeb, 0xb9, 0x76, 0xec, 0x7a, 0xd3, 0xae, 0x1f, 0x47, 0x71, - 0x98, 0x7e, 0xc8, 0xfe, 0x3b, 0x16, 0x8c, 0xce, 0x5c, 0xaf, 0xce, 0xb4, 0xe3, 0x8d, 0xb9, 0xc0, - 0x5f, 0x77, 0x1b, 0xe8, 0x59, 0x18, 0xae, 0x79, 0xed, 0x28, 0x26, 0xe1, 0x15, 0xa7, 0x49, 0x26, - 0xac, 0xb3, 0xd6, 0x63, 0x95, 0xd9, 0x13, 0xdf, 0xd8, 0x99, 0x7c, 0xc3, 0xad, 0x9d, 0xc9, 0xe1, - 0x39, 0x0d, 0xc2, 0x26, 0x1e, 0xfa, 0x31, 0x18, 0x0a, 0x03, 0x8f, 0xcc, 0xe0, 0x2b, 0x13, 0x05, - 0xf6, 0xc8, 0xb8, 0x78, 0x64, 0x08, 0xf3, 0x66, 0x2c, 0xe1, 0x14, 0xb5, 0x15, 0x06, 0xeb, 0xae, - 0x47, 0x26, 0x8a, 0x49, 0xd4, 0x15, 0xde, 0x8c, 0x25, 0xdc, 0xfe, 0x62, 0x01, 0xc6, 0x67, 0x5a, - 0xad, 0x8b, 0xc4, 0xf1, 0xe2, 0x8d, 0x6a, 0xec, 0xc4, 0xed, 0x08, 0x35, 0x60, 0x30, 0x62, 0xbf, - 0x04, 0x6f, 0xcb, 0xe2, 0xe9, 0x41, 0x0e, 0xbf, 0xbd, 0x33, 0xf9, 0xf6, 0xac, 0x19, 0xdd, 0x70, - 0xe3, 0xa0, 0x15, 0x3d, 0x41, 0xfc, 0x86, 0xeb, 0x13, 0x36, 0x2e, 0x1b, 0xac, 0xd7, 0x29, 0xb3, - 0xf3, 0xb9, 0xa0, 0x4e, 0xb0, 0xe8, 0x9e, 0xf2, 0xd9, 0x24, 0x51, 0xe4, 0x34, 0x48, 0xfa, 0x95, - 0x96, 0x78, 0x33, 0x96, 0x70, 0x14, 0x02, 0xf2, 0x9c, 0x28, 0x5e, 0x0d, 0x1d, 0x3f, 0x72, 0xe9, - 0x94, 0x5e, 0x75, 0x9b, 0xfc, 0xed, 0x86, 0x9f, 0xfa, 0xff, 0xa6, 0xf8, 0x87, 0x99, 0x32, 0x3f, - 0x8c, 0x5e, 0x07, 0x74, 0xde, 0x4c, 0x6d, 0x3d, 0x39, 0x45, 0x9f, 0x98, 0xbd, 0xef, 0xd6, 0xce, - 0x24, 0x5a, 0xec, 0xea, 0x09, 0x67, 0xf4, 0x6e, 0xff, 0x71, 0x01, 0x60, 0xa6, 0xd5, 0x5a, 0x09, - 0x83, 0x1b, 0xa4, 0x16, 0xa3, 0xf7, 0x43, 0x99, 0x76, 0x55, 0x77, 0x62, 0x87, 0x0d, 0xcc, 0xf0, - 0x53, 0x3f, 0xde, 0x1f, 0xe1, 0xe5, 0x35, 0xfa, 0xfc, 0x12, 0x89, 0x9d, 0x59, 0x24, 0x5e, 0x10, - 0x74, 0x1b, 0x56, 0xbd, 0x22, 0x1f, 0x06, 0xa2, 0x16, 0xa9, 0xb1, 0xc1, 0x18, 0x7e, 0x6a, 0x71, - 0xea, 0x20, 0x2b, 0x7d, 0x4a, 0x73, 0x5e, 0x6d, 0x91, 0xda, 0xec, 0x88, 0xa0, 0x3c, 0x40, 0xff, - 0x61, 0x46, 0x07, 0x6d, 0xa9, 0x0f, 0xcd, 0x07, 0xf2, 0x4a, 0x6e, 0x14, 0x59, 0xaf, 0xb3, 0x63, - 0xc9, 0x89, 0x23, 0xbf, 0xbb, 0xfd, 0xe7, 0x16, 0x8c, 0x69, 0xe4, 0x45, 0x37, 0x8a, 0xd1, 0x7b, - 0xbb, 0x06, 0x77, 0xaa, 0xbf, 0xc1, 0xa5, 0x4f, 0xb3, 0xa1, 0x3d, 0x26, 0x88, 0x95, 0x65, 0x8b, - 0x31, 0xb0, 0x4d, 0x28, 0xb9, 0x31, 0x69, 0x46, 0x13, 0x85, 0xb3, 0xc5, 0xc7, 0x86, 0x9f, 0xba, - 0x98, 0xd7, 0x7b, 0xce, 0x8e, 0x0a, 0xa2, 0xa5, 0x05, 0xda, 0x3d, 0xe6, 0x54, 0xec, 0xbf, 0x1e, - 0x35, 0xdf, 0x8f, 0x0e, 0x38, 0x7a, 0x12, 0x86, 0xa3, 0xa0, 0x1d, 0xd6, 0x08, 0x26, 0xad, 0x80, - 0x2e, 0xac, 0x22, 0x9d, 0xee, 0x74, 0xc1, 0x57, 0x75, 0x33, 0x36, 0x71, 0xd0, 0x67, 0x2c, 0x18, - 0xa9, 0x93, 0x28, 0x76, 0x7d, 0x46, 0x5f, 0x32, 0xbf, 0x7a, 0x60, 0xe6, 0x65, 0xe3, 0xbc, 0xee, - 0x7c, 0xf6, 0xa4, 0x78, 0x91, 0x11, 0xa3, 0x31, 0xc2, 0x09, 0xfa, 0x54, 0x70, 0xd5, 0x49, 0x54, - 0x0b, 0xdd, 0x16, 0xfd, 0x2f, 0x44, 0x8b, 0x12, 0x5c, 0xf3, 0x1a, 0x84, 0x4d, 0x3c, 0xe4, 0x43, - 0x89, 0x0a, 0xa6, 0x68, 0x62, 0x80, 0xf1, 0xbf, 0x70, 0x30, 0xfe, 0xc5, 0xa0, 0x52, 0x99, 0xa7, - 0x47, 0x9f, 0xfe, 0x8b, 0x30, 0x27, 0x83, 0x3e, 0x6d, 0xc1, 0x84, 0x10, 0x9c, 0x98, 0xf0, 0x01, - 0xbd, 0xbe, 0xe1, 0xc6, 0xc4, 0x73, 0xa3, 0x78, 0xa2, 0xc4, 0x78, 0x98, 0xee, 0x6f, 0x6e, 0x5d, - 0x08, 0x83, 0x76, 0xeb, 0xb2, 0xeb, 0xd7, 0x67, 0xcf, 0x0a, 0x4a, 0x13, 0x73, 0x3d, 0x3a, 0xc6, - 0x3d, 0x49, 0xa2, 0x2f, 0x58, 0x70, 0xc6, 0x77, 0x9a, 0x24, 0x6a, 0x39, 0xf4, 0xd3, 0x72, 0xf0, - 0xac, 0xe7, 0xd4, 0x36, 0x19, 0x47, 0x83, 0x77, 0xc6, 0x91, 0x2d, 0x38, 0x3a, 0x73, 0xa5, 0x67, - 0xd7, 0x78, 0x17, 0xb2, 0xe8, 0x57, 0x2c, 0x38, 0x1e, 0x84, 0xad, 0x0d, 0xc7, 0x27, 0x75, 0x09, - 0x8d, 0x26, 0x86, 0xd8, 0xd2, 0x7b, 0xdf, 0xc1, 0x3e, 0xd1, 0x72, 0xba, 0xdb, 0xa5, 0xc0, 0x77, - 0xe3, 0x20, 0xac, 0x92, 0x38, 0x76, 0xfd, 0x46, 0x34, 0x7b, 0xea, 0xd6, 0xce, 0xe4, 0xf1, 0x2e, - 0x2c, 0xdc, 0xcd, 0x0f, 0xfa, 0x29, 0x18, 0x8e, 0x3a, 0x7e, 0xed, 0xba, 0xeb, 0xd7, 0x83, 0x9b, - 0xd1, 0x44, 0x39, 0x8f, 0xe5, 0x5b, 0x55, 0x1d, 0x8a, 0x05, 0xa8, 0x09, 0x60, 0x93, 0x5a, 0xf6, - 0x87, 0xd3, 0x53, 0xa9, 0x92, 0xf7, 0x87, 0xd3, 0x93, 0x69, 0x17, 0xb2, 0xe8, 0xe7, 0x2c, 0x18, - 0x8d, 0xdc, 0x86, 0xef, 0xc4, 0xed, 0x90, 0x5c, 0x26, 0x9d, 0x68, 0x02, 0x18, 0x23, 0x97, 0x0e, - 0x38, 0x2a, 0x46, 0x97, 0xb3, 0xa7, 0x04, 0x8f, 0xa3, 0x66, 0x6b, 0x84, 0x93, 0x74, 0xb3, 0x16, - 0x9a, 0x9e, 0xd6, 0xc3, 0xf9, 0x2e, 0x34, 0x3d, 0xa9, 0x7b, 0x92, 0x44, 0x3f, 0x09, 0xc7, 0x78, - 0x93, 0x1a, 0xd9, 0x68, 0x62, 0x84, 0x09, 0xda, 0x93, 0xb7, 0x76, 0x26, 0x8f, 0x55, 0x53, 0x30, - 0xdc, 0x85, 0x8d, 0x5e, 0x81, 0xc9, 0x16, 0x09, 0x9b, 0x6e, 0xbc, 0xec, 0x7b, 0x1d, 0x29, 0xbe, - 0x6b, 0x41, 0x8b, 0xd4, 0x05, 0x3b, 0xd1, 0xc4, 0xe8, 0x59, 0xeb, 0xb1, 0xf2, 0xec, 0x9b, 0x04, - 0x9b, 0x93, 0x2b, 0xbb, 0xa3, 0xe3, 0xbd, 0xfa, 0x43, 0x5f, 0xb7, 0xe0, 0x8c, 0x21, 0x65, 0xab, - 0x24, 0xdc, 0x72, 0x6b, 0x64, 0xa6, 0x56, 0x0b, 0xda, 0x7e, 0x1c, 0x4d, 0x8c, 0xb1, 0x61, 0x5c, - 0x3b, 0x0c, 0x99, 0x9f, 0x24, 0xa5, 0xe7, 0x65, 0x4f, 0x94, 0x08, 0xef, 0xc2, 0xa9, 0xfd, 0xaf, - 0x0b, 0x70, 0x2c, 0x6d, 0x01, 0xa0, 0x7f, 0x60, 0xc1, 0xf8, 0x8d, 0x9b, 0xf1, 0x6a, 0xb0, 0x49, - 0xfc, 0x68, 0xb6, 0x43, 0xe5, 0x34, 0xd3, 0x7d, 0xc3, 0x4f, 0xd5, 0xf2, 0xb5, 0x35, 0xa6, 0x2e, - 0x25, 0xa9, 0x9c, 0xf3, 0xe3, 0xb0, 0x33, 0x7b, 0xbf, 0x78, 0xa7, 0xf1, 0x4b, 0xd7, 0x57, 0x4d, - 0x28, 0x4e, 0x33, 0x75, 0xe6, 0x93, 0x16, 0x9c, 0xcc, 0xea, 0x02, 0x1d, 0x83, 0xe2, 0x26, 0xe9, - 0x70, 0x4b, 0x18, 0xd3, 0x9f, 0xe8, 0x25, 0x28, 0x6d, 0x39, 0x5e, 0x9b, 0x08, 0x33, 0xed, 0xc2, - 0xc1, 0x5e, 0x44, 0x71, 0x86, 0x79, 0xaf, 0x6f, 0x2d, 0x3c, 0x67, 0xd9, 0x7f, 0x58, 0x84, 0x61, - 0xe3, 0xa3, 0x1d, 0x81, 0xe9, 0x19, 0x24, 0x4c, 0xcf, 0xa5, 0xdc, 0xe6, 0x5b, 0x4f, 0xdb, 0xf3, - 0x66, 0xca, 0xf6, 0x5c, 0xce, 0x8f, 0xe4, 0xae, 0xc6, 0x27, 0x8a, 0xa1, 0x12, 0xb4, 0xe8, 0x16, - 0x8d, 0xda, 0x30, 0x03, 0x79, 0x7c, 0xc2, 0x65, 0xd9, 0xdd, 0xec, 0xe8, 0xad, 0x9d, 0xc9, 0x8a, - 0xfa, 0x8b, 0x35, 0x21, 0xfb, 0xdb, 0x16, 0x9c, 0x34, 0x78, 0x9c, 0x0b, 0xfc, 0x3a, 0xdb, 0x68, - 0xa0, 0xb3, 0x30, 0x10, 0x77, 0x5a, 0x72, 0x1b, 0xa8, 0x46, 0x6a, 0xb5, 0xd3, 0x22, 0x98, 0x41, - 0xee, 0xf5, 0x5d, 0xd2, 0x17, 0x2c, 0xb8, 0x2f, 0x5b, 0xc0, 0xa0, 0x47, 0x61, 0x90, 0xfb, 0x00, - 0xc4, 0xdb, 0xe9, 0x4f, 0xc2, 0x5a, 0xb1, 0x80, 0xa2, 0x69, 0xa8, 0x28, 0x85, 0x27, 0xde, 0xf1, - 0xb8, 0x40, 0xad, 0x68, 0x2d, 0xa9, 0x71, 0xe8, 0xa0, 0xd1, 0x3f, 0xc2, 0x04, 0x55, 0x83, 0xc6, - 0x36, 0xcd, 0x0c, 0x62, 0x7f, 0xcb, 0x82, 0x37, 0xf6, 0x23, 0xf6, 0x0e, 0x8f, 0xc7, 0x2a, 0x9c, - 0xaa, 0x93, 0x75, 0xa7, 0xed, 0xc5, 0x49, 0x8a, 0x82, 0xe9, 0x87, 0xc4, 0xc3, 0xa7, 0xe6, 0xb3, - 0x90, 0x70, 0xf6, 0xb3, 0xf6, 0x7f, 0xb2, 0xd8, 0x76, 0x5d, 0xbe, 0xd6, 0x11, 0x6c, 0x9d, 0xfc, - 0xe4, 0xd6, 0x69, 0x21, 0xb7, 0x65, 0xda, 0x63, 0xef, 0xf4, 0x69, 0x0b, 0xce, 0x18, 0x58, 0x4b, - 0x4e, 0x5c, 0xdb, 0x38, 0xb7, 0xdd, 0x0a, 0x49, 0x14, 0xd1, 0x29, 0xf5, 0x90, 0x21, 0x8e, 0x67, - 0x87, 0x45, 0x0f, 0xc5, 0xcb, 0xa4, 0xc3, 0x65, 0xf3, 0xe3, 0x50, 0xe6, 0x6b, 0x2e, 0x08, 0xc5, - 0x47, 0x52, 0xef, 0xb6, 0x2c, 0xda, 0xb1, 0xc2, 0x40, 0x36, 0x0c, 0x32, 0x99, 0x4b, 0x65, 0x10, - 0x35, 0x13, 0x80, 0x7e, 0xf7, 0x6b, 0xac, 0x05, 0x0b, 0x88, 0x1d, 0x25, 0xd8, 0x59, 0x09, 0x09, - 0x9b, 0x0f, 0xf5, 0xf3, 0x2e, 0xf1, 0xea, 0x11, 0xdd, 0xd6, 0x39, 0xbe, 0x1f, 0xc4, 0x62, 0x87, - 0x66, 0x6c, 0xeb, 0x66, 0x74, 0x33, 0x36, 0x71, 0x28, 0x51, 0xcf, 0x59, 0x23, 0x1e, 0x1f, 0x51, - 0x41, 0x74, 0x91, 0xb5, 0x60, 0x01, 0xb1, 0x6f, 0x15, 0xd8, 0x06, 0x52, 0x49, 0x34, 0x72, 0x14, - 0xde, 0x87, 0x30, 0xa1, 0x02, 0x56, 0xf2, 0x93, 0xc7, 0xa4, 0xb7, 0x07, 0xe2, 0xd5, 0x94, 0x16, - 0xc0, 0xb9, 0x52, 0xdd, 0xdd, 0x0b, 0xf1, 0xe1, 0x22, 0x4c, 0x26, 0x1f, 0xe8, 0x52, 0x22, 0x74, - 0xcb, 0x6b, 0x10, 0x4a, 0xfb, 0xea, 0x0c, 0x7c, 0x6c, 0xe2, 0xf5, 0x90, 0xc3, 0x85, 0xc3, 0x94, - 0xc3, 0xa6, 0x9a, 0x28, 0xee, 0xa1, 0x26, 0x1e, 0x55, 0xa3, 0x3e, 0x90, 0x92, 0x79, 0x49, 0x55, - 0x79, 0x16, 0x06, 0xa2, 0x98, 0xb4, 0x26, 0x4a, 0x49, 0x31, 0x5b, 0x8d, 0x49, 0x0b, 0x33, 0x08, - 0x7a, 0x3b, 0x8c, 0xc7, 0x4e, 0xd8, 0x20, 0x71, 0x48, 0xb6, 0x5c, 0xe6, 0xd7, 0x65, 0xfb, 0xd9, - 0xca, 0xec, 0x09, 0x6a, 0x75, 0xad, 0x32, 0x10, 0x96, 0x20, 0x9c, 0xc6, 0xb5, 0xff, 0x5b, 0x01, - 0xee, 0x4f, 0x7e, 0x02, 0xad, 0x18, 0xdf, 0x99, 0x50, 0x8c, 0x6f, 0x36, 0x15, 0xe3, 0xed, 0x9d, - 0xc9, 0x07, 0x7a, 0x3c, 0xf6, 0x7d, 0xa3, 0x37, 0xd1, 0x85, 0xd4, 0x47, 0x98, 0xee, 0xf2, 0xb2, - 0x3e, 0xd4, 0xe3, 0x1d, 0x53, 0x5f, 0xe9, 0x51, 0x18, 0x0c, 0x89, 0x13, 0x05, 0xbe, 0xf8, 0x4e, - 0xea, 0x6b, 0x62, 0xd6, 0x8a, 0x05, 0xd4, 0xfe, 0x66, 0x25, 0x3d, 0xd8, 0x17, 0xb8, 0xaf, 0x3a, - 0x08, 0x91, 0x0b, 0x03, 0x6c, 0xd7, 0xc6, 0x25, 0xcb, 0xe5, 0x83, 0xad, 0x42, 0xaa, 0x45, 0x54, - 0xd7, 0xb3, 0x65, 0xfa, 0xd5, 0x68, 0x13, 0x66, 0x24, 0xd0, 0x36, 0x94, 0x6b, 0x72, 0x33, 0x55, - 0xc8, 0xc3, 0xed, 0x28, 0xb6, 0x52, 0x9a, 0xe2, 0x08, 0x15, 0xf7, 0x6a, 0x07, 0xa6, 0xa8, 0x21, - 0x02, 0xc5, 0x86, 0x1b, 0x8b, 0xcf, 0x7a, 0xc0, 0xed, 0xf2, 0x05, 0xd7, 0x78, 0xc5, 0x21, 0xaa, - 0x83, 0x2e, 0xb8, 0x31, 0xa6, 0xfd, 0xa3, 0x8f, 0x5b, 0x30, 0x1c, 0xd5, 0x9a, 0x2b, 0x61, 0xb0, - 0xe5, 0xd6, 0x49, 0x28, 0x6c, 0xcc, 0x03, 0x4a, 0xb6, 0xea, 0xdc, 0x92, 0xec, 0x50, 0xd3, 0xe5, - 0xee, 0x0b, 0x0d, 0xc1, 0x26, 0x5d, 0xba, 0xf7, 0xba, 0x5f, 0xbc, 0xfb, 0x3c, 0xa9, 0xb1, 0x15, - 0x27, 0xf7, 0xcc, 0x6c, 0xa6, 0x1c, 0xd8, 0xe6, 0x9e, 0x6f, 0xd7, 0x36, 0xe9, 0x7a, 0xd3, 0x0c, - 0x3d, 0x70, 0x6b, 0x67, 0xf2, 0xfe, 0xb9, 0x6c, 0x9a, 0xb8, 0x17, 0x33, 0x6c, 0xc0, 0x5a, 0x6d, - 0xcf, 0xc3, 0xe4, 0x95, 0x36, 0x61, 0x1e, 0xb1, 0x1c, 0x06, 0x6c, 0x45, 0x77, 0x98, 0x1a, 0x30, - 0x03, 0x82, 0x4d, 0xba, 0xe8, 0x15, 0x18, 0x6c, 0x3a, 0x71, 0xe8, 0x6e, 0x0b, 0x37, 0xd8, 0x01, - 0x77, 0x41, 0x4b, 0xac, 0x2f, 0x4d, 0x9c, 0x29, 0x7a, 0xde, 0x88, 0x05, 0x21, 0xd4, 0x84, 0x52, - 0x93, 0x84, 0x0d, 0x32, 0x51, 0xce, 0xc3, 0xe5, 0xbf, 0x44, 0xbb, 0xd2, 0x04, 0x2b, 0xd4, 0xb8, - 0x62, 0x6d, 0x98, 0x53, 0x41, 0x2f, 0x41, 0x39, 0x22, 0x1e, 0xa9, 0x51, 0xf3, 0xa8, 0xc2, 0x28, - 0x3e, 0xdd, 0xa7, 0xa9, 0x48, 0xed, 0x92, 0xaa, 0x78, 0x94, 0x2f, 0x30, 0xf9, 0x0f, 0xab, 0x2e, - 0xe9, 0x00, 0xb6, 0xbc, 0x76, 0xc3, 0xf5, 0x27, 0x20, 0x8f, 0x01, 0x5c, 0x61, 0x7d, 0xa5, 0x06, - 0x90, 0x37, 0x62, 0x41, 0xc8, 0xfe, 0xaf, 0x16, 0xa0, 0xa4, 0x50, 0x3b, 0x02, 0x9b, 0xf8, 0x95, - 0xa4, 0x4d, 0xbc, 0x98, 0xa7, 0xd1, 0xd2, 0xc3, 0x2c, 0xfe, 0xcd, 0x0a, 0xa4, 0xd4, 0xc1, 0x15, - 0x12, 0xc5, 0xa4, 0xfe, 0xba, 0x08, 0x7f, 0x5d, 0x84, 0xbf, 0x2e, 0xc2, 0x95, 0x08, 0x5f, 0x4b, - 0x89, 0xf0, 0x77, 0x18, 0xab, 0x5e, 0xc7, 0x1e, 0xbc, 0xac, 0x82, 0x13, 0x4c, 0x0e, 0x0c, 0x04, - 0x2a, 0x09, 0x2e, 0x55, 0x97, 0xaf, 0x64, 0xca, 0xec, 0x97, 0x93, 0x32, 0xfb, 0xa0, 0x24, 0x7e, - 0x18, 0xa4, 0xf4, 0xd7, 0x2d, 0x78, 0x53, 0x52, 0x7a, 0xc9, 0x99, 0xb3, 0xd0, 0xf0, 0x83, 0x90, - 0xcc, 0xbb, 0xeb, 0xeb, 0x24, 0x24, 0x7e, 0x8d, 0x44, 0xca, 0xb7, 0x63, 0xf5, 0xf2, 0xed, 0xa0, - 0x67, 0x60, 0xe4, 0x46, 0x14, 0xf8, 0x2b, 0x81, 0xeb, 0x0b, 0x11, 0x44, 0x77, 0x1c, 0xc7, 0x6e, - 0xed, 0x4c, 0x8e, 0xd0, 0x11, 0x95, 0xed, 0x38, 0x81, 0x85, 0xe6, 0xe0, 0xf8, 0x8d, 0x57, 0x56, - 0x9c, 0xd8, 0xf0, 0x26, 0xc8, 0x7d, 0x3f, 0x3b, 0x8f, 0xba, 0xf4, 0x42, 0x0a, 0x88, 0xbb, 0xf1, - 0xed, 0xbf, 0x5d, 0x80, 0xd3, 0xa9, 0x17, 0x09, 0x3c, 0x2f, 0x68, 0xc7, 0x74, 0x4f, 0x84, 0xbe, - 0x6c, 0xc1, 0xb1, 0x66, 0xd2, 0x61, 0x11, 0x09, 0x77, 0xf7, 0xbb, 0x72, 0xd3, 0x11, 0x29, 0x8f, - 0xc8, 0xec, 0x84, 0x18, 0xa1, 0x63, 0x29, 0x40, 0x84, 0xbb, 0x78, 0x41, 0x2f, 0x41, 0xa5, 0xe9, - 0x6c, 0x5f, 0x6d, 0xd5, 0x9d, 0x58, 0x6e, 0x47, 0x7b, 0x7b, 0x11, 0xda, 0xb1, 0xeb, 0x4d, 0xf1, - 0xa8, 0x96, 0xa9, 0x05, 0x3f, 0x5e, 0x0e, 0xab, 0x71, 0xe8, 0xfa, 0x0d, 0xee, 0xe4, 0x5c, 0x92, - 0xdd, 0x60, 0xdd, 0xa3, 0xfd, 0x25, 0x2b, 0xad, 0xa4, 0xd4, 0xe8, 0x84, 0x4e, 0x4c, 0x1a, 0x1d, - 0xf4, 0x01, 0x28, 0xd1, 0x7d, 0xa3, 0x1c, 0x95, 0xeb, 0x79, 0x6a, 0x4e, 0xe3, 0x4b, 0x68, 0x25, - 0x4a, 0xff, 0x45, 0x98, 0x13, 0xb5, 0xbf, 0x5c, 0x49, 0x1b, 0x0b, 0xec, 0x6c, 0xfe, 0x29, 0x80, - 0x46, 0xb0, 0x4a, 0x9a, 0x2d, 0x8f, 0x0e, 0x8b, 0xc5, 0x0e, 0x78, 0x94, 0xab, 0xe4, 0x82, 0x82, - 0x60, 0x03, 0x0b, 0xfd, 0xbc, 0x05, 0xd0, 0x90, 0x73, 0x5e, 0x1a, 0x02, 0x57, 0xf3, 0x7c, 0x1d, - 0xbd, 0xa2, 0x34, 0x2f, 0x8a, 0x20, 0x36, 0x88, 0xa3, 0x9f, 0xb1, 0xa0, 0x1c, 0x4b, 0xf6, 0xb9, - 0x6a, 0x5c, 0xcd, 0x93, 0x13, 0xf9, 0xd2, 0xda, 0x26, 0x52, 0x43, 0xa2, 0xe8, 0xa2, 0x9f, 0xb5, - 0x00, 0xa2, 0x8e, 0x5f, 0x5b, 0x09, 0x3c, 0xb7, 0xd6, 0x11, 0x1a, 0xf3, 0x5a, 0xae, 0xee, 0x1c, - 0xd5, 0xfb, 0xec, 0x18, 0x1d, 0x0d, 0xfd, 0x1f, 0x1b, 0x94, 0xd1, 0x87, 0xa0, 0x1c, 0x89, 0xe9, - 0x26, 0x74, 0xe4, 0x6a, 0xbe, 0x4e, 0x25, 0xde, 0xb7, 0x10, 0xaf, 0xe2, 0x1f, 0x56, 0x34, 0xd1, - 0x2f, 0x59, 0x30, 0xde, 0x4a, 0xba, 0x09, 0x85, 0x3a, 0xcc, 0x4f, 0x06, 0xa4, 0xdc, 0x90, 0xdc, - 0xdb, 0x92, 0x6a, 0xc4, 0x69, 0x2e, 0xa8, 0x04, 0xd4, 0x33, 0x78, 0xb9, 0xc5, 0x5d, 0x96, 0x43, - 0x5a, 0x02, 0x5e, 0x48, 0x03, 0x71, 0x37, 0x3e, 0x5a, 0x81, 0x93, 0x94, 0xbb, 0x0e, 0x37, 0x3f, - 0xa5, 0x7a, 0x89, 0x98, 0x32, 0x2c, 0xcf, 0x3e, 0x28, 0x66, 0x08, 0x3b, 0xeb, 0x48, 0xe3, 0xe0, - 0xcc, 0x27, 0xd1, 0x1f, 0x5a, 0xf0, 0xa0, 0xcb, 0xd4, 0x80, 0xe9, 0xb0, 0xd7, 0x1a, 0x41, 0x1c, - 0xb4, 0x93, 0x5c, 0x65, 0x45, 0x2f, 0xf5, 0x33, 0xfb, 0x46, 0xf1, 0x06, 0x0f, 0x2e, 0xec, 0xc2, - 0x12, 0xde, 0x95, 0x61, 0xf4, 0x13, 0x30, 0x2a, 0xd7, 0xc5, 0x0a, 0x15, 0xc1, 0x4c, 0xd1, 0x56, - 0x66, 0x8f, 0xdf, 0xda, 0x99, 0x1c, 0x5d, 0x35, 0x01, 0x38, 0x89, 0x67, 0xff, 0x9b, 0x62, 0xe2, - 0x94, 0x48, 0xf9, 0x30, 0x99, 0xb8, 0xa9, 0x49, 0xff, 0x8f, 0x94, 0x9e, 0xb9, 0x8a, 0x1b, 0xe5, - 0x5d, 0xd2, 0xe2, 0x46, 0x35, 0x45, 0xd8, 0x20, 0x4e, 0x8d, 0xd2, 0xe3, 0x4e, 0xda, 0x53, 0x2a, - 0x24, 0xe0, 0x4b, 0x79, 0xb2, 0xd4, 0x7d, 0xa6, 0x77, 0x5a, 0xb0, 0x76, 0xbc, 0x0b, 0x84, 0xbb, - 0x59, 0x42, 0x1f, 0x84, 0x4a, 0xa8, 0x22, 0x5b, 0x8a, 0x79, 0x6c, 0xd5, 0xe4, 0xb4, 0x11, 0xec, - 0xa8, 0x03, 0x20, 0x1d, 0xc3, 0xa2, 0x29, 0xda, 0x7f, 0x90, 0x3c, 0x18, 0x33, 0x64, 0x47, 0x1f, - 0x87, 0x7e, 0x9f, 0xb1, 0x60, 0x38, 0x0c, 0x3c, 0xcf, 0xf5, 0x1b, 0x54, 0xce, 0x09, 0x65, 0xfd, - 0x9e, 0x43, 0xd1, 0x97, 0x42, 0xa0, 0x31, 0xcb, 0x1a, 0x6b, 0x9a, 0xd8, 0x64, 0xc0, 0xfe, 0x73, - 0x0b, 0x26, 0x7a, 0xc9, 0x63, 0x44, 0xe0, 0x01, 0x29, 0x6c, 0xd4, 0x50, 0x2c, 0xfb, 0xf3, 0xc4, - 0x23, 0xca, 0x6d, 0x5e, 0x9e, 0x7d, 0x44, 0xbc, 0xe6, 0x03, 0x2b, 0xbd, 0x51, 0xf1, 0x6e, 0xfd, - 0xa0, 0x17, 0xe1, 0x98, 0xf1, 0x5e, 0x91, 0x1a, 0x98, 0xca, 0xec, 0x14, 0x35, 0x80, 0x66, 0x52, - 0xb0, 0xdb, 0x3b, 0x93, 0xf7, 0xa5, 0xdb, 0x84, 0xc2, 0xe8, 0xea, 0xc7, 0xfe, 0xd5, 0x42, 0xfa, - 0x6b, 0x29, 0x5d, 0xff, 0x9a, 0xd5, 0xe5, 0x4d, 0x78, 0xd7, 0x61, 0xe8, 0x57, 0xe6, 0x77, 0x50, - 0x61, 0x18, 0xbd, 0x71, 0xee, 0xe2, 0xb1, 0xbd, 0xfd, 0x6f, 0x07, 0x60, 0x17, 0xce, 0xfa, 0x30, - 0xde, 0xf7, 0x7d, 0x8e, 0xfa, 0x29, 0x4b, 0x1d, 0x98, 0xf1, 0x35, 0x5c, 0x3f, 0xac, 0xb1, 0xe7, - 0xfb, 0xa7, 0x88, 0x87, 0x8e, 0x28, 0x2f, 0x7a, 0xf2, 0x68, 0x0e, 0x7d, 0xc5, 0x4a, 0x1e, 0xf9, - 0xf1, 0xa0, 0x46, 0xf7, 0xd0, 0x78, 0x32, 0xce, 0x11, 0x39, 0x63, 0xfa, 0xf4, 0xa9, 0xd7, 0x09, - 0xe3, 0x14, 0xc0, 0xba, 0xeb, 0x3b, 0x9e, 0xfb, 0x2a, 0xdd, 0x1d, 0x95, 0x98, 0x82, 0x67, 0x16, - 0xd3, 0x79, 0xd5, 0x8a, 0x0d, 0x8c, 0x33, 0xff, 0x3f, 0x0c, 0x1b, 0x6f, 0x9e, 0x11, 0xf1, 0x72, - 0xd2, 0x8c, 0x78, 0xa9, 0x18, 0x81, 0x2a, 0x67, 0xde, 0x01, 0xc7, 0xd2, 0x0c, 0xee, 0xe7, 0x79, - 0xfb, 0x7f, 0x0d, 0xa5, 0xcf, 0xe0, 0x56, 0x49, 0xd8, 0xa4, 0xac, 0xbd, 0xee, 0xd8, 0x7a, 0xdd, - 0xb1, 0xf5, 0xba, 0x63, 0xcb, 0x3c, 0x9b, 0x10, 0x4e, 0x9b, 0xa1, 0x23, 0x72, 0xda, 0x24, 0xdc, - 0x50, 0xe5, 0xdc, 0xdd, 0x50, 0xf6, 0xc7, 0xbb, 0x3c, 0xf7, 0xab, 0x21, 0x21, 0x28, 0x80, 0x92, - 0x1f, 0xd4, 0x89, 0xb4, 0x71, 0x2f, 0xe5, 0x63, 0xb0, 0x5d, 0x09, 0xea, 0x46, 0xb8, 0x38, 0xfd, - 0x17, 0x61, 0x4e, 0xc7, 0xfe, 0xd8, 0x20, 0x24, 0xcc, 0x49, 0xfe, 0xdd, 0x7f, 0x0c, 0x86, 0x42, - 0xd2, 0x0a, 0xae, 0xe2, 0x45, 0xa1, 0xcb, 0x74, 0xb6, 0x0d, 0x6f, 0xc6, 0x12, 0x4e, 0x75, 0x5e, - 0xcb, 0x89, 0x37, 0x84, 0x32, 0x53, 0x3a, 0x6f, 0xc5, 0x89, 0x37, 0x30, 0x83, 0xa0, 0x77, 0xc0, - 0x58, 0x9c, 0x38, 0x0a, 0x17, 0x47, 0xbe, 0xf7, 0x09, 0xdc, 0xb1, 0xe4, 0x41, 0x39, 0x4e, 0x61, - 0xa3, 0x57, 0x60, 0x60, 0x83, 0x78, 0x4d, 0xf1, 0xe9, 0xab, 0xf9, 0xe9, 0x1a, 0xf6, 0xae, 0x17, - 0x89, 0xd7, 0xe4, 0x92, 0x90, 0xfe, 0xc2, 0x8c, 0x14, 0x9d, 0xf7, 0x95, 0xcd, 0x76, 0x14, 0x07, - 0x4d, 0xf7, 0x55, 0xe9, 0xe9, 0x7c, 0x57, 0xce, 0x84, 0x2f, 0xcb, 0xfe, 0xb9, 0x4b, 0x49, 0xfd, - 0xc5, 0x9a, 0x32, 0xe3, 0xa3, 0xee, 0x86, 0x6c, 0xca, 0x74, 0x84, 0xc3, 0x32, 0x6f, 0x3e, 0xe6, - 0x65, 0xff, 0x9c, 0x0f, 0xf5, 0x17, 0x6b, 0xca, 0xa8, 0xa3, 0xd6, 0xdf, 0x30, 0xe3, 0xe1, 0x6a, - 0xce, 0x3c, 0xf0, 0xb5, 0x97, 0xb9, 0x0e, 0x1f, 0x81, 0x52, 0x6d, 0xc3, 0x09, 0xe3, 0x89, 0x11, - 0x36, 0x69, 0xd4, 0x2c, 0x9e, 0xa3, 0x8d, 0x98, 0xc3, 0xd0, 0x43, 0x50, 0x0c, 0xc9, 0x3a, 0x8b, - 0x4e, 0x36, 0xe2, 0xa2, 0x30, 0x59, 0xc7, 0xb4, 0x5d, 0xd9, 0x65, 0x63, 0x3d, 0x03, 0xe6, 0x7e, - 0xb9, 0x90, 0x34, 0xec, 0x92, 0x23, 0xc3, 0xd7, 0x43, 0xad, 0x1d, 0x46, 0xd2, 0x41, 0x66, 0xac, - 0x07, 0xd6, 0x8c, 0x25, 0x1c, 0x7d, 0xc4, 0x82, 0xa1, 0x1b, 0x51, 0xe0, 0xfb, 0x24, 0x16, 0x4a, - 0xf4, 0x5a, 0xce, 0x83, 0x75, 0x89, 0xf7, 0xae, 0x79, 0x10, 0x0d, 0x58, 0xd2, 0xa5, 0xec, 0x92, - 0xed, 0x9a, 0xd7, 0xae, 0x77, 0x05, 0xc3, 0x9c, 0xe3, 0xcd, 0x58, 0xc2, 0x29, 0xaa, 0xeb, 0x73, - 0xd4, 0x81, 0x24, 0xea, 0x82, 0x2f, 0x50, 0x05, 0xdc, 0xfe, 0xf5, 0x32, 0x9c, 0xca, 0x5c, 0x3e, - 0xd4, 0xe4, 0x62, 0x46, 0xcd, 0x79, 0xd7, 0x23, 0x32, 0x0c, 0x8c, 0x99, 0x5c, 0xd7, 0x54, 0x2b, - 0x36, 0x30, 0xd0, 0x4f, 0x03, 0xb4, 0x9c, 0xd0, 0x69, 0x12, 0xe5, 0xc0, 0x3e, 0xb0, 0x65, 0x43, - 0xf9, 0x58, 0x91, 0x7d, 0xea, 0x4d, 0xbc, 0x6a, 0x8a, 0xb0, 0x41, 0x12, 0x3d, 0x0b, 0xc3, 0x21, - 0xf1, 0x88, 0x13, 0xb1, 0xf0, 0xf7, 0x74, 0x2e, 0x0f, 0xd6, 0x20, 0x6c, 0xe2, 0xa1, 0x47, 0x55, - 0xc4, 0x5c, 0x2a, 0x72, 0x28, 0x19, 0x35, 0x87, 0x3e, 0x6b, 0xc1, 0xd8, 0xba, 0xeb, 0x11, 0x4d, - 0x5d, 0x64, 0xde, 0x2c, 0x1f, 0xfc, 0x25, 0xcf, 0x9b, 0xfd, 0x6a, 0x19, 0x9a, 0x68, 0x8e, 0x70, - 0x8a, 0x3c, 0xfd, 0xcc, 0x5b, 0x24, 0x64, 0xc2, 0x77, 0x30, 0xf9, 0x99, 0xaf, 0xf1, 0x66, 0x2c, - 0xe1, 0x68, 0x06, 0xc6, 0x5b, 0x4e, 0x14, 0xcd, 0x85, 0xa4, 0x4e, 0xfc, 0xd8, 0x75, 0x3c, 0x9e, - 0x17, 0x53, 0xd6, 0xe1, 0xe4, 0x2b, 0x49, 0x30, 0x4e, 0xe3, 0xa3, 0x77, 0xc3, 0xfd, 0xdc, 0x43, - 0xb4, 0xe4, 0x46, 0x91, 0xeb, 0x37, 0xf4, 0x34, 0x10, 0x8e, 0xb2, 0x49, 0xd1, 0xd5, 0xfd, 0x0b, - 0xd9, 0x68, 0xb8, 0xd7, 0xf3, 0xe8, 0x71, 0x28, 0x47, 0x9b, 0x6e, 0x6b, 0x2e, 0xac, 0x47, 0xec, - 0x74, 0xa8, 0xac, 0xdd, 0xb2, 0x55, 0xd1, 0x8e, 0x15, 0x06, 0xaa, 0xc1, 0x08, 0xff, 0x24, 0x3c, - 0xe4, 0x4f, 0x48, 0xd0, 0x27, 0x7a, 0x2a, 0x72, 0x91, 0x02, 0x3b, 0x85, 0x9d, 0x9b, 0xe7, 0xe4, - 0x59, 0x15, 0x3f, 0x5a, 0xb9, 0x66, 0x74, 0x83, 0x13, 0x9d, 0x26, 0xf7, 0x74, 0xc3, 0x7d, 0xec, - 0xe9, 0x9e, 0x85, 0xe1, 0xcd, 0xf6, 0x1a, 0x11, 0x23, 0x2f, 0x04, 0x9b, 0x9a, 0x7d, 0x97, 0x35, - 0x08, 0x9b, 0x78, 0x2c, 0xda, 0xb2, 0xe5, 0x8a, 0x7f, 0xd1, 0xc4, 0xa8, 0x11, 0x6d, 0xb9, 0xb2, - 0x20, 0x9b, 0xb1, 0x89, 0x43, 0x59, 0xa3, 0x63, 0xb1, 0x4a, 0x22, 0x96, 0x4c, 0x41, 0x87, 0x4b, - 0xb1, 0x56, 0x95, 0x00, 0xac, 0x71, 0xd0, 0x0a, 0x9c, 0xa4, 0x7f, 0xaa, 0x2c, 0x05, 0xf8, 0x9a, - 0xe3, 0xb9, 0x75, 0x1e, 0xfa, 0x37, 0x9e, 0xf4, 0x6f, 0x56, 0x33, 0x70, 0x70, 0xe6, 0x93, 0xf6, - 0x17, 0x0b, 0x49, 0xcf, 0x89, 0x29, 0xc2, 0x50, 0x44, 0x05, 0x55, 0x7c, 0xcd, 0x09, 0xa5, 0xc1, - 0x73, 0xc0, 0xe4, 0x26, 0xd1, 0xef, 0x35, 0x27, 0x34, 0x45, 0x1e, 0x23, 0x80, 0x25, 0x25, 0x74, - 0x03, 0x06, 0x62, 0xcf, 0xc9, 0x29, 0x1b, 0xd2, 0xa0, 0xa8, 0x1d, 0x59, 0x8b, 0x33, 0x11, 0x66, - 0x34, 0xd0, 0x83, 0x74, 0xf7, 0xb6, 0x26, 0x4f, 0xda, 0xc4, 0x86, 0x6b, 0x2d, 0xc2, 0xac, 0xd5, - 0xfe, 0xc5, 0xd1, 0x0c, 0xad, 0xa3, 0x0c, 0x01, 0xf4, 0x14, 0x00, 0x9d, 0x34, 0x2b, 0x21, 0x59, - 0x77, 0xb7, 0x85, 0x21, 0xa6, 0x24, 0xdb, 0x15, 0x05, 0xc1, 0x06, 0x96, 0x7c, 0xa6, 0xda, 0x5e, - 0xa7, 0xcf, 0x14, 0xba, 0x9f, 0xe1, 0x10, 0x6c, 0x60, 0xa1, 0x67, 0x60, 0xd0, 0x6d, 0x3a, 0x0d, - 0x15, 0x08, 0xfc, 0x20, 0x15, 0x69, 0x0b, 0xac, 0xe5, 0xf6, 0xce, 0xe4, 0x98, 0x62, 0x88, 0x35, - 0x61, 0x81, 0x8b, 0x7e, 0xd5, 0x82, 0x91, 0x5a, 0xd0, 0x6c, 0x06, 0x3e, 0xdf, 0x3e, 0x0b, 0x5f, - 0xc0, 0x8d, 0xc3, 0x32, 0x93, 0xa6, 0xe6, 0x0c, 0x62, 0xdc, 0x19, 0xa0, 0xd2, 0x36, 0x4d, 0x10, - 0x4e, 0x70, 0x65, 0x4a, 0xbe, 0xd2, 0x1e, 0x92, 0xef, 0x37, 0x2c, 0x38, 0xce, 0x9f, 0x35, 0x76, - 0xf5, 0x22, 0x43, 0x31, 0x38, 0xe4, 0xd7, 0xea, 0x72, 0x74, 0x28, 0x67, 0x6f, 0x17, 0x1c, 0x77, - 0x33, 0x89, 0x2e, 0xc0, 0xf1, 0xf5, 0x20, 0xac, 0x11, 0x73, 0x20, 0x84, 0xd8, 0x56, 0x1d, 0x9d, - 0x4f, 0x23, 0xe0, 0xee, 0x67, 0xd0, 0x35, 0xb8, 0xcf, 0x68, 0x34, 0xc7, 0x81, 0x4b, 0xee, 0x87, - 0x45, 0x6f, 0xf7, 0x9d, 0xcf, 0xc4, 0xc2, 0x3d, 0x9e, 0x4e, 0x0a, 0xc9, 0x4a, 0x1f, 0x42, 0xf2, - 0x65, 0x38, 0x5d, 0xeb, 0x1e, 0x99, 0xad, 0xa8, 0xbd, 0x16, 0x71, 0x39, 0x5e, 0x9e, 0xfd, 0x11, - 0xd1, 0xc1, 0xe9, 0xb9, 0x5e, 0x88, 0xb8, 0x77, 0x1f, 0xe8, 0x03, 0x50, 0x0e, 0x09, 0xfb, 0x2a, - 0x91, 0x48, 0xd7, 0x3b, 0xa0, 0xb7, 0x43, 0x5b, 0xf0, 0xbc, 0x5b, 0xad, 0x99, 0x44, 0x43, 0x84, - 0x15, 0x45, 0x74, 0x13, 0x86, 0x5a, 0x4e, 0x5c, 0xdb, 0x10, 0x49, 0x7a, 0x07, 0xf6, 0xcd, 0x2b, - 0xe2, 0xec, 0x28, 0xc5, 0x28, 0x79, 0xc0, 0x89, 0x60, 0x49, 0x8d, 0xda, 0x6a, 0xb5, 0xa0, 0xd9, - 0x0a, 0x7c, 0xe2, 0xc7, 0x52, 0x89, 0x8c, 0xf1, 0xf3, 0x0e, 0xd9, 0x8a, 0x0d, 0x8c, 0x2e, 0x5d, - 0xae, 0xd1, 0x26, 0x8e, 0xef, 0xa2, 0xcb, 0x8d, 0xde, 0x7a, 0x3d, 0x4f, 0x95, 0x0d, 0x73, 0x2b, - 0x5e, 0x77, 0xe3, 0x8d, 0xa0, 0x1d, 0xcb, 0x5d, 0xb2, 0x50, 0x54, 0x4a, 0xd9, 0x2c, 0x66, 0xe0, - 0xe0, 0xcc, 0x27, 0xd3, 0x9a, 0x75, 0xfc, 0xce, 0x34, 0xeb, 0xb1, 0x3e, 0x34, 0x6b, 0x15, 0x4e, - 0x31, 0x0e, 0x84, 0x95, 0x2c, 0x9d, 0x96, 0xd1, 0x04, 0x62, 0xcc, 0xab, 0xfc, 0x96, 0xc5, 0x2c, - 0x24, 0x9c, 0xfd, 0xec, 0x99, 0x77, 0xc2, 0xf1, 0x2e, 0x21, 0xb7, 0x2f, 0x87, 0xe4, 0x3c, 0xdc, - 0x97, 0x2d, 0x4e, 0xf6, 0xe5, 0x96, 0xfc, 0xf5, 0x54, 0x5c, 0xba, 0xb1, 0x45, 0xeb, 0xc3, 0xc5, - 0xed, 0x40, 0x91, 0xf8, 0x5b, 0x42, 0xbb, 0x9e, 0x3f, 0xd8, 0xac, 0x3e, 0xe7, 0x6f, 0x71, 0x69, - 0xc8, 0xfc, 0x78, 0xe7, 0xfc, 0x2d, 0x4c, 0xfb, 0x46, 0x9f, 0xb7, 0x12, 0x1b, 0x08, 0xee, 0x18, - 0x7f, 0xdf, 0xa1, 0xec, 0x49, 0xfb, 0xde, 0x53, 0xd8, 0xff, 0xae, 0x00, 0x67, 0xf7, 0xea, 0xa4, - 0x8f, 0xe1, 0x7b, 0x04, 0x06, 0x23, 0x16, 0x69, 0x22, 0xd4, 0xd5, 0x30, 0x5d, 0xc5, 0x3c, 0xf6, - 0xe4, 0x65, 0x2c, 0x40, 0xc8, 0x83, 0x62, 0xd3, 0x69, 0x09, 0x7f, 0xe9, 0xc2, 0x41, 0xf3, 0xf7, - 0xe8, 0x7f, 0xc7, 0x5b, 0x72, 0x5a, 0x7c, 0xce, 0x1b, 0x0d, 0x98, 0x92, 0x41, 0x31, 0x94, 0x9c, - 0x30, 0x74, 0x64, 0x58, 0xc3, 0xe5, 0x7c, 0xe8, 0xcd, 0xd0, 0x2e, 0xf9, 0xa9, 0x70, 0xa2, 0x09, - 0x73, 0x62, 0xf6, 0x2f, 0x95, 0x13, 0xc9, 0x5e, 0x2c, 0x56, 0x25, 0x82, 0x41, 0xe1, 0x26, 0xb5, - 0xf2, 0x4e, 0x9b, 0xe4, 0xd9, 0xd4, 0xcc, 0x03, 0x21, 0x6a, 0x52, 0x08, 0x52, 0xe8, 0x93, 0x16, - 0xab, 0xfc, 0x20, 0x33, 0xe8, 0xc4, 0xae, 0xfe, 0x70, 0x0a, 0x51, 0x98, 0xf5, 0x24, 0x64, 0x23, - 0x36, 0xa9, 0x8b, 0xea, 0x36, 0x6c, 0x37, 0xd3, 0x5d, 0xdd, 0x86, 0xed, 0x4e, 0x24, 0x1c, 0x6d, - 0x67, 0xc4, 0xa4, 0xe4, 0x50, 0x3d, 0xa0, 0x8f, 0x28, 0x94, 0xaf, 0x58, 0x70, 0xdc, 0x4d, 0x07, - 0x17, 0x88, 0x3d, 0xf0, 0xf5, 0x7c, 0x7c, 0x9a, 0xdd, 0xb1, 0x0b, 0xca, 0xd0, 0xe9, 0x02, 0xe1, - 0x6e, 0x66, 0x50, 0x1d, 0x06, 0x5c, 0x7f, 0x3d, 0x10, 0xe6, 0xdd, 0xec, 0xc1, 0x98, 0x5a, 0xf0, - 0xd7, 0x03, 0xbd, 0x9a, 0xe9, 0x3f, 0xcc, 0x7a, 0x47, 0x8b, 0x70, 0x52, 0xe6, 0xfb, 0x5c, 0x74, - 0xa3, 0x38, 0x08, 0x3b, 0x8b, 0x6e, 0xd3, 0x8d, 0x99, 0x69, 0x56, 0x9c, 0x9d, 0xa0, 0xea, 0x0d, - 0x67, 0xc0, 0x71, 0xe6, 0x53, 0xe8, 0x55, 0x18, 0x92, 0x07, 0xfa, 0xe5, 0x3c, 0xfc, 0x09, 0xdd, - 0xf3, 0x5f, 0x4d, 0xa6, 0xaa, 0x38, 0xd1, 0x97, 0x04, 0xd1, 0x27, 0x2c, 0x18, 0xe3, 0xbf, 0x2f, - 0x76, 0xea, 0x3c, 0xc5, 0xb0, 0x92, 0x47, 0xd4, 0x7e, 0x35, 0xd1, 0xe7, 0x2c, 0xba, 0xb5, 0x33, - 0x39, 0x96, 0x6c, 0xc3, 0x29, 0xba, 0xf6, 0x3f, 0x1c, 0x81, 0xee, 0x10, 0x88, 0x64, 0xbc, 0x83, - 0x75, 0xd4, 0xf1, 0x0e, 0x74, 0x57, 0x19, 0xe9, 0x50, 0x85, 0x1c, 0x96, 0x99, 0xa0, 0xaa, 0x8f, - 0xa1, 0x3b, 0x7e, 0x0d, 0x33, 0x1a, 0xa8, 0x0d, 0x83, 0xbc, 0xb8, 0x94, 0xd0, 0x00, 0x07, 0x3f, - 0xf9, 0x36, 0x8b, 0x54, 0x69, 0xb7, 0x16, 0x6f, 0xc5, 0x82, 0x18, 0xda, 0x86, 0xa1, 0x0d, 0x3e, - 0x1d, 0xc5, 0x5e, 0x6f, 0xe9, 0xa0, 0xe3, 0x9b, 0x98, 0xe3, 0x7a, 0xf2, 0x89, 0x06, 0x2c, 0xc9, - 0xb1, 0xf0, 0x3a, 0x23, 0x00, 0x88, 0x0b, 0x92, 0xfc, 0xb2, 0x25, 0xfb, 0x8f, 0xfe, 0x79, 0x3f, - 0x8c, 0x84, 0xa4, 0x16, 0xf8, 0x35, 0xd7, 0x23, 0xf5, 0x19, 0x79, 0x20, 0xb6, 0x9f, 0x24, 0x39, - 0xe6, 0x4d, 0xc2, 0x46, 0x1f, 0x38, 0xd1, 0x23, 0x5b, 0x67, 0x2a, 0x71, 0x9e, 0x7e, 0x10, 0x22, - 0x0e, 0x3e, 0x16, 0x73, 0x4a, 0xd3, 0x67, 0x7d, 0xf2, 0x75, 0x96, 0x6c, 0xc3, 0x29, 0xba, 0xe8, - 0x45, 0x80, 0x60, 0x8d, 0xc7, 0xd0, 0xcd, 0xc4, 0xe2, 0x14, 0x64, 0x3f, 0xaf, 0x3a, 0xc6, 0x93, - 0x6d, 0x65, 0x0f, 0xd8, 0xe8, 0x0d, 0x5d, 0x06, 0xe0, 0x2b, 0x67, 0xb5, 0xd3, 0x92, 0x1b, 0x42, - 0x99, 0xe5, 0x08, 0x55, 0x05, 0xb9, 0xbd, 0x33, 0xd9, 0xed, 0x73, 0x66, 0x81, 0x42, 0xc6, 0xe3, - 0xe8, 0xa7, 0x60, 0x28, 0x6a, 0x37, 0x9b, 0x8e, 0x3a, 0x23, 0xc9, 0x31, 0x7d, 0x97, 0xf7, 0x6b, - 0x08, 0x46, 0xde, 0x80, 0x25, 0x45, 0x74, 0x83, 0x8a, 0x78, 0x21, 0xa1, 0xf8, 0x2a, 0xe2, 0x16, - 0x0a, 0xf7, 0x04, 0xbe, 0x45, 0xee, 0x62, 0x70, 0x06, 0xce, 0xed, 0x9d, 0xc9, 0xfb, 0x92, 0xed, - 0x8b, 0x81, 0x48, 0xa8, 0xcd, 0xec, 0x13, 0x5d, 0x92, 0x75, 0xb4, 0xe8, 0x6b, 0xcb, 0xf2, 0x2e, - 0x8f, 0xe9, 0x3a, 0x5a, 0xac, 0xb9, 0xf7, 0x98, 0x99, 0x0f, 0xa3, 0x25, 0x38, 0x51, 0x0b, 0xfc, - 0x38, 0x0c, 0x3c, 0x8f, 0xd7, 0xd8, 0xe3, 0x7b, 0x73, 0x7e, 0x86, 0xf2, 0x80, 0x60, 0xfb, 0xc4, - 0x5c, 0x37, 0x0a, 0xce, 0x7a, 0x8e, 0xda, 0xe4, 0x69, 0xfd, 0x30, 0x96, 0xcb, 0xf1, 0x7a, 0xa2, - 0x4f, 0x21, 0xa1, 0x94, 0xdb, 0x7b, 0x0f, 0x4d, 0xe1, 0x27, 0x0f, 0x59, 0xc5, 0x17, 0x7b, 0x06, - 0x46, 0xc8, 0x76, 0x4c, 0x42, 0xdf, 0xf1, 0xae, 0xe2, 0x45, 0x79, 0x60, 0xc1, 0x16, 0xe6, 0x39, - 0xa3, 0x1d, 0x27, 0xb0, 0x90, 0xad, 0xbc, 0x64, 0x46, 0xe6, 0x3a, 0xf7, 0x92, 0x49, 0x9f, 0x98, - 0xfd, 0xb5, 0x62, 0xc2, 0x66, 0xbd, 0x2b, 0x47, 0xba, 0xac, 0x44, 0x92, 0xac, 0x25, 0xc5, 0x00, - 0x62, 0x2f, 0x96, 0x27, 0x65, 0x55, 0x22, 0x69, 0xd9, 0x24, 0x84, 0x93, 0x74, 0xd1, 0x26, 0x94, - 0x36, 0x82, 0x28, 0x96, 0x3b, 0xb4, 0x03, 0x6e, 0x06, 0x2f, 0x06, 0x51, 0xcc, 0x0c, 0x2d, 0xf5, - 0xda, 0xb4, 0x25, 0xc2, 0x9c, 0x06, 0xdd, 0xfb, 0x47, 0x1b, 0x4e, 0x58, 0x8f, 0xe6, 0x58, 0x9d, - 0x89, 0x01, 0x66, 0x61, 0x29, 0x7b, 0xba, 0xaa, 0x41, 0xd8, 0xc4, 0xb3, 0xbf, 0x67, 0x25, 0x4e, - 0xb5, 0xae, 0xb3, 0xa4, 0x81, 0x2d, 0xe2, 0x53, 0x11, 0x65, 0x86, 0x29, 0xfe, 0x44, 0x2a, 0x05, - 0xfb, 0x4d, 0xbd, 0xca, 0x61, 0xde, 0xa4, 0x3d, 0x4c, 0xb1, 0x2e, 0x8c, 0x88, 0xc6, 0x0f, 0x5b, - 0xc9, 0x5c, 0xfa, 0x42, 0x1e, 0x5b, 0x37, 0xb3, 0x9e, 0xc4, 0x9e, 0x69, 0xf9, 0xf6, 0xe7, 0x2d, - 0x18, 0x9a, 0x75, 0x6a, 0x9b, 0xc1, 0xfa, 0x3a, 0x7a, 0x1c, 0xca, 0xf5, 0x76, 0x68, 0xa6, 0xf5, - 0x2b, 0x67, 0xd5, 0xbc, 0x68, 0xc7, 0x0a, 0x83, 0x4e, 0xfd, 0x75, 0xa7, 0x26, 0xab, 0x4a, 0x14, - 0xf9, 0xd4, 0x3f, 0xcf, 0x5a, 0xb0, 0x80, 0xd0, 0xe1, 0x6f, 0x3a, 0xdb, 0xf2, 0xe1, 0xf4, 0x91, - 0xda, 0x92, 0x06, 0x61, 0x13, 0xcf, 0xfe, 0x97, 0x16, 0x4c, 0xcc, 0x3a, 0x91, 0x5b, 0x9b, 0x69, - 0xc7, 0x1b, 0xb3, 0x6e, 0xbc, 0xd6, 0xae, 0x6d, 0x92, 0x98, 0x57, 0x1f, 0xa1, 0x5c, 0xb6, 0x23, - 0xba, 0x02, 0xd5, 0x8e, 0x59, 0x71, 0x79, 0x55, 0xb4, 0x63, 0x85, 0x81, 0x5e, 0x85, 0xe1, 0x96, - 0x13, 0x45, 0x37, 0x83, 0xb0, 0x8e, 0xc9, 0x7a, 0x3e, 0xf5, 0x89, 0xaa, 0xa4, 0x16, 0x92, 0x18, - 0x93, 0x75, 0x11, 0xa0, 0xa2, 0xfb, 0xc7, 0x26, 0x31, 0xfb, 0xe7, 0x2d, 0x38, 0x39, 0x4b, 0x9c, - 0x90, 0x84, 0xac, 0x9c, 0x91, 0x7a, 0x11, 0xf4, 0x0a, 0x94, 0x63, 0xda, 0x42, 0x39, 0xb2, 0xf2, - 0xe5, 0x88, 0x85, 0x96, 0xac, 0x8a, 0xce, 0xb1, 0x22, 0x63, 0x7f, 0xc6, 0x82, 0xd3, 0x59, 0xbc, - 0xcc, 0x79, 0x41, 0xbb, 0x7e, 0x37, 0x18, 0xfa, 0x5b, 0x16, 0x8c, 0xb0, 0xe3, 0xfa, 0x79, 0x12, - 0x3b, 0xae, 0xd7, 0x55, 0x4a, 0xd1, 0xea, 0xb3, 0x94, 0xe2, 0x59, 0x18, 0xd8, 0x08, 0x9a, 0x24, - 0x1d, 0x6a, 0x72, 0x31, 0x68, 0x12, 0xcc, 0x20, 0xe8, 0x49, 0x3a, 0x09, 0x5d, 0x3f, 0x76, 0xe8, - 0x72, 0x94, 0xc7, 0x19, 0xe3, 0x7c, 0x02, 0xaa, 0x66, 0x6c, 0xe2, 0xd8, 0xbf, 0x5b, 0x81, 0x21, - 0x11, 0x17, 0xd5, 0x77, 0x35, 0x1c, 0xe9, 0xc5, 0x29, 0xf4, 0xf4, 0xe2, 0x44, 0x30, 0x58, 0x63, - 0xf5, 0x6e, 0x85, 0x85, 0x7e, 0x39, 0x97, 0x40, 0x3a, 0x5e, 0x42, 0x57, 0xb3, 0xc5, 0xff, 0x63, - 0x41, 0x0a, 0x7d, 0xce, 0x82, 0xf1, 0x5a, 0xe0, 0xfb, 0xa4, 0xa6, 0x6d, 0xc7, 0x81, 0x3c, 0x36, - 0x08, 0x73, 0xc9, 0x4e, 0xf5, 0x49, 0x70, 0x0a, 0x80, 0xd3, 0xe4, 0xd1, 0xf3, 0x30, 0xca, 0xc7, - 0xec, 0x5a, 0xe2, 0x0c, 0x46, 0x57, 0xd8, 0x33, 0x81, 0x38, 0x89, 0x8b, 0xa6, 0xf8, 0x59, 0x96, - 0xa8, 0x65, 0x37, 0xa8, 0x5d, 0xd5, 0x46, 0x15, 0x3b, 0x03, 0x03, 0x85, 0x80, 0x42, 0xb2, 0x1e, - 0x92, 0x68, 0x43, 0xc4, 0x8d, 0x31, 0xbb, 0x75, 0xe8, 0xce, 0xea, 0x58, 0xe0, 0xae, 0x9e, 0x70, - 0x46, 0xef, 0x68, 0x53, 0xb8, 0x11, 0xca, 0x79, 0xc8, 0x73, 0xf1, 0x99, 0x7b, 0x7a, 0x13, 0x26, - 0xa1, 0xc4, 0x54, 0x17, 0xb3, 0x97, 0x8b, 0x3c, 0x77, 0x92, 0x29, 0x36, 0xcc, 0xdb, 0xd1, 0x3c, - 0x1c, 0x4b, 0xd5, 0x07, 0x8c, 0xc4, 0x59, 0x89, 0xca, 0x93, 0x4b, 0x55, 0x16, 0x8c, 0x70, 0xd7, - 0x13, 0xa6, 0x8b, 0x69, 0x78, 0x0f, 0x17, 0x53, 0x47, 0x45, 0x27, 0xf3, 0x53, 0x8c, 0x17, 0x72, - 0x19, 0x80, 0xbe, 0x42, 0x91, 0x3f, 0x9d, 0x0a, 0x45, 0x1e, 0x65, 0x0c, 0x5c, 0xcb, 0x87, 0x81, - 0xfd, 0xc7, 0x1d, 0xdf, 0xcd, 0x38, 0xe2, 0xff, 0x69, 0x81, 0xfc, 0xae, 0x73, 0x4e, 0x6d, 0x83, - 0xd0, 0x29, 0x83, 0xde, 0x01, 0x63, 0xca, 0x3b, 0xc1, 0x4d, 0x22, 0x8b, 0xcd, 0x1a, 0x65, 0x3b, - 0xe3, 0x04, 0x14, 0xa7, 0xb0, 0xd1, 0x34, 0x54, 0xe8, 0x38, 0xf1, 0x47, 0xb9, 0xde, 0x57, 0x1e, - 0x90, 0x99, 0x95, 0x05, 0xf1, 0x94, 0xc6, 0x41, 0x01, 0x1c, 0xf7, 0x9c, 0x28, 0x66, 0x1c, 0x54, - 0x3b, 0x7e, 0xed, 0x0e, 0xab, 0xc8, 0xb0, 0x64, 0xac, 0xc5, 0x74, 0x47, 0xb8, 0xbb, 0x6f, 0xfb, - 0xdf, 0x97, 0x60, 0x34, 0x21, 0x19, 0xf7, 0x69, 0x30, 0x3c, 0x0e, 0x65, 0xa9, 0xc3, 0xd3, 0xe5, - 0xb2, 0x94, 0xa2, 0x57, 0x18, 0x54, 0x69, 0xad, 0x69, 0xad, 0x9a, 0x36, 0x70, 0x0c, 0x85, 0x8b, - 0x4d, 0x3c, 0x26, 0x94, 0x63, 0x2f, 0x9a, 0xf3, 0x5c, 0xe2, 0xc7, 0x9c, 0xcd, 0x7c, 0x84, 0xf2, - 0xea, 0x62, 0xd5, 0xec, 0x54, 0x0b, 0xe5, 0x14, 0x00, 0xa7, 0xc9, 0xa3, 0x8f, 0x59, 0x30, 0xea, - 0xdc, 0x8c, 0x74, 0x51, 0x76, 0x11, 0x74, 0x7c, 0x40, 0x25, 0x95, 0xa8, 0xf3, 0xce, 0x1d, 0xfb, - 0x89, 0x26, 0x9c, 0x24, 0x8a, 0x5e, 0xb3, 0x00, 0x91, 0x6d, 0x52, 0x93, 0x61, 0xd1, 0x82, 0x97, - 0xc1, 0x3c, 0x76, 0xf0, 0xe7, 0xba, 0xfa, 0xe5, 0x52, 0xbd, 0xbb, 0x1d, 0x67, 0xf0, 0x80, 0x2e, - 0x01, 0xaa, 0xbb, 0x91, 0xb3, 0xe6, 0x91, 0xb9, 0xa0, 0x29, 0x13, 0x88, 0xc5, 0x79, 0xfa, 0x19, - 0x31, 0xce, 0x68, 0xbe, 0x0b, 0x03, 0x67, 0x3c, 0xc5, 0x66, 0x59, 0x18, 0x6c, 0x77, 0xae, 0x86, - 0x1e, 0xd3, 0x12, 0xe6, 0x2c, 0x13, 0xed, 0x58, 0x61, 0xd8, 0x7f, 0x51, 0x54, 0x4b, 0x59, 0xe7, - 0x00, 0x38, 0x46, 0x2c, 0xb2, 0x75, 0xe7, 0xb1, 0xc8, 0x3a, 0x52, 0xaa, 0x3b, 0x2d, 0x3e, 0x91, - 0x45, 0x5b, 0xb8, 0x4b, 0x59, 0xb4, 0x3f, 0x63, 0x25, 0x4a, 0xd2, 0x0d, 0x3f, 0xf5, 0x62, 0xbe, - 0xf9, 0x07, 0x53, 0x3c, 0x8a, 0x2b, 0xa5, 0x57, 0x52, 0xc1, 0x7b, 0x8f, 0x43, 0x79, 0xdd, 0x73, - 0x58, 0x21, 0x15, 0xb6, 0x50, 0x8d, 0x08, 0xb3, 0xf3, 0xa2, 0x1d, 0x2b, 0x0c, 0x2a, 0xf5, 0x8d, - 0x4e, 0xf7, 0x25, 0xb5, 0xff, 0x63, 0x11, 0x86, 0x0d, 0x8d, 0x9f, 0x69, 0xbe, 0x59, 0xf7, 0x98, - 0xf9, 0x56, 0xd8, 0x87, 0xf9, 0xf6, 0xd3, 0x50, 0xa9, 0x49, 0x6d, 0x94, 0x4f, 0x89, 0xfd, 0xb4, - 0x8e, 0xd3, 0x0a, 0x49, 0x35, 0x61, 0x4d, 0x13, 0x5d, 0x48, 0x64, 0x6a, 0x26, 0xfc, 0x02, 0x59, - 0xa9, 0x94, 0x42, 0xa3, 0x75, 0x3f, 0x93, 0x8e, 0x0f, 0x28, 0xed, 0x1d, 0x1f, 0x60, 0x7f, 0xdb, - 0x52, 0x1f, 0xf7, 0x08, 0x4a, 0xf2, 0xdc, 0x48, 0x96, 0xe4, 0x39, 0x97, 0xcb, 0x30, 0xf7, 0xa8, - 0xc5, 0x73, 0x05, 0x86, 0xe6, 0x82, 0x66, 0xd3, 0xf1, 0xeb, 0xe8, 0x47, 0x61, 0xa8, 0xc6, 0x7f, - 0x0a, 0x1f, 0x1a, 0x3b, 0xac, 0x16, 0x50, 0x2c, 0x61, 0xe8, 0x41, 0x18, 0x70, 0xc2, 0x86, 0xf4, - 0x9b, 0xb1, 0x20, 0xb8, 0x99, 0xb0, 0x11, 0x61, 0xd6, 0x6a, 0xff, 0xb3, 0x01, 0x60, 0xb1, 0x27, - 0x4e, 0x48, 0xea, 0xab, 0x01, 0xab, 0x8c, 0x7b, 0xa8, 0x47, 0xbc, 0x7a, 0x53, 0x77, 0x2f, 0x1f, - 0xf3, 0x1a, 0x47, 0x7d, 0xc5, 0xa3, 0x3e, 0xea, 0xcb, 0x3e, 0xbd, 0x1d, 0xb8, 0x87, 0x4e, 0x6f, - 0xed, 0x4f, 0x59, 0x80, 0x54, 0x24, 0x91, 0x0e, 0xaf, 0x98, 0x86, 0x8a, 0x0a, 0x5d, 0x12, 0x06, - 0xa0, 0x16, 0x11, 0x12, 0x80, 0x35, 0x4e, 0x1f, 0x3b, 0xf9, 0x47, 0xa4, 0xfc, 0x2e, 0x26, 0xf3, - 0x0f, 0x98, 0xd4, 0x17, 0xe2, 0xdc, 0xfe, 0xbd, 0x02, 0xdc, 0xc7, 0x4d, 0x87, 0x25, 0xc7, 0x77, - 0x1a, 0xa4, 0x49, 0xb9, 0xea, 0x37, 0x60, 0xa6, 0x46, 0xb7, 0x90, 0xae, 0xcc, 0x16, 0x38, 0xe8, - 0xda, 0xe5, 0x6b, 0x8e, 0xaf, 0xb2, 0x05, 0xdf, 0x8d, 0x31, 0xeb, 0x1c, 0x45, 0x50, 0x96, 0x77, - 0xf3, 0x08, 0x59, 0x9c, 0x13, 0x21, 0x25, 0x96, 0x84, 0x96, 0x25, 0x58, 0x11, 0xa2, 0xaa, 0xd4, - 0x0b, 0x6a, 0x9b, 0x98, 0xb4, 0x82, 0xb4, 0x2a, 0x5d, 0x14, 0xed, 0x58, 0x61, 0xd8, 0x4d, 0x18, - 0x97, 0x63, 0xd8, 0xba, 0x4c, 0x3a, 0x98, 0xac, 0x53, 0xfd, 0x53, 0x93, 0x4d, 0xc6, 0x75, 0x41, - 0x4a, 0xff, 0xcc, 0x99, 0x40, 0x9c, 0xc4, 0x95, 0xc5, 0x72, 0x0b, 0xd9, 0xc5, 0x72, 0xed, 0xdf, - 0xb3, 0x20, 0xad, 0x00, 0x8d, 0xd2, 0xa0, 0xd6, 0xae, 0xa5, 0x41, 0xf7, 0x51, 0x5c, 0xf3, 0xbd, - 0x30, 0xec, 0xc4, 0xd4, 0xc2, 0xe1, 0xde, 0x88, 0xe2, 0x9d, 0x9d, 0xa2, 0x2d, 0x05, 0x75, 0x77, - 0xdd, 0x65, 0x5e, 0x08, 0xb3, 0x3b, 0xfb, 0x35, 0x0b, 0x2a, 0xf3, 0x61, 0x67, 0xff, 0x69, 0x5b, - 0xdd, 0x49, 0x59, 0x85, 0x7d, 0x25, 0x65, 0xc9, 0xb4, 0xaf, 0x62, 0xaf, 0xb4, 0x2f, 0xfb, 0xaf, - 0x07, 0xe0, 0x78, 0x57, 0x1e, 0x22, 0x7a, 0x0e, 0x46, 0xd4, 0x57, 0x92, 0x2e, 0xc8, 0x8a, 0x19, - 0xc8, 0xab, 0x61, 0x38, 0x81, 0xd9, 0xc7, 0x52, 0x5d, 0x80, 0x13, 0x21, 0x79, 0xa5, 0x4d, 0xda, - 0x64, 0x66, 0x3d, 0x26, 0x61, 0x95, 0xd4, 0x02, 0xbf, 0xce, 0x6b, 0xeb, 0x16, 0x67, 0xef, 0xbf, - 0xb5, 0x33, 0x79, 0x02, 0x77, 0x83, 0x71, 0xd6, 0x33, 0xa8, 0x05, 0xa3, 0x9e, 0x69, 0x3b, 0x8b, - 0x2d, 0xdb, 0x1d, 0x99, 0xdd, 0x6a, 0xb6, 0x26, 0x9a, 0x71, 0x92, 0x40, 0xd2, 0x00, 0x2f, 0xdd, - 0x25, 0x03, 0xfc, 0xa3, 0xda, 0x00, 0xe7, 0x71, 0x31, 0xef, 0xc9, 0x39, 0x0f, 0xb5, 0x1f, 0x0b, - 0xfc, 0x20, 0x36, 0xf5, 0x0b, 0x50, 0x96, 0x31, 0x83, 0x7d, 0xc5, 0xda, 0x99, 0xfd, 0xf4, 0x90, - 0xed, 0x8f, 0xc2, 0x1b, 0xcf, 0x85, 0xa1, 0x31, 0x98, 0x57, 0x82, 0x78, 0xc6, 0xf3, 0x82, 0x9b, - 0xd4, 0x5c, 0xb9, 0x1a, 0x11, 0xe1, 0x13, 0xb3, 0x6f, 0x17, 0x20, 0x63, 0x7b, 0x49, 0xd7, 0xa4, - 0xb6, 0x91, 0x12, 0x6b, 0x72, 0x7f, 0x76, 0x12, 0xda, 0xe6, 0x71, 0x95, 0xdc, 0x1a, 0x78, 0x77, - 0xde, 0xdb, 0x63, 0x1d, 0x6a, 0xa9, 0x24, 0xa5, 0x0a, 0xb7, 0x7c, 0x0a, 0x40, 0x9b, 0xb6, 0x22, - 0xf5, 0x49, 0x05, 0x4a, 0x68, 0x0b, 0x18, 0x1b, 0x58, 0xe8, 0x59, 0x18, 0x76, 0xfd, 0x28, 0x76, - 0x3c, 0xef, 0xa2, 0xeb, 0xc7, 0xc2, 0xed, 0xab, 0xcc, 0x9e, 0x05, 0x0d, 0xc2, 0x26, 0xde, 0x99, - 0xb7, 0x18, 0xdf, 0x6f, 0x3f, 0xdf, 0x7d, 0x03, 0x4e, 0x5f, 0x70, 0x63, 0x95, 0xb0, 0xa7, 0xe6, - 0x1b, 0xb5, 0x5c, 0x95, 0xac, 0xb2, 0x7a, 0xa6, 0xa8, 0x1a, 0x09, 0x73, 0x85, 0x64, 0x7e, 0x5f, - 0x3a, 0x61, 0xce, 0xae, 0xc1, 0xc9, 0x0b, 0x6e, 0x7c, 0xde, 0xf5, 0xc8, 0x21, 0x12, 0xf9, 0x9d, - 0x41, 0x18, 0x31, 0xf3, 0xd8, 0xf7, 0x23, 0xd9, 0x3f, 0x43, 0xed, 0x58, 0x31, 0x10, 0xae, 0x3a, - 0xfc, 0xbd, 0x7e, 0xe0, 0xa4, 0xfa, 0xec, 0xc1, 0x35, 0x4c, 0x59, 0x4d, 0x13, 0x9b, 0x0c, 0xa0, - 0x9b, 0x50, 0x5a, 0x67, 0xb9, 0x5f, 0xc5, 0x3c, 0xc2, 0x76, 0xb2, 0x06, 0x5f, 0xaf, 0x5c, 0x9e, - 0x3d, 0xc6, 0xe9, 0x51, 0xf3, 0x23, 0x4c, 0xa6, 0x1c, 0x1b, 0x11, 0xf9, 0x42, 0xaf, 0x29, 0x8c, - 0x5e, 0xda, 0xa3, 0x74, 0x07, 0xda, 0x23, 0x21, 0xcb, 0x07, 0xef, 0x92, 0x2c, 0x67, 0x79, 0x7c, - 0xf1, 0x06, 0x33, 0x8e, 0x45, 0x0a, 0xd1, 0x10, 0x1b, 0x04, 0x23, 0x8f, 0x2f, 0x01, 0xc6, 0x69, - 0x7c, 0xf4, 0x21, 0xa5, 0x0d, 0xca, 0x79, 0x38, 0xd7, 0xcd, 0x19, 0x7d, 0xd8, 0x8a, 0xe0, 0x53, - 0x05, 0x18, 0xbb, 0xe0, 0xb7, 0x57, 0x2e, 0xac, 0xb4, 0xd7, 0x3c, 0xb7, 0x76, 0x99, 0x74, 0xa8, - 0xb4, 0xdf, 0x24, 0x9d, 0x85, 0x79, 0xb1, 0x82, 0xd4, 0x9c, 0xb9, 0x4c, 0x1b, 0x31, 0x87, 0x51, - 0xb9, 0xb5, 0xee, 0xfa, 0x0d, 0x12, 0xb6, 0x42, 0x57, 0xf8, 0xbd, 0x0d, 0xb9, 0x75, 0x5e, 0x83, - 0xb0, 0x89, 0x47, 0xfb, 0x0e, 0x6e, 0xfa, 0x24, 0x4c, 0xef, 0x12, 0x96, 0x69, 0x23, 0xe6, 0x30, - 0x8a, 0x14, 0x87, 0x6d, 0xe1, 0x56, 0x32, 0x90, 0x56, 0x69, 0x23, 0xe6, 0x30, 0xba, 0xd2, 0xa3, - 0xf6, 0x1a, 0x8b, 0x8a, 0x4a, 0xe5, 0x2b, 0x55, 0x79, 0x33, 0x96, 0x70, 0x8a, 0xba, 0x49, 0x3a, - 0xf3, 0x4e, 0xec, 0xa4, 0x93, 0x3a, 0x2f, 0xf3, 0x66, 0x2c, 0xe1, 0xac, 0x50, 0x70, 0x72, 0x38, - 0xbe, 0xef, 0x0a, 0x05, 0x27, 0xd9, 0xef, 0xe1, 0x9c, 0xf8, 0x9b, 0x05, 0x18, 0x79, 0xfd, 0x36, - 0xcf, 0x8c, 0x7b, 0x6a, 0xae, 0xc3, 0xf1, 0xae, 0xec, 0xe1, 0x3e, 0x2c, 0xa4, 0x3d, 0xab, 0x3b, - 0xd8, 0x18, 0x86, 0x69, 0xc7, 0xb2, 0x40, 0xde, 0x1c, 0x1c, 0xe7, 0x8b, 0x97, 0x52, 0x62, 0xc9, - 0xa0, 0x2a, 0x23, 0x9c, 0x1d, 0xec, 0x5c, 0x4b, 0x03, 0x71, 0x37, 0xbe, 0xfd, 0x69, 0x0b, 0x46, - 0x13, 0x09, 0xdd, 0x39, 0xd9, 0x72, 0x6c, 0x75, 0x07, 0x2c, 0xa2, 0x97, 0x65, 0x58, 0x14, 0x99, - 0x1a, 0xd6, 0xab, 0x5b, 0x83, 0xb0, 0x89, 0x67, 0x7f, 0xbe, 0x00, 0x65, 0x19, 0x7d, 0xd4, 0x07, - 0x2b, 0x9f, 0xb4, 0x60, 0x54, 0x1d, 0xa6, 0x31, 0xef, 0x67, 0x21, 0x8f, 0xfc, 0x32, 0xca, 0x81, - 0xf2, 0x9f, 0xf8, 0xeb, 0x81, 0xde, 0x58, 0x60, 0x93, 0x18, 0x4e, 0xd2, 0x46, 0xd7, 0x00, 0xa2, - 0x4e, 0x14, 0x93, 0xa6, 0xe1, 0x87, 0xb5, 0x8d, 0x59, 0x36, 0x55, 0x0b, 0x42, 0x42, 0xe7, 0xd4, - 0x95, 0xa0, 0x4e, 0xaa, 0x0a, 0x53, 0x5b, 0x78, 0xba, 0x0d, 0x1b, 0x3d, 0xd9, 0xbf, 0x56, 0x80, - 0x63, 0x69, 0x96, 0xd0, 0x7b, 0x60, 0x44, 0x52, 0x37, 0xf6, 0xeb, 0x32, 0x76, 0x6a, 0x04, 0x1b, - 0xb0, 0xdb, 0x3b, 0x93, 0x93, 0xdd, 0xf7, 0x2b, 0x4f, 0x99, 0x28, 0x38, 0xd1, 0x19, 0x3f, 0xd1, - 0x14, 0x47, 0xef, 0xb3, 0x9d, 0x99, 0x56, 0x4b, 0x1c, 0x4b, 0x1a, 0x27, 0x9a, 0x26, 0x14, 0xa7, - 0xb0, 0xd1, 0x0a, 0x9c, 0x34, 0x5a, 0xae, 0x10, 0xb7, 0xb1, 0xb1, 0x16, 0x84, 0x72, 0x83, 0xf8, - 0xa0, 0x8e, 0xd4, 0xec, 0xc6, 0xc1, 0x99, 0x4f, 0x52, 0x0b, 0xa3, 0xe6, 0xb4, 0x9c, 0x9a, 0x1b, - 0x77, 0x84, 0x63, 0x59, 0xc9, 0xc3, 0x39, 0xd1, 0x8e, 0x15, 0x86, 0xfd, 0xf7, 0x06, 0xe0, 0x18, - 0x0f, 0x4d, 0x24, 0x2a, 0xf2, 0x16, 0xbd, 0x07, 0x2a, 0x51, 0xec, 0x84, 0xdc, 0x3b, 0x60, 0xed, - 0x5b, 0x06, 0xe8, 0x74, 0x6e, 0xd9, 0x09, 0xd6, 0xfd, 0xa1, 0x17, 0x59, 0x2d, 0x2c, 0x37, 0xda, - 0x60, 0xbd, 0x17, 0xee, 0xcc, 0xf7, 0x70, 0x5e, 0xf5, 0x80, 0x8d, 0xde, 0xd0, 0xdb, 0xa0, 0xd4, - 0xda, 0x70, 0x22, 0xe9, 0x18, 0x7b, 0x54, 0x2e, 0xb8, 0x15, 0xda, 0x78, 0x7b, 0x67, 0xf2, 0x54, - 0xfa, 0x55, 0x19, 0x00, 0xf3, 0x87, 0x4c, 0x71, 0x39, 0xb0, 0xf7, 0x7d, 0x2d, 0xf5, 0xb0, 0x53, - 0xbd, 0x38, 0x93, 0xbe, 0xe1, 0x63, 0x9e, 0xb5, 0x62, 0x01, 0xa5, 0x8b, 0x7b, 0x83, 0x93, 0xac, - 0x53, 0xe4, 0xc1, 0xa4, 0xea, 0xbe, 0xa8, 0x41, 0xd8, 0xc4, 0x43, 0x9f, 0xea, 0x0e, 0x5c, 0x1d, - 0x3a, 0x84, 0xc4, 0x86, 0x7e, 0x43, 0x56, 0xcf, 0x41, 0x45, 0xb0, 0xba, 0x1a, 0xa0, 0xe7, 0x60, - 0x84, 0xfb, 0x5d, 0x66, 0x43, 0xc7, 0xaf, 0x6d, 0xa4, 0xbd, 0x25, 0xab, 0x06, 0x0c, 0x27, 0x30, - 0xed, 0x25, 0x18, 0xe8, 0x53, 0x5a, 0xf5, 0xb5, 0x09, 0x7e, 0x01, 0xca, 0xb4, 0x3b, 0xb9, 0xd3, - 0xc9, 0xa3, 0xcb, 0x00, 0xca, 0xf2, 0xf6, 0x3f, 0x64, 0x43, 0xd1, 0x75, 0x64, 0x80, 0x82, 0x5a, - 0x42, 0x0b, 0x51, 0xd4, 0x66, 0xd3, 0x8e, 0x02, 0xd1, 0x23, 0x50, 0x24, 0xdb, 0xad, 0x74, 0x24, - 0xc2, 0xb9, 0xed, 0x96, 0x1b, 0x92, 0x88, 0x22, 0x91, 0xed, 0x16, 0x3a, 0x03, 0x05, 0xb7, 0x2e, - 0x66, 0x24, 0x08, 0x9c, 0xc2, 0xc2, 0x3c, 0x2e, 0xb8, 0x75, 0x7b, 0x1b, 0x2a, 0xea, 0xba, 0x41, - 0xb4, 0x29, 0x6d, 0x13, 0x2b, 0x8f, 0xd0, 0x54, 0xd9, 0x6f, 0x0f, 0xab, 0xa4, 0x0d, 0xa0, 0xeb, - 0x04, 0xe4, 0xa5, 0xcb, 0xce, 0xc2, 0x40, 0x2d, 0x10, 0x15, 0x5e, 0xca, 0xba, 0x1b, 0x66, 0x94, - 0x30, 0x88, 0x7d, 0x1d, 0xc6, 0x2e, 0xfb, 0xc1, 0x4d, 0x76, 0x2b, 0x10, 0x2b, 0x82, 0x4b, 0x3b, - 0x5e, 0xa7, 0x3f, 0xd2, 0x26, 0x30, 0x83, 0x62, 0x0e, 0x53, 0xe5, 0x39, 0x0b, 0xbd, 0xca, 0x73, - 0xda, 0x1f, 0xb6, 0x60, 0x44, 0x25, 0x1c, 0x5f, 0xd8, 0xda, 0xa4, 0xfd, 0x36, 0xc2, 0xa0, 0xdd, - 0x4a, 0xf7, 0xcb, 0x6e, 0x36, 0xc5, 0x1c, 0x66, 0x66, 0xe2, 0x17, 0xf6, 0xc8, 0xc4, 0x3f, 0x0b, - 0x03, 0x9b, 0xae, 0x5f, 0x4f, 0x7b, 0x17, 0x2f, 0xbb, 0x7e, 0x1d, 0x33, 0x08, 0x65, 0xe1, 0x98, - 0x62, 0x41, 0x1a, 0x1f, 0xcf, 0xc1, 0xc8, 0x5a, 0xdb, 0xf5, 0xea, 0xb2, 0xba, 0x6f, 0x6a, 0xb9, - 0xcc, 0x1a, 0x30, 0x9c, 0xc0, 0x44, 0x4f, 0x01, 0xac, 0xb9, 0xbe, 0x13, 0x76, 0x56, 0xb4, 0xb5, - 0xa3, 0x14, 0xe0, 0xac, 0x82, 0x60, 0x03, 0xcb, 0xfe, 0x6c, 0x11, 0xc6, 0x92, 0x69, 0xd7, 0x7d, - 0x38, 0x01, 0x1e, 0x81, 0x12, 0xcb, 0xc4, 0x4e, 0x7f, 0x5a, 0x5e, 0x10, 0x97, 0xc3, 0x50, 0x04, - 0x83, 0x7c, 0x31, 0xe7, 0x73, 0x3b, 0xa4, 0x62, 0x52, 0xb9, 0x24, 0x59, 0x00, 0xaf, 0xf0, 0xf0, - 0x0a, 0x52, 0xe8, 0x63, 0x16, 0x0c, 0x05, 0x2d, 0xb3, 0xac, 0xe3, 0xbb, 0xf3, 0x4c, 0x49, 0x17, - 0x79, 0x9f, 0x62, 0xc7, 0xa7, 0x3e, 0xbd, 0xfc, 0x1c, 0x92, 0xf4, 0x99, 0xb7, 0xc2, 0x88, 0x89, - 0xb9, 0xd7, 0xa6, 0xaf, 0x6c, 0x6e, 0xfa, 0x3e, 0x69, 0x4e, 0x0a, 0x91, 0x74, 0xdf, 0xc7, 0x72, - 0xbb, 0x0a, 0xa5, 0x9a, 0x8a, 0x72, 0xba, 0xa3, 0x9a, 0xf0, 0xaa, 0x28, 0x15, 0x3b, 0x41, 0xe6, - 0xbd, 0xd9, 0xdf, 0xb6, 0x8c, 0xf9, 0x81, 0x49, 0xb4, 0x50, 0x47, 0x21, 0x14, 0x1b, 0x5b, 0x9b, - 0x42, 0xcd, 0x5f, 0xca, 0x69, 0x78, 0x2f, 0x6c, 0x6d, 0xea, 0x39, 0x6e, 0xb6, 0x62, 0x4a, 0xac, - 0x0f, 0xbf, 0x79, 0xa2, 0x36, 0x43, 0x71, 0xef, 0xda, 0x0c, 0xf6, 0x6b, 0x05, 0x38, 0xde, 0x35, - 0xa9, 0xd0, 0xab, 0x50, 0x0a, 0xe9, 0x5b, 0x8a, 0xd7, 0x5b, 0xcc, 0xad, 0x9a, 0x42, 0xb4, 0x50, - 0xd7, 0xea, 0x33, 0xd9, 0x8e, 0x39, 0x49, 0x74, 0x09, 0x90, 0x8e, 0xc5, 0x53, 0x4e, 0x7b, 0xfe, - 0xca, 0x2a, 0x60, 0x67, 0xa6, 0x0b, 0x03, 0x67, 0x3c, 0x85, 0x9e, 0x4f, 0xfb, 0xfe, 0x8b, 0xc9, - 0x43, 0xa7, 0xdd, 0xdc, 0xf8, 0xf6, 0x6f, 0x15, 0x60, 0x34, 0x51, 0x65, 0x13, 0x79, 0x50, 0x26, - 0x1e, 0x3b, 0x11, 0x94, 0xca, 0xe6, 0xa0, 0x77, 0x66, 0x28, 0x05, 0x79, 0x4e, 0xf4, 0x8b, 0x15, - 0x85, 0x7b, 0x23, 0x8e, 0xe7, 0x39, 0x18, 0x91, 0x0c, 0xbd, 0xdb, 0x69, 0x7a, 0x62, 0x00, 0xd5, - 0x1c, 0x3d, 0x67, 0xc0, 0x70, 0x02, 0xd3, 0xfe, 0xfd, 0x22, 0x4c, 0xf0, 0x23, 0xd4, 0xba, 0x9a, - 0x79, 0x4b, 0xd2, 0x9f, 0xf0, 0x0b, 0xba, 0x16, 0xae, 0x95, 0xc7, 0xc5, 0xd0, 0xbd, 0x08, 0xf5, - 0x15, 0x7e, 0xfa, 0xe5, 0x54, 0xf8, 0x29, 0xdf, 0xe2, 0x35, 0x0e, 0x89, 0xa3, 0xef, 0xaf, 0x78, - 0xd4, 0x7f, 0x54, 0x80, 0xf1, 0xd4, 0xfd, 0x5f, 0xe8, 0xb3, 0xc9, 0x2b, 0x23, 0xac, 0x3c, 0x8e, - 0x97, 0x76, 0xbd, 0x12, 0x6a, 0x7f, 0x17, 0x47, 0xdc, 0xa5, 0xa5, 0x62, 0x7f, 0xab, 0x00, 0x63, - 0xc9, 0x8b, 0xcb, 0xee, 0xc1, 0x91, 0x7a, 0x33, 0x54, 0xd8, 0xdd, 0x3c, 0xec, 0xbe, 0x7d, 0x7e, - 0x3a, 0xc5, 0xaf, 0x41, 0x91, 0x8d, 0x58, 0xc3, 0xef, 0x89, 0xfb, 0x38, 0xec, 0x7f, 0x62, 0xc1, - 0x29, 0xfe, 0x96, 0xe9, 0x79, 0xf8, 0x37, 0xb2, 0x46, 0xf7, 0xa5, 0x7c, 0x19, 0x4c, 0xd5, 0x70, - 0xde, 0x6b, 0x7c, 0xd9, 0xf5, 0xd8, 0x82, 0xdb, 0xe4, 0x54, 0xb8, 0x07, 0x99, 0xdd, 0xd7, 0x64, - 0xb0, 0xbf, 0x55, 0x04, 0x7d, 0x23, 0x38, 0x72, 0x45, 0x8e, 0x7c, 0x2e, 0xb5, 0xac, 0xab, 0x1d, - 0xbf, 0xa6, 0xef, 0x1e, 0x2f, 0xa7, 0x52, 0xe4, 0x7f, 0xce, 0x82, 0x61, 0xd7, 0x77, 0x63, 0xd7, - 0x61, 0x2e, 0x9b, 0x7c, 0xae, 0xf5, 0x55, 0xe4, 0x16, 0x78, 0xcf, 0x41, 0x68, 0x1e, 0x69, 0x2a, - 0x62, 0xd8, 0xa4, 0x8c, 0xde, 0x2f, 0x32, 0x44, 0x8a, 0xb9, 0x15, 0x9a, 0x28, 0xa7, 0xd2, 0x42, - 0x5a, 0xd4, 0xf0, 0x8a, 0xc3, 0x9c, 0xea, 0xb3, 0x60, 0xda, 0x95, 0xba, 0x16, 0x41, 0x99, 0xb6, - 0xac, 0x19, 0x73, 0x42, 0x76, 0x04, 0xa8, 0x7b, 0x2c, 0xf6, 0x19, 0x7d, 0x3f, 0x0d, 0x15, 0xa7, - 0x1d, 0x07, 0x4d, 0x3a, 0x4c, 0xe2, 0x40, 0x54, 0xe7, 0x17, 0x48, 0x00, 0xd6, 0x38, 0xf6, 0x67, - 0x4b, 0x90, 0xca, 0x58, 0x47, 0xdb, 0xe6, 0x6d, 0xf6, 0x56, 0xbe, 0xb7, 0xd9, 0x2b, 0x66, 0xb2, - 0x6e, 0xb4, 0x47, 0x0d, 0xe9, 0xfd, 0xe2, 0x36, 0xe6, 0x0b, 0x69, 0xef, 0xd7, 0x4f, 0xf6, 0x77, - 0xaa, 0x40, 0xe7, 0xea, 0x34, 0xaf, 0x51, 0x36, 0xb5, 0xa7, 0xa3, 0x6c, 0xaf, 0x8b, 0x8d, 0x3f, - 0x22, 0x2e, 0x21, 0xc2, 0x24, 0x6a, 0x7b, 0xb1, 0x98, 0x0d, 0x2f, 0xe4, 0xb8, 0xca, 0x78, 0xc7, - 0xba, 0xf2, 0x0b, 0xff, 0x8f, 0x0d, 0xa2, 0x49, 0x77, 0xe6, 0xe0, 0xa1, 0xba, 0x33, 0x87, 0x72, - 0x75, 0x67, 0x3e, 0x05, 0xc0, 0xe6, 0x36, 0x8f, 0x12, 0x2e, 0x33, 0x2f, 0x93, 0x12, 0x85, 0x58, - 0x41, 0xb0, 0x81, 0x65, 0xff, 0x38, 0x24, 0x4b, 0x17, 0xa1, 0x49, 0x59, 0x29, 0x89, 0x9f, 0x78, - 0xb0, 0x04, 0xad, 0x44, 0x51, 0xa3, 0xdf, 0xb0, 0xc0, 0xac, 0xaf, 0x84, 0x5e, 0xe1, 0x85, 0x9c, - 0xac, 0x3c, 0x4e, 0xc6, 0x8d, 0x7e, 0xa7, 0x96, 0x9c, 0x56, 0x2a, 0x9a, 0x43, 0x56, 0x73, 0x3a, - 0xf3, 0x16, 0x28, 0x4b, 0xe8, 0xbe, 0x8c, 0xba, 0x0f, 0xc1, 0x09, 0x99, 0xec, 0x2d, 0x7d, 0xf4, - 0xe2, 0x54, 0x75, 0x6f, 0xd7, 0x8f, 0xf4, 0xe7, 0x14, 0x7a, 0xf9, 0x73, 0xd4, 0x2e, 0xb5, 0xd8, - 0xb3, 0x44, 0xf3, 0x6f, 0x5a, 0x70, 0x36, 0xcd, 0x40, 0xb4, 0x14, 0xf8, 0x6e, 0x1c, 0x84, 0x55, - 0x12, 0xc7, 0xae, 0xdf, 0x60, 0xf5, 0x36, 0x6f, 0x3a, 0xa1, 0xbc, 0x73, 0x85, 0x09, 0xca, 0xeb, - 0x4e, 0xe8, 0x63, 0xd6, 0x8a, 0x3a, 0x30, 0xc8, 0x43, 0x49, 0x85, 0xb5, 0x7e, 0xc0, 0xb5, 0x91, - 0x31, 0x1c, 0x7a, 0xbb, 0xc0, 0xc3, 0x58, 0xb1, 0x20, 0x68, 0x7f, 0xc7, 0x02, 0xb4, 0xbc, 0x45, - 0xc2, 0xd0, 0xad, 0x1b, 0xc1, 0xaf, 0xec, 0x32, 0x3f, 0xe3, 0xd2, 0x3e, 0xb3, 0x14, 0x41, 0xea, - 0x32, 0x3f, 0xe3, 0x5f, 0xf6, 0x65, 0x7e, 0x85, 0xfd, 0x5d, 0xe6, 0x87, 0x96, 0xe1, 0x54, 0x93, - 0x6f, 0x37, 0xf8, 0x05, 0x59, 0x7c, 0xef, 0xa1, 0xb2, 0x66, 0x4f, 0xdf, 0xda, 0x99, 0x3c, 0xb5, - 0x94, 0x85, 0x80, 0xb3, 0x9f, 0xb3, 0xdf, 0x02, 0x88, 0xc7, 0xbc, 0xce, 0x65, 0x85, 0xed, 0xf5, - 0x74, 0xbf, 0xd8, 0x5f, 0x2a, 0xc1, 0x78, 0xaa, 0x22, 0x3f, 0xdd, 0xea, 0x75, 0xc7, 0x09, 0x1e, - 0x58, 0x7f, 0x77, 0xb3, 0xd7, 0x57, 0xe4, 0xa1, 0x0f, 0x25, 0xd7, 0x6f, 0xb5, 0xe3, 0x7c, 0x92, - 0xf6, 0x39, 0x13, 0x0b, 0xb4, 0x43, 0xc3, 0x5d, 0x4c, 0xff, 0x62, 0x4e, 0x26, 0xcf, 0x38, 0xc6, - 0x84, 0x31, 0x3e, 0x70, 0x97, 0xdc, 0x01, 0x1f, 0xd1, 0x51, 0x85, 0xa5, 0x3c, 0x1c, 0x8b, 0xa9, - 0xc9, 0x72, 0xd8, 0xa1, 0x24, 0x5f, 0x2b, 0xc0, 0xb0, 0xf1, 0xd1, 0xd0, 0x2f, 0x27, 0xab, 0x0f, - 0x5a, 0xf9, 0xbd, 0x12, 0xeb, 0x7f, 0x4a, 0xd7, 0x17, 0xe4, 0xaf, 0xf4, 0x68, 0x77, 0xe1, 0xc1, - 0xdb, 0x3b, 0x93, 0xc7, 0x52, 0xa5, 0x05, 0x13, 0xc5, 0x08, 0xcf, 0x7c, 0x10, 0xc6, 0x53, 0xdd, - 0x64, 0xbc, 0xf2, 0xaa, 0xf9, 0xca, 0x07, 0x76, 0x4b, 0x99, 0x43, 0xf6, 0x55, 0x3a, 0x64, 0x22, - 0x57, 0x38, 0xf0, 0x48, 0x1f, 0x3e, 0xd8, 0x54, 0x49, 0x80, 0x42, 0x9f, 0x25, 0x01, 0x1e, 0x83, - 0x72, 0x2b, 0xf0, 0xdc, 0x9a, 0xab, 0x8a, 0x17, 0xb3, 0x22, 0x04, 0x2b, 0xa2, 0x0d, 0x2b, 0x28, - 0xba, 0x09, 0x95, 0x1b, 0x37, 0x63, 0x7e, 0xfa, 0x23, 0xfc, 0xdb, 0x79, 0x1d, 0xfa, 0x28, 0xa3, - 0x45, 0x1d, 0x2f, 0x61, 0x4d, 0x0b, 0xd9, 0x30, 0xc8, 0x94, 0xa0, 0xcc, 0x1b, 0x62, 0xbe, 0x77, - 0xa6, 0x1d, 0x23, 0x2c, 0x20, 0xf6, 0xf7, 0x00, 0x4e, 0x66, 0x5d, 0x8b, 0x82, 0x3e, 0x00, 0x83, - 0x9c, 0xc7, 0x7c, 0x6e, 0xde, 0xca, 0xa2, 0x71, 0x81, 0x75, 0x28, 0xd8, 0x62, 0xbf, 0xb1, 0xa0, - 0x29, 0xa8, 0x7b, 0xce, 0x9a, 0x98, 0x21, 0x87, 0x43, 0x7d, 0xd1, 0xd1, 0xd4, 0x17, 0x1d, 0x4e, - 0xdd, 0x73, 0xd6, 0xd0, 0x36, 0x94, 0x1a, 0x6e, 0x4c, 0x1c, 0xe1, 0x44, 0xb8, 0x7e, 0x28, 0xc4, - 0x89, 0xc3, 0xad, 0x34, 0xf6, 0x13, 0x73, 0x82, 0xe8, 0x2b, 0x16, 0x8c, 0xaf, 0x25, 0x6b, 0x91, - 0x08, 0xe1, 0xe9, 0x1c, 0xc2, 0xd5, 0x37, 0x49, 0x42, 0xfc, 0x36, 0xcb, 0x54, 0x23, 0x4e, 0xb3, - 0x83, 0x3e, 0x6a, 0xc1, 0xd0, 0xba, 0xeb, 0x19, 0x77, 0x0b, 0x1c, 0xc2, 0xc7, 0x39, 0xcf, 0x08, - 0xe8, 0x1d, 0x07, 0xff, 0x1f, 0x61, 0x49, 0xb9, 0x97, 0xa6, 0x1a, 0x3c, 0xa8, 0xa6, 0x1a, 0xba, - 0x4b, 0x9a, 0xea, 0x13, 0x16, 0x54, 0xd4, 0x48, 0x8b, 0x9a, 0x0e, 0xef, 0x39, 0xc4, 0x4f, 0xce, - 0x3d, 0x27, 0xea, 0x2f, 0xd6, 0xc4, 0xd1, 0xe7, 0x2c, 0x18, 0x76, 0x5e, 0x6d, 0x87, 0xa4, 0x4e, - 0xb6, 0x82, 0x56, 0x24, 0x8a, 0x2d, 0xbe, 0x94, 0x3f, 0x33, 0x33, 0x94, 0xc8, 0x3c, 0xd9, 0x5a, - 0x6e, 0x45, 0x22, 0xa7, 0x51, 0x37, 0x60, 0x93, 0x05, 0xf4, 0xb3, 0x5a, 0x8f, 0x43, 0x1e, 0x25, - 0x77, 0xb3, 0xb8, 0x39, 0x6c, 0x65, 0xbe, 0x53, 0x80, 0xc9, 0x3d, 0x46, 0x01, 0x3d, 0x07, 0x23, - 0x41, 0xd8, 0x70, 0x7c, 0xf7, 0x55, 0xb3, 0x40, 0x92, 0xb2, 0x14, 0x97, 0x0d, 0x18, 0x4e, 0x60, - 0x9a, 0x95, 0x33, 0x0a, 0x7b, 0x54, 0xce, 0x38, 0x0b, 0x03, 0x21, 0x69, 0x05, 0xe9, 0x0d, 0x0f, - 0xcb, 0x89, 0x62, 0x10, 0xf4, 0x10, 0x14, 0x9d, 0x96, 0x2b, 0xc2, 0x63, 0xd4, 0x3e, 0x6e, 0x66, - 0x65, 0x01, 0xd3, 0xf6, 0x44, 0x21, 0x9f, 0xd2, 0x91, 0x14, 0xf2, 0xa1, 0xaa, 0x4c, 0x9c, 0xbf, - 0x0c, 0x6a, 0x55, 0x96, 0x3c, 0x17, 0xb1, 0x5f, 0x2b, 0xc2, 0x43, 0xbb, 0xce, 0x79, 0x1d, 0x2b, - 0x6b, 0xed, 0x12, 0x2b, 0x2b, 0x87, 0xa7, 0xb0, 0xd7, 0xf0, 0x14, 0x7b, 0x0c, 0xcf, 0x47, 0xe9, - 0x52, 0x96, 0x85, 0xa5, 0xf2, 0xb9, 0x90, 0xb9, 0x57, 0x9d, 0x2a, 0xb1, 0x8a, 0x25, 0x14, 0x6b, - 0xba, 0x74, 0x1f, 0x93, 0xa8, 0x1a, 0x51, 0xca, 0x43, 0x95, 0xf5, 0x2c, 0xee, 0xc4, 0xd7, 0x6f, - 0xaf, 0x52, 0x14, 0xf6, 0x6f, 0x0f, 0xc0, 0x23, 0x7d, 0x68, 0x20, 0x73, 0x16, 0x5b, 0x7d, 0xce, - 0xe2, 0xef, 0xf3, 0xcf, 0xf4, 0xf1, 0xcc, 0xcf, 0x84, 0xf3, 0xff, 0x4c, 0xbb, 0x7f, 0x21, 0xf4, - 0x38, 0x94, 0x5d, 0x3f, 0x22, 0xb5, 0x76, 0xc8, 0xf3, 0x06, 0x8c, 0x84, 0xc9, 0x05, 0xd1, 0x8e, - 0x15, 0x06, 0xdd, 0x97, 0xd6, 0x1c, 0xba, 0xfc, 0x87, 0x72, 0xaa, 0x12, 0x60, 0xe6, 0x5e, 0x72, - 0xb3, 0x68, 0x6e, 0x86, 0x4a, 0x00, 0x4e, 0xc6, 0xfe, 0x45, 0x0b, 0xce, 0xf4, 0x36, 0x13, 0xd0, - 0x93, 0x30, 0xbc, 0xc6, 0x82, 0xcf, 0xd8, 0x55, 0xfc, 0x72, 0xea, 0xb0, 0xf7, 0xd5, 0xcd, 0xd8, - 0xc4, 0x41, 0x73, 0x70, 0xdc, 0x8c, 0x5a, 0x5b, 0x32, 0x22, 0x63, 0x98, 0x23, 0x63, 0x35, 0x0d, - 0xc4, 0xdd, 0xf8, 0xf6, 0x77, 0x8b, 0xd9, 0x6c, 0x71, 0x73, 0x72, 0x3f, 0xb3, 0x59, 0xcc, 0xd5, - 0x42, 0x1f, 0x12, 0xb7, 0x78, 0xd4, 0x12, 0x77, 0xa0, 0x97, 0xc4, 0x45, 0xf3, 0x70, 0xcc, 0xb8, - 0x2b, 0x91, 0xd7, 0x8d, 0xe0, 0x91, 0x92, 0xaa, 0xe8, 0xd3, 0x4a, 0x0a, 0x8e, 0xbb, 0x9e, 0xb8, - 0xc7, 0xa7, 0xde, 0xd7, 0x0b, 0x70, 0xba, 0xa7, 0x05, 0x7f, 0x44, 0x1a, 0xc5, 0xfc, 0xfc, 0x03, - 0x47, 0xf3, 0xf9, 0xcd, 0x8f, 0x52, 0xda, 0xf3, 0xa3, 0xf4, 0xa3, 0x9e, 0xff, 0xb8, 0xd0, 0x73, - 0xb1, 0xd0, 0x1d, 0xdf, 0x0f, 0xec, 0x48, 0x3e, 0x0f, 0xa3, 0x4e, 0xab, 0xc5, 0xf1, 0x58, 0x64, - 0x7a, 0xaa, 0x10, 0xdd, 0x8c, 0x09, 0xc4, 0x49, 0xdc, 0xbe, 0x06, 0xf6, 0xcf, 0x2c, 0xa8, 0x60, - 0xb2, 0xce, 0x25, 0x16, 0xba, 0x21, 0x86, 0xc8, 0xca, 0xa3, 0x1a, 0x38, 0x1d, 0xd8, 0xc8, 0x65, - 0x25, 0xb2, 0xb3, 0x06, 0xfb, 0xa0, 0xa9, 0xdc, 0xea, 0x86, 0xc5, 0x62, 0xef, 0x1b, 0x16, 0xed, - 0xbf, 0x2c, 0xd3, 0xd7, 0x6b, 0x05, 0x73, 0x21, 0xa9, 0x47, 0xf4, 0xfb, 0xb6, 0x43, 0x4f, 0x4c, - 0x12, 0xf5, 0x7d, 0xaf, 0xe2, 0x45, 0x4c, 0xdb, 0x13, 0x07, 0x81, 0x85, 0x7d, 0x95, 0xe1, 0x2a, - 0xee, 0x59, 0x86, 0xeb, 0x79, 0x18, 0x8d, 0xa2, 0x8d, 0x95, 0xd0, 0xdd, 0x72, 0x62, 0x72, 0x99, - 0x74, 0x84, 0x7d, 0xac, 0x4b, 0xd2, 0x54, 0x2f, 0x6a, 0x20, 0x4e, 0xe2, 0xa2, 0x0b, 0x70, 0x5c, - 0x17, 0xc3, 0x22, 0x61, 0xcc, 0x72, 0xa7, 0xf8, 0x4c, 0x50, 0xf5, 0x27, 0x74, 0xf9, 0x2c, 0x81, - 0x80, 0xbb, 0x9f, 0xa1, 0x32, 0x37, 0xd1, 0x48, 0x19, 0x19, 0x4c, 0xca, 0xdc, 0x44, 0x3f, 0x94, - 0x97, 0xae, 0x27, 0xd0, 0x12, 0x9c, 0xe0, 0x13, 0x63, 0xa6, 0xd5, 0x32, 0xde, 0x68, 0x28, 0x59, - 0x82, 0xf9, 0x42, 0x37, 0x0a, 0xce, 0x7a, 0x0e, 0x3d, 0x0b, 0xc3, 0xaa, 0x79, 0x61, 0x5e, 0x9c, - 0x61, 0x29, 0x1f, 0x9a, 0xea, 0x66, 0xa1, 0x8e, 0x4d, 0x3c, 0xf4, 0x6e, 0xb8, 0x5f, 0xff, 0xe5, - 0xb9, 0xb8, 0xfc, 0x60, 0x77, 0x5e, 0xd4, 0x19, 0x54, 0x37, 0xfc, 0x5c, 0xc8, 0x44, 0xab, 0xe3, - 0x5e, 0xcf, 0xa3, 0x35, 0x38, 0xa3, 0x40, 0xe7, 0xfc, 0x98, 0x65, 0xcb, 0x45, 0x64, 0xd6, 0x89, - 0xc8, 0xd5, 0xd0, 0x63, 0x95, 0x09, 0x2b, 0xfa, 0xca, 0xf7, 0x0b, 0x6e, 0x7c, 0x31, 0x0b, 0x13, - 0x2f, 0xe2, 0x5d, 0x7a, 0x41, 0xd3, 0x50, 0x21, 0xbe, 0xb3, 0xe6, 0x91, 0xe5, 0xb9, 0x05, 0x56, - 0xaf, 0xd0, 0x38, 0x47, 0x3e, 0x27, 0x01, 0x58, 0xe3, 0xa8, 0xf8, 0xe6, 0x91, 0x5e, 0xf1, 0xcd, - 0x68, 0x05, 0x4e, 0x36, 0x6a, 0x2d, 0x6a, 0x35, 0xba, 0x35, 0x32, 0x53, 0x63, 0xe1, 0x9c, 0xf4, - 0xc3, 0xf0, 0xda, 0xd8, 0x2a, 0x51, 0xe4, 0xc2, 0xdc, 0x4a, 0x17, 0x0e, 0xce, 0x7c, 0x92, 0x85, - 0xfd, 0x86, 0xc1, 0x76, 0x67, 0xe2, 0x44, 0x2a, 0xec, 0x97, 0x36, 0x62, 0x0e, 0x43, 0x97, 0x00, - 0xb1, 0xac, 0xa3, 0x8b, 0x71, 0xdc, 0x52, 0x66, 0xea, 0xc4, 0xc9, 0x64, 0xd5, 0xb1, 0xf3, 0x5d, - 0x18, 0x38, 0xe3, 0x29, 0x6a, 0xf5, 0xf8, 0x01, 0xeb, 0x7d, 0xe2, 0xfe, 0xa4, 0xd5, 0x73, 0x85, - 0x37, 0x63, 0x09, 0x47, 0xef, 0x85, 0x89, 0x76, 0x44, 0xd8, 0x06, 0xf8, 0x7a, 0x10, 0x6e, 0x7a, - 0x81, 0x53, 0x5f, 0x60, 0x57, 0x39, 0xc6, 0x9d, 0x89, 0x09, 0x46, 0xfc, 0xac, 0x78, 0x76, 0xe2, - 0x6a, 0x0f, 0x3c, 0xdc, 0xb3, 0x87, 0x74, 0xd9, 0xbc, 0xd3, 0xfd, 0x95, 0xcd, 0xb3, 0xff, 0xd4, - 0x82, 0x51, 0x25, 0x6f, 0x8e, 0x20, 0x57, 0xd1, 0x4b, 0xe6, 0x2a, 0x5e, 0x38, 0xb8, 0xc4, 0x66, - 0x9c, 0xf7, 0x48, 0x08, 0xf8, 0x57, 0x23, 0x00, 0x5a, 0xaa, 0x2b, 0x85, 0x6a, 0xf5, 0x54, 0xa8, - 0xf7, 0xac, 0x44, 0xcd, 0x2a, 0x5a, 0x56, 0xba, 0xbb, 0x45, 0xcb, 0xaa, 0x70, 0x4a, 0x9a, 0x44, - 0xfc, 0xa4, 0xf5, 0x62, 0x10, 0x29, 0x01, 0x6d, 0x5c, 0xcd, 0xb5, 0x90, 0x85, 0x84, 0xb3, 0x9f, - 0x4d, 0x58, 0x62, 0x43, 0x7b, 0x5a, 0x62, 0x4a, 0x26, 0x2d, 0xae, 0xcb, 0x8b, 0xf3, 0x52, 0x32, - 0x69, 0xf1, 0x7c, 0x15, 0x6b, 0x9c, 0x6c, 0xc5, 0x54, 0xc9, 0x49, 0x31, 0xc1, 0xbe, 0x15, 0x93, - 0x14, 0x91, 0xc3, 0x3d, 0x45, 0xa4, 0x3c, 0xd1, 0x19, 0xe9, 0x79, 0xa2, 0xf3, 0x0e, 0x18, 0x73, - 0xfd, 0x0d, 0x12, 0xba, 0x31, 0xa9, 0xb3, 0xb5, 0xc0, 0xc4, 0x67, 0x59, 0x9b, 0x25, 0x0b, 0x09, - 0x28, 0x4e, 0x61, 0x27, 0xe5, 0xfa, 0x58, 0x1f, 0x72, 0xbd, 0x87, 0x36, 0x1d, 0xcf, 0x47, 0x9b, - 0x1e, 0x3b, 0xb8, 0x36, 0x3d, 0x7e, 0xa8, 0xda, 0x14, 0xe5, 0xa2, 0x4d, 0xfb, 0x52, 0x54, 0xc6, - 0x96, 0xfa, 0xe4, 0x1e, 0x5b, 0xea, 0x5e, 0xaa, 0xf4, 0xd4, 0x1d, 0xab, 0xd2, 0x6c, 0x2d, 0x79, - 0xdf, 0x0f, 0xa5, 0x96, 0xfc, 0x44, 0x01, 0x4e, 0x69, 0x3d, 0x42, 0x57, 0xaf, 0xbb, 0x4e, 0x25, - 0x29, 0xbb, 0x3b, 0x96, 0x9f, 0xda, 0x1a, 0x69, 0xb8, 0x3a, 0xa3, 0x57, 0x41, 0xb0, 0x81, 0xc5, - 0xb2, 0x59, 0x49, 0xc8, 0x6e, 0x2d, 0x48, 0x2b, 0x99, 0x39, 0xd1, 0x8e, 0x15, 0x06, 0x65, 0x99, - 0xfe, 0x16, 0x55, 0x09, 0xd2, 0xf5, 0x70, 0xe7, 0x34, 0x08, 0x9b, 0x78, 0xe8, 0x31, 0x4e, 0x84, - 0x09, 0x38, 0xaa, 0x68, 0x46, 0xf8, 0x96, 0x4d, 0xc9, 0x34, 0x05, 0x95, 0xec, 0xb0, 0xb4, 0xe5, - 0x52, 0x37, 0x3b, 0x2c, 0x00, 0x52, 0x61, 0xd8, 0xff, 0xc3, 0x82, 0xd3, 0x99, 0x43, 0x71, 0x04, - 0xc6, 0xc3, 0x76, 0xd2, 0x78, 0xa8, 0xe6, 0xb5, 0xdd, 0x33, 0xde, 0xa2, 0x87, 0x21, 0xf1, 0x1f, - 0x2c, 0x18, 0xd3, 0xf8, 0x47, 0xf0, 0xaa, 0x6e, 0xf2, 0x55, 0xf3, 0xdb, 0xd9, 0x56, 0xba, 0xde, - 0xed, 0xf7, 0x0b, 0xa0, 0x6a, 0x54, 0xcf, 0xd4, 0xe4, 0x0d, 0x00, 0x7b, 0xc4, 0x11, 0x74, 0x60, - 0x90, 0x85, 0x41, 0x44, 0xf9, 0x84, 0x78, 0x25, 0xe9, 0xb3, 0x90, 0x0a, 0x7d, 0x2a, 0xc5, 0xfe, - 0x46, 0x58, 0x10, 0x64, 0x77, 0x6a, 0xf0, 0xf2, 0xbf, 0x75, 0x91, 0x94, 0xa9, 0xef, 0xd4, 0x10, - 0xed, 0x58, 0x61, 0x50, 0xf5, 0xe6, 0xd6, 0x02, 0x7f, 0xce, 0x73, 0x22, 0x79, 0x9d, 0xbc, 0x52, - 0x6f, 0x0b, 0x12, 0x80, 0x35, 0x0e, 0x8b, 0x90, 0x70, 0xa3, 0x96, 0xe7, 0x74, 0x0c, 0xff, 0x85, - 0x51, 0x7d, 0x47, 0x81, 0xb0, 0x89, 0x67, 0x37, 0x61, 0x22, 0xf9, 0x12, 0xf3, 0x64, 0x9d, 0x85, - 0x27, 0xf7, 0x35, 0x9c, 0xd3, 0x50, 0x71, 0xd8, 0x53, 0x8b, 0x6d, 0x47, 0xc8, 0x04, 0x1d, 0xa4, - 0x2b, 0x01, 0x58, 0xe3, 0xd8, 0xff, 0xd8, 0x82, 0x13, 0x19, 0x83, 0x96, 0x63, 0xd2, 0x6b, 0xac, - 0xa5, 0x4d, 0x96, 0x61, 0xf2, 0x63, 0x30, 0x54, 0x27, 0xeb, 0x8e, 0x0c, 0x80, 0x35, 0x44, 0xfa, - 0x3c, 0x6f, 0xc6, 0x12, 0x6e, 0xff, 0x56, 0x01, 0xc6, 0x93, 0xbc, 0x46, 0x2c, 0x91, 0x8c, 0x0f, - 0x93, 0x1b, 0xd5, 0x82, 0x2d, 0x12, 0x76, 0xe8, 0x9b, 0x5b, 0xa9, 0x44, 0xb2, 0x2e, 0x0c, 0x9c, - 0xf1, 0x14, 0xab, 0x50, 0x5f, 0x57, 0xa3, 0x2d, 0x67, 0xe4, 0xb5, 0x3c, 0x67, 0xa4, 0xfe, 0x98, - 0x66, 0xb0, 0x8c, 0x22, 0x89, 0x4d, 0xfa, 0xd4, 0x40, 0x62, 0x91, 0xf9, 0xb3, 0x6d, 0xd7, 0x8b, - 0x5d, 0x5f, 0xbc, 0xb2, 0x98, 0xab, 0xca, 0x40, 0x5a, 0xea, 0x46, 0xc1, 0x59, 0xcf, 0xd9, 0xdf, - 0x19, 0x00, 0x55, 0xd0, 0x81, 0x05, 0x33, 0xe6, 0x14, 0x0a, 0xba, 0xdf, 0x74, 0x44, 0x35, 0xb7, - 0x06, 0x76, 0x8b, 0x2e, 0xe2, 0x4e, 0x2f, 0xd3, 0x3b, 0xae, 0x06, 0x6c, 0x55, 0x83, 0xb0, 0x89, - 0x47, 0x39, 0xf1, 0xdc, 0x2d, 0xc2, 0x1f, 0x1a, 0x4c, 0x72, 0xb2, 0x28, 0x01, 0x58, 0xe3, 0x50, - 0x4e, 0xea, 0xee, 0xfa, 0xba, 0xf0, 0xe0, 0x28, 0x4e, 0xe8, 0xe8, 0x60, 0x06, 0xe1, 0x77, 0x98, - 0x04, 0x9b, 0x62, 0x53, 0x60, 0xdc, 0x61, 0x12, 0x6c, 0x62, 0x06, 0xa1, 0x5f, 0xc9, 0x0f, 0xc2, - 0xa6, 0xe3, 0xb9, 0xaf, 0x92, 0xba, 0xa2, 0x22, 0x36, 0x03, 0xea, 0x2b, 0x5d, 0xe9, 0x46, 0xc1, - 0x59, 0xcf, 0xd1, 0x09, 0xdd, 0x0a, 0x49, 0xdd, 0xad, 0xc5, 0x66, 0x6f, 0x90, 0x9c, 0xd0, 0x2b, - 0x5d, 0x18, 0x38, 0xe3, 0x29, 0x34, 0x03, 0xe3, 0xb2, 0x20, 0x87, 0xac, 0x06, 0x37, 0x9c, 0x2c, - 0x29, 0x85, 0x93, 0x60, 0x9c, 0xc6, 0xa7, 0x42, 0xb2, 0x29, 0x6a, 0x59, 0xb2, 0xbd, 0x83, 0x21, - 0x24, 0x65, 0x8d, 0x4b, 0xac, 0x30, 0xec, 0x8f, 0x14, 0xa9, 0x52, 0xef, 0x51, 0x32, 0xf6, 0xc8, - 0x42, 0x8f, 0x93, 0x33, 0x72, 0xa0, 0x8f, 0x19, 0xf9, 0x0c, 0x8c, 0xdc, 0x88, 0x02, 0x5f, 0x85, - 0xf5, 0x96, 0x7a, 0x86, 0xf5, 0x1a, 0x58, 0xd9, 0x61, 0xbd, 0x83, 0x79, 0x85, 0xf5, 0x0e, 0xdd, - 0x61, 0x58, 0xef, 0x1f, 0x94, 0x40, 0x5d, 0x52, 0x77, 0x85, 0xc4, 0x37, 0x83, 0x70, 0xd3, 0xf5, - 0x1b, 0xac, 0xb8, 0xc4, 0x57, 0x2c, 0x59, 0x9f, 0x62, 0xd1, 0x4c, 0xcb, 0x5c, 0xcf, 0xe9, 0xa2, - 0xb1, 0x04, 0xb1, 0xa9, 0x55, 0x83, 0x50, 0xea, 0xfa, 0x7f, 0x13, 0x84, 0x13, 0x1c, 0xa1, 0x0f, - 0x02, 0x48, 0x77, 0xf7, 0xba, 0x94, 0xc0, 0x0b, 0xf9, 0xf0, 0x87, 0xc9, 0xba, 0x36, 0xa9, 0x57, - 0x15, 0x11, 0x6c, 0x10, 0x44, 0x9f, 0xd0, 0x29, 0xab, 0x3c, 0xff, 0xe7, 0xfd, 0x87, 0x32, 0x36, - 0xfd, 0x24, 0xac, 0x62, 0x18, 0x72, 0xfd, 0x06, 0x9d, 0x27, 0x22, 0xfc, 0xf1, 0x4d, 0x59, 0x45, - 0x80, 0x16, 0x03, 0xa7, 0x3e, 0xeb, 0x78, 0x8e, 0x5f, 0x23, 0xe1, 0x02, 0x47, 0xd7, 0x1a, 0x54, - 0x34, 0x60, 0xd9, 0x51, 0xd7, 0x4d, 0x7a, 0xa5, 0x7e, 0x6e, 0xd2, 0x3b, 0xf3, 0x4e, 0x38, 0xde, - 0xf5, 0x31, 0xf7, 0x95, 0x9f, 0x7a, 0xe7, 0xa9, 0xad, 0xf6, 0x6f, 0x0f, 0x6a, 0xa5, 0x75, 0x25, - 0xa8, 0xf3, 0x8b, 0xd9, 0x42, 0xfd, 0x45, 0x85, 0xc9, 0x9c, 0xe3, 0x14, 0x51, 0x6a, 0xc6, 0x68, - 0xc4, 0x26, 0x49, 0x3a, 0x47, 0x5b, 0x4e, 0x48, 0xfc, 0xc3, 0x9e, 0xa3, 0x2b, 0x8a, 0x08, 0x36, - 0x08, 0xa2, 0x8d, 0x44, 0x82, 0xda, 0xf9, 0x83, 0x27, 0xa8, 0xb1, 0x92, 0x8c, 0x59, 0xf7, 0x17, - 0x7d, 0xce, 0x82, 0x31, 0x3f, 0x31, 0x73, 0xf3, 0x89, 0x49, 0xcf, 0x5e, 0x15, 0xfc, 0x8e, 0xd3, - 0x64, 0x1b, 0x4e, 0xd1, 0xcf, 0x52, 0x69, 0xa5, 0x7d, 0xaa, 0x34, 0x7d, 0x31, 0xe4, 0x60, 0xaf, - 0x8b, 0x21, 0x91, 0xaf, 0x6e, 0xec, 0x1d, 0xca, 0xa3, 0xf6, 0x43, 0xe2, 0xba, 0x5e, 0xc8, 0xb8, - 0xaa, 0xf7, 0x3a, 0x54, 0x6a, 0x21, 0x71, 0xe2, 0x3b, 0xbc, 0xb9, 0x95, 0x45, 0xca, 0xcc, 0xc9, - 0x0e, 0xb0, 0xee, 0xcb, 0xfe, 0xdf, 0x03, 0x70, 0x4c, 0x8e, 0x88, 0xcc, 0x67, 0xa1, 0xfa, 0x91, - 0xd3, 0xd5, 0xb6, 0xb2, 0xd2, 0x8f, 0x17, 0x25, 0x00, 0x6b, 0x1c, 0x6a, 0x8f, 0xb5, 0x23, 0xb2, - 0xdc, 0x22, 0xfe, 0xa2, 0xbb, 0x16, 0x89, 0xa3, 0x6d, 0xb5, 0x50, 0xae, 0x6a, 0x10, 0x36, 0xf1, - 0xa8, 0x6d, 0xef, 0x18, 0x46, 0xab, 0x61, 0xdb, 0x4b, 0x43, 0x55, 0xc2, 0xd1, 0x17, 0x33, 0x6b, - 0xd8, 0xe7, 0x93, 0x05, 0xda, 0x95, 0xc6, 0xb3, 0xcf, 0xab, 0xc7, 0xff, 0xbe, 0x05, 0xa7, 0x78, - 0xab, 0x1c, 0xc9, 0xab, 0xad, 0xba, 0x13, 0x93, 0x28, 0x9f, 0xbb, 0x6f, 0x32, 0xf8, 0xd3, 0x3e, - 0xef, 0x2c, 0xb2, 0x38, 0x9b, 0x1b, 0xf4, 0x59, 0x0b, 0xc6, 0x37, 0x13, 0x05, 0x84, 0xa4, 0xea, - 0x38, 0x68, 0x6d, 0x8f, 0x44, 0xa7, 0x7a, 0xa9, 0x25, 0xdb, 0x23, 0x9c, 0xa6, 0x6e, 0xff, 0x77, - 0x0b, 0x4c, 0x31, 0x7a, 0xf4, 0x75, 0x87, 0xf6, 0x6f, 0x0a, 0x4a, 0xeb, 0xb2, 0xd4, 0xd3, 0xba, - 0x7c, 0x08, 0x8a, 0x6d, 0xb7, 0x2e, 0xf6, 0x17, 0xfa, 0x30, 0x7d, 0x61, 0x1e, 0xd3, 0x76, 0xfb, - 0x5f, 0x94, 0xb4, 0x1b, 0x44, 0x24, 0x59, 0xfe, 0x40, 0xbc, 0xf6, 0xba, 0xaa, 0xcc, 0xc9, 0xdf, - 0xfc, 0x4a, 0x57, 0x65, 0xce, 0xb7, 0xed, 0x3f, 0x87, 0x96, 0x0f, 0x50, 0xaf, 0xc2, 0x9c, 0x43, - 0x7b, 0x24, 0xd0, 0xde, 0x80, 0x32, 0xdd, 0x82, 0x31, 0x7f, 0x66, 0x39, 0xc1, 0x54, 0xf9, 0xa2, - 0x68, 0xbf, 0xbd, 0x33, 0xf9, 0xd6, 0xfd, 0xb3, 0x25, 0x9f, 0xc6, 0xaa, 0x7f, 0x14, 0x41, 0x85, - 0xfe, 0x66, 0xb9, 0xbe, 0x62, 0x73, 0x77, 0x55, 0xc9, 0x4c, 0x09, 0xc8, 0x25, 0x91, 0x58, 0xd3, - 0x41, 0x3e, 0x54, 0x28, 0x22, 0x27, 0xca, 0xf7, 0x80, 0x2b, 0x2a, 0xe3, 0x56, 0x02, 0x6e, 0xef, - 0x4c, 0x3e, 0xbf, 0x7f, 0xa2, 0xea, 0x71, 0xac, 0x49, 0xd8, 0xff, 0x67, 0x40, 0xcf, 0x5d, 0x51, - 0x90, 0xf5, 0x07, 0x62, 0xee, 0x3e, 0x97, 0x9a, 0xbb, 0x67, 0xbb, 0xe6, 0xee, 0x98, 0xbe, 0xc2, - 0x3f, 0x31, 0x1b, 0x8f, 0xda, 0x10, 0xd8, 0xdb, 0xdf, 0xc0, 0x2c, 0xa0, 0x57, 0xda, 0x6e, 0x48, - 0xa2, 0x95, 0xb0, 0xed, 0xbb, 0x7e, 0x83, 0x4d, 0xc7, 0xb2, 0x69, 0x01, 0x25, 0xc0, 0x38, 0x8d, - 0x4f, 0x37, 0xf5, 0xf4, 0x9b, 0x5f, 0x77, 0xb6, 0xf8, 0xac, 0x32, 0x6a, 0xf8, 0x55, 0x45, 0x3b, - 0x56, 0x18, 0x68, 0x03, 0x1e, 0x94, 0x1d, 0xcc, 0x13, 0x8f, 0x88, 0x0b, 0xf8, 0xd7, 0xdd, 0xb0, - 0xc9, 0xc3, 0xed, 0x79, 0x0c, 0xc7, 0x1b, 0x45, 0x0f, 0x0f, 0xe2, 0x5d, 0x70, 0xf1, 0xae, 0x3d, - 0xd9, 0x5f, 0x65, 0x41, 0x04, 0x46, 0x39, 0x03, 0x3a, 0xfb, 0x3c, 0xb7, 0xe9, 0xca, 0x52, 0x83, - 0x6a, 0xf6, 0x2d, 0xd2, 0x46, 0xcc, 0x61, 0xe8, 0x26, 0x0c, 0xad, 0xf1, 0x7b, 0x92, 0xf3, 0xb9, - 0x93, 0x45, 0x5c, 0xba, 0xcc, 0xea, 0xf5, 0xca, 0x1b, 0x98, 0x6f, 0xeb, 0x9f, 0x58, 0x52, 0xb3, - 0xbf, 0x59, 0x82, 0x71, 0x19, 0x96, 0x75, 0xd1, 0x8d, 0x58, 0x6c, 0x80, 0x59, 0xc4, 0xbc, 0xb0, - 0x67, 0x11, 0xf3, 0xf7, 0x01, 0xd4, 0x49, 0xcb, 0x0b, 0x3a, 0xcc, 0xf0, 0x1b, 0xd8, 0xb7, 0xe1, - 0xa7, 0xf6, 0x0a, 0xf3, 0xaa, 0x17, 0x6c, 0xf4, 0x28, 0xea, 0x2b, 0xf2, 0x9a, 0xe8, 0xa9, 0xfa, - 0x8a, 0xc6, 0xcd, 0x4d, 0x83, 0x47, 0x7b, 0x73, 0x93, 0x0b, 0xe3, 0x9c, 0x45, 0x55, 0x34, 0xe0, - 0x0e, 0x6a, 0x03, 0xb0, 0xb4, 0xab, 0xf9, 0x64, 0x37, 0x38, 0xdd, 0xaf, 0x79, 0x2d, 0x53, 0xf9, - 0xa8, 0xaf, 0x65, 0x7a, 0x33, 0x54, 0xe4, 0x77, 0x8e, 0x26, 0x2a, 0xba, 0xf0, 0x8a, 0x9c, 0x06, - 0x11, 0xd6, 0xf0, 0xae, 0xfa, 0x27, 0x70, 0xb7, 0xea, 0x9f, 0xd8, 0x9f, 0x29, 0xd0, 0x1d, 0x03, - 0xe7, 0x4b, 0x95, 0xf2, 0x7a, 0x14, 0x06, 0x9d, 0x76, 0xbc, 0x11, 0x74, 0xdd, 0xb4, 0x3c, 0xc3, - 0x5a, 0xb1, 0x80, 0xa2, 0x45, 0x18, 0xa8, 0xeb, 0xf2, 0x4c, 0xfb, 0xf9, 0x9e, 0xda, 0xf9, 0xea, - 0xc4, 0x04, 0xb3, 0x5e, 0xd0, 0x83, 0x30, 0x10, 0x3b, 0x0d, 0x99, 0x29, 0xca, 0xaa, 0x03, 0xac, - 0x3a, 0x8d, 0x08, 0xb3, 0xd6, 0xfd, 0x94, 0xa4, 0x7d, 0x1e, 0x46, 0x23, 0xb7, 0xe1, 0x3b, 0x71, - 0x3b, 0x24, 0xc6, 0xf9, 0xa4, 0x0e, 0x99, 0x31, 0x81, 0x38, 0x89, 0x6b, 0xff, 0xce, 0x08, 0x9c, - 0xac, 0xce, 0x2d, 0xc9, 0xfb, 0x37, 0x0e, 0x2d, 0xd9, 0x33, 0x8b, 0xc6, 0xd1, 0x25, 0x7b, 0xf6, - 0xa0, 0xee, 0x19, 0xc9, 0x9e, 0x9e, 0x91, 0xec, 0x99, 0xcc, 0xbc, 0x2b, 0xe6, 0x91, 0x79, 0x97, - 0xc5, 0x41, 0x3f, 0x99, 0x77, 0x87, 0x96, 0xfd, 0xb9, 0x2b, 0x43, 0xfb, 0xca, 0xfe, 0x54, 0xa9, - 0xb1, 0xb9, 0xe4, 0x13, 0xf5, 0xf8, 0x54, 0x99, 0xa9, 0xb1, 0x2a, 0x2d, 0x91, 0xe7, 0xca, 0x09, - 0x51, 0xff, 0x52, 0xfe, 0x0c, 0xf4, 0x91, 0x96, 0x28, 0xd2, 0xf5, 0xcc, 0x54, 0xd8, 0xa1, 0x3c, - 0x52, 0x61, 0xb3, 0xd8, 0xd9, 0x33, 0x15, 0xf6, 0x79, 0x18, 0xad, 0x79, 0x81, 0x4f, 0x56, 0xc2, - 0x20, 0x0e, 0x6a, 0x81, 0xbc, 0xeb, 0x55, 0x5f, 0x55, 0x66, 0x02, 0x71, 0x12, 0xb7, 0x57, 0x1e, - 0x6d, 0xe5, 0xa0, 0x79, 0xb4, 0x70, 0x97, 0xf2, 0x68, 0x8d, 0x4c, 0xd1, 0xe1, 0x3c, 0x32, 0x45, - 0xb3, 0xbe, 0x48, 0x5f, 0x97, 0xb9, 0xbe, 0xc6, 0xaf, 0x3a, 0xa6, 0x26, 0xf8, 0x5c, 0xd0, 0xa4, - 0x86, 0xdf, 0x08, 0x1b, 0x92, 0x97, 0x0f, 0x61, 0xc2, 0x5e, 0xaf, 0x6a, 0x32, 0xea, 0xfa, 0x63, - 0xdd, 0x84, 0x93, 0x8c, 0x1c, 0x24, 0x89, 0xf5, 0x4b, 0x05, 0xf8, 0x91, 0x3d, 0x59, 0x40, 0x37, - 0x01, 0x62, 0xa7, 0x21, 0x26, 0xaa, 0x38, 0x9a, 0x39, 0x60, 0x5c, 0xeb, 0xaa, 0xec, 0x8f, 0x97, - 0x52, 0x52, 0x7f, 0xd9, 0xa1, 0x87, 0xfc, 0xcd, 0xc2, 0x59, 0x03, 0xaf, 0xab, 0xe2, 0x2c, 0x0e, - 0x3c, 0x82, 0x19, 0x84, 0xaa, 0xff, 0x90, 0x34, 0xa8, 0x49, 0x5b, 0x4c, 0xaa, 0x7f, 0xcc, 0x5a, - 0xb1, 0x80, 0xa2, 0x67, 0x61, 0xd8, 0xf1, 0x3c, 0x9e, 0xec, 0x45, 0x22, 0x71, 0x87, 0xa0, 0x2e, - 0x7d, 0xa9, 0x41, 0xd8, 0xc4, 0xb3, 0xff, 0xaa, 0x00, 0x93, 0x7b, 0xc8, 0x94, 0xae, 0x24, 0xdf, - 0x52, 0xdf, 0x49, 0xbe, 0x22, 0xb9, 0x65, 0xb0, 0x47, 0x72, 0xcb, 0xb3, 0x30, 0x1c, 0x13, 0xa7, - 0x29, 0x22, 0xe1, 0x84, 0xcf, 0x41, 0x9f, 0x35, 0x6b, 0x10, 0x36, 0xf1, 0xa8, 0x14, 0x1b, 0x73, - 0x6a, 0x35, 0x12, 0x45, 0x32, 0x7b, 0x45, 0xf8, 0x6d, 0x73, 0x4b, 0x8d, 0x61, 0xee, 0xf0, 0x99, - 0x04, 0x09, 0x9c, 0x22, 0x99, 0x1e, 0xf0, 0x4a, 0x9f, 0x03, 0xfe, 0x2b, 0x05, 0x78, 0x68, 0x57, - 0xed, 0xd6, 0x77, 0x62, 0x51, 0x3b, 0x22, 0x61, 0x7a, 0xe2, 0x5c, 0x8d, 0x48, 0x88, 0x19, 0x84, - 0x8f, 0x52, 0xab, 0xa5, 0xa2, 0x98, 0xf3, 0xcf, 0xc4, 0xe3, 0xa3, 0x94, 0x20, 0x81, 0x53, 0x24, - 0xef, 0x74, 0x5a, 0x7e, 0x73, 0x00, 0x1e, 0xe9, 0xc3, 0x06, 0xc8, 0x31, 0x63, 0x31, 0x99, 0x5d, - 0x5b, 0xbc, 0x4b, 0xd9, 0xb5, 0x77, 0x36, 0x5c, 0xaf, 0x27, 0xe5, 0xf6, 0x95, 0x19, 0xf9, 0xd5, - 0x02, 0x9c, 0xe9, 0x6d, 0xb0, 0xa0, 0xb7, 0xc3, 0x78, 0xa8, 0x82, 0xec, 0xcc, 0xc4, 0xdc, 0x13, - 0xdc, 0xb3, 0x93, 0x00, 0xe1, 0x34, 0x2e, 0x9a, 0x02, 0x68, 0x39, 0xf1, 0x46, 0x74, 0x6e, 0xdb, - 0x8d, 0x62, 0x51, 0x62, 0x6c, 0x8c, 0x9f, 0x25, 0xca, 0x56, 0x6c, 0x60, 0x50, 0x72, 0xec, 0xdf, - 0x7c, 0x70, 0x25, 0x88, 0xf9, 0x43, 0x7c, 0xb3, 0x75, 0x42, 0x5e, 0x38, 0x66, 0x80, 0x70, 0x1a, - 0x97, 0x92, 0x63, 0xa7, 0xd5, 0x9c, 0x51, 0xbe, 0x0b, 0x63, 0xe4, 0x16, 0x55, 0x2b, 0x36, 0x30, - 0xd2, 0x29, 0xc7, 0xa5, 0xbd, 0x53, 0x8e, 0xed, 0x7f, 0x5e, 0x80, 0xd3, 0x3d, 0x0d, 0xde, 0xfe, - 0xc4, 0xd4, 0xbd, 0x97, 0x26, 0x7c, 0x87, 0x2b, 0x6c, 0x5f, 0xe9, 0xa5, 0xf6, 0x9f, 0xf5, 0x98, - 0x69, 0x22, 0x75, 0xf4, 0xce, 0xab, 0x66, 0xdc, 0x7b, 0xe3, 0xd9, 0x95, 0x2d, 0x3a, 0xb0, 0x8f, - 0x6c, 0xd1, 0xd4, 0xc7, 0x28, 0xf5, 0xa9, 0x1d, 0xfe, 0xcb, 0x40, 0xcf, 0xe1, 0xa5, 0x1b, 0xe4, - 0xbe, 0xfc, 0xe6, 0xf3, 0x70, 0xcc, 0xf5, 0xd9, 0x15, 0x92, 0xd5, 0xf6, 0x9a, 0xa8, 0x3a, 0xc5, - 0x4b, 0xab, 0xaa, 0xec, 0x8f, 0x85, 0x14, 0x1c, 0x77, 0x3d, 0x71, 0x0f, 0x66, 0xef, 0xde, 0xd9, - 0x90, 0xee, 0x53, 0x72, 0x2f, 0xc3, 0x29, 0x39, 0x14, 0x1b, 0x4e, 0x48, 0xea, 0x42, 0xd9, 0x46, - 0x22, 0xdf, 0xe7, 0x34, 0xcf, 0x19, 0xca, 0x40, 0xc0, 0xd9, 0xcf, 0xb1, 0xfb, 0xfe, 0x82, 0x96, - 0x5b, 0x13, 0x5b, 0x41, 0x7d, 0xdf, 0x1f, 0x6d, 0xc4, 0x1c, 0xa6, 0xf5, 0x45, 0xe5, 0x68, 0xf4, - 0xc5, 0xfb, 0xa0, 0xa2, 0xc6, 0x9b, 0x67, 0x09, 0xa8, 0x49, 0xde, 0x95, 0x25, 0xa0, 0x66, 0xb8, - 0x81, 0xb5, 0xd7, 0xb5, 0xda, 0x4f, 0xc3, 0x88, 0xf2, 0x7e, 0xf5, 0x7b, 0xeb, 0xa2, 0xfd, 0x7f, - 0x0b, 0x90, 0xba, 0x17, 0x09, 0x6d, 0x43, 0xa5, 0x2e, 0x2f, 0xb6, 0xce, 0xa7, 0xb4, 0xaf, 0xba, - 0x27, 0x5b, 0x1f, 0xff, 0xa8, 0x26, 0xac, 0x89, 0xa1, 0x0f, 0xf0, 0x2a, 0xba, 0x82, 0x74, 0x21, - 0x8f, 0x0c, 0xee, 0xaa, 0xea, 0xcf, 0xbc, 0x56, 0x4d, 0xb6, 0x61, 0x83, 0x1e, 0x8a, 0xa1, 0xb2, - 0x21, 0xef, 0x7f, 0xca, 0x47, 0xdc, 0xa9, 0xeb, 0xa4, 0xb8, 0x89, 0xa6, 0xfe, 0x62, 0x4d, 0xc8, - 0xfe, 0xd3, 0x02, 0x9c, 0x4c, 0x7e, 0x00, 0x71, 0x5c, 0xf7, 0x6b, 0x16, 0xdc, 0xef, 0x39, 0x51, - 0x5c, 0x6d, 0xb3, 0x8d, 0xc2, 0x7a, 0xdb, 0x5b, 0x4e, 0x15, 0x5c, 0x3e, 0xa8, 0xb3, 0x45, 0x75, - 0x9c, 0xbe, 0x2f, 0x6c, 0xf6, 0x81, 0x5b, 0x3b, 0x93, 0xf7, 0x2f, 0x66, 0x13, 0xc7, 0xbd, 0xb8, - 0x42, 0x9f, 0xb3, 0xe0, 0x58, 0xad, 0x1d, 0x86, 0xc4, 0x8f, 0x35, 0xab, 0xfc, 0x2b, 0x5e, 0xc9, - 0x65, 0x20, 0x35, 0x83, 0x27, 0xa9, 0x40, 0x9d, 0x4b, 0xd1, 0xc2, 0x5d, 0xd4, 0xed, 0x5f, 0xa0, - 0x9a, 0xb3, 0xe7, 0x7b, 0xfe, 0x90, 0x5d, 0x70, 0xf6, 0xbd, 0x41, 0x18, 0x4d, 0x54, 0x95, 0x4e, - 0x1c, 0x71, 0x59, 0x7b, 0x1e, 0x71, 0xb1, 0x0c, 0xb5, 0xb6, 0x2f, 0x2f, 0x51, 0x36, 0x32, 0xd4, - 0xda, 0x3e, 0xc1, 0x1c, 0x26, 0x86, 0x14, 0xb7, 0x7d, 0x11, 0xdd, 0x6e, 0x0e, 0x29, 0x6e, 0xfb, - 0x58, 0x40, 0xd1, 0x87, 0x2d, 0x18, 0x61, 0x8b, 0x4f, 0x1c, 0x10, 0x0a, 0x85, 0x76, 0x29, 0x87, - 0xe5, 0x2e, 0x2b, 0xa8, 0xb3, 0x68, 0x48, 0xb3, 0x05, 0x27, 0x28, 0xa2, 0x8f, 0x59, 0x50, 0x51, - 0x37, 0x36, 0x8a, 0x6b, 0xd7, 0xab, 0xf9, 0x16, 0xed, 0x4e, 0x49, 0x3d, 0x55, 0x3d, 0x19, 0x6b, - 0xc2, 0x28, 0x52, 0xa7, 0x77, 0x43, 0x87, 0x73, 0x7a, 0x07, 0x19, 0x27, 0x77, 0x6f, 0x86, 0x4a, - 0xd3, 0xf1, 0xdd, 0x75, 0x12, 0xc5, 0xfc, 0x40, 0x4d, 0xde, 0x25, 0x20, 0x1b, 0xb1, 0x86, 0x53, - 0x63, 0x3f, 0x62, 0x2f, 0x16, 0x1b, 0x27, 0x60, 0xcc, 0xd8, 0xaf, 0xea, 0x66, 0x6c, 0xe2, 0x98, - 0xc7, 0x75, 0x70, 0x57, 0x8f, 0xeb, 0x86, 0xf7, 0x38, 0xae, 0xab, 0xc2, 0x29, 0xa7, 0x1d, 0x07, - 0x17, 0x89, 0xe3, 0xcd, 0xc4, 0x31, 0x69, 0xb6, 0xe2, 0x88, 0x17, 0x22, 0x1f, 0x61, 0x2e, 0x60, - 0x15, 0xbf, 0x55, 0x25, 0xde, 0x7a, 0x17, 0x12, 0xce, 0x7e, 0xd6, 0xfe, 0xa7, 0x16, 0x9c, 0xca, - 0x9c, 0x0a, 0xf7, 0x6e, 0xe4, 0xbc, 0xfd, 0x85, 0x12, 0x9c, 0xc8, 0xa8, 0x39, 0x8f, 0x3a, 0xe6, - 0x22, 0xb1, 0xf2, 0x08, 0x42, 0x4b, 0xc6, 0x54, 0xc9, 0x6f, 0x93, 0xb1, 0x32, 0xf6, 0x77, 0x02, - 0xaf, 0x4f, 0xc1, 0x8b, 0x47, 0x7b, 0x0a, 0x6e, 0xcc, 0xf5, 0x81, 0xbb, 0x3a, 0xd7, 0x4b, 0x7b, - 0xcc, 0xf5, 0xaf, 0x59, 0x30, 0xd1, 0xec, 0x71, 0xd1, 0x91, 0x38, 0x4f, 0xba, 0x76, 0x38, 0xd7, - 0x28, 0xcd, 0x3e, 0x78, 0x6b, 0x67, 0xb2, 0xe7, 0xfd, 0x52, 0xb8, 0x27, 0x57, 0xf6, 0x77, 0x8a, - 0xc0, 0xec, 0x35, 0x56, 0x57, 0xb8, 0x83, 0x3e, 0x64, 0x5e, 0x5d, 0x61, 0xe5, 0x75, 0xcd, 0x02, - 0xef, 0x5c, 0x5d, 0x7d, 0xc1, 0x47, 0x30, 0xeb, 0x26, 0x8c, 0xb4, 0x24, 0x2c, 0xf4, 0x21, 0x09, - 0x3d, 0x79, 0x47, 0x48, 0x31, 0xff, 0x3b, 0x42, 0x2a, 0xe9, 0xfb, 0x41, 0x76, 0xff, 0xc4, 0x03, - 0xf7, 0xe4, 0x27, 0xfe, 0x5d, 0x8b, 0x0b, 0x9e, 0xd4, 0x57, 0xd0, 0xe6, 0x86, 0xb5, 0x8b, 0xb9, - 0xf1, 0x38, 0x94, 0x23, 0x21, 0x99, 0x85, 0x59, 0xa2, 0x03, 0xa0, 0x44, 0x3b, 0x56, 0x18, 0x74, - 0xd7, 0xe5, 0x78, 0x5e, 0x70, 0xf3, 0x5c, 0xb3, 0x15, 0x77, 0x84, 0x81, 0xa2, 0xb6, 0x05, 0x33, - 0x0a, 0x82, 0x0d, 0x2c, 0xf4, 0x08, 0x0c, 0xf2, 0x4a, 0x07, 0xc2, 0xb9, 0x33, 0x4c, 0xd7, 0x21, - 0x2f, 0x83, 0x50, 0xc7, 0x02, 0x64, 0x6f, 0x80, 0xb1, 0xab, 0xb8, 0xf3, 0xcb, 0x63, 0xfb, 0xb8, - 0xf5, 0xfb, 0xef, 0x16, 0x04, 0x29, 0xbe, 0x4b, 0x78, 0x2e, 0x75, 0xcb, 0x7a, 0xff, 0xf1, 0x70, - 0x1f, 0x00, 0xa8, 0x05, 0xcd, 0x16, 0xdd, 0x37, 0xaf, 0x06, 0xf9, 0x6c, 0xb6, 0xe6, 0x54, 0x7f, - 0x7a, 0x54, 0x75, 0x1b, 0x36, 0xe8, 0x25, 0x44, 0x7b, 0x71, 0x4f, 0xd1, 0x9e, 0x90, 0x72, 0x03, - 0xbb, 0x4b, 0x39, 0xfb, 0xaf, 0x2c, 0x48, 0x58, 0x7d, 0xa8, 0x05, 0x25, 0xca, 0x6e, 0x47, 0x08, - 0x8c, 0xe5, 0xfc, 0x4c, 0x4c, 0x2a, 0xa9, 0xc5, 0x2a, 0x64, 0x3f, 0x31, 0x27, 0x84, 0x3c, 0x11, - 0xfb, 0x97, 0xcb, 0xe6, 0xc7, 0x24, 0x78, 0x31, 0x08, 0x36, 0x79, 0xf8, 0x8c, 0x8e, 0x23, 0xb4, - 0x9f, 0x83, 0xe3, 0x5d, 0x4c, 0xb1, 0x0b, 0x67, 0x03, 0xb9, 0x83, 0x37, 0x56, 0x0f, 0xab, 0xcf, - 0x80, 0x39, 0xcc, 0xfe, 0xaa, 0x05, 0xc7, 0xd2, 0xdd, 0xa3, 0xd7, 0x2c, 0x38, 0x1e, 0xa5, 0xfb, - 0x3b, 0xac, 0xb1, 0x53, 0xf1, 0xfb, 0x5d, 0x20, 0xdc, 0xcd, 0x84, 0xfd, 0x97, 0x42, 0x1b, 0x5c, - 0x77, 0xfd, 0x7a, 0x70, 0x53, 0xd9, 0x49, 0x56, 0x4f, 0x3b, 0x89, 0x8a, 0x87, 0xda, 0x06, 0xa9, - 0xb7, 0xbd, 0xae, 0xc2, 0x0a, 0x55, 0xd1, 0x8e, 0x15, 0x06, 0xcb, 0x23, 0x6f, 0x8b, 0x7d, 0x6b, - 0x6a, 0x52, 0xce, 0x8b, 0x76, 0xac, 0x30, 0xd0, 0x33, 0x30, 0x62, 0xbc, 0xa4, 0x9c, 0x97, 0x6c, - 0xd3, 0x61, 0x68, 0xf0, 0x08, 0x27, 0xb0, 0xd0, 0x14, 0x80, 0xb2, 0xb9, 0xa4, 0xc6, 0x66, 0x8e, - 0x76, 0x25, 0x18, 0x23, 0x6c, 0x60, 0xb0, 0xaa, 0x0d, 0x5e, 0x3b, 0x62, 0x27, 0xc9, 0x83, 0xba, - 0xce, 0xfe, 0x9c, 0x68, 0xc3, 0x0a, 0x4a, 0x85, 0x5b, 0xd3, 0xf1, 0xdb, 0x8e, 0x47, 0x47, 0x48, - 0xb8, 0xce, 0xd4, 0x32, 0x5c, 0x52, 0x10, 0x6c, 0x60, 0xd1, 0x37, 0x8e, 0xdd, 0x26, 0x79, 0x31, - 0xf0, 0x65, 0xdc, 0xb5, 0x0e, 0x2e, 0x10, 0xed, 0x58, 0x61, 0xa0, 0xe7, 0x60, 0xd8, 0xf1, 0xeb, - 0xdc, 0x40, 0x0c, 0x42, 0x71, 0x46, 0xa9, 0x76, 0x9f, 0x57, 0x23, 0x32, 0xa3, 0xa1, 0xd8, 0x44, - 0x4d, 0x5f, 0x32, 0x00, 0xfd, 0x5d, 0x32, 0x60, 0xff, 0x85, 0x05, 0xe3, 0xba, 0x68, 0x0e, 0xf3, - 0xb0, 0x25, 0x5c, 0x8b, 0xd6, 0x9e, 0xae, 0xc5, 0x64, 0x35, 0x8e, 0x42, 0x5f, 0xd5, 0x38, 0xcc, - 0x42, 0x19, 0xc5, 0x5d, 0x0b, 0x65, 0xfc, 0x28, 0x0c, 0x6d, 0x92, 0x8e, 0x51, 0x51, 0x83, 0x29, - 0x87, 0xcb, 0xbc, 0x09, 0x4b, 0x18, 0xb2, 0x61, 0xb0, 0xe6, 0xa8, 0x8a, 0x77, 0x23, 0x7c, 0x43, - 0x36, 0x37, 0xc3, 0x90, 0x04, 0xc4, 0x5e, 0x86, 0x8a, 0x3a, 0xd4, 0x97, 0x9e, 0x3e, 0x2b, 0xdb, - 0xd3, 0xd7, 0x57, 0xc2, 0xfe, 0xec, 0xda, 0x37, 0xbe, 0xfb, 0xf0, 0x1b, 0xfe, 0xe8, 0xbb, 0x0f, - 0xbf, 0xe1, 0x4f, 0xbe, 0xfb, 0xf0, 0x1b, 0x3e, 0x7c, 0xeb, 0x61, 0xeb, 0x1b, 0xb7, 0x1e, 0xb6, - 0xfe, 0xe8, 0xd6, 0xc3, 0xd6, 0x9f, 0xdc, 0x7a, 0xd8, 0xfa, 0xce, 0xad, 0x87, 0xad, 0xcf, 0xfd, - 0xe7, 0x87, 0xdf, 0xf0, 0x62, 0x66, 0xa4, 0x3f, 0xfd, 0xf1, 0x44, 0xad, 0x3e, 0xbd, 0xf5, 0x34, - 0x0b, 0x36, 0xa7, 0xeb, 0x79, 0xda, 0x98, 0xc4, 0xd3, 0x72, 0x3d, 0xff, 0xbf, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x65, 0xd7, 0x8c, 0xdf, 0x62, 0xfa, 0x00, 0x00, +var fileDescriptor_030104ce3b95bcac = []byte{ + // 11861 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7d, 0x70, 0x1c, 0xc9, + 0x75, 0x18, 0xae, 0xd9, 0xc5, 0x02, 0xbb, 0x0f, 0x5f, 0x64, 0x93, 0xbc, 0xc3, 0xf1, 0x3e, 0x40, + 0xcf, 0xc9, 0xa7, 0xf3, 0x4f, 0x77, 0x80, 0x8f, 0xbe, 0x93, 0xef, 0xe7, 0xb3, 0x24, 0xe3, 0x83, + 0x04, 0x41, 0x02, 0x04, 0xae, 0x17, 0x24, 0xa5, 0x93, 0x4f, 0xa7, 0xc1, 0x6e, 0x63, 0x31, 0xc4, + 0xec, 0xcc, 0xde, 0xcc, 0x2c, 0x88, 0x3d, 0x4b, 0xb2, 0x64, 0x49, 0xb6, 0x6c, 0x7d, 0x46, 0x4a, + 0xc5, 0xe7, 0xc4, 0x52, 0x64, 0x4b, 0x49, 0x25, 0x95, 0x52, 0x59, 0x89, 0xff, 0x88, 0x53, 0xb6, + 0xcb, 0x15, 0x3b, 0xe5, 0x52, 0xe2, 0xa4, 0xec, 0xa8, 0x54, 0x96, 0x12, 0xdb, 0x88, 0xc4, 0x38, + 0x65, 0x57, 0xfe, 0x70, 0x55, 0x9c, 0xfc, 0x91, 0x62, 0x5c, 0xa9, 0x54, 0x7f, 0xf7, 0xcc, 0xce, + 0x02, 0x0b, 0x62, 0x00, 0x52, 0xf2, 0xfd, 0xb7, 0xdb, 0xef, 0xcd, 0x7b, 0x3d, 0x3d, 0xdd, 0xef, + 0xbd, 0x7e, 0xfd, 0xde, 0x6b, 0x58, 0x6a, 0xb8, 0xf1, 0x66, 0x7b, 0x7d, 0xaa, 0x16, 0x34, 0xa7, + 0x9d, 0xb0, 0x11, 0xb4, 0xc2, 0xe0, 0x26, 0xfb, 0xf1, 0x74, 0xad, 0x3e, 0xbd, 0x7d, 0x7e, 0xba, + 0xb5, 0xd5, 0x98, 0x76, 0x5a, 0x6e, 0x34, 0xed, 0xb4, 0x5a, 0x9e, 0x5b, 0x73, 0x62, 0x37, 0xf0, + 0xa7, 0xb7, 0x9f, 0x71, 0xbc, 0xd6, 0xa6, 0xf3, 0xcc, 0x74, 0x83, 0xf8, 0x24, 0x74, 0x62, 0x52, + 0x9f, 0x6a, 0x85, 0x41, 0x1c, 0xa0, 0x1f, 0xd7, 0xd4, 0xa6, 0x24, 0x35, 0xf6, 0xe3, 0x95, 0x5a, + 0x7d, 0x6a, 0xfb, 0xfc, 0x54, 0x6b, 0xab, 0x31, 0x45, 0xa9, 0x4d, 0x19, 0xd4, 0xa6, 0x24, 0xb5, + 0xb3, 0x4f, 0x1b, 0x7d, 0x69, 0x04, 0x8d, 0x60, 0x9a, 0x11, 0x5d, 0x6f, 0x6f, 0xb0, 0x7f, 0xec, + 0x0f, 0xfb, 0xc5, 0x99, 0x9d, 0xb5, 0xb7, 0x9e, 0x8f, 0xa6, 0xdc, 0x80, 0x76, 0x6f, 0xba, 0x16, + 0x84, 0x64, 0x7a, 0xbb, 0xab, 0x43, 0x67, 0x2f, 0x69, 0x1c, 0xb2, 0x13, 0x13, 0x3f, 0x72, 0x03, + 0x3f, 0x7a, 0x9a, 0x76, 0x81, 0x84, 0xdb, 0x24, 0x34, 0x5f, 0xcf, 0x40, 0xc8, 0xa2, 0xf4, 0xac, + 0xa6, 0xd4, 0x74, 0x6a, 0x9b, 0xae, 0x4f, 0xc2, 0x8e, 0x7e, 0xbc, 0x49, 0x62, 0x27, 0xeb, 0xa9, + 0xe9, 0x5e, 0x4f, 0x85, 0x6d, 0x3f, 0x76, 0x9b, 0xa4, 0xeb, 0x81, 0xb7, 0xed, 0xf7, 0x40, 0x54, + 0xdb, 0x24, 0x4d, 0xa7, 0xeb, 0xb9, 0x1f, 0xe9, 0xf5, 0x5c, 0x3b, 0x76, 0xbd, 0x69, 0xd7, 0x8f, + 0xa3, 0x38, 0x4c, 0x3f, 0x64, 0xff, 0xb2, 0x05, 0xa3, 0x33, 0x37, 0xaa, 0x33, 0xed, 0x78, 0x73, + 0x2e, 0xf0, 0x37, 0xdc, 0x06, 0x7a, 0x0e, 0x86, 0x6b, 0x5e, 0x3b, 0x8a, 0x49, 0x78, 0xd5, 0x69, + 0x92, 0x09, 0xeb, 0x9c, 0xf5, 0x64, 0x65, 0xf6, 0xd4, 0xd7, 0x77, 0x27, 0xdf, 0x74, 0x7b, 0x77, + 0x72, 0x78, 0x4e, 0x83, 0xb0, 0x89, 0x87, 0x7e, 0x08, 0x86, 0xc2, 0xc0, 0x23, 0x33, 0xf8, 0xea, + 0x44, 0x81, 0x3d, 0x32, 0x2e, 0x1e, 0x19, 0xc2, 0xbc, 0x19, 0x4b, 0x38, 0x45, 0x6d, 0x85, 0xc1, + 0x86, 0xeb, 0x91, 0x89, 0x62, 0x12, 0x75, 0x95, 0x37, 0x63, 0x09, 0xb7, 0xff, 0xb8, 0x00, 0x30, + 0xd3, 0x6a, 0xad, 0x86, 0xc1, 0x4d, 0x52, 0x8b, 0xd1, 0xfb, 0xa0, 0x4c, 0x87, 0xb9, 0xee, 0xc4, + 0x0e, 0xeb, 0xd8, 0xf0, 0xf9, 0x1f, 0x9e, 0xe2, 0x6f, 0x3d, 0x65, 0xbe, 0xb5, 0x9e, 0x64, 0x14, + 0x7b, 0x6a, 0xfb, 0x99, 0xa9, 0x95, 0x75, 0xfa, 0xfc, 0x32, 0x89, 0x9d, 0x59, 0x24, 0x98, 0x81, + 0x6e, 0xc3, 0x8a, 0x2a, 0xf2, 0x61, 0x20, 0x6a, 0x91, 0x1a, 0x7b, 0x87, 0xe1, 0xf3, 0x4b, 0x53, + 0x87, 0x99, 0xcd, 0x53, 0xba, 0xe7, 0xd5, 0x16, 0xa9, 0xcd, 0x8e, 0x08, 0xce, 0x03, 0xf4, 0x1f, + 0x66, 0x7c, 0xd0, 0x36, 0x0c, 0x46, 0xb1, 0x13, 0xb7, 0x23, 0x36, 0x14, 0xc3, 0xe7, 0xaf, 0xe6, + 0xc6, 0x91, 0x51, 0x9d, 0x1d, 0x13, 0x3c, 0x07, 0xf9, 0x7f, 0x2c, 0xb8, 0xd9, 0x7f, 0x66, 0xc1, + 0x98, 0x46, 0x5e, 0x72, 0xa3, 0x18, 0xfd, 0x64, 0xd7, 0xe0, 0x4e, 0xf5, 0x37, 0xb8, 0xf4, 0x69, + 0x36, 0xb4, 0x27, 0x04, 0xb3, 0xb2, 0x6c, 0x31, 0x06, 0xb6, 0x09, 0x25, 0x37, 0x26, 0xcd, 0x68, + 0xa2, 0x70, 0xae, 0xf8, 0xe4, 0xf0, 0xf9, 0x4b, 0x79, 0xbd, 0xe7, 0xec, 0xa8, 0x60, 0x5a, 0x5a, + 0xa4, 0xe4, 0x31, 0xe7, 0x62, 0xff, 0xf5, 0xa8, 0xf9, 0x7e, 0x74, 0xc0, 0xd1, 0x33, 0x30, 0x1c, + 0x05, 0xed, 0xb0, 0x46, 0x30, 0x69, 0x05, 0xd1, 0x84, 0x75, 0xae, 0x48, 0xa7, 0x1e, 0x9d, 0xd4, + 0x55, 0xdd, 0x8c, 0x4d, 0x1c, 0xf4, 0x69, 0x0b, 0x46, 0xea, 0x24, 0x8a, 0x5d, 0x9f, 0xf1, 0x97, + 0x9d, 0x5f, 0x3b, 0x74, 0xe7, 0x65, 0xe3, 0xbc, 0x26, 0x3e, 0x7b, 0x5a, 0xbc, 0xc8, 0x88, 0xd1, + 0x18, 0xe1, 0x04, 0x7f, 0xba, 0x38, 0xeb, 0x24, 0xaa, 0x85, 0x6e, 0x8b, 0xfe, 0x17, 0xcb, 0x47, + 0x2d, 0xce, 0x79, 0x0d, 0xc2, 0x26, 0x1e, 0xf2, 0xa1, 0x44, 0x17, 0x5f, 0x34, 0x31, 0xc0, 0xfa, + 0xbf, 0x78, 0xb8, 0xfe, 0x8b, 0x41, 0xa5, 0xeb, 0x5a, 0x8f, 0x3e, 0xfd, 0x17, 0x61, 0xce, 0x06, + 0x7d, 0xca, 0x82, 0x09, 0x21, 0x1c, 0x30, 0xe1, 0x03, 0x7a, 0x63, 0xd3, 0x8d, 0x89, 0xe7, 0x46, + 0xf1, 0x44, 0x89, 0xf5, 0x61, 0xba, 0xbf, 0xb9, 0xb5, 0x10, 0x06, 0xed, 0xd6, 0x15, 0xd7, 0xaf, + 0xcf, 0x9e, 0x13, 0x9c, 0x26, 0xe6, 0x7a, 0x10, 0xc6, 0x3d, 0x59, 0xa2, 0xcf, 0x5b, 0x70, 0xd6, + 0x77, 0x9a, 0x24, 0x6a, 0x39, 0xf4, 0xd3, 0x72, 0xf0, 0xac, 0xe7, 0xd4, 0xb6, 0x58, 0x8f, 0x06, + 0xef, 0xae, 0x47, 0xb6, 0xe8, 0xd1, 0xd9, 0xab, 0x3d, 0x49, 0xe3, 0x3d, 0xd8, 0xa2, 0x2f, 0x5b, + 0x70, 0x32, 0x08, 0x5b, 0x9b, 0x8e, 0x4f, 0xea, 0x12, 0x1a, 0x4d, 0x0c, 0xb1, 0xa5, 0xf7, 0xde, + 0xc3, 0x7d, 0xa2, 0x95, 0x34, 0xd9, 0xe5, 0xc0, 0x77, 0xe3, 0x20, 0xac, 0x92, 0x38, 0x76, 0xfd, + 0x46, 0x34, 0x7b, 0xe6, 0xf6, 0xee, 0xe4, 0xc9, 0x2e, 0x2c, 0xdc, 0xdd, 0x1f, 0xf4, 0x53, 0x30, + 0x1c, 0x75, 0xfc, 0xda, 0x0d, 0xd7, 0xaf, 0x07, 0xb7, 0xa2, 0x89, 0x72, 0x1e, 0xcb, 0xb7, 0xaa, + 0x08, 0x8a, 0x05, 0xa8, 0x19, 0x60, 0x93, 0x5b, 0xf6, 0x87, 0xd3, 0x53, 0xa9, 0x92, 0xf7, 0x87, + 0xd3, 0x93, 0x69, 0x0f, 0xb6, 0xe8, 0xe7, 0x2c, 0x18, 0x8d, 0xdc, 0x86, 0xef, 0xc4, 0xed, 0x90, + 0x5c, 0x21, 0x9d, 0x68, 0x02, 0x58, 0x47, 0x2e, 0x1f, 0x72, 0x54, 0x0c, 0x92, 0xb3, 0x67, 0x44, + 0x1f, 0x47, 0xcd, 0xd6, 0x08, 0x27, 0xf9, 0x66, 0x2d, 0x34, 0x3d, 0xad, 0x87, 0xf3, 0x5d, 0x68, + 0x7a, 0x52, 0xf7, 0x64, 0x89, 0x7e, 0x02, 0x4e, 0xf0, 0x26, 0x35, 0xb2, 0xd1, 0xc4, 0x08, 0x13, + 0xb4, 0xa7, 0x6f, 0xef, 0x4e, 0x9e, 0xa8, 0xa6, 0x60, 0xb8, 0x0b, 0x1b, 0xbd, 0x0a, 0x93, 0x2d, + 0x12, 0x36, 0xdd, 0x78, 0xc5, 0xf7, 0x3a, 0x52, 0x7c, 0xd7, 0x82, 0x16, 0xa9, 0x8b, 0xee, 0x44, + 0x13, 0xa3, 0xe7, 0xac, 0x27, 0xcb, 0xb3, 0x6f, 0x11, 0xdd, 0x9c, 0x5c, 0xdd, 0x1b, 0x1d, 0xef, + 0x47, 0x0f, 0xfd, 0xbe, 0x05, 0x67, 0x0d, 0x29, 0x5b, 0x25, 0xe1, 0xb6, 0x5b, 0x23, 0x33, 0xb5, + 0x5a, 0xd0, 0xf6, 0xe3, 0x68, 0x62, 0x8c, 0x0d, 0xe3, 0xfa, 0x51, 0xc8, 0xfc, 0x24, 0x2b, 0x3d, + 0x2f, 0x7b, 0xa2, 0x44, 0x78, 0x8f, 0x9e, 0xda, 0xff, 0xb6, 0x00, 0x27, 0xd2, 0x16, 0x00, 0xfa, + 0xc7, 0x16, 0x8c, 0xdf, 0xbc, 0x15, 0xaf, 0x05, 0x5b, 0xc4, 0x8f, 0x66, 0x3b, 0x54, 0x4e, 0x33, + 0xdd, 0x37, 0x7c, 0xbe, 0x96, 0xaf, 0xad, 0x31, 0x75, 0x39, 0xc9, 0xe5, 0x82, 0x1f, 0x87, 0x9d, + 0xd9, 0x07, 0xc5, 0x3b, 0x8d, 0x5f, 0xbe, 0xb1, 0x66, 0x42, 0x71, 0xba, 0x53, 0x67, 0x3f, 0x61, + 0xc1, 0xe9, 0x2c, 0x12, 0xe8, 0x04, 0x14, 0xb7, 0x48, 0x87, 0x5b, 0xa2, 0x98, 0xfe, 0x44, 0x2f, + 0x43, 0x69, 0xdb, 0xf1, 0xda, 0x44, 0x98, 0x69, 0x0b, 0x87, 0x7b, 0x11, 0xd5, 0x33, 0xcc, 0xa9, + 0xfe, 0x58, 0xe1, 0x79, 0xcb, 0xfe, 0xc3, 0x22, 0x0c, 0x1b, 0x1f, 0xed, 0x18, 0x4c, 0xcf, 0x20, + 0x61, 0x7a, 0x2e, 0xe7, 0x36, 0xdf, 0x7a, 0xda, 0x9e, 0xb7, 0x52, 0xb6, 0xe7, 0x4a, 0x7e, 0x2c, + 0xf7, 0x34, 0x3e, 0x51, 0x0c, 0x95, 0xa0, 0x45, 0xb7, 0x21, 0xd4, 0x86, 0x19, 0xc8, 0xe3, 0x13, + 0xae, 0x48, 0x72, 0xb3, 0xa3, 0xb7, 0x77, 0x27, 0x2b, 0xea, 0x2f, 0xd6, 0x8c, 0xec, 0x6f, 0x59, + 0x70, 0xda, 0xe8, 0xe3, 0x5c, 0xe0, 0xd7, 0x5d, 0xf6, 0x69, 0xcf, 0xc1, 0x40, 0xdc, 0x69, 0xc9, + 0xad, 0x8e, 0x1a, 0xa9, 0xb5, 0x4e, 0x8b, 0x60, 0x06, 0xa1, 0x3b, 0x96, 0x26, 0x89, 0x22, 0xa7, + 0x41, 0xd2, 0x9b, 0x9b, 0x65, 0xde, 0x8c, 0x25, 0x1c, 0x85, 0x80, 0x3c, 0x27, 0x8a, 0xd7, 0x42, + 0xc7, 0x8f, 0x18, 0xf9, 0x35, 0xb7, 0x49, 0xc4, 0x00, 0xff, 0x7f, 0xfd, 0xcd, 0x18, 0xfa, 0xc4, + 0xec, 0x03, 0xb7, 0x77, 0x27, 0xd1, 0x52, 0x17, 0x25, 0x9c, 0x41, 0xdd, 0xfe, 0xbc, 0x05, 0x0f, + 0x64, 0x0b, 0x18, 0xf4, 0x04, 0x0c, 0xf2, 0x7d, 0xae, 0x78, 0x3b, 0xfd, 0x49, 0x58, 0x2b, 0x16, + 0x50, 0x34, 0x0d, 0x15, 0xa5, 0xf0, 0xc4, 0x3b, 0x9e, 0x14, 0xa8, 0x15, 0xad, 0x25, 0x35, 0x0e, + 0x1d, 0x34, 0xfa, 0x47, 0x98, 0xa0, 0x6a, 0xd0, 0xd8, 0xc6, 0x90, 0x41, 0xec, 0x6f, 0x5a, 0xf0, + 0xe6, 0x7e, 0xc4, 0xde, 0xd1, 0xf5, 0xb1, 0x0a, 0x67, 0xea, 0x64, 0xc3, 0x69, 0x7b, 0x71, 0x92, + 0xa3, 0xe8, 0xf4, 0xa3, 0xe2, 0xe1, 0x33, 0xf3, 0x59, 0x48, 0x38, 0xfb, 0x59, 0xfb, 0xbf, 0x58, + 0x30, 0x6e, 0xbc, 0xd6, 0x31, 0x6c, 0x9d, 0xfc, 0xe4, 0xd6, 0x69, 0x31, 0xb7, 0x65, 0xda, 0x63, + 0xef, 0xf4, 0x29, 0x0b, 0xce, 0x1a, 0x58, 0xcb, 0x4e, 0x5c, 0xdb, 0xbc, 0xb0, 0xd3, 0x0a, 0x49, + 0x14, 0xd1, 0x29, 0xf5, 0xa8, 0x21, 0x8e, 0x67, 0x87, 0x05, 0x85, 0xe2, 0x15, 0xd2, 0xe1, 0xb2, + 0xf9, 0x29, 0x28, 0xf3, 0x35, 0x17, 0x84, 0xe2, 0x23, 0xa9, 0x77, 0x5b, 0x11, 0xed, 0x58, 0x61, + 0x20, 0x1b, 0x06, 0x99, 0xcc, 0xa5, 0x32, 0x88, 0x9a, 0x09, 0x40, 0xbf, 0xfb, 0x75, 0xd6, 0x82, + 0x05, 0xc4, 0x8e, 0x12, 0xdd, 0x59, 0x0d, 0x09, 0x9b, 0x0f, 0xf5, 0x8b, 0x2e, 0xf1, 0xea, 0x11, + 0xdd, 0xd6, 0x39, 0xbe, 0x1f, 0xc4, 0x62, 0x87, 0x66, 0x6c, 0xeb, 0x66, 0x74, 0x33, 0x36, 0x71, + 0x28, 0x53, 0xcf, 0x59, 0x27, 0x1e, 0x1f, 0x51, 0xc1, 0x74, 0x89, 0xb5, 0x60, 0x01, 0xb1, 0x6f, + 0x17, 0xd8, 0x06, 0x52, 0x49, 0x34, 0x72, 0x1c, 0xde, 0x87, 0x30, 0xa1, 0x02, 0x56, 0xf3, 0x93, + 0xc7, 0xa4, 0xb7, 0x07, 0xe2, 0xb5, 0x94, 0x16, 0xc0, 0xb9, 0x72, 0xdd, 0xdb, 0x0b, 0xf1, 0xa1, + 0x22, 0x4c, 0x26, 0x1f, 0xe8, 0x52, 0x22, 0x74, 0xcb, 0x6b, 0x30, 0x4a, 0xfb, 0xa3, 0x0c, 0x7c, + 0x6c, 0xe2, 0xf5, 0x90, 0xc3, 0x85, 0xa3, 0x94, 0xc3, 0xa6, 0x9a, 0x28, 0xee, 0xa3, 0x26, 0x9e, + 0x50, 0xa3, 0x3e, 0x90, 0x92, 0x79, 0x49, 0x55, 0x79, 0x0e, 0x06, 0xa2, 0x98, 0xb4, 0x26, 0x4a, + 0x49, 0x31, 0x5b, 0x8d, 0x49, 0x0b, 0x33, 0x08, 0x7a, 0x3b, 0x8c, 0xc7, 0x4e, 0xd8, 0x20, 0x71, + 0x48, 0xb6, 0x5d, 0xe6, 0xbb, 0x64, 0xfb, 0xd9, 0xca, 0xec, 0x29, 0x6a, 0x75, 0xad, 0x31, 0x10, + 0x96, 0x20, 0x9c, 0xc6, 0xb5, 0xff, 0x7b, 0x01, 0x1e, 0x4c, 0x7e, 0x02, 0xad, 0x18, 0xdf, 0x99, + 0x50, 0x8c, 0x6f, 0x35, 0x15, 0xe3, 0x9d, 0xdd, 0xc9, 0x87, 0x7b, 0x3c, 0xf6, 0x3d, 0xa3, 0x37, + 0xd1, 0x42, 0xea, 0x23, 0x4c, 0x27, 0x3f, 0xc2, 0x9d, 0xdd, 0xc9, 0x47, 0x7b, 0xbc, 0x63, 0xea, + 0x2b, 0x3d, 0x01, 0x83, 0x21, 0x71, 0xa2, 0xc0, 0x17, 0xdf, 0x49, 0x7d, 0x4d, 0xcc, 0x5a, 0xb1, + 0x80, 0xda, 0xdf, 0xa8, 0xa4, 0x07, 0x7b, 0x81, 0xfb, 0x63, 0x83, 0x10, 0xb9, 0x30, 0xc0, 0x76, + 0x6d, 0x5c, 0xb2, 0x5c, 0x39, 0xdc, 0x2a, 0xa4, 0x5a, 0x44, 0x91, 0x9e, 0x2d, 0xd3, 0xaf, 0x46, + 0x9b, 0x30, 0x63, 0x81, 0x76, 0xa0, 0x5c, 0x93, 0x9b, 0xa9, 0x42, 0x1e, 0x6e, 0x47, 0xb1, 0x95, + 0xd2, 0x1c, 0x47, 0xa8, 0xb8, 0x57, 0x3b, 0x30, 0xc5, 0x0d, 0x11, 0x28, 0x36, 0xdc, 0x58, 0x7c, + 0xd6, 0x43, 0x6e, 0x97, 0x17, 0x5c, 0xe3, 0x15, 0x87, 0xa8, 0x0e, 0x5a, 0x70, 0x63, 0x4c, 0xe9, + 0xa3, 0x8f, 0x59, 0x30, 0x1c, 0xd5, 0x9a, 0xab, 0x61, 0xb0, 0xed, 0xd6, 0x49, 0x28, 0x6c, 0xcc, + 0x43, 0x4a, 0xb6, 0xea, 0xdc, 0xb2, 0x24, 0xa8, 0xf9, 0x72, 0xf7, 0x85, 0x86, 0x60, 0x93, 0x2f, + 0xdd, 0x7b, 0x3d, 0x28, 0xde, 0x7d, 0x9e, 0xd4, 0xd8, 0x8a, 0x93, 0x7b, 0x66, 0x36, 0x53, 0x0e, + 0x6d, 0x73, 0xcf, 0xb7, 0x6b, 0x5b, 0x74, 0xbd, 0xe9, 0x0e, 0x3d, 0x7c, 0x7b, 0x77, 0xf2, 0xc1, + 0xb9, 0x6c, 0x9e, 0xb8, 0x57, 0x67, 0xd8, 0x80, 0xb5, 0xda, 0x9e, 0x87, 0xc9, 0xab, 0x6d, 0xc2, + 0x3c, 0x62, 0x39, 0x0c, 0xd8, 0xaa, 0x26, 0x98, 0x1a, 0x30, 0x03, 0x82, 0x4d, 0xbe, 0xe8, 0x55, + 0x18, 0x6c, 0x3a, 0x71, 0xe8, 0xee, 0x08, 0x37, 0xd8, 0x21, 0x77, 0x41, 0xcb, 0x8c, 0x96, 0x66, + 0xce, 0x14, 0x3d, 0x6f, 0xc4, 0x82, 0x11, 0x6a, 0x42, 0xa9, 0x49, 0xc2, 0x06, 0x99, 0x28, 0xe7, + 0xe1, 0xf2, 0x5f, 0xa6, 0xa4, 0x34, 0xc3, 0x0a, 0x35, 0xae, 0x58, 0x1b, 0xe6, 0x5c, 0xd0, 0xcb, + 0x50, 0x8e, 0x88, 0x47, 0x6a, 0xd4, 0x3c, 0xaa, 0x30, 0x8e, 0x3f, 0xd2, 0xa7, 0xa9, 0x48, 0xed, + 0x92, 0xaa, 0x78, 0x94, 0x2f, 0x30, 0xf9, 0x0f, 0x2b, 0x92, 0x74, 0x00, 0x5b, 0x5e, 0xbb, 0xe1, + 0xfa, 0x13, 0x90, 0xc7, 0x00, 0xae, 0x32, 0x5a, 0xa9, 0x01, 0xe4, 0x8d, 0x58, 0x30, 0xb2, 0xff, + 0x9b, 0x05, 0x28, 0x29, 0xd4, 0x8e, 0xc1, 0x26, 0x7e, 0x35, 0x69, 0x13, 0x2f, 0xe5, 0x69, 0xb4, + 0xf4, 0x30, 0x8b, 0x7f, 0xb3, 0x02, 0x29, 0x75, 0x70, 0x95, 0x44, 0x31, 0xa9, 0xbf, 0x21, 0xc2, + 0xdf, 0x10, 0xe1, 0x6f, 0x88, 0x70, 0x25, 0xc2, 0xd7, 0x53, 0x22, 0xfc, 0x1d, 0xc6, 0xaa, 0xd7, + 0xe7, 0xeb, 0xaf, 0xa8, 0x03, 0x78, 0xb3, 0x07, 0x06, 0x02, 0x95, 0x04, 0x97, 0xab, 0x2b, 0x57, + 0x33, 0x65, 0xf6, 0x2b, 0x49, 0x99, 0x7d, 0x58, 0x16, 0x7f, 0x1b, 0xa4, 0xf4, 0xef, 0x5b, 0xf0, + 0x96, 0xa4, 0xf4, 0x92, 0x33, 0x67, 0xb1, 0xe1, 0x07, 0x21, 0x99, 0x77, 0x37, 0x36, 0x48, 0x48, + 0xfc, 0x1a, 0x89, 0x94, 0x6f, 0xc7, 0xea, 0xe5, 0xdb, 0x41, 0xcf, 0xc2, 0xc8, 0xcd, 0x28, 0xf0, + 0x57, 0x03, 0xd7, 0x17, 0x22, 0x88, 0xee, 0x38, 0x4e, 0xdc, 0xde, 0x9d, 0x1c, 0xa1, 0x23, 0x2a, + 0xdb, 0x71, 0x02, 0x0b, 0xcd, 0xc1, 0xc9, 0x9b, 0xaf, 0xae, 0x3a, 0xb1, 0xe1, 0x4d, 0x90, 0xfb, + 0x7e, 0x76, 0x1e, 0x75, 0xf9, 0xc5, 0x14, 0x10, 0x77, 0xe3, 0xdb, 0xff, 0xa0, 0x00, 0x0f, 0xa5, + 0x5e, 0x24, 0xf0, 0xbc, 0xa0, 0x1d, 0xd3, 0x3d, 0x11, 0xfa, 0xa2, 0x05, 0x27, 0x9a, 0x49, 0x87, + 0x45, 0x24, 0xdc, 0xdd, 0xef, 0xca, 0x4d, 0x47, 0xa4, 0x3c, 0x22, 0xb3, 0x13, 0x62, 0x84, 0x4e, + 0xa4, 0x00, 0x11, 0xee, 0xea, 0x0b, 0x7a, 0x19, 0x2a, 0x4d, 0x67, 0xe7, 0x5a, 0xab, 0xee, 0xc4, + 0x72, 0x3b, 0xda, 0xdb, 0x8b, 0xd0, 0x8e, 0x5d, 0x6f, 0x8a, 0x47, 0x6e, 0x4c, 0x2d, 0xfa, 0xf1, + 0x4a, 0x58, 0x8d, 0x43, 0xd7, 0x6f, 0x70, 0x27, 0xe7, 0xb2, 0x24, 0x83, 0x35, 0x45, 0xfb, 0x0b, + 0x56, 0x5a, 0x49, 0xa9, 0xd1, 0x09, 0x9d, 0x98, 0x34, 0x3a, 0xe8, 0xfd, 0x50, 0xa2, 0xfb, 0x46, + 0x39, 0x2a, 0x37, 0xf2, 0xd4, 0x9c, 0xc6, 0x97, 0xd0, 0x4a, 0x94, 0xfe, 0x8b, 0x30, 0x67, 0x6a, + 0x7f, 0xb1, 0x92, 0x36, 0x16, 0xd8, 0xd9, 0xfc, 0x79, 0x80, 0x46, 0xb0, 0x46, 0x9a, 0x2d, 0x8f, + 0x0e, 0x8b, 0xc5, 0x0e, 0x78, 0x94, 0xab, 0x64, 0x41, 0x41, 0xb0, 0x81, 0x85, 0x7e, 0xde, 0x02, + 0x68, 0xc8, 0x39, 0x2f, 0x0d, 0x81, 0x6b, 0x79, 0xbe, 0x8e, 0x5e, 0x51, 0xba, 0x2f, 0x8a, 0x21, + 0x36, 0x98, 0xa3, 0x9f, 0xb1, 0xa0, 0x1c, 0xcb, 0xee, 0x73, 0xd5, 0xb8, 0x96, 0x67, 0x4f, 0xe4, + 0x4b, 0x6b, 0x9b, 0x48, 0x0d, 0x89, 0xe2, 0x8b, 0x7e, 0xd6, 0x02, 0x88, 0x3a, 0x7e, 0x6d, 0x35, + 0xf0, 0xdc, 0x5a, 0x47, 0x68, 0xcc, 0xeb, 0xb9, 0xba, 0x73, 0x14, 0xf5, 0xd9, 0x31, 0x3a, 0x1a, + 0xfa, 0x3f, 0x36, 0x38, 0xa3, 0x0f, 0x42, 0x39, 0x12, 0xd3, 0x4d, 0xe8, 0xc8, 0xb5, 0x7c, 0x9d, + 0x4a, 0x9c, 0xb6, 0x10, 0xaf, 0xe2, 0x1f, 0x56, 0x3c, 0xd1, 0x2f, 0x5a, 0x30, 0xde, 0x4a, 0xba, + 0x09, 0x85, 0x3a, 0xcc, 0x4f, 0x06, 0xa4, 0xdc, 0x90, 0xdc, 0xdb, 0x92, 0x6a, 0xc4, 0xe9, 0x5e, + 0x50, 0x09, 0xa8, 0x67, 0xf0, 0x4a, 0x8b, 0xbb, 0x2c, 0x87, 0xb4, 0x04, 0x5c, 0x48, 0x03, 0x71, + 0x37, 0x3e, 0x5a, 0x85, 0xd3, 0xb4, 0x77, 0x1d, 0x6e, 0x7e, 0x4a, 0xf5, 0x12, 0x31, 0x65, 0x58, + 0x9e, 0x7d, 0x44, 0xcc, 0x10, 0x76, 0xd6, 0x91, 0xc6, 0xc1, 0x99, 0x4f, 0xa2, 0x3f, 0xb4, 0xe0, + 0x11, 0x97, 0xa9, 0x01, 0xd3, 0x61, 0xaf, 0x35, 0x82, 0x38, 0x68, 0x27, 0xb9, 0xca, 0x8a, 0x5e, + 0xea, 0x67, 0xf6, 0xcd, 0xe2, 0x0d, 0x1e, 0x59, 0xdc, 0xa3, 0x4b, 0x78, 0xcf, 0x0e, 0xa3, 0x1f, + 0x85, 0x51, 0xb9, 0x2e, 0x56, 0xa9, 0x08, 0x66, 0x8a, 0xb6, 0x32, 0x7b, 0xf2, 0xf6, 0xee, 0xe4, + 0xe8, 0x9a, 0x09, 0xc0, 0x49, 0x3c, 0xfb, 0xdf, 0x15, 0x13, 0xa7, 0x44, 0xca, 0x87, 0xc9, 0xc4, + 0x4d, 0x4d, 0xfa, 0x7f, 0xa4, 0xf4, 0xcc, 0x55, 0xdc, 0x28, 0xef, 0x92, 0x16, 0x37, 0xaa, 0x29, + 0xc2, 0x06, 0x73, 0x6a, 0x94, 0x9e, 0x74, 0xd2, 0x9e, 0x52, 0x21, 0x01, 0x5f, 0xce, 0xb3, 0x4b, + 0xdd, 0x67, 0x7a, 0x0f, 0x89, 0xae, 0x9d, 0xec, 0x02, 0xe1, 0xee, 0x2e, 0xa1, 0x0f, 0x40, 0x25, + 0x54, 0x91, 0x2d, 0xc5, 0x3c, 0xb6, 0x6a, 0x72, 0xda, 0x88, 0xee, 0xa8, 0x03, 0x20, 0x1d, 0xc3, + 0xa2, 0x39, 0xda, 0x7f, 0x90, 0x3c, 0x18, 0x33, 0x64, 0x47, 0x1f, 0x87, 0x7e, 0x9f, 0xb6, 0x60, + 0x38, 0x0c, 0x3c, 0xcf, 0xf5, 0x1b, 0x54, 0xce, 0x09, 0x65, 0xfd, 0x9e, 0x23, 0xd1, 0x97, 0x42, + 0xa0, 0x31, 0xcb, 0x1a, 0x6b, 0x9e, 0xd8, 0xec, 0x80, 0xfd, 0x67, 0x16, 0x4c, 0xf4, 0x92, 0xc7, + 0x88, 0xc0, 0xc3, 0x52, 0xd8, 0xa8, 0xa1, 0x58, 0xf1, 0xe7, 0x89, 0x47, 0x94, 0xdb, 0xbc, 0x3c, + 0xfb, 0xb8, 0x78, 0xcd, 0x87, 0x57, 0x7b, 0xa3, 0xe2, 0xbd, 0xe8, 0xa0, 0x97, 0xe0, 0x84, 0xf1, + 0x5e, 0x91, 0x1a, 0x98, 0xca, 0xec, 0x14, 0x35, 0x80, 0x66, 0x52, 0xb0, 0x3b, 0xbb, 0x93, 0x0f, + 0xa4, 0xdb, 0x84, 0xc2, 0xe8, 0xa2, 0x63, 0x7f, 0xa5, 0x90, 0xfe, 0x5a, 0x4a, 0xd7, 0xbf, 0x6e, + 0x75, 0x79, 0x13, 0xde, 0x75, 0x14, 0xfa, 0x95, 0xf9, 0x1d, 0x54, 0x18, 0x46, 0x6f, 0x9c, 0x7b, + 0x78, 0x6c, 0x6f, 0xff, 0xfb, 0x01, 0xd8, 0xa3, 0x67, 0x7d, 0x18, 0xef, 0x07, 0x3e, 0x47, 0xfd, + 0xa4, 0xa5, 0x0e, 0xcc, 0xf8, 0x1a, 0xae, 0x1f, 0xd5, 0xd8, 0xf3, 0xfd, 0x53, 0xc4, 0x43, 0x47, + 0x94, 0x17, 0x3d, 0x79, 0x34, 0x87, 0xbe, 0x64, 0x25, 0x8f, 0xfc, 0x78, 0x50, 0xa3, 0x7b, 0x64, + 0x7d, 0x32, 0xce, 0x11, 0x79, 0xc7, 0xf4, 0xe9, 0x53, 0xaf, 0x13, 0xc6, 0x29, 0x80, 0x0d, 0xd7, + 0x77, 0x3c, 0xf7, 0x35, 0xba, 0x3b, 0x2a, 0x31, 0x05, 0xcf, 0x2c, 0xa6, 0x8b, 0xaa, 0x15, 0x1b, + 0x18, 0x67, 0xff, 0x7f, 0x18, 0x36, 0xde, 0x3c, 0x23, 0xe2, 0xe5, 0xb4, 0x19, 0xf1, 0x52, 0x31, + 0x02, 0x55, 0xce, 0xbe, 0x03, 0x4e, 0xa4, 0x3b, 0x78, 0x90, 0xe7, 0xed, 0xff, 0x3d, 0x94, 0x3e, + 0x83, 0x5b, 0x23, 0x61, 0x93, 0x76, 0xed, 0x0d, 0xc7, 0xd6, 0x1b, 0x8e, 0xad, 0x37, 0x1c, 0x5b, + 0xe6, 0xd9, 0x84, 0x70, 0xda, 0x0c, 0x1d, 0x93, 0xd3, 0x26, 0xe1, 0x86, 0x2a, 0xe7, 0xee, 0x86, + 0xb2, 0x3f, 0xd6, 0xe5, 0xb9, 0x5f, 0x0b, 0x09, 0x41, 0x01, 0x94, 0xfc, 0xa0, 0x4e, 0xa4, 0x8d, + 0x7b, 0x39, 0x1f, 0x83, 0xed, 0x6a, 0x50, 0x37, 0xc2, 0xc5, 0xe9, 0xbf, 0x08, 0x73, 0x3e, 0xf6, + 0x47, 0x07, 0x21, 0x61, 0x4e, 0xf2, 0xef, 0xfe, 0x43, 0x30, 0x14, 0x92, 0x56, 0x70, 0x0d, 0x2f, + 0x09, 0x5d, 0xa6, 0x33, 0x4a, 0x78, 0x33, 0x96, 0x70, 0xaa, 0xf3, 0x5a, 0x4e, 0xbc, 0x29, 0x94, + 0x99, 0xd2, 0x79, 0xab, 0x4e, 0xbc, 0x89, 0x19, 0x04, 0xbd, 0x03, 0xc6, 0xe2, 0xc4, 0x51, 0xb8, + 0x38, 0xf2, 0x7d, 0x40, 0xe0, 0x8e, 0x25, 0x0f, 0xca, 0x71, 0x0a, 0x1b, 0xbd, 0x0a, 0x03, 0x9b, + 0xc4, 0x6b, 0x8a, 0x4f, 0x5f, 0xcd, 0x4f, 0xd7, 0xb0, 0x77, 0xbd, 0x44, 0xbc, 0x26, 0x97, 0x84, + 0xf4, 0x17, 0x66, 0xac, 0xe8, 0xbc, 0xaf, 0x6c, 0xb5, 0xa3, 0x38, 0x68, 0xba, 0xaf, 0x49, 0x4f, + 0xe7, 0xbb, 0x72, 0x66, 0x7c, 0x45, 0xd2, 0xe7, 0x2e, 0x25, 0xf5, 0x17, 0x6b, 0xce, 0xac, 0x1f, + 0x75, 0x37, 0x64, 0x53, 0xa6, 0x23, 0x1c, 0x96, 0x79, 0xf7, 0x63, 0x5e, 0xd2, 0xe7, 0xfd, 0x50, + 0x7f, 0xb1, 0xe6, 0x8c, 0x3a, 0x6a, 0xfd, 0x0d, 0xb3, 0x3e, 0x5c, 0xcb, 0xb9, 0x0f, 0x7c, 0xed, + 0x65, 0xae, 0xc3, 0xc7, 0xa1, 0x54, 0xdb, 0x74, 0xc2, 0x78, 0x62, 0x84, 0x4d, 0x1a, 0x35, 0x8b, + 0xe7, 0x68, 0x23, 0xe6, 0x30, 0xf4, 0x28, 0x14, 0x43, 0xb2, 0xc1, 0xa2, 0x93, 0x8d, 0xb8, 0x28, + 0x4c, 0x36, 0x30, 0x6d, 0x57, 0x76, 0xd9, 0x58, 0xcf, 0x80, 0xb9, 0x5f, 0x29, 0x24, 0x0d, 0xbb, + 0xe4, 0xc8, 0xf0, 0xf5, 0x50, 0x6b, 0x87, 0x91, 0x74, 0x90, 0x19, 0xeb, 0x81, 0x35, 0x63, 0x09, + 0x47, 0x1f, 0xb6, 0x60, 0xe8, 0x66, 0x14, 0xf8, 0x3e, 0x89, 0x85, 0x12, 0xbd, 0x9e, 0xf3, 0x60, + 0x5d, 0xe6, 0xd4, 0x75, 0x1f, 0x44, 0x03, 0x96, 0x7c, 0x69, 0x77, 0xc9, 0x4e, 0xcd, 0x6b, 0xd7, + 0xbb, 0x82, 0x61, 0x2e, 0xf0, 0x66, 0x2c, 0xe1, 0x14, 0xd5, 0xf5, 0x39, 0xea, 0x40, 0x12, 0x75, + 0xd1, 0x17, 0xa8, 0x02, 0x6e, 0xff, 0x7a, 0x19, 0xce, 0x64, 0x2e, 0x1f, 0x6a, 0x72, 0x31, 0xa3, + 0xe6, 0xa2, 0xeb, 0x11, 0x19, 0x06, 0xc6, 0x4c, 0xae, 0xeb, 0xaa, 0x15, 0x1b, 0x18, 0xe8, 0xa7, + 0x01, 0x5a, 0x4e, 0xe8, 0x34, 0x89, 0x72, 0x60, 0x1f, 0xda, 0xb2, 0xa1, 0xfd, 0x58, 0x95, 0x34, + 0xf5, 0x26, 0x5e, 0x35, 0x45, 0xd8, 0x60, 0x89, 0x9e, 0x83, 0xe1, 0x90, 0x78, 0xc4, 0x89, 0x58, + 0xf8, 0x7b, 0x3a, 0x97, 0x07, 0x6b, 0x10, 0x36, 0xf1, 0xd0, 0x13, 0x2a, 0x62, 0x2e, 0x15, 0x39, + 0x94, 0x8c, 0x9a, 0x43, 0x9f, 0xb1, 0x60, 0x6c, 0xc3, 0xf5, 0x88, 0xe6, 0x2e, 0x32, 0x6f, 0x56, + 0x0e, 0xff, 0x92, 0x17, 0x4d, 0xba, 0x5a, 0x86, 0x26, 0x9a, 0x23, 0x9c, 0x62, 0x4f, 0x3f, 0xf3, + 0x36, 0x09, 0x99, 0xf0, 0x1d, 0x4c, 0x7e, 0xe6, 0xeb, 0xbc, 0x19, 0x4b, 0x38, 0x9a, 0x81, 0xf1, + 0x96, 0x13, 0x45, 0x73, 0x21, 0xa9, 0x13, 0x3f, 0x76, 0x1d, 0x8f, 0xe7, 0xc5, 0x94, 0x75, 0x38, + 0xf9, 0x6a, 0x12, 0x8c, 0xd3, 0xf8, 0xe8, 0xdd, 0xf0, 0x20, 0xf7, 0x10, 0x2d, 0xbb, 0x51, 0xe4, + 0xfa, 0x0d, 0x3d, 0x0d, 0x84, 0xa3, 0x6c, 0x52, 0x90, 0x7a, 0x70, 0x31, 0x1b, 0x0d, 0xf7, 0x7a, + 0x1e, 0x3d, 0x05, 0xe5, 0x68, 0xcb, 0x6d, 0xcd, 0x85, 0xf5, 0x88, 0x9d, 0x0e, 0x95, 0xb5, 0x5b, + 0xb6, 0x2a, 0xda, 0xb1, 0xc2, 0x40, 0x35, 0x18, 0xe1, 0x9f, 0x84, 0x87, 0xfc, 0x09, 0x09, 0xfa, + 0x74, 0x4f, 0x45, 0x2e, 0xd2, 0x3c, 0xa7, 0xb0, 0x73, 0xeb, 0x82, 0x3c, 0xab, 0xe2, 0x47, 0x2b, + 0xd7, 0x0d, 0x32, 0x38, 0x41, 0x34, 0xb9, 0xa7, 0x1b, 0xee, 0x63, 0x4f, 0xf7, 0x1c, 0x0c, 0x6f, + 0xb5, 0xd7, 0x89, 0x18, 0x79, 0x21, 0xd8, 0xd4, 0xec, 0xbb, 0xa2, 0x41, 0xd8, 0xc4, 0x63, 0xd1, + 0x96, 0x2d, 0x57, 0xfc, 0x8b, 0x26, 0x46, 0x8d, 0x68, 0xcb, 0xd5, 0x45, 0xd9, 0x8c, 0x4d, 0x1c, + 0xda, 0x35, 0x3a, 0x16, 0x6b, 0x24, 0x62, 0xc9, 0x14, 0x74, 0xb8, 0x54, 0xd7, 0xaa, 0x12, 0x80, + 0x35, 0x0e, 0x5a, 0x85, 0xd3, 0xf4, 0x4f, 0x95, 0xa5, 0xb9, 0x5e, 0x77, 0x3c, 0xb7, 0xce, 0x43, + 0xff, 0xc6, 0x93, 0xfe, 0xcd, 0x6a, 0x06, 0x0e, 0xce, 0x7c, 0xd2, 0xfe, 0xa5, 0x42, 0xd2, 0x73, + 0x62, 0x8a, 0x30, 0x14, 0x51, 0x41, 0x15, 0x5f, 0x77, 0x42, 0x69, 0xf0, 0x1c, 0x32, 0xb9, 0x49, + 0xd0, 0xbd, 0xee, 0x84, 0xa6, 0xc8, 0x63, 0x0c, 0xb0, 0xe4, 0x84, 0x6e, 0xc2, 0x40, 0xec, 0x39, + 0x39, 0x65, 0x43, 0x1a, 0x1c, 0xb5, 0x23, 0x6b, 0x69, 0x26, 0xc2, 0x8c, 0x07, 0x7a, 0x84, 0xee, + 0xde, 0xd6, 0xe5, 0x49, 0x9b, 0xd8, 0x70, 0xad, 0x47, 0x98, 0xb5, 0xda, 0x7f, 0x3e, 0x9c, 0xa1, + 0x75, 0x94, 0x21, 0x80, 0xce, 0x03, 0xd0, 0x49, 0xb3, 0x1a, 0x92, 0x0d, 0x77, 0x47, 0x18, 0x62, + 0x4a, 0xb2, 0x5d, 0x55, 0x10, 0x6c, 0x60, 0xc9, 0x67, 0xaa, 0xed, 0x0d, 0xfa, 0x4c, 0xa1, 0xfb, + 0x19, 0x0e, 0xc1, 0x06, 0x16, 0x7a, 0x16, 0x06, 0xdd, 0xa6, 0xd3, 0x50, 0x81, 0xc0, 0x8f, 0x50, + 0x91, 0xb6, 0xc8, 0x5a, 0xee, 0xec, 0x4e, 0x8e, 0xa9, 0x0e, 0xb1, 0x26, 0x2c, 0x70, 0xd1, 0x57, + 0x2c, 0x18, 0xa9, 0x05, 0xcd, 0x66, 0xe0, 0xf3, 0xed, 0xb3, 0xf0, 0x05, 0xdc, 0x3c, 0x2a, 0x33, + 0x69, 0x6a, 0xce, 0x60, 0xc6, 0x9d, 0x01, 0x2a, 0x6d, 0xd3, 0x04, 0xe1, 0x44, 0xaf, 0x4c, 0xc9, + 0x57, 0xda, 0x47, 0xf2, 0xfd, 0x86, 0x05, 0x27, 0xf9, 0xb3, 0xc6, 0xae, 0x5e, 0x64, 0x28, 0x06, + 0x47, 0xfc, 0x5a, 0x5d, 0x8e, 0x0e, 0xe5, 0xec, 0xed, 0x82, 0xe3, 0xee, 0x4e, 0xa2, 0x05, 0x38, + 0xb9, 0x11, 0x84, 0x35, 0x62, 0x0e, 0x84, 0x10, 0xdb, 0x8a, 0xd0, 0xc5, 0x34, 0x02, 0xee, 0x7e, + 0x06, 0x5d, 0x87, 0x07, 0x8c, 0x46, 0x73, 0x1c, 0xb8, 0xe4, 0x7e, 0x4c, 0x50, 0x7b, 0xe0, 0x62, + 0x26, 0x16, 0xee, 0xf1, 0x74, 0x52, 0x48, 0x56, 0xfa, 0x10, 0x92, 0xaf, 0xc0, 0x43, 0xb5, 0xee, + 0x91, 0xd9, 0x8e, 0xda, 0xeb, 0x11, 0x97, 0xe3, 0xe5, 0xd9, 0x1f, 0x10, 0x04, 0x1e, 0x9a, 0xeb, + 0x85, 0x88, 0x7b, 0xd3, 0x40, 0xef, 0x87, 0x72, 0x48, 0xd8, 0x57, 0x89, 0x44, 0xba, 0xde, 0x21, + 0xbd, 0x1d, 0xda, 0x82, 0xe7, 0x64, 0xb5, 0x66, 0x12, 0x0d, 0x11, 0x56, 0x1c, 0xd1, 0x2d, 0x18, + 0x6a, 0x39, 0x71, 0x6d, 0x53, 0x24, 0xe9, 0x1d, 0xda, 0x37, 0xaf, 0x98, 0xb3, 0xa3, 0x14, 0x23, + 0xad, 0x9f, 0x33, 0xc1, 0x92, 0x1b, 0xb5, 0xd5, 0x6a, 0x41, 0xb3, 0x15, 0xf8, 0xc4, 0x8f, 0xa5, + 0x12, 0x19, 0xe3, 0xe7, 0x1d, 0xb2, 0x15, 0x1b, 0x18, 0x54, 0x23, 0x30, 0xdf, 0xdf, 0x0d, 0x37, + 0xde, 0x0c, 0xda, 0xb1, 0xdc, 0xca, 0x0a, 0x6d, 0xa2, 0x34, 0xc2, 0x52, 0x06, 0x0e, 0xce, 0x7c, + 0x32, 0xad, 0xfe, 0xc6, 0xef, 0x4e, 0xfd, 0x9d, 0xd8, 0x5f, 0xfd, 0x9d, 0x7d, 0x27, 0x9c, 0xec, + 0x12, 0x1a, 0x07, 0x72, 0xf0, 0xcd, 0xc3, 0x03, 0xd9, 0xcb, 0xf3, 0x40, 0x6e, 0xbe, 0x5f, 0x4f, + 0xc5, 0x79, 0x1b, 0x5b, 0x9e, 0x3e, 0x5c, 0xc6, 0x0e, 0x14, 0x89, 0xbf, 0x2d, 0xb4, 0xd5, 0xc5, + 0xc3, 0xcd, 0x92, 0x0b, 0xfe, 0x36, 0x97, 0x2e, 0xcc, 0x2f, 0x76, 0xc1, 0xdf, 0xc6, 0x94, 0x36, + 0xfa, 0x9c, 0x95, 0x30, 0xc8, 0xb9, 0xa3, 0xf9, 0xbd, 0x47, 0xb2, 0xc7, 0xeb, 0xdb, 0x46, 0xb7, + 0xff, 0x43, 0x01, 0xce, 0xed, 0x47, 0xa4, 0x8f, 0xe1, 0x7b, 0x1c, 0x06, 0x23, 0x16, 0xb9, 0x21, + 0xc4, 0xff, 0x30, 0x5d, 0x15, 0x3c, 0x96, 0xe3, 0x15, 0x2c, 0x40, 0xc8, 0x83, 0x62, 0xd3, 0x69, + 0x09, 0xff, 0xe3, 0xe2, 0x61, 0xf3, 0xe1, 0xe8, 0x7f, 0xc7, 0x5b, 0x76, 0x5a, 0x7c, 0x7a, 0x1a, + 0x0d, 0x98, 0xb2, 0x41, 0x31, 0x94, 0x9c, 0x30, 0x74, 0x64, 0x98, 0xc0, 0x95, 0x7c, 0xf8, 0xcd, + 0x50, 0x92, 0xfc, 0x94, 0x35, 0xd1, 0x84, 0x39, 0x33, 0xfb, 0x17, 0xcb, 0x89, 0xe4, 0x29, 0x16, + 0xfb, 0x11, 0xc1, 0xa0, 0x70, 0x3b, 0x5a, 0x79, 0xa7, 0x21, 0xf2, 0xec, 0x64, 0xb6, 0xa3, 0x17, + 0x35, 0x1e, 0x04, 0x2b, 0xf4, 0x09, 0x8b, 0x55, 0x52, 0x90, 0x19, 0x69, 0x62, 0x97, 0x7c, 0x34, + 0x85, 0x1d, 0xcc, 0xfa, 0x0c, 0xb2, 0x11, 0x9b, 0xdc, 0x45, 0x45, 0x14, 0xb6, 0x3b, 0xe8, 0xae, + 0x88, 0xc2, 0xac, 0x7d, 0x09, 0x47, 0x3b, 0x19, 0x31, 0x1e, 0x39, 0x64, 0xe3, 0xf7, 0x11, 0xd5, + 0xf1, 0x25, 0x0b, 0x4e, 0xba, 0xe9, 0xc3, 0x7a, 0xb1, 0xa7, 0xbc, 0x91, 0x8f, 0x8f, 0xb0, 0x3b, + 0x16, 0x40, 0x19, 0x0e, 0x5d, 0x20, 0xdc, 0xdd, 0x19, 0x54, 0x87, 0x01, 0xd7, 0xdf, 0x08, 0x84, + 0xb9, 0x34, 0x7b, 0xb8, 0x4e, 0x2d, 0xfa, 0x1b, 0x81, 0x5e, 0xcd, 0xf4, 0x1f, 0x66, 0xd4, 0xd1, + 0x12, 0x9c, 0x96, 0xf9, 0x33, 0x97, 0xdc, 0x28, 0x0e, 0xc2, 0xce, 0x92, 0xdb, 0x74, 0x63, 0x66, + 0xea, 0x14, 0x67, 0x27, 0xa8, 0x26, 0xc2, 0x19, 0x70, 0x9c, 0xf9, 0x14, 0x7a, 0x0d, 0x86, 0xe4, + 0x01, 0x79, 0x39, 0x8f, 0xfd, 0x79, 0xf7, 0xfc, 0x57, 0x93, 0xa9, 0x2a, 0x4e, 0xc8, 0x25, 0x43, + 0xf4, 0x71, 0x0b, 0xc6, 0xf8, 0xef, 0x4b, 0x9d, 0x3a, 0x4f, 0xd9, 0xab, 0xe4, 0x11, 0x05, 0x5f, + 0x4d, 0xd0, 0x9c, 0x45, 0xb7, 0x77, 0x27, 0xc7, 0x92, 0x6d, 0x38, 0xc5, 0xd7, 0xfe, 0xca, 0x08, + 0x74, 0x87, 0x14, 0x24, 0xe3, 0x07, 0xac, 0xe3, 0x8e, 0x1f, 0xa0, 0xbb, 0xb4, 0x48, 0x1f, 0xfd, + 0xe7, 0xb0, 0xcc, 0x04, 0x57, 0x7d, 0xac, 0xdb, 0xf1, 0x6b, 0x98, 0xf1, 0x40, 0x21, 0x0c, 0x6e, + 0x12, 0xc7, 0x8b, 0x37, 0xf3, 0x39, 0x81, 0xba, 0xc4, 0x68, 0xa5, 0xf3, 0xef, 0x78, 0x2b, 0x16, + 0x9c, 0xd0, 0x0e, 0x0c, 0x6d, 0xf2, 0xb9, 0x28, 0x36, 0x4e, 0xcb, 0x87, 0x1d, 0xdc, 0xc4, 0x04, + 0xd7, 0x33, 0x4f, 0x34, 0x60, 0xc9, 0x8e, 0xc5, 0xaa, 0x19, 0xd1, 0x34, 0x5c, 0x8a, 0xe4, 0x97, + 0x7a, 0xd8, 0x7f, 0x28, 0xcd, 0xfb, 0x60, 0x24, 0x24, 0xb5, 0xc0, 0xaf, 0xb9, 0x1e, 0xa9, 0xcf, + 0xc8, 0xd3, 0xa5, 0x83, 0x64, 0x9c, 0x31, 0xd7, 0x0c, 0x36, 0x68, 0xe0, 0x04, 0x45, 0xb6, 0xc8, + 0x54, 0x16, 0x3a, 0xfd, 0x20, 0x44, 0x9c, 0x22, 0x2c, 0xe5, 0x94, 0xf3, 0xce, 0x68, 0xf2, 0x45, + 0x96, 0x6c, 0xc3, 0x29, 0xbe, 0xe8, 0x25, 0x80, 0x60, 0x9d, 0x07, 0xa4, 0xcd, 0xc4, 0xe2, 0x48, + 0xe1, 0x20, 0xaf, 0x3a, 0xc6, 0x33, 0x57, 0x25, 0x05, 0x6c, 0x50, 0x43, 0x57, 0x00, 0xf8, 0xb2, + 0x59, 0xeb, 0xb4, 0xe4, 0xee, 0x4a, 0xa6, 0x0c, 0x42, 0x55, 0x41, 0xee, 0xec, 0x4e, 0x76, 0x3b, + 0x70, 0x59, 0xd4, 0x8d, 0xf1, 0x38, 0xfa, 0x29, 0x18, 0x8a, 0xda, 0xcd, 0xa6, 0xa3, 0x0e, 0x1c, + 0x72, 0xcc, 0x85, 0xe5, 0x74, 0x0d, 0xa9, 0xc8, 0x1b, 0xb0, 0xe4, 0x88, 0x6e, 0x52, 0xf9, 0x2e, + 0xc4, 0x13, 0x5f, 0x45, 0xdc, 0x3c, 0xe1, 0x6e, 0xb5, 0xb7, 0xc9, 0xdd, 0x06, 0xce, 0xc0, 0xb9, + 0xb3, 0x3b, 0xf9, 0x40, 0xb2, 0x7d, 0x29, 0x10, 0xd9, 0xa9, 0x99, 0x34, 0xd1, 0x65, 0x59, 0x94, + 0x8a, 0xbe, 0xb6, 0xac, 0x95, 0xf2, 0xa4, 0x2e, 0x4a, 0xc5, 0x9a, 0x7b, 0x8f, 0x99, 0xf9, 0x30, + 0x5a, 0x86, 0x53, 0xb5, 0xc0, 0x8f, 0xc3, 0xc0, 0xf3, 0x78, 0x51, 0x36, 0xbe, 0xd1, 0xe5, 0x07, + 0x12, 0x0f, 0x8b, 0x6e, 0x9f, 0x9a, 0xeb, 0x46, 0xc1, 0x59, 0xcf, 0x51, 0x83, 0x3c, 0xad, 0x1c, + 0xc6, 0x72, 0x39, 0xab, 0x4e, 0xd0, 0x14, 0x12, 0x4a, 0xf9, 0x90, 0xf7, 0x51, 0x13, 0x7e, 0xf2, + 0xc4, 0x52, 0x7c, 0xb1, 0x67, 0x61, 0x84, 0xec, 0xc4, 0x24, 0xf4, 0x1d, 0xef, 0x1a, 0x5e, 0x92, + 0xde, 0x7f, 0xb6, 0x30, 0x2f, 0x18, 0xed, 0x38, 0x81, 0x85, 0x6c, 0xe5, 0x72, 0x32, 0xd2, 0xc0, + 0xb9, 0xcb, 0x49, 0x3a, 0x98, 0xec, 0xaf, 0x15, 0x13, 0x06, 0xeb, 0x3d, 0x39, 0x1f, 0x65, 0xf5, + 0x86, 0x64, 0x61, 0x26, 0x06, 0x10, 0x1b, 0xb1, 0x3c, 0x39, 0xab, 0x7a, 0x43, 0x2b, 0x26, 0x23, + 0x9c, 0xe4, 0x8b, 0xb6, 0xa0, 0xb4, 0x19, 0x44, 0xb1, 0xdc, 0x9e, 0x1d, 0x72, 0x27, 0x78, 0x29, + 0x88, 0x62, 0x66, 0x65, 0xa9, 0xd7, 0xa6, 0x2d, 0x11, 0xe6, 0x3c, 0xe8, 0x1e, 0x3d, 0xda, 0x74, + 0xc2, 0x7a, 0x34, 0xc7, 0x8a, 0x36, 0x0c, 0x30, 0xf3, 0x4a, 0x19, 0xd3, 0x55, 0x0d, 0xc2, 0x26, + 0x9e, 0xfd, 0x17, 0x56, 0xe2, 0x88, 0xe8, 0x06, 0x8b, 0xc0, 0xdf, 0x26, 0x3e, 0x15, 0x51, 0x66, + 0xcc, 0xdf, 0x8f, 0xa6, 0xf2, 0x99, 0xdf, 0xd2, 0xab, 0x7e, 0xe2, 0x2d, 0x4a, 0x61, 0x8a, 0x91, + 0x30, 0xc2, 0x03, 0x3f, 0x64, 0x25, 0x13, 0xd3, 0x0b, 0x79, 0xec, 0xdb, 0xcc, 0xe2, 0x0c, 0xfb, + 0xe6, 0xb8, 0xdb, 0x9f, 0xb3, 0x60, 0x68, 0xd6, 0xa9, 0x6d, 0x05, 0x1b, 0x1b, 0xe8, 0x29, 0x28, + 0xd7, 0xdb, 0xa1, 0x99, 0x23, 0xaf, 0x3c, 0x3f, 0xf3, 0xa2, 0x1d, 0x2b, 0x0c, 0x3a, 0xf5, 0x37, + 0x9c, 0x9a, 0x2c, 0xd1, 0x50, 0xe4, 0x53, 0xff, 0x22, 0x6b, 0xc1, 0x02, 0x42, 0x87, 0xbf, 0xe9, + 0xec, 0xc8, 0x87, 0xd3, 0xe7, 0x53, 0xcb, 0x1a, 0x84, 0x4d, 0x3c, 0xfb, 0xdf, 0x58, 0x30, 0x31, + 0xeb, 0x44, 0x6e, 0x6d, 0xa6, 0x1d, 0x6f, 0xce, 0xba, 0xf1, 0x7a, 0xbb, 0xb6, 0x45, 0x62, 0x5e, + 0xca, 0x83, 0xf6, 0xb2, 0x1d, 0xd1, 0x15, 0xa8, 0xb6, 0xcb, 0xaa, 0x97, 0xd7, 0x44, 0x3b, 0x56, + 0x18, 0xe8, 0x35, 0x18, 0x6e, 0x39, 0x51, 0x74, 0x2b, 0x08, 0xeb, 0x98, 0x6c, 0xe4, 0x53, 0xec, + 0xa7, 0x4a, 0x6a, 0x21, 0x89, 0x31, 0xd9, 0x10, 0xd1, 0x1e, 0x9a, 0x3e, 0x36, 0x99, 0xd9, 0x3f, + 0x6f, 0xc1, 0xe9, 0x59, 0xe2, 0x84, 0x24, 0x64, 0xb5, 0x81, 0xd4, 0x8b, 0xa0, 0x57, 0xa1, 0x1c, + 0xd3, 0x16, 0xda, 0x23, 0x2b, 0xdf, 0x1e, 0xb1, 0x38, 0x8d, 0x35, 0x41, 0x1c, 0x2b, 0x36, 0xf6, + 0xa7, 0x2d, 0x78, 0x28, 0xab, 0x2f, 0x73, 0x5e, 0xd0, 0xae, 0xdf, 0x8b, 0x0e, 0xfd, 0x7d, 0x0b, + 0x46, 0xd8, 0xd9, 0xf7, 0x3c, 0x89, 0x1d, 0xd7, 0xeb, 0xaa, 0x4b, 0x68, 0xf5, 0x59, 0x97, 0xf0, + 0x1c, 0x0c, 0x6c, 0x06, 0x4d, 0x92, 0x8e, 0xdb, 0xb8, 0x14, 0x34, 0x09, 0x66, 0x10, 0xf4, 0x0c, + 0x9d, 0x84, 0xae, 0x1f, 0x3b, 0x74, 0x39, 0xca, 0xb3, 0x81, 0x71, 0x3e, 0x01, 0x55, 0x33, 0x36, + 0x71, 0xec, 0x7f, 0x5d, 0x81, 0x21, 0x11, 0x64, 0xd4, 0x77, 0x69, 0x19, 0xe9, 0xc2, 0x29, 0xf4, + 0x74, 0xe1, 0x44, 0x30, 0x58, 0x63, 0x05, 0x52, 0x85, 0x79, 0x7e, 0x25, 0x97, 0xa8, 0x34, 0x5e, + 0x73, 0x55, 0x77, 0x8b, 0xff, 0xc7, 0x82, 0x15, 0xfa, 0xac, 0x05, 0xe3, 0xb5, 0xc0, 0xf7, 0x49, + 0x4d, 0xdb, 0x8e, 0x03, 0x79, 0x04, 0x1f, 0xcd, 0x25, 0x89, 0xea, 0x63, 0xd5, 0x14, 0x00, 0xa7, + 0xd9, 0xa3, 0x17, 0x60, 0x94, 0x8f, 0xd9, 0xf5, 0xc4, 0x81, 0x86, 0x2e, 0x57, 0x67, 0x02, 0x71, + 0x12, 0x17, 0x4d, 0xf1, 0x83, 0x21, 0x51, 0x18, 0x6e, 0x50, 0xfb, 0x7d, 0x8d, 0x92, 0x70, 0x06, + 0x06, 0x0a, 0x01, 0x85, 0x64, 0x23, 0x24, 0xd1, 0xa6, 0x08, 0xc2, 0x62, 0x76, 0xeb, 0xd0, 0xdd, + 0x15, 0x85, 0xc0, 0x5d, 0x94, 0x70, 0x06, 0x75, 0xb4, 0x25, 0x7c, 0x08, 0xe5, 0x3c, 0xe4, 0xb9, + 0xf8, 0xcc, 0x3d, 0x5d, 0x09, 0x93, 0x50, 0x62, 0xaa, 0x8b, 0xd9, 0xcb, 0x45, 0x9e, 0x88, 0xc8, + 0x14, 0x1b, 0xe6, 0xed, 0x68, 0x1e, 0x4e, 0xa4, 0x8a, 0xed, 0x45, 0xe2, 0xe0, 0x41, 0x25, 0x9d, + 0xa5, 0xca, 0xf4, 0x45, 0xb8, 0xeb, 0x09, 0xd3, 0xbf, 0x34, 0xbc, 0x8f, 0x7f, 0xa9, 0xa3, 0x42, + 0x7d, 0xf9, 0x91, 0xc0, 0x8b, 0xb9, 0x0c, 0x40, 0x5f, 0x71, 0xbd, 0x9f, 0x4a, 0xc5, 0xf5, 0x8e, + 0xb2, 0x0e, 0x5c, 0xcf, 0xa7, 0x03, 0x07, 0x0f, 0xe2, 0xbd, 0x97, 0x41, 0xb9, 0xff, 0xcb, 0x02, + 0xf9, 0x5d, 0xe7, 0x9c, 0xda, 0x26, 0xa1, 0x53, 0x06, 0xbd, 0x03, 0xc6, 0x94, 0x6b, 0x82, 0x9b, + 0x44, 0x16, 0x9b, 0x35, 0xca, 0x76, 0xc6, 0x09, 0x28, 0x4e, 0x61, 0xa3, 0x69, 0xa8, 0xd0, 0x71, + 0xe2, 0x8f, 0x72, 0xbd, 0xaf, 0xdc, 0x1f, 0x33, 0xab, 0x8b, 0xe2, 0x29, 0x8d, 0x83, 0x02, 0x38, + 0xe9, 0x39, 0x51, 0xcc, 0x7a, 0x50, 0xed, 0xf8, 0xb5, 0xbb, 0x2c, 0xc9, 0xc2, 0x32, 0x9b, 0x96, + 0xd2, 0x84, 0x70, 0x37, 0x6d, 0xfb, 0x3f, 0x96, 0x60, 0x34, 0x21, 0x19, 0x0f, 0x68, 0x30, 0x3c, + 0x05, 0x65, 0xa9, 0xc3, 0xd3, 0xb5, 0xa7, 0x94, 0xa2, 0x57, 0x18, 0x54, 0x69, 0xad, 0x6b, 0xad, + 0x9a, 0x36, 0x70, 0x0c, 0x85, 0x8b, 0x4d, 0x3c, 0x26, 0x94, 0x63, 0x2f, 0x9a, 0xf3, 0x5c, 0xe2, + 0xc7, 0xbc, 0x9b, 0xf9, 0x08, 0xe5, 0xb5, 0xa5, 0xaa, 0x49, 0x54, 0x0b, 0xe5, 0x14, 0x00, 0xa7, + 0xd9, 0xa3, 0x8f, 0x5a, 0x30, 0xea, 0xdc, 0x8a, 0x74, 0x15, 0x6f, 0x11, 0xc1, 0x7b, 0x48, 0x25, + 0x95, 0x28, 0x0c, 0xce, 0xbd, 0xfa, 0x89, 0x26, 0x9c, 0x64, 0x8a, 0x5e, 0xb7, 0x00, 0x91, 0x1d, + 0x52, 0x93, 0x31, 0xc6, 0xa2, 0x2f, 0x83, 0x79, 0xec, 0xe0, 0x2f, 0x74, 0xd1, 0xe5, 0x52, 0xbd, + 0xbb, 0x1d, 0x67, 0xf4, 0x01, 0x5d, 0x06, 0x54, 0x77, 0x23, 0x67, 0xdd, 0x23, 0x73, 0x41, 0x53, + 0x66, 0xe3, 0x8a, 0xc3, 0xe9, 0xb3, 0x62, 0x9c, 0xd1, 0x7c, 0x17, 0x06, 0xce, 0x78, 0x8a, 0xcd, + 0xb2, 0x30, 0xd8, 0xe9, 0x5c, 0x0b, 0x3d, 0xa6, 0x25, 0xcc, 0x59, 0x26, 0xda, 0xb1, 0xc2, 0xb0, + 0xff, 0xb2, 0xa8, 0x96, 0xb2, 0x0e, 0xa8, 0x77, 0x8c, 0xc0, 0x5e, 0xeb, 0xee, 0x03, 0x7b, 0x75, + 0xd8, 0x51, 0x77, 0x8e, 0x79, 0x22, 0x25, 0xb5, 0x70, 0x8f, 0x52, 0x52, 0x7f, 0xc6, 0x4a, 0xd4, + 0x77, 0x1b, 0x3e, 0xff, 0x52, 0xbe, 0xc1, 0xfc, 0x53, 0x3c, 0x24, 0x2a, 0xa5, 0x57, 0x52, 0x91, + 0x70, 0x4f, 0x41, 0x79, 0xc3, 0x73, 0x58, 0x55, 0x12, 0xb6, 0x50, 0x8d, 0x70, 0xad, 0x8b, 0xa2, + 0x1d, 0x2b, 0x0c, 0x2a, 0xf5, 0x0d, 0xa2, 0x07, 0x92, 0xda, 0xff, 0xb9, 0x08, 0xc3, 0x86, 0xc6, + 0xcf, 0x34, 0xdf, 0xac, 0xfb, 0xcc, 0x7c, 0x2b, 0x1c, 0xc0, 0x7c, 0xfb, 0x69, 0xa8, 0xd4, 0xa4, + 0x36, 0xca, 0xa7, 0x5e, 0x7d, 0x5a, 0xc7, 0x69, 0x85, 0xa4, 0x9a, 0xb0, 0xe6, 0x89, 0x16, 0x12, + 0x69, 0x8f, 0x09, 0xbf, 0x40, 0x56, 0x5e, 0xa2, 0xd0, 0x68, 0xdd, 0xcf, 0xa4, 0xcf, 0xf1, 0x4b, + 0xfb, 0x9f, 0xe3, 0xdb, 0xdf, 0xb2, 0xd4, 0xc7, 0x3d, 0x86, 0xfa, 0x36, 0x37, 0x93, 0xf5, 0x6d, + 0x2e, 0xe4, 0x32, 0xcc, 0x3d, 0x0a, 0xdb, 0x5c, 0x85, 0xa1, 0xb9, 0xa0, 0xd9, 0x74, 0xfc, 0x3a, + 0xfa, 0x41, 0x18, 0xaa, 0xf1, 0x9f, 0xc2, 0x87, 0xc6, 0x4e, 0xaa, 0x05, 0x14, 0x4b, 0x18, 0x7a, + 0x04, 0x06, 0x9c, 0xb0, 0x21, 0xfd, 0x66, 0x2c, 0xa2, 0x6c, 0x26, 0x6c, 0x44, 0x98, 0xb5, 0xda, + 0xff, 0x62, 0x00, 0x58, 0x20, 0x87, 0x13, 0x92, 0xfa, 0x5a, 0xc0, 0xca, 0xcc, 0x1e, 0xe9, 0xf9, + 0xae, 0xde, 0xd4, 0xdd, 0xcf, 0x67, 0xbc, 0xc6, 0x39, 0x5f, 0xf1, 0xb8, 0xcf, 0xf9, 0xb2, 0x8f, + 0x6e, 0x07, 0xee, 0xa3, 0xa3, 0x5b, 0xfb, 0x93, 0x16, 0x20, 0x15, 0xfd, 0xa3, 0x63, 0x2b, 0xa6, + 0xa1, 0xa2, 0xe2, 0x80, 0x84, 0x01, 0xa8, 0x45, 0x84, 0x04, 0x60, 0x8d, 0xd3, 0xc7, 0x4e, 0xfe, + 0x71, 0x29, 0xbf, 0x8b, 0xc9, 0x60, 0x7e, 0x26, 0xf5, 0x85, 0x38, 0xb7, 0x7f, 0xb7, 0x00, 0x0f, + 0x70, 0xd3, 0x61, 0xd9, 0xf1, 0x9d, 0x06, 0x69, 0xd2, 0x5e, 0xf5, 0x1b, 0x2d, 0x53, 0xa3, 0x5b, + 0x48, 0x57, 0x86, 0xde, 0x1f, 0x76, 0xed, 0xf2, 0x35, 0xc7, 0x57, 0xd9, 0xa2, 0xef, 0xc6, 0x98, + 0x11, 0x47, 0x11, 0x94, 0xe5, 0x65, 0x2e, 0x42, 0x16, 0xe7, 0xc4, 0x48, 0x89, 0x25, 0xa1, 0x65, + 0x09, 0x56, 0x8c, 0xa8, 0x2a, 0xf5, 0x82, 0xda, 0x16, 0x26, 0xad, 0x20, 0xad, 0x4a, 0x97, 0x44, + 0x3b, 0x56, 0x18, 0x76, 0x13, 0xc6, 0xe5, 0x18, 0xb6, 0xae, 0x90, 0x0e, 0x26, 0x1b, 0x54, 0xff, + 0xd4, 0x64, 0x93, 0x71, 0xbf, 0x8c, 0xd2, 0x3f, 0x73, 0x26, 0x10, 0x27, 0x71, 0x65, 0xe5, 0xd9, + 0x42, 0x76, 0xe5, 0x59, 0xfb, 0x77, 0x2d, 0x48, 0x2b, 0x40, 0xa3, 0xce, 0xa6, 0xb5, 0x67, 0x9d, + 0xcd, 0x03, 0x54, 0xaa, 0xfc, 0x49, 0x18, 0x76, 0x62, 0x6a, 0xe1, 0x70, 0x6f, 0x44, 0xf1, 0xee, + 0x4e, 0xd1, 0x96, 0x83, 0xba, 0xbb, 0xe1, 0x32, 0x2f, 0x84, 0x49, 0xce, 0x7e, 0xdd, 0x82, 0xca, + 0x7c, 0xd8, 0x39, 0x78, 0x0e, 0x54, 0x77, 0x86, 0x53, 0xe1, 0x40, 0x19, 0x4e, 0x32, 0x87, 0xaa, + 0xd8, 0x2b, 0x87, 0xca, 0xfe, 0xeb, 0x01, 0x38, 0xd9, 0x95, 0xd4, 0x87, 0x9e, 0x87, 0x11, 0xf5, + 0x95, 0xa4, 0x0b, 0xb2, 0x62, 0x46, 0xc5, 0x6a, 0x18, 0x4e, 0x60, 0xf6, 0xb1, 0x54, 0x17, 0xe1, + 0x54, 0x48, 0x5e, 0x6d, 0x93, 0x36, 0x99, 0xd9, 0x88, 0x49, 0x58, 0x25, 0xb5, 0xc0, 0xaf, 0xf3, + 0x42, 0xb5, 0xc5, 0xd9, 0x07, 0x6f, 0xef, 0x4e, 0x9e, 0xc2, 0xdd, 0x60, 0x9c, 0xf5, 0x0c, 0x6a, + 0xc1, 0xa8, 0x67, 0xda, 0xce, 0x62, 0xcb, 0x76, 0x57, 0x66, 0xb7, 0x9a, 0xad, 0x89, 0x66, 0x9c, + 0x64, 0x90, 0x34, 0xc0, 0x4b, 0xf7, 0xc8, 0x00, 0xff, 0x88, 0x36, 0xc0, 0x79, 0x50, 0xcc, 0x7b, + 0x72, 0x4e, 0xea, 0xec, 0xc7, 0x02, 0x3f, 0x8c, 0x4d, 0xfd, 0x22, 0x94, 0x65, 0xc0, 0x60, 0x5f, + 0x81, 0x76, 0x26, 0x9d, 0x1e, 0xb2, 0xfd, 0x09, 0x78, 0xf3, 0x85, 0x30, 0x34, 0x06, 0xf3, 0x6a, + 0x10, 0xcf, 0x78, 0x5e, 0x70, 0x8b, 0x9a, 0x2b, 0xd7, 0x22, 0x22, 0x7c, 0x62, 0xf6, 0x9d, 0x02, + 0x64, 0x6c, 0x2f, 0xe9, 0x9a, 0xd4, 0x36, 0x52, 0x62, 0x4d, 0x1e, 0xcc, 0x4e, 0x42, 0x3b, 0x3c, + 0xa8, 0x92, 0x5b, 0x03, 0xef, 0xce, 0x7b, 0x7b, 0xac, 0xe3, 0x2c, 0x95, 0xa4, 0x54, 0xb1, 0x96, + 0xe7, 0x01, 0xb4, 0x69, 0x2b, 0xf2, 0x88, 0x54, 0xa0, 0x84, 0xb6, 0x80, 0xb1, 0x81, 0x85, 0x9e, + 0x83, 0x61, 0xd7, 0x8f, 0x62, 0xc7, 0xf3, 0x2e, 0xb9, 0x7e, 0x2c, 0xdc, 0xbe, 0xca, 0xec, 0x59, + 0xd4, 0x20, 0x6c, 0xe2, 0x9d, 0x7d, 0x9b, 0xf1, 0xfd, 0x0e, 0xf2, 0xdd, 0x37, 0xe1, 0xa1, 0x05, + 0x37, 0x56, 0xd9, 0x6f, 0x6a, 0xbe, 0x51, 0xcb, 0x55, 0xc9, 0x2a, 0xab, 0x67, 0xbe, 0xa7, 0x91, + 0x7d, 0x56, 0x48, 0x26, 0xcb, 0xa5, 0xb3, 0xcf, 0xec, 0xe7, 0xe1, 0xf4, 0x82, 0x1b, 0x5f, 0x74, + 0x3d, 0x72, 0x40, 0x26, 0xf6, 0xef, 0x0c, 0xc2, 0x88, 0x99, 0xe9, 0x7d, 0x10, 0x71, 0xfd, 0x69, + 0x6a, 0x9c, 0x8a, 0xb7, 0x73, 0xd5, 0x89, 0xee, 0x8d, 0x43, 0xa7, 0x9d, 0x67, 0x8f, 0x98, 0x61, + 0x9f, 0x6a, 0x9e, 0xd8, 0xec, 0x00, 0xba, 0x05, 0xa5, 0x0d, 0x96, 0x1d, 0x55, 0xcc, 0x23, 0x16, + 0x27, 0x6b, 0x44, 0xf5, 0x72, 0xe4, 0xf9, 0x55, 0x9c, 0x1f, 0xb5, 0x29, 0xc2, 0x64, 0x52, 0xae, + 0x11, 0xb3, 0x2e, 0x94, 0x95, 0xc2, 0xe8, 0xa5, 0x12, 0x4a, 0x77, 0xa1, 0x12, 0x12, 0x02, 0x7a, + 0xf0, 0x1e, 0x09, 0x68, 0x96, 0xe9, 0x16, 0x6f, 0x32, 0x8b, 0x57, 0x24, 0xd9, 0x0c, 0xb1, 0x41, + 0x30, 0x32, 0xdd, 0x12, 0x60, 0x9c, 0xc6, 0x47, 0x1f, 0x54, 0x22, 0xbe, 0x9c, 0x87, 0xc7, 0xdc, + 0x9c, 0xd1, 0x47, 0x2d, 0xdd, 0x3f, 0x59, 0x80, 0xb1, 0x05, 0xbf, 0xbd, 0xba, 0xb0, 0xda, 0x5e, + 0xf7, 0xdc, 0xda, 0x15, 0xd2, 0xa1, 0x22, 0x7c, 0x8b, 0x74, 0x16, 0xe7, 0xc5, 0x0a, 0x52, 0x73, + 0xe6, 0x0a, 0x6d, 0xc4, 0x1c, 0x46, 0x85, 0xd1, 0x86, 0xeb, 0x37, 0x48, 0xd8, 0x0a, 0x5d, 0xe1, + 0xcc, 0x36, 0x84, 0xd1, 0x45, 0x0d, 0xc2, 0x26, 0x1e, 0xa5, 0x1d, 0xdc, 0xf2, 0x49, 0x98, 0x36, + 0xfd, 0x57, 0x68, 0x23, 0xe6, 0x30, 0x8a, 0x14, 0x87, 0x6d, 0xe1, 0x2b, 0x32, 0x90, 0xd6, 0x68, + 0x23, 0xe6, 0x30, 0xba, 0xd2, 0xa3, 0xf6, 0x3a, 0x0b, 0x75, 0x4a, 0x65, 0xf4, 0x54, 0x79, 0x33, + 0x96, 0x70, 0x8a, 0xba, 0x45, 0x3a, 0xf3, 0x4e, 0xec, 0xa4, 0xd3, 0x1e, 0xaf, 0xf0, 0x66, 0x2c, + 0xe1, 0xac, 0x94, 0x6e, 0x72, 0x38, 0xbe, 0xe7, 0x4a, 0xe9, 0x26, 0xbb, 0xdf, 0xc3, 0xe3, 0xf0, + 0xf7, 0x0a, 0x30, 0x62, 0x06, 0x28, 0xa2, 0x46, 0xca, 0x4c, 0x5f, 0xe9, 0xaa, 0xc4, 0xfe, 0xf6, + 0xac, 0x5b, 0x4a, 0x1b, 0x6e, 0x1c, 0xb4, 0xa2, 0xa7, 0x89, 0xdf, 0x70, 0x7d, 0xc2, 0x62, 0x35, + 0x78, 0x60, 0x63, 0x22, 0xfa, 0x71, 0x2e, 0xa8, 0x93, 0xbb, 0xb1, 0xf3, 0xef, 0xc5, 0x4d, 0x2e, + 0x37, 0xe0, 0x64, 0x57, 0x7e, 0x6d, 0x1f, 0x66, 0xcf, 0xbe, 0xf5, 0x0f, 0x6c, 0x0c, 0xc3, 0x94, + 0xb0, 0x2c, 0x21, 0x37, 0x07, 0x27, 0xf9, 0xe2, 0xa5, 0x9c, 0x58, 0xba, 0xa4, 0xca, 0x99, 0x66, + 0xa7, 0x35, 0xd7, 0xd3, 0x40, 0xdc, 0x8d, 0x6f, 0x7f, 0xca, 0x82, 0xd1, 0x44, 0xca, 0x73, 0x4e, + 0x06, 0x1a, 0x5b, 0xdd, 0x01, 0x8b, 0xd1, 0x65, 0x39, 0x13, 0x45, 0xa6, 0xc0, 0xf5, 0xea, 0xd6, + 0x20, 0x6c, 0xe2, 0xd9, 0x9f, 0x2b, 0x40, 0x59, 0x86, 0x14, 0xf5, 0xd1, 0x95, 0x4f, 0x58, 0x30, + 0xaa, 0x4e, 0xc8, 0x98, 0x4b, 0xb3, 0x90, 0x47, 0x06, 0x16, 0xed, 0x81, 0x72, 0x8a, 0xf8, 0x1b, + 0x81, 0xde, 0x2d, 0x60, 0x93, 0x19, 0x4e, 0xf2, 0x46, 0xd7, 0x01, 0xa2, 0x4e, 0x14, 0x93, 0xa6, + 0xe1, 0x5c, 0xb5, 0x8d, 0x59, 0x36, 0x55, 0x0b, 0x42, 0x42, 0xe7, 0xd4, 0xd5, 0xa0, 0x4e, 0xaa, + 0x0a, 0x53, 0x9b, 0x6d, 0xba, 0x0d, 0x1b, 0x94, 0xec, 0x5f, 0x2b, 0xc0, 0x89, 0x74, 0x97, 0xd0, + 0x7b, 0x60, 0x44, 0x72, 0x37, 0x36, 0xe1, 0x32, 0x20, 0x6a, 0x04, 0x1b, 0xb0, 0x3b, 0xbb, 0x93, + 0x93, 0xdd, 0xb7, 0xec, 0x4e, 0x99, 0x28, 0x38, 0x41, 0x8c, 0x1f, 0x53, 0x8a, 0xf3, 0xf4, 0xd9, + 0xce, 0x4c, 0xab, 0x25, 0xce, 0x1a, 0x8d, 0x63, 0x4a, 0x13, 0x8a, 0x53, 0xd8, 0x68, 0x15, 0x4e, + 0x1b, 0x2d, 0x57, 0x89, 0xdb, 0xd8, 0x5c, 0x0f, 0x42, 0xb9, 0xeb, 0x7b, 0x44, 0x87, 0x5f, 0x76, + 0xe3, 0xe0, 0xcc, 0x27, 0xa9, 0x85, 0x51, 0x73, 0x5a, 0x4e, 0xcd, 0x8d, 0x3b, 0xc2, 0x5b, 0xac, + 0xe4, 0xe1, 0x9c, 0x68, 0xc7, 0x0a, 0xc3, 0xfe, 0xd5, 0x01, 0x38, 0xc1, 0xe3, 0x0d, 0x89, 0x0a, + 0xa7, 0x45, 0xef, 0x81, 0x4a, 0x14, 0x3b, 0x21, 0xdf, 0xf2, 0x5b, 0x07, 0x96, 0x01, 0x3a, 0xe1, + 0x59, 0x12, 0xc1, 0x9a, 0x1e, 0x7a, 0x89, 0x55, 0x8b, 0x72, 0xa3, 0x4d, 0x46, 0xbd, 0x70, 0x77, + 0x0e, 0x85, 0x8b, 0x8a, 0x02, 0x36, 0xa8, 0xa1, 0x1f, 0x87, 0x52, 0x6b, 0xd3, 0x89, 0xa4, 0xb7, + 0xeb, 0x09, 0xb9, 0xe0, 0x56, 0x69, 0xe3, 0x9d, 0xdd, 0xc9, 0x33, 0xe9, 0x57, 0x65, 0x00, 0xcc, + 0x1f, 0x32, 0xc5, 0xe5, 0xc0, 0xfe, 0x37, 0x9a, 0xd4, 0xc3, 0x4e, 0xf5, 0xd2, 0x4c, 0xfa, 0x0e, + 0x8c, 0x79, 0xd6, 0x8a, 0x05, 0x94, 0x2e, 0xee, 0x4d, 0xce, 0xb2, 0x4e, 0x91, 0x07, 0x93, 0xaa, + 0xfb, 0x92, 0x06, 0x61, 0x13, 0x0f, 0x7d, 0xb2, 0x3b, 0x1a, 0x75, 0xe8, 0x08, 0x52, 0x15, 0xfa, + 0x8d, 0x43, 0xbd, 0x00, 0x15, 0xd1, 0xd5, 0xb5, 0x00, 0x3d, 0x0f, 0x23, 0xdc, 0x99, 0x32, 0x1b, + 0x3a, 0x7e, 0x6d, 0x33, 0xed, 0x02, 0x59, 0x33, 0x60, 0x38, 0x81, 0x69, 0x2f, 0xc3, 0x40, 0x9f, + 0xd2, 0xaa, 0xaf, 0x9d, 0xed, 0x8b, 0x50, 0xa6, 0xe4, 0xe4, 0xf6, 0x25, 0x0f, 0x92, 0x01, 0x94, + 0xe5, 0xfd, 0x78, 0xc8, 0x86, 0xa2, 0xeb, 0xc8, 0xa8, 0x03, 0xb5, 0x84, 0x16, 0xa3, 0xa8, 0xcd, + 0xa6, 0x1d, 0x05, 0xa2, 0xc7, 0xa1, 0x48, 0x76, 0x5a, 0xe9, 0xf0, 0x82, 0x0b, 0x3b, 0x2d, 0x37, + 0x24, 0x11, 0x45, 0x22, 0x3b, 0x2d, 0x74, 0x16, 0x0a, 0x6e, 0x5d, 0xcc, 0x48, 0x10, 0x38, 0x85, + 0xc5, 0x79, 0x5c, 0x70, 0xeb, 0xf6, 0x0e, 0x54, 0xd4, 0x85, 0x7c, 0x68, 0x4b, 0xda, 0x26, 0x56, + 0x1e, 0xf1, 0xa6, 0x92, 0x6e, 0x0f, 0xab, 0xa4, 0x0d, 0xa0, 0x33, 0xe9, 0xf3, 0xd2, 0x65, 0xe7, + 0x60, 0xa0, 0x16, 0x88, 0x1a, 0x28, 0x65, 0x4d, 0x86, 0x19, 0x25, 0x0c, 0x62, 0xdf, 0x80, 0xb1, + 0x2b, 0x7e, 0x70, 0x8b, 0xdd, 0x9b, 0xc3, 0xca, 0xc4, 0x52, 0xc2, 0x1b, 0xf4, 0x47, 0xda, 0x04, + 0x66, 0x50, 0xcc, 0x61, 0xaa, 0x80, 0x65, 0xa1, 0x57, 0x01, 0x4b, 0xfb, 0x43, 0x16, 0x8c, 0xa8, + 0x94, 0xdc, 0x85, 0xed, 0x2d, 0x4a, 0xb7, 0x11, 0x06, 0xed, 0x56, 0x9a, 0x2e, 0xbb, 0xfb, 0x13, + 0x73, 0x98, 0x99, 0xab, 0x5e, 0xd8, 0x27, 0x57, 0xfd, 0x1c, 0x0c, 0x6c, 0xb9, 0x7e, 0x3d, 0xed, + 0x32, 0xbc, 0xe2, 0xfa, 0x75, 0xcc, 0x20, 0xb4, 0x0b, 0x27, 0x54, 0x17, 0xa4, 0xf1, 0xf1, 0x3c, + 0x8c, 0xac, 0xb7, 0x5d, 0xaf, 0x2e, 0xeb, 0xdf, 0xa6, 0x96, 0xcb, 0xac, 0x01, 0xc3, 0x09, 0x4c, + 0x74, 0x1e, 0x60, 0xdd, 0xf5, 0x9d, 0xb0, 0xb3, 0xaa, 0xad, 0x1d, 0xa5, 0x00, 0x67, 0x15, 0x04, + 0x1b, 0x58, 0xf6, 0x67, 0x8a, 0x30, 0x96, 0x4c, 0x4c, 0xee, 0xc3, 0x7d, 0xf0, 0x38, 0x94, 0x58, + 0xae, 0x72, 0xfa, 0xd3, 0xf2, 0x92, 0xb1, 0x1c, 0x86, 0x22, 0x18, 0xe4, 0x8b, 0x39, 0x9f, 0xfb, + 0x13, 0x55, 0x27, 0x95, 0x9f, 0x91, 0x45, 0xe5, 0x0a, 0xb7, 0xad, 0x60, 0x85, 0x3e, 0x6a, 0xc1, + 0x50, 0xd0, 0x32, 0x0b, 0x1f, 0xbe, 0x3b, 0xcf, 0xa4, 0x6d, 0x91, 0xc9, 0x29, 0x76, 0x7c, 0xea, + 0xd3, 0xcb, 0xcf, 0x21, 0x59, 0x9f, 0xfd, 0x31, 0x18, 0x31, 0x31, 0xf7, 0xdb, 0xf4, 0x95, 0xcd, + 0x4d, 0xdf, 0x27, 0xcc, 0x49, 0x21, 0xd2, 0xd2, 0xfb, 0x58, 0x6e, 0xd7, 0xa0, 0x54, 0x53, 0xa1, + 0x4b, 0x77, 0x55, 0x35, 0x5d, 0x95, 0x6d, 0x62, 0xc7, 0xc2, 0x9c, 0x9a, 0xfd, 0x2d, 0xcb, 0x98, + 0x1f, 0x98, 0x44, 0x8b, 0x75, 0x14, 0x42, 0xb1, 0xb1, 0xbd, 0x25, 0xd4, 0xfc, 0xe5, 0x9c, 0x86, + 0x77, 0x61, 0x7b, 0x4b, 0xcf, 0x71, 0xb3, 0x15, 0x53, 0x66, 0x7d, 0x38, 0xc3, 0x13, 0xd5, 0x0b, + 0x8a, 0xfb, 0x57, 0x2f, 0xb0, 0x5f, 0x2f, 0xc0, 0xc9, 0xae, 0x49, 0x85, 0x5e, 0x83, 0x52, 0x48, + 0xdf, 0x52, 0xbc, 0xde, 0x52, 0x6e, 0xf5, 0x06, 0xa2, 0xc5, 0xba, 0x56, 0x9f, 0xc9, 0x76, 0xcc, + 0x59, 0xa2, 0xcb, 0x80, 0x74, 0x80, 0x9d, 0xf2, 0xc4, 0xf3, 0x57, 0x56, 0x51, 0x38, 0x33, 0x5d, + 0x18, 0x38, 0xe3, 0x29, 0xf4, 0x42, 0xda, 0xa1, 0x5f, 0x4c, 0x9e, 0x24, 0xed, 0xe5, 0x9b, 0xb7, + 0x7f, 0xab, 0x00, 0xa3, 0x89, 0x3a, 0x94, 0xc8, 0x83, 0x32, 0xf1, 0xd8, 0x31, 0x9f, 0x54, 0x36, + 0x87, 0xbd, 0x55, 0x42, 0x29, 0xc8, 0x0b, 0x82, 0x2e, 0x56, 0x1c, 0xee, 0x8f, 0xe0, 0x9c, 0xe7, + 0x61, 0x44, 0x76, 0xe8, 0xdd, 0x4e, 0xd3, 0x13, 0x03, 0xa8, 0xe6, 0xe8, 0x05, 0x03, 0x86, 0x13, + 0x98, 0xf6, 0xef, 0x15, 0x61, 0x82, 0x9f, 0x8b, 0xd6, 0xd5, 0xcc, 0x5b, 0x96, 0xfe, 0x84, 0x5f, + 0xd0, 0xd5, 0x62, 0xad, 0x3c, 0xae, 0x4e, 0xee, 0xc5, 0xa8, 0xaf, 0x98, 0xd2, 0x2f, 0xa6, 0x62, + 0x4a, 0xf9, 0x16, 0xaf, 0x71, 0x44, 0x3d, 0xfa, 0xde, 0x0a, 0x32, 0xfd, 0x27, 0x05, 0x18, 0x4f, + 0xdd, 0x90, 0x85, 0x3e, 0x93, 0xbc, 0x54, 0xc1, 0xca, 0xe3, 0xcc, 0x68, 0xcf, 0x4b, 0x93, 0x0e, + 0x76, 0xb5, 0xc2, 0x3d, 0x5a, 0x2a, 0xf6, 0x37, 0x0b, 0x30, 0x96, 0xbc, 0xda, 0xeb, 0x3e, 0x1c, + 0xa9, 0xb7, 0x42, 0x85, 0xdd, 0x5e, 0xc3, 0x6e, 0xa4, 0xe7, 0x47, 0x4e, 0xfc, 0xa2, 0x10, 0xd9, + 0x88, 0x35, 0xfc, 0xbe, 0xb8, 0xb1, 0xc2, 0xfe, 0x67, 0x16, 0x9c, 0xe1, 0x6f, 0x99, 0x9e, 0x87, + 0x7f, 0x27, 0x6b, 0x74, 0x5f, 0xce, 0xb7, 0x83, 0xa9, 0x2a, 0xc7, 0xfb, 0x8d, 0x2f, 0xbb, 0x40, + 0x5a, 0xf4, 0x36, 0x39, 0x15, 0xee, 0xc3, 0xce, 0x1e, 0x68, 0x32, 0xd8, 0xdf, 0x2c, 0x82, 0xbe, + 0x33, 0x1b, 0xb9, 0x22, 0xeb, 0x3d, 0x97, 0x6a, 0xcf, 0xd5, 0x8e, 0x5f, 0xd3, 0xb7, 0x73, 0x97, + 0x53, 0x49, 0xef, 0x3f, 0x67, 0xc1, 0xb0, 0xeb, 0xbb, 0xb1, 0xeb, 0x30, 0x97, 0x4d, 0x3e, 0x17, + 0xdf, 0x2a, 0x76, 0x8b, 0x9c, 0x72, 0x10, 0x9a, 0xe7, 0x94, 0x8a, 0x19, 0x36, 0x39, 0xa3, 0xf7, + 0x89, 0xb4, 0x8f, 0x62, 0x6e, 0xa5, 0x23, 0xca, 0xa9, 0x5c, 0x8f, 0x16, 0x35, 0xbc, 0xe2, 0x30, + 0xa7, 0x8a, 0x2b, 0x98, 0x92, 0x52, 0x17, 0x07, 0x28, 0xd3, 0x96, 0x35, 0x63, 0xce, 0xc8, 0x8e, + 0x00, 0x75, 0x8f, 0xc5, 0x01, 0x43, 0xea, 0xa7, 0xa1, 0xe2, 0xb4, 0xe3, 0xa0, 0x49, 0x87, 0x49, + 0x1c, 0xa5, 0xea, 0xa4, 0x01, 0x09, 0xc0, 0x1a, 0xc7, 0xfe, 0x4c, 0x09, 0x52, 0x69, 0xe8, 0x68, + 0xc7, 0xbc, 0xef, 0xdd, 0xca, 0xf7, 0xbe, 0x77, 0xd5, 0x99, 0xac, 0x3b, 0xdf, 0x51, 0x43, 0x7a, + 0xbf, 0xb8, 0x8d, 0xf9, 0x62, 0xda, 0xfb, 0xf5, 0x13, 0xfd, 0x9d, 0x2a, 0xd0, 0xb9, 0x3a, 0xcd, + 0xab, 0x78, 0x4d, 0xed, 0xeb, 0x28, 0xdb, 0xef, 0xea, 0xdf, 0x0f, 0x8b, 0x6b, 0x7a, 0x30, 0x89, + 0xda, 0x5e, 0x2c, 0x66, 0xc3, 0x8b, 0x39, 0xae, 0x32, 0x4e, 0x58, 0xd7, 0x72, 0xe1, 0xff, 0xb1, + 0xc1, 0x34, 0xe9, 0xce, 0x1c, 0x3c, 0x52, 0x77, 0xe6, 0x50, 0xae, 0xee, 0xcc, 0xf3, 0x00, 0x6c, + 0x6e, 0xf3, 0xd0, 0xdf, 0x32, 0xf3, 0x32, 0x29, 0x51, 0x88, 0x15, 0x04, 0x1b, 0x58, 0xf6, 0x0f, + 0x43, 0xb2, 0x18, 0x11, 0x9a, 0x94, 0xb5, 0x8f, 0xf8, 0x89, 0x07, 0xcb, 0xba, 0x4a, 0x94, 0x29, + 0xfa, 0x0d, 0x0b, 0xcc, 0x8a, 0x49, 0xe8, 0x55, 0x5e, 0x9a, 0xc9, 0xca, 0xe3, 0x64, 0xdc, 0xa0, + 0x3b, 0xb5, 0xec, 0xb4, 0x52, 0x21, 0x1a, 0xb2, 0x3e, 0xd3, 0xd9, 0xb7, 0x41, 0x59, 0x42, 0x0f, + 0x64, 0xd4, 0x7d, 0x10, 0x4e, 0xc9, 0x0c, 0x6e, 0xe9, 0xa3, 0x17, 0xa7, 0xaa, 0xfb, 0xbb, 0x7e, + 0xa4, 0x3f, 0xa7, 0xd0, 0xcb, 0x9f, 0xd3, 0xc7, 0xad, 0xff, 0xbf, 0x69, 0xc1, 0xb9, 0x74, 0x07, + 0xa2, 0xe5, 0xc0, 0x77, 0xe3, 0x20, 0xac, 0x92, 0x38, 0x76, 0xfd, 0x06, 0xab, 0x48, 0x79, 0xcb, + 0x09, 0xe5, 0xad, 0x24, 0x4c, 0x50, 0xde, 0x70, 0x42, 0x1f, 0xb3, 0x56, 0xd4, 0x81, 0x41, 0x1e, + 0x1f, 0x2a, 0xac, 0xf5, 0x43, 0xae, 0x8d, 0x8c, 0xe1, 0xd0, 0xdb, 0x05, 0x1e, 0x9b, 0x8a, 0x05, + 0x43, 0xfb, 0x3b, 0x16, 0xa0, 0x95, 0x6d, 0x12, 0x86, 0x6e, 0xdd, 0x88, 0x68, 0x65, 0xd7, 0xdd, + 0x19, 0xd7, 0xda, 0x99, 0xf5, 0x05, 0x52, 0xd7, 0xdd, 0x19, 0xff, 0xb2, 0xaf, 0xbb, 0x2b, 0x1c, + 0xec, 0xba, 0x3b, 0xb4, 0x02, 0x67, 0x9a, 0x7c, 0xbb, 0xc1, 0xaf, 0x90, 0xe2, 0x7b, 0x0f, 0x95, + 0x0a, 0xfb, 0xd0, 0xed, 0xdd, 0xc9, 0x33, 0xcb, 0x59, 0x08, 0x38, 0xfb, 0x39, 0xfb, 0x6d, 0x80, + 0x78, 0x20, 0xeb, 0x5c, 0x56, 0x2c, 0x5e, 0x4f, 0xf7, 0x8b, 0xfd, 0x85, 0x12, 0x8c, 0xa7, 0x6a, + 0xd6, 0xd3, 0xad, 0x5e, 0x77, 0xf0, 0xdf, 0xa1, 0xf5, 0x77, 0x77, 0xf7, 0xfa, 0x0a, 0x27, 0xf4, + 0xa1, 0xe4, 0xfa, 0xad, 0x76, 0x9c, 0x4f, 0x26, 0x3e, 0xef, 0xc4, 0x22, 0x25, 0x68, 0xb8, 0x8b, + 0xe9, 0x5f, 0xcc, 0xd9, 0xe4, 0x19, 0x9c, 0x98, 0x30, 0xc6, 0x07, 0xee, 0x91, 0x3b, 0xe0, 0xc3, + 0x3a, 0x54, 0xb0, 0x94, 0x87, 0x63, 0x31, 0x35, 0x59, 0x8e, 0x3a, 0x94, 0xe4, 0x6b, 0x05, 0x18, + 0x36, 0x3e, 0x1a, 0xfa, 0x95, 0x64, 0x3d, 0x41, 0x2b, 0xbf, 0x57, 0x62, 0xf4, 0xa7, 0x74, 0xc5, + 0x40, 0xfe, 0x4a, 0x4f, 0x74, 0x97, 0x12, 0xbc, 0xb3, 0x3b, 0x79, 0x22, 0x55, 0x2c, 0x30, 0x51, + 0x5e, 0xf0, 0xec, 0x07, 0x60, 0x3c, 0x45, 0x26, 0xe3, 0x95, 0xd7, 0xcc, 0x57, 0x3e, 0xb4, 0x5b, + 0xca, 0x1c, 0xb2, 0xaf, 0xd2, 0x21, 0x13, 0x09, 0xc0, 0x81, 0x47, 0xfa, 0xf0, 0xc1, 0xa6, 0xf2, + 0xfc, 0x0b, 0x7d, 0xe6, 0xf9, 0x3f, 0x09, 0xe5, 0x56, 0xe0, 0xb9, 0x35, 0x57, 0x95, 0xf7, 0x65, + 0x95, 0x05, 0x56, 0x45, 0x1b, 0x56, 0x50, 0x74, 0x0b, 0x2a, 0x37, 0x6f, 0xc5, 0xfc, 0xf4, 0x47, + 0xf8, 0xb7, 0xf3, 0x3a, 0xf4, 0x51, 0x46, 0x8b, 0x3a, 0x5e, 0xc2, 0x9a, 0x17, 0xb2, 0x61, 0x90, + 0x29, 0x41, 0x99, 0x0c, 0xc4, 0x7c, 0xef, 0x4c, 0x3b, 0x46, 0x58, 0x40, 0xec, 0x2f, 0x57, 0xe0, + 0x74, 0xd6, 0xc5, 0x21, 0xe8, 0xfd, 0x30, 0xc8, 0xfb, 0x98, 0xcf, 0xdd, 0x54, 0x59, 0x3c, 0x16, + 0x18, 0x41, 0xd1, 0x2d, 0xf6, 0x1b, 0x0b, 0x9e, 0x82, 0xbb, 0xe7, 0xac, 0x8b, 0x19, 0x72, 0x34, + 0xdc, 0x97, 0x1c, 0xcd, 0x7d, 0xc9, 0xe1, 0xdc, 0x3d, 0x67, 0x1d, 0xed, 0x40, 0xa9, 0xe1, 0xc6, + 0xc4, 0x11, 0x4e, 0x84, 0x1b, 0x47, 0xc2, 0x9c, 0x38, 0xdc, 0x4a, 0x63, 0x3f, 0x31, 0x67, 0x88, + 0xbe, 0x64, 0xc1, 0xf8, 0x7a, 0xb2, 0xc0, 0x88, 0x10, 0x9e, 0xce, 0x11, 0x5c, 0x0e, 0x93, 0x64, + 0xc4, 0xef, 0x7b, 0x4c, 0x35, 0xe2, 0x74, 0x77, 0xd0, 0x47, 0x2c, 0x18, 0xda, 0x70, 0x3d, 0xa3, + 0xfa, 0xfe, 0x11, 0x7c, 0x9c, 0x8b, 0x8c, 0x81, 0xde, 0x71, 0xf0, 0xff, 0x11, 0x96, 0x9c, 0x7b, + 0x69, 0xaa, 0xc1, 0xc3, 0x6a, 0xaa, 0xa1, 0x7b, 0xa4, 0xa9, 0x3e, 0x6e, 0x41, 0x45, 0x8d, 0xb4, + 0x28, 0xd4, 0xf0, 0x9e, 0x23, 0xfc, 0xe4, 0xdc, 0x73, 0xa2, 0xfe, 0x62, 0xcd, 0x1c, 0x7d, 0xd6, + 0x82, 0x61, 0xe7, 0xb5, 0x76, 0x48, 0xea, 0x64, 0x3b, 0x68, 0x45, 0xa2, 0x7c, 0xe2, 0xcb, 0xf9, + 0x77, 0x66, 0x86, 0x32, 0x99, 0x27, 0xdb, 0x2b, 0xad, 0x48, 0x24, 0x2a, 0xea, 0x06, 0x6c, 0x76, + 0xc1, 0xde, 0x2d, 0xc0, 0xe4, 0x3e, 0x14, 0xd0, 0xf3, 0x30, 0x12, 0x84, 0x0d, 0xc7, 0x77, 0x5f, + 0x33, 0x2b, 0x06, 0x29, 0x2b, 0x6b, 0xc5, 0x80, 0xe1, 0x04, 0xa6, 0x59, 0x4a, 0xa2, 0xb0, 0x4f, + 0x29, 0x89, 0x73, 0x30, 0x10, 0x92, 0x56, 0x90, 0xde, 0x2c, 0xb0, 0x24, 0x21, 0x06, 0x41, 0x8f, + 0x42, 0xd1, 0x69, 0xb9, 0x22, 0xb4, 0x44, 0xed, 0x81, 0x66, 0x56, 0x17, 0x31, 0x6d, 0x4f, 0x54, + 0xb6, 0x29, 0x1d, 0x4b, 0x65, 0x1b, 0xaa, 0x06, 0xc4, 0xd9, 0xc5, 0xa0, 0x56, 0x03, 0xc9, 0x33, + 0x05, 0xfb, 0xf5, 0x22, 0x3c, 0xba, 0xe7, 0x7c, 0xd1, 0x71, 0xa6, 0xd6, 0x1e, 0x71, 0xa6, 0x72, + 0x78, 0x0a, 0xfb, 0x0d, 0x4f, 0xb1, 0xc7, 0xf0, 0x7c, 0x84, 0x2e, 0x03, 0x59, 0x69, 0x29, 0x9f, + 0xeb, 0x7e, 0x7b, 0x15, 0x6e, 0x12, 0x2b, 0x40, 0x42, 0xb1, 0xe6, 0x4b, 0xf7, 0x00, 0x89, 0x32, + 0x0a, 0xa5, 0x3c, 0xd4, 0x40, 0xcf, 0x6a, 0x47, 0x7c, 0xee, 0xf7, 0xaa, 0xcd, 0x60, 0xff, 0xf6, + 0x00, 0x3c, 0xde, 0x87, 0xf4, 0x36, 0x67, 0xb1, 0xd5, 0xe7, 0x2c, 0xfe, 0x1e, 0xff, 0x4c, 0x1f, + 0xcb, 0xfc, 0x4c, 0x38, 0xff, 0xcf, 0xb4, 0xf7, 0x17, 0x42, 0x4f, 0x41, 0xd9, 0xf5, 0x23, 0x52, + 0x6b, 0x87, 0x3c, 0xe6, 0xde, 0xc8, 0x20, 0x5c, 0x14, 0xed, 0x58, 0x61, 0xd0, 0x3d, 0x5d, 0xcd, + 0xa1, 0xcb, 0x7f, 0x28, 0xa7, 0xb4, 0x79, 0x33, 0x19, 0x91, 0x9b, 0x14, 0x73, 0x33, 0x54, 0x02, + 0x70, 0x36, 0xf6, 0xdf, 0xb5, 0xe0, 0x6c, 0x6f, 0x15, 0x8b, 0x9e, 0x81, 0xe1, 0x75, 0x16, 0xb8, + 0xc5, 0x2e, 0x7a, 0x97, 0x53, 0x87, 0xbd, 0xaf, 0x6e, 0xc6, 0x26, 0x0e, 0x9a, 0x83, 0x93, 0x66, + 0xc4, 0xd7, 0xb2, 0x11, 0x55, 0xc2, 0x9c, 0x00, 0x6b, 0x69, 0x20, 0xee, 0xc6, 0xb7, 0xbf, 0x5b, + 0xcc, 0xee, 0x16, 0x37, 0xc5, 0x0e, 0x32, 0x9b, 0xc5, 0x5c, 0x2d, 0xf4, 0x21, 0x71, 0x8b, 0xc7, + 0x2d, 0x71, 0x07, 0x7a, 0x49, 0x5c, 0x34, 0x0f, 0x27, 0x8c, 0x9b, 0xf8, 0x78, 0x21, 0x05, 0x1e, + 0x65, 0xa8, 0xaa, 0x20, 0xad, 0xa6, 0xe0, 0xb8, 0xeb, 0x89, 0xfb, 0x7c, 0xea, 0xfd, 0x6a, 0x01, + 0x1e, 0xea, 0x69, 0xfd, 0x1e, 0x93, 0x46, 0x31, 0x3f, 0xff, 0xc0, 0xf1, 0x7c, 0x7e, 0xf3, 0xa3, + 0x94, 0xf6, 0xfb, 0x28, 0xf6, 0x1f, 0x17, 0x7a, 0x2e, 0x04, 0xba, 0x13, 0xfa, 0xbe, 0x1d, 0xa5, + 0x17, 0x60, 0xd4, 0x69, 0xb5, 0x38, 0x1e, 0x8b, 0xd8, 0x4e, 0x55, 0x5d, 0x9b, 0x31, 0x81, 0x38, + 0x89, 0xdb, 0x97, 0x4d, 0xf3, 0xa7, 0x16, 0x54, 0x30, 0xd9, 0xe0, 0xd2, 0x08, 0xdd, 0x14, 0x43, + 0x64, 0xe5, 0x51, 0xf7, 0x9a, 0x0e, 0x6c, 0xe4, 0xb2, 0x7a, 0xd0, 0x59, 0x83, 0x7d, 0xd8, 0xbc, + 0x65, 0x75, 0x37, 0x5f, 0xb1, 0xf7, 0xdd, 0x7c, 0xf6, 0xb7, 0x87, 0xe8, 0xeb, 0xb5, 0x82, 0xb9, + 0x90, 0xd4, 0x23, 0xfa, 0x7d, 0xdb, 0xa1, 0x27, 0x26, 0x89, 0xfa, 0xbe, 0xd7, 0xf0, 0x12, 0xa6, + 0xed, 0x89, 0x03, 0xb2, 0xc2, 0x81, 0x6a, 0x4e, 0x15, 0xf7, 0xad, 0x39, 0xf5, 0x02, 0x8c, 0x46, + 0xd1, 0xe6, 0x6a, 0xe8, 0x6e, 0x3b, 0x31, 0xb9, 0x42, 0x3a, 0xc2, 0xf6, 0xd5, 0xf5, 0x57, 0xaa, + 0x97, 0x34, 0x10, 0x27, 0x71, 0xd1, 0x02, 0x9c, 0xd4, 0x95, 0x9f, 0x48, 0x18, 0xb3, 0x9c, 0x22, + 0x3e, 0x13, 0x54, 0xb1, 0x05, 0x5d, 0x2b, 0x4a, 0x20, 0xe0, 0xee, 0x67, 0xa8, 0x3c, 0x4d, 0x34, + 0xd2, 0x8e, 0x0c, 0x26, 0xe5, 0x69, 0x82, 0x0e, 0xed, 0x4b, 0xd7, 0x13, 0x68, 0x19, 0x4e, 0xf1, + 0x89, 0x31, 0xd3, 0x6a, 0x19, 0x6f, 0x34, 0x94, 0xac, 0x37, 0xbc, 0xd0, 0x8d, 0x82, 0xb3, 0x9e, + 0x43, 0xcf, 0xc1, 0xb0, 0x6a, 0x5e, 0x9c, 0x17, 0x67, 0x3b, 0xca, 0xb7, 0xa4, 0xc8, 0x2c, 0xd6, + 0xb1, 0x89, 0x87, 0xde, 0x0d, 0x0f, 0xea, 0xbf, 0x3c, 0xf1, 0x94, 0x1f, 0x78, 0xce, 0x8b, 0xa2, + 0x7a, 0xea, 0x9e, 0xb7, 0x85, 0x4c, 0xb4, 0x3a, 0xee, 0xf5, 0x3c, 0x5a, 0x87, 0xb3, 0x0a, 0x74, + 0xc1, 0x8f, 0x59, 0x16, 0x59, 0x44, 0x66, 0x9d, 0x88, 0x5c, 0x0b, 0x3d, 0x56, 0x86, 0xaf, 0xa2, + 0x2f, 0x0b, 0x5f, 0x70, 0xe3, 0x4b, 0x59, 0x98, 0x78, 0x09, 0xef, 0x41, 0x05, 0x4d, 0x43, 0x85, + 0xf8, 0xce, 0xba, 0x47, 0x56, 0xe6, 0x16, 0x59, 0x71, 0x3e, 0xe3, 0x7c, 0xf5, 0x82, 0x04, 0x60, + 0x8d, 0xa3, 0xe2, 0x7e, 0x47, 0x7a, 0x5e, 0x5c, 0xbf, 0x0a, 0xa7, 0x1b, 0xb5, 0x16, 0xb5, 0x08, + 0xdd, 0x1a, 0x99, 0xa9, 0xb1, 0x30, 0x47, 0xfa, 0x61, 0x78, 0x21, 0x68, 0x95, 0x40, 0xb1, 0x30, + 0xb7, 0xda, 0x85, 0x83, 0x33, 0x9f, 0x64, 0xe1, 0xb0, 0x61, 0xb0, 0xd3, 0x99, 0x38, 0x95, 0x0a, + 0x87, 0xa5, 0x8d, 0x98, 0xc3, 0xd0, 0x65, 0x40, 0x2c, 0x1b, 0xe7, 0x52, 0x1c, 0xb7, 0x94, 0x09, + 0x3a, 0x71, 0x3a, 0x59, 0x62, 0xeb, 0x62, 0x17, 0x06, 0xce, 0x78, 0x8a, 0x5a, 0x34, 0x7e, 0xc0, + 0xa8, 0x4f, 0x3c, 0x98, 0xb4, 0x68, 0xae, 0xf2, 0x66, 0x2c, 0xe1, 0xf6, 0x9f, 0x58, 0x30, 0xaa, + 0x96, 0xf6, 0x31, 0xa4, 0xcb, 0x79, 0xc9, 0x74, 0xb9, 0x85, 0xc3, 0x0b, 0x47, 0xd6, 0xf3, 0x1e, + 0x31, 0xe9, 0x5f, 0x1b, 0x06, 0xd0, 0x02, 0x54, 0xe9, 0x2e, 0xab, 0xa7, 0xee, 0xba, 0x6f, 0x85, + 0x57, 0x56, 0x31, 0xac, 0xd2, 0xbd, 0x2d, 0x86, 0x55, 0x85, 0x33, 0xd2, 0xb2, 0xe0, 0x87, 0x7d, + 0x97, 0x82, 0x48, 0xc9, 0xc2, 0xf2, 0xec, 0xa3, 0x82, 0xd0, 0x99, 0xc5, 0x2c, 0x24, 0x9c, 0xfd, + 0x6c, 0xc2, 0xa0, 0x19, 0xda, 0xd7, 0xca, 0x54, 0xcb, 0x7f, 0x69, 0x43, 0xde, 0x6e, 0x96, 0x5a, + 0xfe, 0x4b, 0x17, 0xab, 0x58, 0xe3, 0x64, 0xeb, 0x80, 0x4a, 0x4e, 0x3a, 0x00, 0x0e, 0xac, 0x03, + 0xa4, 0x34, 0x1a, 0xee, 0x29, 0x8d, 0xe4, 0xa1, 0xc2, 0x48, 0xcf, 0x43, 0x85, 0x77, 0xc0, 0x98, + 0xeb, 0x6f, 0x92, 0xd0, 0x8d, 0x49, 0x9d, 0xad, 0x05, 0x26, 0xa9, 0xca, 0xda, 0x02, 0x58, 0x4c, + 0x40, 0x71, 0x0a, 0x3b, 0x29, 0x42, 0xc7, 0xfa, 0x10, 0xa1, 0x3d, 0x14, 0xd7, 0x78, 0x3e, 0x8a, + 0xeb, 0xc4, 0xe1, 0x15, 0xd7, 0xc9, 0x23, 0x55, 0x5c, 0x28, 0x17, 0xc5, 0xd5, 0x97, 0x4e, 0x30, + 0x76, 0xa6, 0xa7, 0xf7, 0xd9, 0x99, 0xf6, 0xd2, 0x5a, 0x67, 0xee, 0x5a, 0x6b, 0x65, 0x2b, 0xa4, + 0x07, 0x8e, 0x5a, 0x21, 0x7d, 0xbc, 0x00, 0x67, 0xb4, 0xc8, 0xa6, 0x0b, 0xc5, 0xdd, 0xa0, 0x42, + 0x8b, 0xdd, 0xa5, 0xc9, 0xcf, 0xe8, 0x8c, 0xa4, 0x4b, 0x9d, 0xbf, 0xa9, 0x20, 0xd8, 0xc0, 0x62, + 0xb9, 0x8b, 0x24, 0x64, 0x85, 0xe7, 0xd3, 0xf2, 0x7c, 0x4e, 0xb4, 0x63, 0x85, 0x41, 0xa7, 0x22, + 0xfd, 0x2d, 0x72, 0xd0, 0xd3, 0x25, 0x4d, 0xe7, 0x34, 0x08, 0x9b, 0x78, 0xe8, 0x49, 0xce, 0x84, + 0xc9, 0x12, 0x2a, 0xd3, 0x47, 0xf8, 0x46, 0x44, 0x89, 0x0f, 0x05, 0x95, 0xdd, 0x61, 0x49, 0xaa, + 0xa5, 0xee, 0xee, 0xb0, 0x70, 0x37, 0x85, 0x61, 0xff, 0x4f, 0x0b, 0x1e, 0xca, 0x1c, 0x8a, 0x63, + 0xd0, 0xd3, 0x3b, 0x49, 0x3d, 0x5d, 0xcd, 0x6b, 0x13, 0x63, 0xbc, 0x45, 0x0f, 0x9d, 0xfd, 0x9f, + 0x2c, 0x18, 0xd3, 0xf8, 0xc7, 0xf0, 0xaa, 0x6e, 0xf2, 0x55, 0xf3, 0xdb, 0xaf, 0x55, 0xba, 0xde, + 0xed, 0xf7, 0x0a, 0xa0, 0xca, 0x0c, 0xcf, 0xd4, 0x64, 0x11, 0xf7, 0x7d, 0x4e, 0x8d, 0x3b, 0x30, + 0xc8, 0x0e, 0xbd, 0xa3, 0x7c, 0x02, 0x7a, 0x92, 0xfc, 0xd9, 0x01, 0xba, 0x0e, 0x28, 0x60, 0x7f, + 0x23, 0x2c, 0x18, 0xb2, 0x6b, 0x11, 0x78, 0x05, 0xd7, 0xba, 0x48, 0xc1, 0xd3, 0xd7, 0x22, 0x88, + 0x76, 0xac, 0x30, 0xa8, 0x26, 0x71, 0x6b, 0x81, 0x3f, 0xe7, 0x39, 0x91, 0xbc, 0x5e, 0x5b, 0x69, + 0x92, 0x45, 0x09, 0xc0, 0x1a, 0x87, 0x9d, 0x87, 0xbb, 0x51, 0xcb, 0x73, 0x3a, 0xc6, 0xae, 0xdc, + 0xa8, 0xb5, 0xa2, 0x40, 0xd8, 0xc4, 0xb3, 0x9b, 0x30, 0x91, 0x7c, 0x89, 0x79, 0xb2, 0xc1, 0x82, + 0x51, 0xfb, 0x1a, 0xce, 0x69, 0xa8, 0x38, 0xec, 0xa9, 0xa5, 0xb6, 0x23, 0x64, 0x82, 0x0e, 0xc9, + 0x94, 0x00, 0xac, 0x71, 0xec, 0x7f, 0x6a, 0xc1, 0xa9, 0x8c, 0x41, 0xcb, 0x31, 0xc5, 0x31, 0xd6, + 0xd2, 0x26, 0xcb, 0x06, 0xf8, 0x21, 0x18, 0xaa, 0x93, 0x0d, 0x47, 0x86, 0x3b, 0x1a, 0xd2, 0x73, + 0x9e, 0x37, 0x63, 0x09, 0xb7, 0x7f, 0xab, 0x00, 0xe3, 0xc9, 0xbe, 0x46, 0x2c, 0x6d, 0x88, 0x0f, + 0x93, 0x1b, 0xd5, 0x82, 0x6d, 0x12, 0x76, 0xe8, 0x9b, 0x5b, 0xa9, 0xb4, 0xa1, 0x2e, 0x0c, 0x9c, + 0xf1, 0x14, 0x2b, 0x32, 0x5e, 0x57, 0xa3, 0x2d, 0x67, 0xe4, 0xf5, 0x3c, 0x67, 0xa4, 0xfe, 0x98, + 0x66, 0x68, 0x84, 0x62, 0x89, 0x4d, 0xfe, 0xd4, 0x16, 0x61, 0x71, 0xd8, 0xb3, 0x6d, 0xd7, 0x8b, + 0x5d, 0x5f, 0xbc, 0xb2, 0x98, 0xab, 0xca, 0x16, 0x59, 0xee, 0x46, 0xc1, 0x59, 0xcf, 0xd9, 0xdf, + 0x19, 0x00, 0x95, 0xbe, 0xcf, 0x42, 0xd7, 0x72, 0x0a, 0xfc, 0x3b, 0x68, 0xf2, 0x99, 0x9a, 0x5b, + 0x03, 0x7b, 0xc5, 0x92, 0x70, 0x57, 0x8e, 0xe9, 0xcf, 0x55, 0x03, 0xb6, 0xa6, 0x41, 0xd8, 0xc4, + 0xa3, 0x3d, 0xf1, 0xdc, 0x6d, 0xc2, 0x1f, 0x1a, 0x4c, 0xf6, 0x64, 0x49, 0x02, 0xb0, 0xc6, 0xa1, + 0x3d, 0xa9, 0xbb, 0x1b, 0x1b, 0xc2, 0x2f, 0xa1, 0x7a, 0x42, 0x47, 0x07, 0x33, 0x08, 0xbf, 0x86, + 0x22, 0xd8, 0x12, 0xf6, 0xb7, 0x71, 0x0d, 0x45, 0xb0, 0x85, 0x19, 0x84, 0x7e, 0x25, 0x3f, 0x08, + 0x9b, 0x8e, 0xe7, 0xbe, 0x46, 0xea, 0x8a, 0x8b, 0xb0, 0xbb, 0xd5, 0x57, 0xba, 0xda, 0x8d, 0x82, + 0xb3, 0x9e, 0xa3, 0x13, 0xba, 0x15, 0x92, 0xba, 0x5b, 0x8b, 0x4d, 0x6a, 0x90, 0x9c, 0xd0, 0xab, + 0x5d, 0x18, 0x38, 0xe3, 0x29, 0x34, 0x03, 0xe3, 0xb2, 0xfc, 0x82, 0x2c, 0xe8, 0x35, 0x9c, 0x2c, + 0x20, 0x84, 0x93, 0x60, 0x9c, 0xc6, 0xa7, 0x42, 0xb2, 0x29, 0xca, 0x11, 0x32, 0x33, 0xdd, 0x10, + 0x92, 0xb2, 0x4c, 0x21, 0x56, 0x18, 0xf6, 0x87, 0x8b, 0x54, 0xa9, 0xf7, 0xa8, 0xfa, 0x79, 0x6c, + 0x81, 0xa6, 0xc9, 0x19, 0x39, 0xd0, 0xc7, 0x8c, 0x7c, 0x16, 0x46, 0x6e, 0x46, 0x81, 0xaf, 0x82, + 0x38, 0x4b, 0x3d, 0x83, 0x38, 0x0d, 0xac, 0xec, 0x20, 0xce, 0xc1, 0xbc, 0x82, 0x38, 0x87, 0xee, + 0x32, 0x88, 0xf3, 0x0f, 0x4a, 0xa0, 0xee, 0x19, 0xbb, 0x4a, 0xe2, 0x5b, 0x41, 0xb8, 0xe5, 0xfa, + 0x0d, 0x56, 0x4a, 0xe0, 0x4b, 0x96, 0xac, 0x46, 0xb0, 0x64, 0x26, 0xe1, 0x6d, 0xe4, 0x74, 0x57, + 0x54, 0x82, 0xd9, 0xd4, 0x9a, 0xc1, 0x28, 0x75, 0x1d, 0xba, 0x09, 0xc2, 0x89, 0x1e, 0xa1, 0x0f, + 0x00, 0x48, 0x27, 0xee, 0x86, 0x94, 0xc0, 0x8b, 0xf9, 0xf4, 0x0f, 0x93, 0x0d, 0x6d, 0x52, 0xaf, + 0x29, 0x26, 0xd8, 0x60, 0x88, 0x3e, 0xae, 0x13, 0x14, 0x79, 0xb6, 0xc7, 0xfb, 0x8e, 0x64, 0x6c, + 0xfa, 0x49, 0x4f, 0xc4, 0x30, 0xe4, 0xfa, 0x0d, 0x3a, 0x4f, 0x44, 0xb0, 0xdb, 0x5b, 0xb2, 0x4a, + 0xbe, 0x2c, 0x05, 0x4e, 0x7d, 0xd6, 0xf1, 0x1c, 0xbf, 0x46, 0xc2, 0x45, 0x8e, 0xae, 0x35, 0xa8, + 0x68, 0xc0, 0x92, 0x50, 0xd7, 0x65, 0x68, 0xa5, 0x7e, 0x2e, 0x43, 0x3b, 0xfb, 0x4e, 0x38, 0xd9, + 0xf5, 0x31, 0x0f, 0x94, 0x8d, 0x78, 0xf7, 0x89, 0x8c, 0xf6, 0x6f, 0x0f, 0x6a, 0xa5, 0x75, 0x35, + 0xa8, 0xf3, 0xbb, 0xb5, 0x42, 0xfd, 0x45, 0x85, 0xc9, 0x9c, 0xe3, 0x14, 0x51, 0x6a, 0xc6, 0x68, + 0xc4, 0x26, 0x4b, 0x3a, 0x47, 0x5b, 0x4e, 0x48, 0xfc, 0xa3, 0x9e, 0xa3, 0xab, 0x8a, 0x09, 0x36, + 0x18, 0xa2, 0xcd, 0x44, 0x3a, 0xd2, 0xc5, 0xc3, 0xa7, 0x23, 0xb1, 0x02, 0x7c, 0x59, 0x57, 0xd0, + 0x7c, 0xd6, 0x82, 0x31, 0x3f, 0x31, 0x73, 0xf3, 0x89, 0x40, 0xce, 0x5e, 0x15, 0xfc, 0x9a, 0xca, + 0x64, 0x1b, 0x4e, 0xf1, 0xcf, 0x52, 0x69, 0xa5, 0x03, 0xaa, 0x34, 0x7d, 0xb7, 0xdf, 0x60, 0xaf, + 0xbb, 0xfd, 0x90, 0xaf, 0x6e, 0x5c, 0x1d, 0xca, 0xfd, 0xc6, 0x55, 0xc8, 0xb8, 0x6d, 0xf5, 0x06, + 0x54, 0x6a, 0x21, 0x71, 0xe2, 0xbb, 0xbc, 0x7c, 0x93, 0xc5, 0x76, 0xcc, 0x49, 0x02, 0x58, 0xd3, + 0xb2, 0xff, 0xcf, 0x00, 0x9c, 0x90, 0x23, 0x22, 0xb3, 0x17, 0xa8, 0x7e, 0xe4, 0x7c, 0xb5, 0xad, + 0xac, 0xf4, 0xe3, 0x25, 0x09, 0xc0, 0x1a, 0x87, 0xda, 0x63, 0xed, 0x88, 0xac, 0xb4, 0x88, 0xbf, + 0xe4, 0xae, 0x47, 0xe2, 0x30, 0x56, 0x2d, 0x94, 0x6b, 0x1a, 0x84, 0x4d, 0x3c, 0x6a, 0xdb, 0x3b, + 0x86, 0xd1, 0x6a, 0xd8, 0xf6, 0xd2, 0x50, 0x95, 0x70, 0xf4, 0x4b, 0x99, 0x65, 0xc8, 0xf3, 0xc9, + 0xf9, 0xeb, 0x4a, 0xda, 0x38, 0xe0, 0xd5, 0xd1, 0xff, 0xc8, 0x82, 0x33, 0xbc, 0x55, 0x8e, 0xe4, + 0xb5, 0x56, 0xdd, 0x89, 0x49, 0x94, 0xcf, 0xf5, 0x25, 0x19, 0xfd, 0xd3, 0xee, 0xe5, 0x2c, 0xb6, + 0x38, 0xbb, 0x37, 0xe8, 0x33, 0x16, 0x8c, 0x6f, 0x25, 0xca, 0xc5, 0x48, 0xd5, 0x71, 0xd8, 0x4a, + 0x0e, 0x09, 0xa2, 0x7a, 0xa9, 0x25, 0xdb, 0x23, 0x9c, 0xe6, 0x6e, 0xff, 0x0f, 0x0b, 0x4c, 0x31, + 0x7a, 0xfc, 0x55, 0x66, 0x0e, 0x6e, 0x0a, 0x4a, 0xeb, 0xb2, 0xd4, 0xd3, 0xba, 0x7c, 0x14, 0x8a, + 0x6d, 0xb7, 0x2e, 0xf6, 0x17, 0xfa, 0x88, 0x78, 0x71, 0x1e, 0xd3, 0x76, 0xfb, 0x5f, 0x95, 0xb4, + 0x1b, 0x44, 0xa4, 0xd4, 0x7d, 0x5f, 0xbc, 0xf6, 0x86, 0xaa, 0xc3, 0xc8, 0xdf, 0xfc, 0x6a, 0x57, + 0x1d, 0xc6, 0x1f, 0x3f, 0x78, 0xc6, 0x24, 0x1f, 0xa0, 0x5e, 0x65, 0x18, 0x87, 0xf6, 0x49, 0x97, + 0xbc, 0x09, 0x65, 0xba, 0x05, 0x63, 0xfe, 0xcc, 0x72, 0xa2, 0x53, 0xe5, 0x4b, 0xa2, 0xfd, 0xce, + 0xee, 0xe4, 0x8f, 0x1d, 0xbc, 0x5b, 0xf2, 0x69, 0xac, 0xe8, 0xa3, 0x08, 0x2a, 0xf4, 0x37, 0xcb, + 0xec, 0x14, 0x9b, 0xbb, 0x6b, 0x4a, 0x66, 0x4a, 0x40, 0x2e, 0x69, 0xa3, 0x9a, 0x0f, 0xf2, 0xa1, + 0xc2, 0x6e, 0xd9, 0x67, 0x4c, 0xf9, 0x1e, 0x70, 0x55, 0xe5, 0x57, 0x4a, 0xc0, 0x9d, 0xdd, 0xc9, + 0x17, 0x0e, 0xce, 0x54, 0x3d, 0x8e, 0x35, 0x0b, 0xfb, 0x6f, 0x06, 0xf4, 0xdc, 0x15, 0xe5, 0x37, + 0xbf, 0x2f, 0xe6, 0xee, 0xf3, 0xa9, 0xb9, 0x7b, 0xae, 0x6b, 0xee, 0x8e, 0xe9, 0x2b, 0xd8, 0x13, + 0xb3, 0xf1, 0xb8, 0x0d, 0x81, 0xfd, 0xfd, 0x0d, 0xcc, 0x02, 0x7a, 0xb5, 0xed, 0x86, 0x24, 0x5a, + 0x0d, 0xdb, 0xbe, 0xeb, 0x37, 0xd8, 0x74, 0x2c, 0x9b, 0x16, 0x50, 0x02, 0x8c, 0xd3, 0xf8, 0x74, + 0x53, 0x4f, 0xbf, 0xf9, 0x0d, 0x67, 0x9b, 0xcf, 0x2a, 0xa3, 0x62, 0x5b, 0x55, 0xb4, 0x63, 0x85, + 0x81, 0x36, 0xe1, 0x11, 0x49, 0x60, 0x9e, 0x78, 0x44, 0xdc, 0xa1, 0xbe, 0xe1, 0x86, 0x4d, 0x1e, + 0x20, 0xce, 0x23, 0x13, 0xde, 0x2c, 0x28, 0x3c, 0x82, 0xf7, 0xc0, 0xc5, 0x7b, 0x52, 0xb2, 0xbf, + 0xca, 0xce, 0xeb, 0x8d, 0xe4, 0x75, 0x3a, 0xfb, 0x3c, 0xb7, 0xe9, 0xca, 0xc2, 0x72, 0x6a, 0xf6, + 0x2d, 0xd1, 0x46, 0xcc, 0x61, 0xe8, 0x16, 0x0c, 0xad, 0xf3, 0xab, 0x6e, 0xf3, 0xb9, 0x56, 0x43, + 0xdc, 0x9b, 0xcb, 0xaa, 0xb3, 0xca, 0x4b, 0x74, 0xef, 0xe8, 0x9f, 0x58, 0x72, 0xb3, 0xbf, 0x51, + 0x82, 0xf1, 0xd4, 0xbd, 0xf6, 0x89, 0x92, 0xd5, 0x85, 0x7d, 0x4b, 0x56, 0xbf, 0x17, 0xa0, 0x4e, + 0x5a, 0x5e, 0xd0, 0x61, 0x86, 0xdf, 0xc0, 0x81, 0x0d, 0x3f, 0xb5, 0x57, 0x98, 0x57, 0x54, 0xb0, + 0x41, 0x51, 0x54, 0xd3, 0xe3, 0x15, 0xb0, 0x53, 0xd5, 0xf4, 0x8c, 0xcb, 0x77, 0x06, 0x8f, 0xf7, + 0xf2, 0x1d, 0x17, 0xc6, 0x79, 0x17, 0x55, 0x8a, 0xf8, 0x5d, 0x64, 0x82, 0xb3, 0x24, 0x9b, 0xf9, + 0x24, 0x19, 0x9c, 0xa6, 0x6b, 0xde, 0xac, 0x53, 0x3e, 0xee, 0x9b, 0x75, 0xde, 0x0a, 0x15, 0xf9, + 0x9d, 0xa3, 0x89, 0x8a, 0x2e, 0xb3, 0x21, 0xa7, 0x41, 0x84, 0x35, 0xbc, 0xab, 0xda, 0x05, 0xdc, + 0xab, 0x6a, 0x17, 0xf6, 0xa7, 0x0b, 0x74, 0xc7, 0xc0, 0xfb, 0xa5, 0x0a, 0x37, 0x3d, 0x01, 0x83, + 0x4e, 0x3b, 0xde, 0x0c, 0xba, 0x2e, 0xcb, 0x9d, 0x61, 0xad, 0x58, 0x40, 0xd1, 0x12, 0x0c, 0xd4, + 0x75, 0x31, 0x9e, 0x83, 0x7c, 0x4f, 0xed, 0x7c, 0x75, 0x62, 0x82, 0x19, 0x15, 0xf4, 0x08, 0x0c, + 0xc4, 0x4e, 0x43, 0xe6, 0x05, 0xb2, 0x5c, 0xf0, 0x35, 0xa7, 0x11, 0x61, 0xd6, 0x7a, 0x90, 0x02, + 0xa4, 0x2f, 0xc0, 0x68, 0xe4, 0x36, 0x7c, 0x27, 0x6e, 0x87, 0xc4, 0x38, 0x9f, 0xd4, 0xd1, 0x29, + 0x26, 0x10, 0x27, 0x71, 0xed, 0xdf, 0x19, 0x81, 0xd3, 0xd5, 0xb9, 0x65, 0x79, 0x85, 0xc2, 0x91, + 0xa5, 0xf6, 0x65, 0xf1, 0x38, 0xbe, 0xd4, 0xbe, 0x1e, 0xdc, 0x3d, 0x23, 0xb5, 0xcf, 0x33, 0x52, + 0xfb, 0x92, 0x79, 0x56, 0xc5, 0x3c, 0xf2, 0xac, 0xb2, 0x7a, 0xd0, 0x4f, 0x9e, 0xd5, 0x91, 0xe5, + 0xfa, 0xed, 0xd9, 0xa1, 0x03, 0xe5, 0xfa, 0xa9, 0x44, 0xc8, 0x5c, 0x32, 0x60, 0x7a, 0x7c, 0xaa, + 0xcc, 0x44, 0x48, 0x95, 0x84, 0xc6, 0xb3, 0xbb, 0x84, 0xa8, 0x7f, 0x39, 0xff, 0x0e, 0xf4, 0x91, + 0x84, 0x26, 0x12, 0xcc, 0xcc, 0xc4, 0xc7, 0xa1, 0x3c, 0x12, 0x1f, 0xb3, 0xba, 0xb3, 0x6f, 0xe2, + 0xe3, 0x0b, 0x30, 0x5a, 0xf3, 0x02, 0x9f, 0xac, 0x86, 0x41, 0x1c, 0xd4, 0x02, 0x79, 0x5d, 0xa7, + 0xbe, 0x6d, 0xca, 0x04, 0xe2, 0x24, 0x6e, 0xaf, 0xac, 0xc9, 0xca, 0x61, 0xb3, 0x26, 0xe1, 0x1e, + 0x65, 0x4d, 0xfe, 0xac, 0xce, 0xef, 0x1f, 0x66, 0x5f, 0xe4, 0xbd, 0xf9, 0x7f, 0x91, 0xbe, 0xee, + 0xe3, 0x7c, 0x9d, 0xdf, 0x56, 0x4b, 0x4d, 0xf0, 0xb9, 0xa0, 0x49, 0x0d, 0xbf, 0x11, 0x36, 0x24, + 0xaf, 0x1c, 0xc1, 0x84, 0xbd, 0x51, 0xd5, 0x6c, 0xd4, 0x0d, 0xb6, 0xba, 0x09, 0x27, 0x3b, 0x72, + 0x98, 0xfa, 0x03, 0x5f, 0x28, 0xc0, 0x0f, 0xec, 0xdb, 0x05, 0x74, 0x0b, 0x20, 0x76, 0x1a, 0x62, + 0xa2, 0x8a, 0xa3, 0x99, 0x43, 0x86, 0x90, 0xae, 0x49, 0x7a, 0xbc, 0x70, 0x8e, 0xfa, 0xcb, 0x0e, + 0x3d, 0xe4, 0x6f, 0x16, 0x39, 0x1a, 0x78, 0x5d, 0xf5, 0x45, 0x71, 0xe0, 0x11, 0xcc, 0x20, 0x54, + 0xfd, 0x87, 0xa4, 0x41, 0x4d, 0xda, 0x62, 0x52, 0xfd, 0x63, 0xd6, 0x8a, 0x05, 0x14, 0x3d, 0x07, + 0xc3, 0x8e, 0xe7, 0xf1, 0xf4, 0x24, 0x12, 0x89, 0x6b, 0xe0, 0x74, 0xa1, 0x43, 0x0d, 0xc2, 0x26, + 0x9e, 0xfd, 0x57, 0x05, 0x98, 0xdc, 0x47, 0xa6, 0x74, 0xa5, 0xa5, 0x96, 0xfa, 0x4e, 0x4b, 0x15, + 0x29, 0x1b, 0x83, 0x3d, 0x52, 0x36, 0x9e, 0x83, 0xe1, 0x98, 0x38, 0x4d, 0x11, 0x74, 0x26, 0x7c, + 0x0e, 0xfa, 0xac, 0x59, 0x83, 0xb0, 0x89, 0x47, 0xa5, 0xd8, 0x98, 0x53, 0xab, 0x91, 0x28, 0x92, + 0x39, 0x19, 0xc2, 0x6f, 0x9b, 0x5b, 0xc2, 0x07, 0x73, 0x87, 0xcf, 0x24, 0x58, 0xe0, 0x14, 0xcb, + 0xf4, 0x80, 0x57, 0xfa, 0x1c, 0xf0, 0x2f, 0x17, 0xe0, 0xd1, 0x3d, 0xb5, 0x5b, 0xdf, 0xe9, 0x32, + 0xed, 0x88, 0x84, 0xe9, 0x89, 0x73, 0x2d, 0x22, 0x21, 0x66, 0x10, 0x3e, 0x4a, 0xad, 0x96, 0x0a, + 0x18, 0xce, 0x3f, 0x77, 0x8c, 0x8f, 0x52, 0x82, 0x05, 0x4e, 0xb1, 0xbc, 0xdb, 0x69, 0xf9, 0x8d, + 0x01, 0x78, 0xbc, 0x0f, 0x1b, 0x20, 0xc7, 0x1c, 0xbb, 0x64, 0x3e, 0x68, 0xf1, 0x1e, 0xe5, 0x83, + 0xde, 0xdd, 0x70, 0xbd, 0x91, 0x46, 0xda, 0x57, 0x2e, 0xdf, 0x57, 0x0b, 0x70, 0xb6, 0xb7, 0xc1, + 0x82, 0xde, 0x0e, 0xe3, 0xa1, 0x0a, 0xb2, 0x33, 0x53, 0x49, 0x4f, 0x71, 0xcf, 0x4e, 0x02, 0x84, + 0xd3, 0xb8, 0x68, 0x0a, 0xa0, 0xe5, 0xc4, 0x9b, 0xd1, 0x85, 0x1d, 0x37, 0x8a, 0x45, 0x41, 0xa9, + 0x31, 0x7e, 0x96, 0x28, 0x5b, 0xb1, 0x81, 0x41, 0xd9, 0xb1, 0x7f, 0xf3, 0xc1, 0xd5, 0x20, 0xe6, + 0x0f, 0xf1, 0xcd, 0xd6, 0x29, 0x79, 0xbd, 0x94, 0x01, 0xc2, 0x69, 0x5c, 0xca, 0x8e, 0x9d, 0x56, + 0xf3, 0x8e, 0xf2, 0x5d, 0x18, 0x63, 0xb7, 0xa4, 0x5a, 0xb1, 0x81, 0x91, 0x4e, 0x92, 0x2d, 0xed, + 0x9f, 0x24, 0x6b, 0xff, 0xcb, 0x02, 0x3c, 0xd4, 0xd3, 0xe0, 0xed, 0x4f, 0x4c, 0xdd, 0x7f, 0x89, + 0xad, 0x77, 0xb9, 0xc2, 0x0e, 0x96, 0x10, 0xf9, 0xa7, 0x3d, 0x66, 0x9a, 0x48, 0x88, 0xbc, 0xfb, + 0x3a, 0x0f, 0xf7, 0xdf, 0x78, 0x76, 0xe5, 0x40, 0x0e, 0x1c, 0x20, 0x07, 0x32, 0xf5, 0x31, 0x4a, + 0x7d, 0x6a, 0x87, 0x3f, 0x1f, 0xe8, 0x39, 0xbc, 0x74, 0x83, 0xdc, 0x97, 0xdf, 0x7c, 0x1e, 0x4e, + 0xb8, 0x3e, 0xbb, 0x6a, 0xb0, 0xda, 0x5e, 0x17, 0x35, 0x86, 0x78, 0x21, 0x4d, 0x95, 0x68, 0xb1, + 0x98, 0x82, 0xe3, 0xae, 0x27, 0xee, 0xc3, 0x9c, 0xd4, 0xbb, 0x1b, 0xd2, 0x03, 0x4a, 0xee, 0x15, + 0x38, 0x23, 0x87, 0x62, 0xd3, 0x09, 0x49, 0x5d, 0x28, 0xdb, 0x48, 0xa4, 0xd6, 0x3c, 0xc4, 0xd3, + 0x73, 0x32, 0x10, 0x70, 0xf6, 0x73, 0xec, 0x76, 0xb7, 0xa0, 0xe5, 0xd6, 0xc4, 0x56, 0x50, 0xdf, + 0xee, 0x46, 0x1b, 0x31, 0x87, 0x69, 0x7d, 0x51, 0x39, 0x1e, 0x7d, 0xf1, 0x5e, 0xa8, 0xa8, 0xf1, + 0xe6, 0x59, 0x02, 0x6a, 0x92, 0x77, 0x65, 0x09, 0xa8, 0x19, 0x6e, 0x60, 0xed, 0x77, 0x33, 0xf2, + 0x8f, 0xc0, 0x88, 0xf2, 0x7e, 0xf5, 0x7b, 0xc7, 0x9e, 0xfd, 0x7f, 0x0b, 0x90, 0xba, 0x05, 0x07, + 0xed, 0x40, 0xa5, 0x2e, 0xef, 0x26, 0xce, 0xa7, 0x90, 0xab, 0xba, 0xea, 0x58, 0x1f, 0xff, 0xa8, + 0x26, 0xac, 0x99, 0xa1, 0xf7, 0xf3, 0x9a, 0xa9, 0x82, 0x75, 0x21, 0x8f, 0xbc, 0xe4, 0xaa, 0xa2, + 0x67, 0x5e, 0xa2, 0x25, 0xdb, 0xb0, 0xc1, 0x0f, 0xc5, 0x50, 0xd9, 0x94, 0xb7, 0xfd, 0xe4, 0x23, + 0xee, 0xd4, 0xe5, 0x41, 0xdc, 0x44, 0x53, 0x7f, 0xb1, 0x66, 0x64, 0xff, 0x49, 0x01, 0x4e, 0x27, + 0x3f, 0x80, 0x38, 0xae, 0xfb, 0x35, 0x0b, 0x1e, 0xf4, 0x9c, 0x28, 0xae, 0xb6, 0xd9, 0x46, 0x61, + 0xa3, 0xed, 0xad, 0xa4, 0xca, 0xeb, 0x1e, 0xd6, 0xd9, 0xa2, 0x08, 0xa7, 0x6f, 0x87, 0x9a, 0x7d, + 0xf8, 0xf6, 0xee, 0xe4, 0x83, 0x4b, 0xd9, 0xcc, 0x71, 0xaf, 0x5e, 0xa1, 0xcf, 0x5a, 0x70, 0xa2, + 0xd6, 0x0e, 0x43, 0xe2, 0xc7, 0xba, 0xab, 0xfc, 0x2b, 0x5e, 0xcd, 0x65, 0x20, 0x75, 0x07, 0x4f, + 0x53, 0x81, 0x3a, 0x97, 0xe2, 0x85, 0xbb, 0xb8, 0xdb, 0xbf, 0x40, 0x35, 0x67, 0xcf, 0xf7, 0xfc, + 0x5b, 0x76, 0x9d, 0xd5, 0x5f, 0x0c, 0xc2, 0x68, 0xa2, 0x86, 0x70, 0xe2, 0x88, 0xcb, 0xda, 0xf7, + 0x88, 0x8b, 0x25, 0x83, 0xb5, 0x7d, 0x79, 0xd9, 0xae, 0x91, 0x0c, 0xd6, 0xf6, 0x09, 0xe6, 0x30, + 0x31, 0xa4, 0xb8, 0xed, 0x8b, 0xe8, 0x76, 0x73, 0x48, 0x71, 0xdb, 0xc7, 0x02, 0x8a, 0x3e, 0x64, + 0xc1, 0x08, 0x5b, 0x7c, 0xe2, 0x80, 0x50, 0x28, 0xb4, 0xcb, 0x39, 0x2c, 0x77, 0x59, 0x2f, 0x9b, + 0x45, 0x43, 0x9a, 0x2d, 0x38, 0xc1, 0x11, 0x7d, 0xd4, 0x82, 0x8a, 0xba, 0x9f, 0x4f, 0xdc, 0x9c, + 0x5d, 0xcd, 0xb7, 0x44, 0x73, 0x4a, 0xea, 0xa9, 0x5a, 0xb9, 0x58, 0x33, 0x46, 0x91, 0x3a, 0xbd, + 0x1b, 0x3a, 0x9a, 0xd3, 0x3b, 0xc8, 0x38, 0xb9, 0x7b, 0x2b, 0x54, 0x9a, 0x8e, 0xef, 0x6e, 0x90, + 0x28, 0xe6, 0x07, 0x6a, 0xb2, 0x72, 0xbc, 0x6c, 0xc4, 0x1a, 0x4e, 0x8d, 0xfd, 0x88, 0xbd, 0x58, + 0x6c, 0x9c, 0x80, 0x31, 0x63, 0xbf, 0xaa, 0x9b, 0xb1, 0x89, 0x63, 0x1e, 0xd7, 0xc1, 0x3d, 0x3d, + 0xae, 0x1b, 0xde, 0xe7, 0xb8, 0xae, 0x0a, 0x67, 0x9c, 0x76, 0x1c, 0x5c, 0x22, 0x8e, 0x37, 0xc3, + 0x6f, 0xe8, 0x8f, 0x78, 0xd9, 0xe9, 0x11, 0xe6, 0x02, 0x56, 0xf1, 0x5b, 0x55, 0xe2, 0x6d, 0x74, + 0x21, 0xe1, 0xec, 0x67, 0xed, 0x7f, 0x6e, 0xc1, 0x99, 0xcc, 0xa9, 0x70, 0xff, 0x46, 0xce, 0xdb, + 0x9f, 0x2f, 0xc1, 0xa9, 0x8c, 0x0a, 0xe3, 0xa8, 0x63, 0x2e, 0x12, 0x2b, 0x8f, 0x20, 0xb4, 0x64, + 0x4c, 0x95, 0xfc, 0x36, 0x19, 0x2b, 0xe3, 0x60, 0x27, 0xf0, 0xfa, 0x14, 0xbc, 0x78, 0xbc, 0xa7, + 0xe0, 0xc6, 0x5c, 0x1f, 0xb8, 0xa7, 0x73, 0xbd, 0xb4, 0xcf, 0x5c, 0xff, 0x9a, 0x05, 0x13, 0xcd, + 0x1e, 0xd7, 0xda, 0x88, 0xf3, 0xa4, 0xeb, 0x47, 0x73, 0x69, 0xce, 0xec, 0x23, 0xb7, 0x77, 0x27, + 0x7b, 0xde, 0x26, 0x84, 0x7b, 0xf6, 0xca, 0xfe, 0x4e, 0x11, 0x98, 0xbd, 0xc6, 0xaa, 0xc8, 0x76, + 0xd0, 0x07, 0xcd, 0x8b, 0x0a, 0xac, 0xbc, 0x8a, 0xea, 0x73, 0xe2, 0xea, 0xa2, 0x03, 0x3e, 0x82, + 0x59, 0xf7, 0x1e, 0xa4, 0x25, 0x61, 0xa1, 0x0f, 0x49, 0xe8, 0xc9, 0x1b, 0x21, 0x8a, 0xf9, 0xdf, + 0x08, 0x51, 0x49, 0xdf, 0x06, 0xb1, 0xf7, 0x27, 0x1e, 0xb8, 0x2f, 0x3f, 0xf1, 0x2f, 0x5b, 0x5c, + 0xf0, 0xa4, 0xbe, 0x82, 0x36, 0x37, 0xac, 0x3d, 0xcc, 0x8d, 0xa7, 0xa0, 0x1c, 0x09, 0xc9, 0x2c, + 0xcc, 0x12, 0x1d, 0x00, 0x25, 0xda, 0xb1, 0xc2, 0xa0, 0xbb, 0x2e, 0xc7, 0xf3, 0x82, 0x5b, 0x17, + 0x9a, 0xad, 0xb8, 0x23, 0x0c, 0x14, 0xb5, 0x2d, 0x98, 0x51, 0x10, 0x6c, 0x60, 0xd9, 0x9b, 0x60, + 0x6c, 0x18, 0xee, 0xfe, 0x16, 0xd0, 0x3e, 0xae, 0x6f, 0xfe, 0x87, 0x05, 0xc1, 0x8a, 0x6f, 0x00, + 0x9e, 0x4f, 0x5d, 0x97, 0xdd, 0x7f, 0xa8, 0xdb, 0xfb, 0x01, 0x6a, 0x41, 0xb3, 0x45, 0xb7, 0xc4, + 0x6b, 0x41, 0x3e, 0xfb, 0xa8, 0x39, 0x45, 0x4f, 0x0f, 0x98, 0x6e, 0xc3, 0x06, 0xbf, 0x84, 0xd4, + 0x2e, 0xee, 0x2b, 0xb5, 0x13, 0x02, 0x6c, 0x60, 0x6f, 0x01, 0x66, 0xff, 0x95, 0x05, 0x09, 0x83, + 0x0e, 0xb5, 0xa0, 0x44, 0xbb, 0xdb, 0x11, 0xb2, 0x60, 0x25, 0x3f, 0xeb, 0x91, 0x0a, 0x61, 0xb1, + 0xc0, 0xd8, 0x4f, 0xcc, 0x19, 0x21, 0x4f, 0x84, 0xf5, 0xe5, 0xb2, 0xaf, 0x31, 0x19, 0x5e, 0x0a, + 0x82, 0x2d, 0x1e, 0x19, 0xa3, 0x43, 0x04, 0xed, 0xe7, 0xe1, 0x64, 0x57, 0xa7, 0xd8, 0xcd, 0xa1, + 0x81, 0xdc, 0x9c, 0x1b, 0x0b, 0x83, 0x55, 0x39, 0xc0, 0x1c, 0x66, 0x7f, 0xd5, 0x82, 0x13, 0x69, + 0xf2, 0xe8, 0x75, 0x0b, 0x4e, 0x46, 0x69, 0x7a, 0x47, 0x35, 0x76, 0x2a, 0x34, 0xbf, 0x0b, 0x84, + 0xbb, 0x3b, 0x61, 0xff, 0x8d, 0x98, 0xfc, 0x37, 0x5c, 0xbf, 0x1e, 0xdc, 0x52, 0x26, 0x90, 0xd5, + 0xd3, 0x04, 0xa2, 0x2b, 0xbf, 0xb6, 0x49, 0xea, 0x6d, 0xaf, 0xab, 0x66, 0x42, 0x55, 0xb4, 0x63, + 0x85, 0xc1, 0x52, 0xc4, 0xdb, 0x62, 0x4b, 0x9a, 0x9a, 0x94, 0xf3, 0xa2, 0x1d, 0x2b, 0x0c, 0xf4, + 0x2c, 0x8c, 0x18, 0x2f, 0x29, 0xe7, 0x25, 0xdb, 0x4f, 0x18, 0xca, 0x39, 0xc2, 0x09, 0x2c, 0x34, + 0x05, 0xa0, 0xcc, 0x29, 0xa9, 0x8c, 0x99, 0x0f, 0x5d, 0xc9, 0xbc, 0x08, 0x1b, 0x18, 0xac, 0x20, + 0x83, 0xd7, 0x8e, 0xd8, 0x21, 0xf1, 0xa0, 0x2e, 0x98, 0x3e, 0x27, 0xda, 0xb0, 0x82, 0x52, 0xb9, + 0xd5, 0x74, 0xfc, 0xb6, 0xe3, 0xd1, 0x11, 0x12, 0x5e, 0x31, 0xb5, 0x0c, 0x97, 0x15, 0x04, 0x1b, + 0x58, 0xf4, 0x8d, 0x63, 0xb7, 0x49, 0x5e, 0x0a, 0x7c, 0x19, 0x52, 0xad, 0xe3, 0x06, 0x44, 0x3b, + 0x56, 0x18, 0xf6, 0x5f, 0x5a, 0x30, 0xae, 0x2b, 0xc1, 0x30, 0x5f, 0x56, 0xc2, 0x89, 0x67, 0xed, + 0xeb, 0xc4, 0x4b, 0xd6, 0xbd, 0x28, 0xf4, 0x55, 0xf7, 0xc2, 0x2c, 0x49, 0x51, 0xdc, 0xb3, 0x24, + 0xc5, 0x0f, 0xc2, 0xd0, 0x16, 0xe9, 0x18, 0xb5, 0x2b, 0x86, 0xa9, 0x39, 0x74, 0x85, 0x37, 0x61, + 0x09, 0x43, 0x36, 0x0c, 0xd6, 0x1c, 0x55, 0x31, 0x6d, 0x84, 0x6f, 0x7d, 0xe6, 0x66, 0x18, 0x92, + 0x80, 0xd8, 0x2b, 0x50, 0x51, 0xc7, 0xe7, 0xd2, 0xa7, 0x66, 0x65, 0xfb, 0xd4, 0xfa, 0x4a, 0x8d, + 0x9f, 0x5d, 0xff, 0xfa, 0x77, 0x1f, 0x7b, 0xd3, 0x1f, 0x7d, 0xf7, 0xb1, 0x37, 0x7d, 0xfb, 0xbb, + 0x8f, 0xbd, 0xe9, 0x43, 0xb7, 0x1f, 0xb3, 0xbe, 0x7e, 0xfb, 0x31, 0xeb, 0x8f, 0x6e, 0x3f, 0x66, + 0x7d, 0xfb, 0xf6, 0x63, 0xd6, 0x77, 0x6e, 0x3f, 0x66, 0x7d, 0xf6, 0xbf, 0x3e, 0xf6, 0xa6, 0x97, + 0x32, 0x63, 0xea, 0xe9, 0x8f, 0xa7, 0x6b, 0xf5, 0xe9, 0xed, 0xf3, 0x2c, 0xac, 0x9b, 0x2e, 0xaf, + 0x69, 0x63, 0x4e, 0x4d, 0xcb, 0xe5, 0xf5, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xa6, 0xfc, 0x44, + 0xf5, 0xc0, 0xf5, 0x00, 0x00, } func (m *AWSAuthConfig) Marshal() (dAtA []byte, err error) { @@ -5619,51 +5579,6 @@ func (m *AWSAuthConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *AppHealthStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AppHealthStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AppHealthStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.LastTransitionTime != nil { - { - size, err := m.LastTransitionTime.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - i -= len(m.Message) - copy(dAtA[i:], m.Message) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) - i-- - dAtA[i] = 0x12 - i -= len(m.Status) - copy(dAtA[i:], m.Status) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - func (m *AppProject) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -7900,26 +7815,6 @@ func (m *ApplicationSourceKustomize) MarshalToSizedBuffer(dAtA []byte) (int, err _ = i var l int _ = l - i-- - if m.LabelIncludeTemplates { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x90 - i-- - if m.IgnoreMissingComponents { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x88 if len(m.APIVersions) > 0 { for iNdEx := len(m.APIVersions) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.APIVersions[iNdEx]) @@ -9875,14 +9770,6 @@ func (m *GitFileGeneratorItem) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - i-- - if m.Exclude { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x10 i -= len(m.Path) copy(dAtA[i:], m.Path) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Path))) @@ -11872,30 +11759,6 @@ func (m *PullRequestGenerator) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Values) > 0 { - keysForValues := make([]string, 0, len(m.Values)) - for k := range m.Values { - keysForValues = append(keysForValues, string(k)) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForValues) - for iNdEx := len(keysForValues) - 1; iNdEx >= 0; iNdEx-- { - v := m.Values[string(keysForValues[iNdEx])] - baseI := i - i -= len(v) - copy(dAtA[i:], v) - i = encodeVarintGenerated(dAtA, i, uint64(len(v))) - i-- - dAtA[i] = 0x12 - i -= len(keysForValues[iNdEx]) - copy(dAtA[i:], keysForValues[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(keysForValues[iNdEx]))) - i-- - dAtA[i] = 0xa - i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x52 - } - } if m.AzureDevOps != nil { { size, err := m.AzureDevOps.MarshalToSizedBuffer(dAtA[:i]) @@ -12344,15 +12207,6 @@ func (m *PullRequestGeneratorGitea) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l - if len(m.Labels) > 0 { - for iNdEx := len(m.Labels) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Labels[iNdEx]) - copy(dAtA[i:], m.Labels[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Labels[iNdEx]))) - i-- - dAtA[i] = 0x32 - } - } i-- if m.Insecure { dAtA[i] = 1 @@ -12518,23 +12372,6 @@ func (m *RepoCreds) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - i -= len(m.BearerToken) - copy(dAtA[i:], m.BearerToken) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.BearerToken))) - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xca - i-- - if m.UseAzureWorkloadIdentity { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xc0 i -= len(m.NoProxy) copy(dAtA[i:], m.NoProxy) i = encodeVarintGenerated(dAtA, i, uint64(len(m.NoProxy))) @@ -12693,23 +12530,6 @@ func (m *Repository) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - i -= len(m.BearerToken) - copy(dAtA[i:], m.BearerToken) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.BearerToken))) - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xca - i-- - if m.UseAzureWorkloadIdentity { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xc0 i -= len(m.NoProxy) copy(dAtA[i:], m.NoProxy) i = encodeVarintGenerated(dAtA, i, uint64(len(m.NoProxy))) @@ -15298,16 +15118,6 @@ func (m *SyncPolicyAutomated) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.Enabled != nil { - i-- - if *m.Enabled { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x20 - } i-- if m.AllowEmpty { dAtA[i] = 1 @@ -15551,19 +15361,6 @@ func (m *SyncWindow) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - i -= len(m.Description) - copy(dAtA[i:], m.Description) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Description))) - i-- - dAtA[i] = 0x52 - i-- - if m.UseAndOperator { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x48 i -= len(m.TimeZone) copy(dAtA[i:], m.TimeZone) i = encodeVarintGenerated(dAtA, i, uint64(len(m.TimeZone))) @@ -15738,23 +15535,6 @@ func (m *AWSAuthConfig) Size() (n int) { return n } -func (m *AppHealthStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Status) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Message) - n += 1 + l + sovGenerated(uint64(l)) - if m.LastTransitionTime != nil { - l = m.LastTransitionTime.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - func (m *AppProject) Size() (n int) { if m == nil { return 0 @@ -16650,8 +16430,6 @@ func (m *ApplicationSourceKustomize) Size() (n int) { n += 2 + l + sovGenerated(uint64(l)) } } - n += 3 - n += 3 return n } @@ -17324,7 +17102,6 @@ func (m *GitFileGeneratorItem) Size() (n int) { _ = l l = len(m.Path) n += 1 + l + sovGenerated(uint64(l)) - n += 2 return n } @@ -18111,14 +17888,6 @@ func (m *PullRequestGenerator) Size() (n int) { l = m.AzureDevOps.Size() n += 1 + l + sovGenerated(uint64(l)) } - if len(m.Values) > 0 { - for k, v := range m.Values { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) - n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) - } - } return n } @@ -18264,12 +18033,6 @@ func (m *PullRequestGeneratorGitea) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } n += 2 - if len(m.Labels) > 0 { - for _, s := range m.Labels { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } return n } @@ -18349,9 +18112,6 @@ func (m *RepoCreds) Size() (n int) { n += 3 l = len(m.NoProxy) n += 2 + l + sovGenerated(uint64(l)) - n += 3 - l = len(m.BearerToken) - n += 2 + l + sovGenerated(uint64(l)) return n } @@ -18416,9 +18176,6 @@ func (m *Repository) Size() (n int) { n += 3 l = len(m.NoProxy) n += 2 + l + sovGenerated(uint64(l)) - n += 3 - l = len(m.BearerToken) - n += 2 + l + sovGenerated(uint64(l)) return n } @@ -19330,9 +19087,6 @@ func (m *SyncPolicyAutomated) Size() (n int) { n += 2 n += 2 n += 2 - if m.Enabled != nil { - n += 2 - } return n } @@ -19441,9 +19195,6 @@ func (m *SyncWindow) Size() (n int) { n += 2 l = len(m.TimeZone) n += 1 + l + sovGenerated(uint64(l)) - n += 2 - l = len(m.Description) - n += 1 + l + sovGenerated(uint64(l)) return n } @@ -19502,18 +19253,6 @@ func (this *AWSAuthConfig) String() string { }, "") return s } -func (this *AppHealthStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&AppHealthStatus{`, - `Status:` + fmt.Sprintf("%v", this.Status) + `,`, - `Message:` + fmt.Sprintf("%v", this.Message) + `,`, - `LastTransitionTime:` + strings.Replace(fmt.Sprintf("%v", this.LastTransitionTime), "Time", "v1.Time", 1) + `,`, - `}`, - }, "") - return s -} func (this *AppProject) String() string { if this == nil { return "nil" @@ -20150,8 +19889,6 @@ func (this *ApplicationSourceKustomize) String() string { `LabelWithoutSelector:` + fmt.Sprintf("%v", this.LabelWithoutSelector) + `,`, `KubeVersion:` + fmt.Sprintf("%v", this.KubeVersion) + `,`, `APIVersions:` + fmt.Sprintf("%v", this.APIVersions) + `,`, - `IgnoreMissingComponents:` + fmt.Sprintf("%v", this.IgnoreMissingComponents) + `,`, - `LabelIncludeTemplates:` + fmt.Sprintf("%v", this.LabelIncludeTemplates) + `,`, `}`, }, "") return s @@ -20246,7 +19983,7 @@ func (this *ApplicationStatus) String() string { s := strings.Join([]string{`&ApplicationStatus{`, `Resources:` + repeatedStringForResources + `,`, `Sync:` + strings.Replace(strings.Replace(this.Sync.String(), "SyncStatus", "SyncStatus", 1), `&`, ``, 1) + `,`, - `Health:` + strings.Replace(strings.Replace(this.Health.String(), "AppHealthStatus", "AppHealthStatus", 1), `&`, ``, 1) + `,`, + `Health:` + strings.Replace(strings.Replace(this.Health.String(), "HealthStatus", "HealthStatus", 1), `&`, ``, 1) + `,`, `History:` + repeatedStringForHistory + `,`, `Conditions:` + repeatedStringForConditions + `,`, `ReconciledAt:` + strings.Replace(fmt.Sprintf("%v", this.ReconciledAt), "Time", "v1.Time", 1) + `,`, @@ -20671,7 +20408,6 @@ func (this *GitFileGeneratorItem) String() string { } s := strings.Join([]string{`&GitFileGeneratorItem{`, `Path:` + fmt.Sprintf("%v", this.Path) + `,`, - `Exclude:` + fmt.Sprintf("%v", this.Exclude) + `,`, `}`, }, "") return s @@ -21307,16 +21043,6 @@ func (this *PullRequestGenerator) String() string { repeatedStringForFilters += strings.Replace(strings.Replace(f.String(), "PullRequestGeneratorFilter", "PullRequestGeneratorFilter", 1), `&`, ``, 1) + "," } repeatedStringForFilters += "}" - keysForValues := make([]string, 0, len(this.Values)) - for k := range this.Values { - keysForValues = append(keysForValues, k) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForValues) - mapStringForValues := "map[string]string{" - for _, k := range keysForValues { - mapStringForValues += fmt.Sprintf("%v: %v,", k, this.Values[k]) - } - mapStringForValues += "}" s := strings.Join([]string{`&PullRequestGenerator{`, `Github:` + strings.Replace(this.Github.String(), "PullRequestGeneratorGithub", "PullRequestGeneratorGithub", 1) + `,`, `GitLab:` + strings.Replace(this.GitLab.String(), "PullRequestGeneratorGitLab", "PullRequestGeneratorGitLab", 1) + `,`, @@ -21327,7 +21053,6 @@ func (this *PullRequestGenerator) String() string { `Template:` + strings.Replace(strings.Replace(this.Template.String(), "ApplicationSetTemplate", "ApplicationSetTemplate", 1), `&`, ``, 1) + `,`, `Bitbucket:` + strings.Replace(this.Bitbucket.String(), "PullRequestGeneratorBitbucket", "PullRequestGeneratorBitbucket", 1) + `,`, `AzureDevOps:` + strings.Replace(this.AzureDevOps.String(), "PullRequestGeneratorAzureDevOps", "PullRequestGeneratorAzureDevOps", 1) + `,`, - `Values:` + mapStringForValues + `,`, `}`, }, "") return s @@ -21414,7 +21139,6 @@ func (this *PullRequestGeneratorGitea) String() string { `API:` + fmt.Sprintf("%v", this.API) + `,`, `TokenRef:` + strings.Replace(this.TokenRef.String(), "SecretRef", "SecretRef", 1) + `,`, `Insecure:` + fmt.Sprintf("%v", this.Insecure) + `,`, - `Labels:` + fmt.Sprintf("%v", this.Labels) + `,`, `}`, }, "") return s @@ -21467,8 +21191,6 @@ func (this *RepoCreds) String() string { `Proxy:` + fmt.Sprintf("%v", this.Proxy) + `,`, `ForceHttpBasicAuth:` + fmt.Sprintf("%v", this.ForceHttpBasicAuth) + `,`, `NoProxy:` + fmt.Sprintf("%v", this.NoProxy) + `,`, - `UseAzureWorkloadIdentity:` + fmt.Sprintf("%v", this.UseAzureWorkloadIdentity) + `,`, - `BearerToken:` + fmt.Sprintf("%v", this.BearerToken) + `,`, `}`, }, "") return s @@ -21517,8 +21239,6 @@ func (this *Repository) String() string { `GCPServiceAccountKey:` + fmt.Sprintf("%v", this.GCPServiceAccountKey) + `,`, `ForceHttpBasicAuth:` + fmt.Sprintf("%v", this.ForceHttpBasicAuth) + `,`, `NoProxy:` + fmt.Sprintf("%v", this.NoProxy) + `,`, - `UseAzureWorkloadIdentity:` + fmt.Sprintf("%v", this.UseAzureWorkloadIdentity) + `,`, - `BearerToken:` + fmt.Sprintf("%v", this.BearerToken) + `,`, `}`, }, "") return s @@ -22160,7 +21880,6 @@ func (this *SyncPolicyAutomated) String() string { `Prune:` + fmt.Sprintf("%v", this.Prune) + `,`, `SelfHeal:` + fmt.Sprintf("%v", this.SelfHeal) + `,`, `AllowEmpty:` + fmt.Sprintf("%v", this.AllowEmpty) + `,`, - `Enabled:` + valueToStringGenerated(this.Enabled) + `,`, `}`, }, "") return s @@ -22233,8 +21952,6 @@ func (this *SyncWindow) String() string { `Clusters:` + fmt.Sprintf("%v", this.Clusters) + `,`, `ManualSync:` + fmt.Sprintf("%v", this.ManualSync) + `,`, `TimeZone:` + fmt.Sprintf("%v", this.TimeZone) + `,`, - `UseAndOperator:` + fmt.Sprintf("%v", this.UseAndOperator) + `,`, - `Description:` + fmt.Sprintf("%v", this.Description) + `,`, `}`, }, "") return s @@ -22418,156 +22135,6 @@ func (m *AWSAuthConfig) Unmarshal(dAtA []byte) error { } return nil } -func (m *AppHealthStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AppHealthStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AppHealthStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Status = github_com_argoproj_gitops_engine_pkg_health.HealthStatusCode(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Message = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastTransitionTime", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.LastTransitionTime == nil { - m.LastTransitionTime = &v1.Time{} - } - if err := m.LastTransitionTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *AppProject) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -29964,46 +29531,6 @@ func (m *ApplicationSourceKustomize) Unmarshal(dAtA []byte) error { } m.APIVersions = append(m.APIVersions, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 17: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field IgnoreMissingComponents", 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.IgnoreMissingComponents = bool(v != 0) - case 18: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LabelIncludeTemplates", 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.LabelIncludeTemplates = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -35826,26 +35353,6 @@ func (m *GitFileGeneratorItem) Unmarshal(dAtA []byte) error { } m.Path = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Exclude", 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.Exclude = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -42599,133 +42106,6 @@ func (m *PullRequestGenerator) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Values == nil { - m.Values = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Values[mapkey] = mapvalue - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -44052,38 +43432,6 @@ func (m *PullRequestGeneratorGitea) Unmarshal(dAtA []byte) error { } } m.Insecure = bool(v != 0) - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Labels", 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.Labels = append(m.Labels, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -44989,58 +44337,6 @@ func (m *RepoCreds) Unmarshal(dAtA []byte) error { } m.NoProxy = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 24: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field UseAzureWorkloadIdentity", 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.UseAzureWorkloadIdentity = bool(v != 0) - case 25: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BearerToken", 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.BearerToken = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -45847,58 +45143,6 @@ func (m *Repository) Unmarshal(dAtA []byte) error { } m.NoProxy = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 24: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field UseAzureWorkloadIdentity", 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.UseAzureWorkloadIdentity = bool(v != 0) - case 25: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BearerToken", 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.BearerToken = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -54182,27 +53426,6 @@ func (m *SyncPolicyAutomated) Unmarshal(dAtA []byte) error { } } m.AllowEmpty = bool(v != 0) - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Enabled", 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 - } - } - b := bool(v != 0) - m.Enabled = &b default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -55065,58 +54288,6 @@ func (m *SyncWindow) Unmarshal(dAtA []byte) error { } m.TimeZone = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field UseAndOperator", 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.UseAndOperator = bool(v != 0) - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", 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.Description = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex 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 5186fd5fbd..6823a76261 100644 --- a/pkg/apis/application/v1alpha1/generated.proto +++ b/pkg/apis/application/v1alpha1/generated.proto @@ -3,7 +3,7 @@ syntax = "proto2"; -package github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1; +package github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1; import "k8s.io/api/core/v1/generated.proto"; import "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto"; @@ -13,7 +13,7 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; import "k8s.io/apimachinery/pkg/util/intstr/generated.proto"; // Package-wide variables from generator "generated". -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"; // AWSAuthConfig is an AWS IAM authentication configuration message AWSAuthConfig { @@ -27,20 +27,6 @@ message AWSAuthConfig { optional string profile = 3; } -// AppHealthStatus contains information about the currently observed health state of an application -message AppHealthStatus { - // Status holds the status code of the application - optional string status = 1; - - // Message is a human-readable informational message describing the health status - // - // Deprecated: this field is not used and will be removed in a future release. - optional string message = 2; - - // LastTransitionTime is the time the HealthStatus was set or updated - optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 3; -} - // AppProject provides a logical grouping of applications, providing controls for: // * where the apps may deploy to (cluster whitelist) // * what may be deployed (repository whitelist, resource whitelist/blacklist) @@ -76,7 +62,6 @@ message AppProjectSpec { repeated ApplicationDestination destinations = 2; // Description contains optional project description - // +kubebuilder:validation:MaxLength=255 optional string description = 3; // Roles are user defined RBAC roles associated with this project @@ -350,8 +335,6 @@ message ApplicationSetSpec { repeated string goTemplateOptions = 7; // ApplyNestedSelectors enables selectors defined within the generators of two level-nested matrix or merge generators - // Deprecated: This field is ignored, and the behavior is always enabled. The field will be removed in a future - // version of the ApplicationSet CRD. optional bool applyNestedSelectors = 8; repeated ApplicationSetResourceIgnoreDifferences ignoreApplicationDifferences = 9; @@ -596,9 +579,6 @@ message ApplicationSourceKustomize { // Components specifies a list of kustomize components to add to the kustomization before building repeated string components = 13; - // IgnoreMissingComponents prevents kustomize from failing when components do not exist locally by not appending them to kustomization file - optional bool ignoreMissingComponents = 17; - // LabelWithoutSelector specifies whether to apply common labels to resource selectors or not optional bool labelWithoutSelector = 14; @@ -609,9 +589,6 @@ message ApplicationSourceKustomize { // 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 = 16; - - // LabelIncludeTemplates specifies whether to apply common labels to resource templates or not - optional bool labelIncludeTemplates = 18; } // ApplicationSourcePlugin holds options specific to config management plugins @@ -681,7 +658,7 @@ message ApplicationStatus { optional SyncStatus sync = 2; // Health contains information about the application's current health status - optional AppHealthStatus health = 3; + optional HealthStatus health = 3; // History contains information about the application's sync history repeated RevisionHistory history = 4; @@ -727,22 +704,19 @@ message ApplicationSummary { repeated string images = 2; } -// ApplicationTree represents the hierarchical structure of resources associated with an Argo CD application. +// ApplicationTree holds nodes which belongs to the application +// TODO: describe purpose of this type message ApplicationTree { - // Nodes contains a list of resources that are either directly managed by the application - // or are children of directly managed resources. + // Nodes contains list of nodes which either directly managed by the application and children of directly managed nodes. repeated ResourceNode nodes = 1; - // OrphanedNodes contains resources that exist in the same namespace as the application - // but are not managed by it. This list is populated only if orphaned resource tracking - // is enabled in the application's project settings. + // OrphanedNodes contains if or orphaned nodes: nodes which are not managed by the app but in the same namespace. List is populated only if orphaned resources enabled in app project. repeated ResourceNode orphanedNodes = 2; - // Hosts provides a list of Kubernetes nodes that are running pods related to the application. + // Hosts holds list of Kubernetes nodes that run application related pods repeated HostInfo hosts = 3; - // ShardsCount represents the total number of shards the application tree is split into. - // This is used to distribute resource processing across multiple shards. + // ShardsCount contains total number of shards the application tree is split into optional int64 shardsCount = 4; } @@ -1060,8 +1034,6 @@ message GitDirectoryGeneratorItem { message GitFileGeneratorItem { optional string path = 1; - - optional bool exclude = 2; } message GitGenerator { @@ -1111,17 +1083,15 @@ message GnuPGPublicKeyList { repeated GnuPGPublicKey items = 2; } -// HealthStatus contains information about the currently observed health state of a resource +// HealthStatus contains information about the currently observed health state of an application or resource message HealthStatus { - // Status holds the status code of the resource + // Status holds the status code of the application or resource optional string status = 1; // Message is a human-readable informational message describing the health status optional string message = 2; // LastTransitionTime is the time the HealthStatus was set or updated - // - // Deprecated: this field is not used and will be removed in a future release. optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 3; } @@ -1151,30 +1121,25 @@ message HelmParameter { optional bool forceString = 3; } -// HostInfo holds metadata and resource usage metrics for a specific host in the cluster. +// HostInfo holds host name and resources metrics +// TODO: describe purpose of this type +// TODO: describe members of this type message HostInfo { - // Name is the hostname or node name in the Kubernetes cluster. optional string name = 1; - // ResourcesInfo provides a list of resource usage details for different resource types on this host. repeated HostResourceInfo resourcesInfo = 2; - // SystemInfo contains detailed system-level information about the host, such as OS, kernel version, and architecture. optional .k8s.io.api.core.v1.NodeSystemInfo systemInfo = 3; } -// HostResourceInfo represents resource usage details for a specific resource type on a host. +// TODO: describe this type message HostResourceInfo { - // ResourceName specifies the type of resource (e.g., CPU, memory, storage). optional string resourceName = 1; - // RequestedByApp indicates the total amount of this resource requested by the application running on the host. optional int64 requestedByApp = 2; - // RequestedByNeighbors indicates the total amount of this resource requested by other workloads on the same host. optional int64 requestedByNeighbors = 3; - // Capacity represents the total available capacity of this resource on the host. optional int64 capacity = 4; } @@ -1247,16 +1212,12 @@ message JsonnetVar { optional bool code = 3; } -// KnownTypeField contains a mapping between a Custom Resource Definition (CRD) field -// and a well-known Kubernetes type. This mapping is primarily used for unit conversions -// in resources where the type is not explicitly defined (e.g., converting "0.1" to "100m" for CPU requests). +// KnownTypeField contains mapping between CRD field and known Kubernetes type. +// This is mainly used for unit conversion in unknown resources (e.g. 0.1 == 100mi) +// TODO: Describe the members of this type message KnownTypeField { - // Field represents the JSON path to the specific field in the CRD that requires type conversion. - // Example: "spec.resources.requests.cpu" optional string field = 1; - // Type specifies the expected Kubernetes type for the field, such as "cpu" or "memory". - // This helps in converting values between different formats (e.g., "0.1" to "100m" for CPU). optional string type = 2; } @@ -1537,9 +1498,6 @@ message PullRequestGenerator { // Additional provider to use and config for it. optional PullRequestGeneratorAzureDevOps azuredevops = 9; - - // Values contains key/value pairs which are passed directly as parameters to the template - map values = 10; } // PullRequestGeneratorAzureDevOps defines connection info specific to AzureDevOps. @@ -1628,8 +1586,7 @@ message PullRequestGeneratorGitLab { // Labels is used to filter the MRs that you want to target repeated string labels = 4; - // PullRequestState is an additional MRs filter to get only those with a certain state. Default: "" (all states). - // Valid values: opened, closed, merged, locked". + // PullRequestState is an additional MRs filter to get only those with a certain state. Default: "" (all states) optional string pullRequestState = 5; // Skips validating the SCM provider's TLS certificate - useful for self-signed certificates.; default: false @@ -1655,9 +1612,6 @@ message PullRequestGeneratorGitea { // Allow insecure tls, for self-signed certificates; default: false. optional bool insecure = 5; - - // Labels is used to filter the PRs that you want to target - repeated string labels = 6; } // PullRequestGenerator defines connection info specific to GitHub. @@ -1738,12 +1692,6 @@ message RepoCreds { // NoProxy specifies a list of targets where the proxy isn't used, applies only in cases where the proxy is applied optional string noProxy = 23; - - // UseAzureWorkloadIdentity specifies whether to use Azure Workload Identity for authentication - optional bool useAzureWorkloadIdentity = 24; - - // BearerToken contains the bearer token used for Git BitBucket Data Center auth at the repo server - optional string bearerToken = 25; } // RepositoryList is a collection of Repositories. @@ -1824,12 +1772,6 @@ message Repository { // NoProxy specifies a list of targets where the proxy isn't used, applies only in cases where the proxy is applied optional string noProxy = 23; - - // UseAzureWorkloadIdentity specifies whether to use Azure Workload Identity for authentication - optional bool useAzureWorkloadIdentity = 24; - - // BearerToken contains the bearer token used for Git BitBucket Data Center auth at the repo server - optional string bearerToken = 25; } // A RepositoryCertificate is either SSH known hosts entry or TLS certificate @@ -1865,105 +1807,81 @@ message RepositoryList { repeated Repository items = 2; } -// ResourceAction represents an individual action that can be performed on a resource. -// It includes parameters, an optional disabled flag, an icon for display, and a name for the action. +// TODO: describe this type +// TODO: describe members of this type message ResourceAction { - // Name is the name or identifier for the action. optional string name = 1; - // Params contains the parameters required to execute the action. repeated ResourceActionParam params = 2; - // Disabled indicates whether the action is disabled. optional bool disabled = 3; - // IconClass specifies the CSS class for the action's icon. optional string iconClass = 4; - // DisplayName provides a user-friendly name for the action. optional string displayName = 5; } -// ResourceActionDefinition defines an individual action that can be executed on a resource. -// It includes a name for the action and a Lua script that defines the action's behavior. +// TODO: describe this type +// TODO: describe members of this type message ResourceActionDefinition { - // Name is the identifier for the action. optional string name = 1; - // ActionLua contains the Lua script that defines the behavior of the action. optional string actionLua = 2; } -// ResourceActionParam represents a parameter for a resource action. -// It includes a name, value, type, and an optional default value for the parameter. +// TODO: describe this type +// TODO: describe members of this type message ResourceActionParam { - // Name is the name of the parameter. optional string name = 1; - // Value is the value of the parameter. optional string value = 2; - // Type is the type of the parameter (e.g., string, integer). optional string type = 3; - // Default is the default value of the parameter, if any. optional string default = 4; } -// ResourceActions holds the set of actions that can be applied to a resource. -// It defines custom Lua scripts for discovery and action execution, as well as options -// for merging built-in actions with custom ones. +// TODO: describe this type +// TODO: describe members of this type message ResourceActions { - // ActionDiscoveryLua contains a Lua script for discovering actions. optional string actionDiscoveryLua = 1; - // Definitions holds the list of action definitions available for the resource. repeated ResourceActionDefinition definitions = 2; - // MergeBuiltinActions indicates whether built-in actions should be merged with custom actions. optional bool mergeBuiltinActions = 3; } -// ResourceDiff holds the diff between a live and target resource object in Argo CD. -// It is used to compare the desired state (from Git/Helm) with the actual state in the cluster. +// ResourceDiff holds the diff of a live and target resource object +// TODO: describe members of this type message ResourceDiff { - // Group represents the API group of the resource (e.g., "apps" for Deployments). optional string group = 1; - // Kind represents the Kubernetes resource kind (e.g., "Deployment", "Service"). optional string kind = 2; - // Namespace specifies the namespace where the resource exists. optional string namespace = 3; - // Name is the name of the resource. optional string name = 4; - // TargetState contains the JSON-serialized resource manifest as defined in the Git/Helm repository. + // TargetState contains the JSON serialized resource manifest defined in the Git/Helm optional string targetState = 5; - // LiveState contains the JSON-serialized resource manifest of the resource currently running in the cluster. + // TargetState contains the JSON live resource manifest optional string liveState = 6; - // Diff contains the JSON patch representing the difference between the live and target resource. - // Deprecated: Use NormalizedLiveState and PredictedLiveState instead to compute differences. + // Diff contains the JSON patch between target and live resource + // Deprecated: use NormalizedLiveState and PredictedLiveState to render the difference optional string diff = 7; - // Hook indicates whether this resource is a hook resource (e.g., pre-sync or post-sync hooks). optional bool hook = 8; - // NormalizedLiveState contains the JSON-serialized live resource state after applying normalizations. - // Normalizations may include ignoring irrelevant fields like timestamps or defaults applied by Kubernetes. + // NormalizedLiveState contains JSON serialized live resource state with applied normalizations optional string normalizedLiveState = 9; - // PredictedLiveState contains the JSON-serialized resource state that Argo CD predicts based on the - // combination of the normalized live state and the desired target state. + // PredictedLiveState contains JSON serialized resource state that is calculated based on normalized and target resource state optional string predictedLiveState = 10; - // ResourceVersion is the Kubernetes resource version, which helps in tracking changes. optional string resourceVersion = 11; - // Modified indicates whether the live resource has changes compared to the target resource. optional bool modified = 12; } @@ -1986,73 +1904,54 @@ message ResourceIgnoreDifferences { repeated string managedFieldsManagers = 7; } -// ResourceNetworkingInfo holds networking-related information for a resource. +// ResourceNetworkingInfo holds networking resource related information +// TODO: describe members of this type message ResourceNetworkingInfo { - // TargetLabels represents labels associated with the target resources that this resource communicates with. map targetLabels = 1; - // TargetRefs contains references to other resources that this resource interacts with, such as Services or Pods. repeated ResourceRef targetRefs = 2; - // Labels holds the labels associated with this networking resource. map labels = 3; - // Ingress provides information about external access points (e.g., load balancer ingress) for this resource. repeated .k8s.io.api.core.v1.LoadBalancerIngress ingress = 4; - // ExternalURLs holds a list of URLs that should be accessible externally. - // This field is typically populated for Ingress resources based on their hostname rules. + // ExternalURLs holds list of URLs which should be available externally. List is populated for ingress resources using rules hostnames. repeated string externalURLs = 5; } -// ResourceNode contains information about a live Kubernetes resource and its relationships with other resources. +// ResourceNode contains information about live resource and its children +// TODO: describe members of this type message ResourceNode { - // ResourceRef uniquely identifies the resource using its group, kind, namespace, and name. optional ResourceRef resourceRef = 1; - // ParentRefs lists the parent resources that reference this resource. - // This helps in understanding ownership and hierarchical relationships. repeated ResourceRef parentRefs = 2; - // Info provides additional metadata or annotations about the resource. repeated InfoItem info = 3; - // NetworkingInfo contains details about the resource's networking attributes, - // such as ingress information and external URLs. optional ResourceNetworkingInfo networkingInfo = 4; - // ResourceVersion indicates the version of the resource, used to track changes. optional string resourceVersion = 5; - // Images lists container images associated with the resource. - // This is primarily useful for pods and other workload resources. repeated string images = 6; - // Health represents the health status of the resource (e.g., Healthy, Degraded, Progressing). optional HealthStatus health = 7; - // CreatedAt records the timestamp when the resource was created. optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time createdAt = 8; } // ResourceOverride holds configuration to customize resource diffing and health assessment +// TODO: describe the members of this type message ResourceOverride { - // HealthLua contains a Lua script that defines custom health checks for the resource. optional string healthLua = 1; - // UseOpenLibs indicates whether to use open-source libraries for the resource. optional bool useOpenLibs = 5; - // Actions defines the set of actions that can be performed on the resource, as a Lua script. optional string actions = 3; - // IgnoreDifferences contains configuration for which differences should be ignored during the resource diffing. optional OverrideIgnoreDiff ignoreDifferences = 2; - // IgnoreResourceUpdates holds configuration for ignoring updates to specific resource fields. optional OverrideIgnoreDiff ignoreResourceUpdates = 6; - // KnownTypeFields lists fields for which unit conversions should be applied. repeated KnownTypeField knownTypeFields = 4; } @@ -2105,40 +2004,29 @@ message ResourceResult { optional string syncPhase = 10; } -// ResourceStatus holds the current synchronization and health status of a Kubernetes resource. +// ResourceStatus holds the current sync and health status of a resource +// TODO: describe members of this type message ResourceStatus { - // Group represents the API group of the resource (e.g., "apps" for Deployments). optional string group = 1; - // Version indicates the API version of the resource (e.g., "v1", "v1beta1"). optional string version = 2; - // Kind specifies the type of the resource (e.g., "Deployment", "Service"). optional string kind = 3; - // Namespace defines the Kubernetes namespace where the resource is located. optional string namespace = 4; - // Name is the unique name of the resource within the namespace. optional string name = 5; - // Status represents the synchronization state of the resource (e.g., Synced, OutOfSync). optional string status = 6; - // Health indicates the health status of the resource (e.g., Healthy, Degraded, Progressing). optional HealthStatus health = 7; - // Hook is true if the resource is used as a lifecycle hook in an Argo CD application. optional bool hook = 8; - // RequiresPruning is true if the resource needs to be pruned (deleted) as part of synchronization. optional bool requiresPruning = 9; - // SyncWave determines the order in which resources are applied during a sync operation. - // Lower values are applied first. optional int64 syncWave = 10; - // RequiresDeletionConfirmation is true if the resource requires explicit user confirmation before deletion. optional bool requiresDeletionConfirmation = 11; } @@ -2537,9 +2425,6 @@ message SyncPolicyAutomated { // AllowEmpty allows apps have zero live resources (default: false) optional bool allowEmpty = 3; - - // Enable allows apps to explicitly control automated sync - optional bool enable = 4; } // SyncSource specifies a location from which hydrated manifests may be synced. RepoURL is assumed based on the @@ -2618,12 +2503,6 @@ message SyncWindow { // TimeZone of the sync that will be applied to the schedule optional string timeZone = 8; - - // UseAndOperator use AND operator for matching applications, namespaces and clusters instead of the default OR operator - optional bool andOperator = 9; - - // Description of the sync that will be applied to the schedule, can be used to add any information such as a ticket number for example - optional string description = 10; } // TLSClientConfig contains settings to enable transport layer security diff --git a/pkg/apis/application/v1alpha1/openapi_generated.go b/pkg/apis/application/v1alpha1/openapi_generated.go index b4f026b8d2..28492686a8 100644 --- a/pkg/apis/application/v1alpha1/openapi_generated.go +++ b/pkg/apis/application/v1alpha1/openapi_generated.go @@ -14,171 +14,171 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AWSAuthConfig": schema_pkg_apis_application_v1alpha1_AWSAuthConfig(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AppProject": schema_pkg_apis_application_v1alpha1_AppProject(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AppProjectList": schema_pkg_apis_application_v1alpha1_AppProjectList(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AppProjectSpec": schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AppProjectStatus": schema_pkg_apis_application_v1alpha1_AppProjectStatus(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Application": schema_pkg_apis_application_v1alpha1_Application(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationCondition": schema_pkg_apis_application_v1alpha1_ApplicationCondition(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationDestination": schema_pkg_apis_application_v1alpha1_ApplicationDestination(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationDestinationServiceAccount": schema_pkg_apis_application_v1alpha1_ApplicationDestinationServiceAccount(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationList": schema_pkg_apis_application_v1alpha1_ApplicationList(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationMatchExpression": schema_pkg_apis_application_v1alpha1_ApplicationMatchExpression(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationPreservedFields": schema_pkg_apis_application_v1alpha1_ApplicationPreservedFields(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSet": schema_pkg_apis_application_v1alpha1_ApplicationSet(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetApplicationStatus": schema_pkg_apis_application_v1alpha1_ApplicationSetApplicationStatus(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetCondition": schema_pkg_apis_application_v1alpha1_ApplicationSetCondition(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetGenerator": schema_pkg_apis_application_v1alpha1_ApplicationSetGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetList": schema_pkg_apis_application_v1alpha1_ApplicationSetList(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetNestedGenerator": schema_pkg_apis_application_v1alpha1_ApplicationSetNestedGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetResourceIgnoreDifferences": schema_pkg_apis_application_v1alpha1_ApplicationSetResourceIgnoreDifferences(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetRolloutStep": schema_pkg_apis_application_v1alpha1_ApplicationSetRolloutStep(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetRolloutStrategy": schema_pkg_apis_application_v1alpha1_ApplicationSetRolloutStrategy(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetSpec": schema_pkg_apis_application_v1alpha1_ApplicationSetSpec(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetStatus": schema_pkg_apis_application_v1alpha1_ApplicationSetStatus(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetStrategy": schema_pkg_apis_application_v1alpha1_ApplicationSetStrategy(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetSyncPolicy": schema_pkg_apis_application_v1alpha1_ApplicationSetSyncPolicy(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate": schema_pkg_apis_application_v1alpha1_ApplicationSetTemplate(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplateMeta": schema_pkg_apis_application_v1alpha1_ApplicationSetTemplateMeta(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTerminalGenerator": schema_pkg_apis_application_v1alpha1_ApplicationSetTerminalGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTree": schema_pkg_apis_application_v1alpha1_ApplicationSetTree(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource": schema_pkg_apis_application_v1alpha1_ApplicationSource(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourceDirectory": schema_pkg_apis_application_v1alpha1_ApplicationSourceDirectory(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourceHelm": schema_pkg_apis_application_v1alpha1_ApplicationSourceHelm(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourceJsonnet": schema_pkg_apis_application_v1alpha1_ApplicationSourceJsonnet(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourceKustomize": schema_pkg_apis_application_v1alpha1_ApplicationSourceKustomize(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourcePlugin": schema_pkg_apis_application_v1alpha1_ApplicationSourcePlugin(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourcePluginParameter": schema_pkg_apis_application_v1alpha1_ApplicationSourcePluginParameter(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSpec": schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationStatus": schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSummary": schema_pkg_apis_application_v1alpha1_ApplicationSummary(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationTree": schema_pkg_apis_application_v1alpha1_ApplicationTree(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationWatchEvent": schema_pkg_apis_application_v1alpha1_ApplicationWatchEvent(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Backoff": schema_pkg_apis_application_v1alpha1_Backoff(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer": schema_pkg_apis_application_v1alpha1_BasicAuthBitbucketServer(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BearerTokenBitbucket": schema_pkg_apis_application_v1alpha1_BearerTokenBitbucket(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BearerTokenBitbucketCloud": schema_pkg_apis_application_v1alpha1_BearerTokenBitbucketCloud(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ChartDetails": schema_pkg_apis_application_v1alpha1_ChartDetails(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Cluster": schema_pkg_apis_application_v1alpha1_Cluster(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterCacheInfo": schema_pkg_apis_application_v1alpha1_ClusterCacheInfo(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterConfig": schema_pkg_apis_application_v1alpha1_ClusterConfig(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterGenerator": schema_pkg_apis_application_v1alpha1_ClusterGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterInfo": schema_pkg_apis_application_v1alpha1_ClusterInfo(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterList": schema_pkg_apis_application_v1alpha1_ClusterList(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Command": schema_pkg_apis_application_v1alpha1_Command(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ComparedTo": schema_pkg_apis_application_v1alpha1_ComparedTo(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ComponentParameter": schema_pkg_apis_application_v1alpha1_ComponentParameter(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConfigManagementPlugin": schema_pkg_apis_application_v1alpha1_ConfigManagementPlugin(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConfigMapKeyRef": schema_pkg_apis_application_v1alpha1_ConfigMapKeyRef(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConnectionState": schema_pkg_apis_application_v1alpha1_ConnectionState(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.DrySource": schema_pkg_apis_application_v1alpha1_DrySource(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.DuckTypeGenerator": schema_pkg_apis_application_v1alpha1_DuckTypeGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.EnvEntry": schema_pkg_apis_application_v1alpha1_EnvEntry(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ErrApplicationNotAllowedToUseProject": schema_pkg_apis_application_v1alpha1_ErrApplicationNotAllowedToUseProject(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ExecProviderConfig": schema_pkg_apis_application_v1alpha1_ExecProviderConfig(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitDirectoryGeneratorItem": schema_pkg_apis_application_v1alpha1_GitDirectoryGeneratorItem(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitFileGeneratorItem": schema_pkg_apis_application_v1alpha1_GitFileGeneratorItem(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitGenerator": schema_pkg_apis_application_v1alpha1_GitGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GnuPGPublicKey": schema_pkg_apis_application_v1alpha1_GnuPGPublicKey(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GnuPGPublicKeyList": schema_pkg_apis_application_v1alpha1_GnuPGPublicKeyList(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HealthStatus": schema_pkg_apis_application_v1alpha1_HealthStatus(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HelmFileParameter": schema_pkg_apis_application_v1alpha1_HelmFileParameter(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HelmOptions": schema_pkg_apis_application_v1alpha1_HelmOptions(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HelmParameter": schema_pkg_apis_application_v1alpha1_HelmParameter(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HostInfo": schema_pkg_apis_application_v1alpha1_HostInfo(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HostResourceInfo": schema_pkg_apis_application_v1alpha1_HostResourceInfo(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HydrateOperation": schema_pkg_apis_application_v1alpha1_HydrateOperation(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HydrateTo": schema_pkg_apis_application_v1alpha1_HydrateTo(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Info": schema_pkg_apis_application_v1alpha1_Info(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.InfoItem": schema_pkg_apis_application_v1alpha1_InfoItem(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.JWTToken": schema_pkg_apis_application_v1alpha1_JWTToken(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.JWTTokens": schema_pkg_apis_application_v1alpha1_JWTTokens(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.JsonnetVar": schema_pkg_apis_application_v1alpha1_JsonnetVar(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KnownTypeField": schema_pkg_apis_application_v1alpha1_KnownTypeField(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KustomizeGvk": schema_pkg_apis_application_v1alpha1_KustomizeGvk(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KustomizeOptions": schema_pkg_apis_application_v1alpha1_KustomizeOptions(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KustomizePatch": schema_pkg_apis_application_v1alpha1_KustomizePatch(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KustomizeReplica": schema_pkg_apis_application_v1alpha1_KustomizeReplica(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KustomizeResId": schema_pkg_apis_application_v1alpha1_KustomizeResId(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KustomizeSelector": schema_pkg_apis_application_v1alpha1_KustomizeSelector(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ListGenerator": schema_pkg_apis_application_v1alpha1_ListGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ManagedNamespaceMetadata": schema_pkg_apis_application_v1alpha1_ManagedNamespaceMetadata(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.MatrixGenerator": schema_pkg_apis_application_v1alpha1_MatrixGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.MergeGenerator": schema_pkg_apis_application_v1alpha1_MergeGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.NestedMatrixGenerator": schema_pkg_apis_application_v1alpha1_NestedMatrixGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.NestedMergeGenerator": schema_pkg_apis_application_v1alpha1_NestedMergeGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Operation": schema_pkg_apis_application_v1alpha1_Operation(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OperationInitiator": schema_pkg_apis_application_v1alpha1_OperationInitiator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OperationState": schema_pkg_apis_application_v1alpha1_OperationState(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OptionalArray": schema_pkg_apis_application_v1alpha1_OptionalArray(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OptionalMap": schema_pkg_apis_application_v1alpha1_OptionalMap(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OrphanedResourceKey": schema_pkg_apis_application_v1alpha1_OrphanedResourceKey(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OrphanedResourcesMonitorSettings": schema_pkg_apis_application_v1alpha1_OrphanedResourcesMonitorSettings(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OverrideIgnoreDiff": schema_pkg_apis_application_v1alpha1_OverrideIgnoreDiff(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginConfigMapRef": schema_pkg_apis_application_v1alpha1_PluginConfigMapRef(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginGenerator": schema_pkg_apis_application_v1alpha1_PluginGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginInput": schema_pkg_apis_application_v1alpha1_PluginInput(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ProjectRole": schema_pkg_apis_application_v1alpha1_ProjectRole(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGenerator": schema_pkg_apis_application_v1alpha1_PullRequestGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorAzureDevOps": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorAzureDevOps(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorBitbucket": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorBitbucket(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorBitbucketServer": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorBitbucketServer(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorFilter": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorFilter(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorGitLab": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGitLab(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorGitea": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGitea(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorGithub": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGithub(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RefTarget": schema_pkg_apis_application_v1alpha1_RefTarget(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RepoCreds": schema_pkg_apis_application_v1alpha1_RepoCreds(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RepoCredsList": schema_pkg_apis_application_v1alpha1_RepoCredsList(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Repository": schema_pkg_apis_application_v1alpha1_Repository(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RepositoryCertificate": schema_pkg_apis_application_v1alpha1_RepositoryCertificate(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RepositoryCertificateList": schema_pkg_apis_application_v1alpha1_RepositoryCertificateList(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RepositoryList": schema_pkg_apis_application_v1alpha1_RepositoryList(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceAction": schema_pkg_apis_application_v1alpha1_ResourceAction(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceActionDefinition": schema_pkg_apis_application_v1alpha1_ResourceActionDefinition(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceActionParam": schema_pkg_apis_application_v1alpha1_ResourceActionParam(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceActions": schema_pkg_apis_application_v1alpha1_ResourceActions(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceDiff": schema_pkg_apis_application_v1alpha1_ResourceDiff(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences": schema_pkg_apis_application_v1alpha1_ResourceIgnoreDifferences(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceNetworkingInfo": schema_pkg_apis_application_v1alpha1_ResourceNetworkingInfo(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceNode": schema_pkg_apis_application_v1alpha1_ResourceNode(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceOverride": schema_pkg_apis_application_v1alpha1_ResourceOverride(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceRef": schema_pkg_apis_application_v1alpha1_ResourceRef(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceResult": schema_pkg_apis_application_v1alpha1_ResourceResult(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceStatus": schema_pkg_apis_application_v1alpha1_ResourceStatus(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RetryStrategy": schema_pkg_apis_application_v1alpha1_RetryStrategy(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RevisionHistory": schema_pkg_apis_application_v1alpha1_RevisionHistory(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RevisionMetadata": schema_pkg_apis_application_v1alpha1_RevisionMetadata(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGenerator": schema_pkg_apis_application_v1alpha1_SCMProviderGenerator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorAWSCodeCommit": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorAWSCodeCommit(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorAzureDevOps": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorAzureDevOps(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorBitbucket": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorBitbucket(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorBitbucketServer": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorBitbucketServer(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorFilter": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorFilter(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitea": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGitea(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorGithub": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGithub(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitlab": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGitlab(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef": schema_pkg_apis_application_v1alpha1_SecretRef(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SignatureKey": schema_pkg_apis_application_v1alpha1_SignatureKey(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SourceHydrator": schema_pkg_apis_application_v1alpha1_SourceHydrator(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SourceHydratorStatus": schema_pkg_apis_application_v1alpha1_SourceHydratorStatus(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SuccessfulHydrateOperation": schema_pkg_apis_application_v1alpha1_SuccessfulHydrateOperation(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncOperation": schema_pkg_apis_application_v1alpha1_SyncOperation(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncOperationResource": schema_pkg_apis_application_v1alpha1_SyncOperationResource(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncOperationResult": schema_pkg_apis_application_v1alpha1_SyncOperationResult(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncPolicy": schema_pkg_apis_application_v1alpha1_SyncPolicy(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncPolicyAutomated": schema_pkg_apis_application_v1alpha1_SyncPolicyAutomated(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncSource": schema_pkg_apis_application_v1alpha1_SyncSource(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncStatus": schema_pkg_apis_application_v1alpha1_SyncStatus(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncStrategy": schema_pkg_apis_application_v1alpha1_SyncStrategy(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncStrategyApply": schema_pkg_apis_application_v1alpha1_SyncStrategyApply(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncStrategyHook": schema_pkg_apis_application_v1alpha1_SyncStrategyHook(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncWindow": schema_pkg_apis_application_v1alpha1_SyncWindow(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.TLSClientConfig": schema_pkg_apis_application_v1alpha1_TLSClientConfig(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.TagFilter": schema_pkg_apis_application_v1alpha1_TagFilter(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.objectMeta": schema_pkg_apis_application_v1alpha1_objectMeta(ref), - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.rawResourceOverride": schema_pkg_apis_application_v1alpha1_rawResourceOverride(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AWSAuthConfig": schema_pkg_apis_application_v1alpha1_AWSAuthConfig(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AppProject": schema_pkg_apis_application_v1alpha1_AppProject(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AppProjectList": schema_pkg_apis_application_v1alpha1_AppProjectList(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AppProjectSpec": schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AppProjectStatus": schema_pkg_apis_application_v1alpha1_AppProjectStatus(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Application": schema_pkg_apis_application_v1alpha1_Application(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationCondition": schema_pkg_apis_application_v1alpha1_ApplicationCondition(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestination": schema_pkg_apis_application_v1alpha1_ApplicationDestination(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestinationServiceAccount": schema_pkg_apis_application_v1alpha1_ApplicationDestinationServiceAccount(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationList": schema_pkg_apis_application_v1alpha1_ApplicationList(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationMatchExpression": schema_pkg_apis_application_v1alpha1_ApplicationMatchExpression(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationPreservedFields": schema_pkg_apis_application_v1alpha1_ApplicationPreservedFields(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSet": schema_pkg_apis_application_v1alpha1_ApplicationSet(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetApplicationStatus": schema_pkg_apis_application_v1alpha1_ApplicationSetApplicationStatus(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetCondition": schema_pkg_apis_application_v1alpha1_ApplicationSetCondition(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetGenerator": schema_pkg_apis_application_v1alpha1_ApplicationSetGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetList": schema_pkg_apis_application_v1alpha1_ApplicationSetList(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetNestedGenerator": schema_pkg_apis_application_v1alpha1_ApplicationSetNestedGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetResourceIgnoreDifferences": schema_pkg_apis_application_v1alpha1_ApplicationSetResourceIgnoreDifferences(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetRolloutStep": schema_pkg_apis_application_v1alpha1_ApplicationSetRolloutStep(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetRolloutStrategy": schema_pkg_apis_application_v1alpha1_ApplicationSetRolloutStrategy(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetSpec": schema_pkg_apis_application_v1alpha1_ApplicationSetSpec(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetStatus": schema_pkg_apis_application_v1alpha1_ApplicationSetStatus(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetStrategy": schema_pkg_apis_application_v1alpha1_ApplicationSetStrategy(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetSyncPolicy": schema_pkg_apis_application_v1alpha1_ApplicationSetSyncPolicy(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate": schema_pkg_apis_application_v1alpha1_ApplicationSetTemplate(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplateMeta": schema_pkg_apis_application_v1alpha1_ApplicationSetTemplateMeta(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTerminalGenerator": schema_pkg_apis_application_v1alpha1_ApplicationSetTerminalGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTree": schema_pkg_apis_application_v1alpha1_ApplicationSetTree(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource": schema_pkg_apis_application_v1alpha1_ApplicationSource(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourceDirectory": schema_pkg_apis_application_v1alpha1_ApplicationSourceDirectory(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourceHelm": schema_pkg_apis_application_v1alpha1_ApplicationSourceHelm(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourceJsonnet": schema_pkg_apis_application_v1alpha1_ApplicationSourceJsonnet(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourceKustomize": schema_pkg_apis_application_v1alpha1_ApplicationSourceKustomize(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourcePlugin": schema_pkg_apis_application_v1alpha1_ApplicationSourcePlugin(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourcePluginParameter": schema_pkg_apis_application_v1alpha1_ApplicationSourcePluginParameter(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSpec": schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationStatus": schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSummary": schema_pkg_apis_application_v1alpha1_ApplicationSummary(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationTree": schema_pkg_apis_application_v1alpha1_ApplicationTree(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationWatchEvent": schema_pkg_apis_application_v1alpha1_ApplicationWatchEvent(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Backoff": schema_pkg_apis_application_v1alpha1_Backoff(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer": schema_pkg_apis_application_v1alpha1_BasicAuthBitbucketServer(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BearerTokenBitbucket": schema_pkg_apis_application_v1alpha1_BearerTokenBitbucket(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BearerTokenBitbucketCloud": schema_pkg_apis_application_v1alpha1_BearerTokenBitbucketCloud(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ChartDetails": schema_pkg_apis_application_v1alpha1_ChartDetails(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Cluster": schema_pkg_apis_application_v1alpha1_Cluster(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterCacheInfo": schema_pkg_apis_application_v1alpha1_ClusterCacheInfo(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterConfig": schema_pkg_apis_application_v1alpha1_ClusterConfig(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterGenerator": schema_pkg_apis_application_v1alpha1_ClusterGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterInfo": schema_pkg_apis_application_v1alpha1_ClusterInfo(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterList": schema_pkg_apis_application_v1alpha1_ClusterList(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Command": schema_pkg_apis_application_v1alpha1_Command(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ComparedTo": schema_pkg_apis_application_v1alpha1_ComparedTo(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ComponentParameter": schema_pkg_apis_application_v1alpha1_ComponentParameter(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigManagementPlugin": schema_pkg_apis_application_v1alpha1_ConfigManagementPlugin(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef": schema_pkg_apis_application_v1alpha1_ConfigMapKeyRef(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConnectionState": schema_pkg_apis_application_v1alpha1_ConnectionState(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DrySource": schema_pkg_apis_application_v1alpha1_DrySource(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DuckTypeGenerator": schema_pkg_apis_application_v1alpha1_DuckTypeGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.EnvEntry": schema_pkg_apis_application_v1alpha1_EnvEntry(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ErrApplicationNotAllowedToUseProject": schema_pkg_apis_application_v1alpha1_ErrApplicationNotAllowedToUseProject(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ExecProviderConfig": schema_pkg_apis_application_v1alpha1_ExecProviderConfig(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitDirectoryGeneratorItem": schema_pkg_apis_application_v1alpha1_GitDirectoryGeneratorItem(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitFileGeneratorItem": schema_pkg_apis_application_v1alpha1_GitFileGeneratorItem(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitGenerator": schema_pkg_apis_application_v1alpha1_GitGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GnuPGPublicKey": schema_pkg_apis_application_v1alpha1_GnuPGPublicKey(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GnuPGPublicKeyList": schema_pkg_apis_application_v1alpha1_GnuPGPublicKeyList(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HealthStatus": schema_pkg_apis_application_v1alpha1_HealthStatus(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HelmFileParameter": schema_pkg_apis_application_v1alpha1_HelmFileParameter(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HelmOptions": schema_pkg_apis_application_v1alpha1_HelmOptions(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HelmParameter": schema_pkg_apis_application_v1alpha1_HelmParameter(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HostInfo": schema_pkg_apis_application_v1alpha1_HostInfo(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HostResourceInfo": schema_pkg_apis_application_v1alpha1_HostResourceInfo(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HydrateOperation": schema_pkg_apis_application_v1alpha1_HydrateOperation(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HydrateTo": schema_pkg_apis_application_v1alpha1_HydrateTo(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Info": schema_pkg_apis_application_v1alpha1_Info(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.InfoItem": schema_pkg_apis_application_v1alpha1_InfoItem(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JWTToken": schema_pkg_apis_application_v1alpha1_JWTToken(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JWTTokens": schema_pkg_apis_application_v1alpha1_JWTTokens(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JsonnetVar": schema_pkg_apis_application_v1alpha1_JsonnetVar(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KnownTypeField": schema_pkg_apis_application_v1alpha1_KnownTypeField(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KustomizeGvk": schema_pkg_apis_application_v1alpha1_KustomizeGvk(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KustomizeOptions": schema_pkg_apis_application_v1alpha1_KustomizeOptions(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KustomizePatch": schema_pkg_apis_application_v1alpha1_KustomizePatch(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KustomizeReplica": schema_pkg_apis_application_v1alpha1_KustomizeReplica(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KustomizeResId": schema_pkg_apis_application_v1alpha1_KustomizeResId(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KustomizeSelector": schema_pkg_apis_application_v1alpha1_KustomizeSelector(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ListGenerator": schema_pkg_apis_application_v1alpha1_ListGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ManagedNamespaceMetadata": schema_pkg_apis_application_v1alpha1_ManagedNamespaceMetadata(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.MatrixGenerator": schema_pkg_apis_application_v1alpha1_MatrixGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.MergeGenerator": schema_pkg_apis_application_v1alpha1_MergeGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.NestedMatrixGenerator": schema_pkg_apis_application_v1alpha1_NestedMatrixGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.NestedMergeGenerator": schema_pkg_apis_application_v1alpha1_NestedMergeGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Operation": schema_pkg_apis_application_v1alpha1_Operation(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OperationInitiator": schema_pkg_apis_application_v1alpha1_OperationInitiator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OperationState": schema_pkg_apis_application_v1alpha1_OperationState(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OptionalArray": schema_pkg_apis_application_v1alpha1_OptionalArray(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OptionalMap": schema_pkg_apis_application_v1alpha1_OptionalMap(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OrphanedResourceKey": schema_pkg_apis_application_v1alpha1_OrphanedResourceKey(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OrphanedResourcesMonitorSettings": schema_pkg_apis_application_v1alpha1_OrphanedResourcesMonitorSettings(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OverrideIgnoreDiff": schema_pkg_apis_application_v1alpha1_OverrideIgnoreDiff(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginConfigMapRef": schema_pkg_apis_application_v1alpha1_PluginConfigMapRef(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginGenerator": schema_pkg_apis_application_v1alpha1_PluginGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginInput": schema_pkg_apis_application_v1alpha1_PluginInput(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ProjectRole": schema_pkg_apis_application_v1alpha1_ProjectRole(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGenerator": schema_pkg_apis_application_v1alpha1_PullRequestGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorAzureDevOps": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorAzureDevOps(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorBitbucket": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorBitbucket(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorBitbucketServer": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorBitbucketServer(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorFilter": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorFilter(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorGitLab": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGitLab(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorGitea": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGitea(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorGithub": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGithub(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RefTarget": schema_pkg_apis_application_v1alpha1_RefTarget(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RepoCreds": schema_pkg_apis_application_v1alpha1_RepoCreds(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RepoCredsList": schema_pkg_apis_application_v1alpha1_RepoCredsList(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Repository": schema_pkg_apis_application_v1alpha1_Repository(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RepositoryCertificate": schema_pkg_apis_application_v1alpha1_RepositoryCertificate(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RepositoryCertificateList": schema_pkg_apis_application_v1alpha1_RepositoryCertificateList(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RepositoryList": schema_pkg_apis_application_v1alpha1_RepositoryList(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceAction": schema_pkg_apis_application_v1alpha1_ResourceAction(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceActionDefinition": schema_pkg_apis_application_v1alpha1_ResourceActionDefinition(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceActionParam": schema_pkg_apis_application_v1alpha1_ResourceActionParam(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceActions": schema_pkg_apis_application_v1alpha1_ResourceActions(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceDiff": schema_pkg_apis_application_v1alpha1_ResourceDiff(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences": schema_pkg_apis_application_v1alpha1_ResourceIgnoreDifferences(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceNetworkingInfo": schema_pkg_apis_application_v1alpha1_ResourceNetworkingInfo(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceNode": schema_pkg_apis_application_v1alpha1_ResourceNode(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceOverride": schema_pkg_apis_application_v1alpha1_ResourceOverride(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceRef": schema_pkg_apis_application_v1alpha1_ResourceRef(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceResult": schema_pkg_apis_application_v1alpha1_ResourceResult(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceStatus": schema_pkg_apis_application_v1alpha1_ResourceStatus(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RetryStrategy": schema_pkg_apis_application_v1alpha1_RetryStrategy(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RevisionHistory": schema_pkg_apis_application_v1alpha1_RevisionHistory(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RevisionMetadata": schema_pkg_apis_application_v1alpha1_RevisionMetadata(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGenerator": schema_pkg_apis_application_v1alpha1_SCMProviderGenerator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorAWSCodeCommit": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorAWSCodeCommit(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorAzureDevOps": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorAzureDevOps(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorBitbucket": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorBitbucket(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorBitbucketServer": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorBitbucketServer(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorFilter": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorFilter(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitea": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGitea(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorGithub": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGithub(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitlab": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGitlab(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef": schema_pkg_apis_application_v1alpha1_SecretRef(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SignatureKey": schema_pkg_apis_application_v1alpha1_SignatureKey(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator": schema_pkg_apis_application_v1alpha1_SourceHydrator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydratorStatus": schema_pkg_apis_application_v1alpha1_SourceHydratorStatus(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SuccessfulHydrateOperation": schema_pkg_apis_application_v1alpha1_SuccessfulHydrateOperation(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncOperation": schema_pkg_apis_application_v1alpha1_SyncOperation(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncOperationResource": schema_pkg_apis_application_v1alpha1_SyncOperationResource(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncOperationResult": schema_pkg_apis_application_v1alpha1_SyncOperationResult(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncPolicy": schema_pkg_apis_application_v1alpha1_SyncPolicy(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncPolicyAutomated": schema_pkg_apis_application_v1alpha1_SyncPolicyAutomated(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncSource": schema_pkg_apis_application_v1alpha1_SyncSource(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStatus": schema_pkg_apis_application_v1alpha1_SyncStatus(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStrategy": schema_pkg_apis_application_v1alpha1_SyncStrategy(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStrategyApply": schema_pkg_apis_application_v1alpha1_SyncStrategyApply(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStrategyHook": schema_pkg_apis_application_v1alpha1_SyncStrategyHook(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncWindow": schema_pkg_apis_application_v1alpha1_SyncWindow(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.TLSClientConfig": schema_pkg_apis_application_v1alpha1_TLSClientConfig(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.TagFilter": schema_pkg_apis_application_v1alpha1_TagFilter(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.objectMeta": schema_pkg_apis_application_v1alpha1_objectMeta(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.rawResourceOverride": schema_pkg_apis_application_v1alpha1_rawResourceOverride(ref), } } @@ -239,20 +239,20 @@ func schema_pkg_apis_application_v1alpha1_AppProject(ref common.ReferenceCallbac }, "metadata": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), }, }, "spec": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AppProjectSpec"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AppProjectSpec"), }, }, "status": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AppProjectStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AppProjectStatus"), }, }, }, @@ -260,7 +260,7 @@ func schema_pkg_apis_application_v1alpha1_AppProject(ref common.ReferenceCallbac }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AppProjectSpec", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AppProjectStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AppProjectSpec", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AppProjectStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, } } @@ -287,7 +287,7 @@ func schema_pkg_apis_application_v1alpha1_AppProjectList(ref common.ReferenceCal }, "metadata": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), }, }, @@ -297,8 +297,8 @@ func schema_pkg_apis_application_v1alpha1_AppProjectList(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AppProject"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AppProject"), }, }, }, @@ -309,7 +309,7 @@ func schema_pkg_apis_application_v1alpha1_AppProjectList(ref common.ReferenceCal }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AppProject", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AppProject", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, } } @@ -342,8 +342,8 @@ func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationDestination"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestination"), }, }, }, @@ -363,8 +363,8 @@ func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ProjectRole"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ProjectRole"), }, }, }, @@ -377,7 +377,7 @@ func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind"), }, }, @@ -391,7 +391,7 @@ func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind"), }, }, @@ -401,7 +401,7 @@ func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCal "orphanedResources": { SchemaProps: spec.SchemaProps{ Description: "OrphanedResources specifies if controller should monitor orphaned resources of apps in this project", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OrphanedResourcesMonitorSettings"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OrphanedResourcesMonitorSettings"), }, }, "syncWindows": { @@ -411,7 +411,7 @@ func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncWindow"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncWindow"), }, }, }, @@ -424,7 +424,7 @@ func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind"), }, }, @@ -438,8 +438,8 @@ func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SignatureKey"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SignatureKey"), }, }, }, @@ -452,7 +452,7 @@ func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind"), }, }, @@ -488,8 +488,8 @@ func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationDestinationServiceAccount"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestinationServiceAccount"), }, }, }, @@ -499,7 +499,7 @@ func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCal }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationDestination", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationDestinationServiceAccount", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OrphanedResourcesMonitorSettings", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ProjectRole", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SignatureKey", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncWindow", "k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestination", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestinationServiceAccount", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OrphanedResourcesMonitorSettings", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ProjectRole", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SignatureKey", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncWindow", "k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind"}, } } @@ -518,8 +518,8 @@ func schema_pkg_apis_application_v1alpha1_AppProjectStatus(ref common.ReferenceC Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.JWTTokens"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JWTTokens"), }, }, }, @@ -529,7 +529,7 @@ func schema_pkg_apis_application_v1alpha1_AppProjectStatus(ref common.ReferenceC }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.JWTTokens"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JWTTokens"}, } } @@ -556,25 +556,25 @@ func schema_pkg_apis_application_v1alpha1_Application(ref common.ReferenceCallba }, "metadata": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), }, }, "spec": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSpec"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSpec"), }, }, "status": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationStatus"), }, }, "operation": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Operation"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Operation"), }, }, }, @@ -582,7 +582,7 @@ func schema_pkg_apis_application_v1alpha1_Application(ref common.ReferenceCallba }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSpec", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationStatus", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Operation", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSpec", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationStatus", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Operation", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, } } @@ -715,7 +715,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationList(ref common.ReferenceCa }, "metadata": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), }, }, @@ -725,8 +725,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationList(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Application"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Application"), }, }, }, @@ -737,7 +737,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationList(ref common.ReferenceCa }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Application", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Application", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, } } @@ -842,20 +842,20 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSet(ref common.ReferenceCal }, "metadata": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), }, }, "spec": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetSpec"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetSpec"), }, }, "status": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetStatus"), }, }, }, @@ -863,7 +863,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSet(ref common.ReferenceCal }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetSpec", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetSpec", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, } } @@ -999,42 +999,42 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetGenerator(ref common.Ref Properties: map[string]spec.Schema{ "list": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ListGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ListGenerator"), }, }, "clusters": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterGenerator"), }, }, "git": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitGenerator"), }, }, "scmProvider": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGenerator"), }, }, "clusterDecisionResource": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.DuckTypeGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DuckTypeGenerator"), }, }, "pullRequest": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGenerator"), }, }, "matrix": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.MatrixGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.MatrixGenerator"), }, }, "merge": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.MergeGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.MergeGenerator"), }, }, "selector": { @@ -1045,14 +1045,14 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetGenerator(ref common.Ref }, "plugin": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginGenerator"), }, }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.DuckTypeGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ListGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.MatrixGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.MergeGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGenerator", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DuckTypeGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ListGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.MatrixGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.MergeGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGenerator", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, } } @@ -1079,7 +1079,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetList(ref common.Referenc }, "metadata": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), }, }, @@ -1089,8 +1089,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetList(ref common.Referenc Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSet"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSet"), }, }, }, @@ -1101,7 +1101,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetList(ref common.Referenc }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSet", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSet", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, } } @@ -1114,32 +1114,32 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetNestedGenerator(ref comm Properties: map[string]spec.Schema{ "list": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ListGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ListGenerator"), }, }, "clusters": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterGenerator"), }, }, "git": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitGenerator"), }, }, "scmProvider": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGenerator"), }, }, "clusterDecisionResource": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.DuckTypeGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DuckTypeGenerator"), }, }, "pullRequest": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGenerator"), }, }, "matrix": { @@ -1162,14 +1162,14 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetNestedGenerator(ref comm }, "plugin": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginGenerator"), }, }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.DuckTypeGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ListGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGenerator", "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DuckTypeGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ListGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGenerator", "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, } } @@ -1235,8 +1235,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetRolloutStep(ref common.R Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationMatchExpression"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationMatchExpression"), }, }, }, @@ -1251,7 +1251,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetRolloutStep(ref common.R }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationMatchExpression", "k8s.io/apimachinery/pkg/util/intstr.IntOrString"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationMatchExpression", "k8s.io/apimachinery/pkg/util/intstr.IntOrString"}, } } @@ -1267,8 +1267,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetRolloutStrategy(ref comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetRolloutStep"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetRolloutStep"), }, }, }, @@ -1278,7 +1278,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetRolloutStrategy(ref comm }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetRolloutStep"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetRolloutStep"}, } } @@ -1301,8 +1301,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetSpec(ref common.Referenc Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetGenerator"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetGenerator"), }, }, }, @@ -1310,23 +1310,23 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetSpec(ref common.Referenc }, "template": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), }, }, "syncPolicy": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetSyncPolicy"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetSyncPolicy"), }, }, "strategy": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetStrategy"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetStrategy"), }, }, "preservedFields": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationPreservedFields"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationPreservedFields"), }, }, "goTemplateOptions": { @@ -1356,8 +1356,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetSpec(ref common.Referenc Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetResourceIgnoreDifferences"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetResourceIgnoreDifferences"), }, }, }, @@ -1374,7 +1374,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetSpec(ref common.Referenc }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationPreservedFields", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetResourceIgnoreDifferences", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetStrategy", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetSyncPolicy", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationPreservedFields", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetResourceIgnoreDifferences", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetStrategy", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetSyncPolicy", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"}, } } @@ -1392,8 +1392,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetStatus(ref common.Refere Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetCondition"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetCondition"), }, }, }, @@ -1405,8 +1405,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetStatus(ref common.Refere Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetApplicationStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetApplicationStatus"), }, }, }, @@ -1419,8 +1419,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetStatus(ref common.Refere Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceStatus"), }, }, }, @@ -1430,7 +1430,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetStatus(ref common.Refere }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetApplicationStatus", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetCondition", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceStatus"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetApplicationStatus", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetCondition", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceStatus"}, } } @@ -1449,14 +1449,14 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetStrategy(ref common.Refe }, "rollingSync": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetRolloutStrategy"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetRolloutStrategy"), }, }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetRolloutStrategy"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetRolloutStrategy"}, } } @@ -1496,14 +1496,14 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetTemplate(ref common.Refe Properties: map[string]spec.Schema{ "metadata": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplateMeta"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplateMeta"), }, }, "spec": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSpec"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSpec"), }, }, }, @@ -1511,7 +1511,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetTemplate(ref common.Refe }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplateMeta", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSpec"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplateMeta", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSpec"}, } } @@ -1593,37 +1593,37 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetTerminalGenerator(ref co Properties: map[string]spec.Schema{ "list": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ListGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ListGenerator"), }, }, "clusters": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterGenerator"), }, }, "git": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitGenerator"), }, }, "scmProvider": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGenerator"), }, }, "clusterDecisionResource": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.DuckTypeGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DuckTypeGenerator"), }, }, "pullRequest": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGenerator"), }, }, "plugin": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginGenerator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginGenerator"), }, }, "selector": { @@ -1636,7 +1636,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetTerminalGenerator(ref co }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.DuckTypeGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ListGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGenerator", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DuckTypeGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ListGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGenerator", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, } } @@ -1654,8 +1654,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetTree(ref common.Referenc Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceNode"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceNode"), }, }, }, @@ -1665,7 +1665,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetTree(ref common.Referenc }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceNode"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceNode"}, } } @@ -1701,25 +1701,25 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSource(ref common.Reference "helm": { SchemaProps: spec.SchemaProps{ Description: "Helm holds helm specific options", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourceHelm"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourceHelm"), }, }, "kustomize": { SchemaProps: spec.SchemaProps{ Description: "Kustomize holds kustomize specific options", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourceKustomize"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourceKustomize"), }, }, "directory": { SchemaProps: spec.SchemaProps{ Description: "Directory holds path/directory specific options", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourceDirectory"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourceDirectory"), }, }, "plugin": { SchemaProps: spec.SchemaProps{ Description: "Plugin holds config management plugin specific options", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourcePlugin"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourcePlugin"), }, }, "chart": { @@ -1741,7 +1741,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSource(ref common.Reference }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourceDirectory", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourceHelm", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourceKustomize", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourcePlugin"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourceDirectory", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourceHelm", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourceKustomize", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourcePlugin"}, } } @@ -1762,8 +1762,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceDirectory(ref common. "jsonnet": { SchemaProps: spec.SchemaProps{ Description: "Jsonnet holds options specific to Jsonnet", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourceJsonnet"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourceJsonnet"), }, }, "exclude": { @@ -1784,7 +1784,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceDirectory(ref common. }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourceJsonnet"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourceJsonnet"}, } } @@ -1817,8 +1817,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceHelm(ref common.Refer Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HelmParameter"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HelmParameter"), }, }, }, @@ -1850,8 +1850,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceHelm(ref common.Refer Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HelmFileParameter"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HelmFileParameter"), }, }, }, @@ -1924,7 +1924,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceHelm(ref common.Refer }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HelmFileParameter", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HelmParameter", "k8s.io/apimachinery/pkg/runtime.RawExtension"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HelmFileParameter", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HelmParameter", "k8s.io/apimachinery/pkg/runtime.RawExtension"}, } } @@ -1942,8 +1942,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceJsonnet(ref common.Re Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.JsonnetVar"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JsonnetVar"), }, }, }, @@ -1956,8 +1956,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceJsonnet(ref common.Re Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.JsonnetVar"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JsonnetVar"), }, }, }, @@ -1982,7 +1982,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceJsonnet(ref common.Re }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.JsonnetVar"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JsonnetVar"}, } } @@ -2096,8 +2096,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceKustomize(ref common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KustomizeReplica"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KustomizeReplica"), }, }, }, @@ -2110,8 +2110,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceKustomize(ref common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KustomizePatch"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KustomizePatch"), }, }, }, @@ -2165,7 +2165,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceKustomize(ref common. }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KustomizePatch", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KustomizeReplica"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KustomizePatch", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KustomizeReplica"}, } } @@ -2188,7 +2188,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourcePlugin(ref common.Ref Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.EnvEntry"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.EnvEntry"), }, }, }, @@ -2200,8 +2200,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourcePlugin(ref common.Ref Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourcePluginParameter"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourcePluginParameter"), }, }, }, @@ -2211,7 +2211,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourcePlugin(ref common.Ref }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSourcePluginParameter", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.EnvEntry"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourcePluginParameter", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.EnvEntry"}, } } @@ -2251,14 +2251,14 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref common.ReferenceCa "source": { SchemaProps: spec.SchemaProps{ Description: "Source is a reference to the location of the application's manifests or chart", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), }, }, "destination": { SchemaProps: spec.SchemaProps{ Description: "Destination is a reference to the target Kubernetes server and namespace", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationDestination"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestination"), }, }, "project": { @@ -2272,7 +2272,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref common.ReferenceCa "syncPolicy": { SchemaProps: spec.SchemaProps{ Description: "SyncPolicy controls when and how a sync will be performed", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncPolicy"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncPolicy"), }, }, "ignoreDifferences": { @@ -2282,8 +2282,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences"), }, }, }, @@ -2296,8 +2296,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Info"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Info"), }, }, }, @@ -2317,8 +2317,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), }, }, }, @@ -2327,7 +2327,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref common.ReferenceCa "sourceHydrator": { SchemaProps: spec.SchemaProps{ Description: "SourceHydrator provides a way to push hydrated manifests back to git before syncing them to the cluster.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SourceHydrator"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator"), }, }, }, @@ -2335,7 +2335,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref common.ReferenceCa }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationDestination", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Info", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SourceHydrator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncPolicy"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestination", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Info", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncPolicy"}, } } @@ -2353,8 +2353,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceStatus"), }, }, }, @@ -2363,15 +2363,15 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference "sync": { SchemaProps: spec.SchemaProps{ Description: "Sync contains information about the application's current sync status", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStatus"), }, }, "health": { SchemaProps: spec.SchemaProps{ Description: "Health contains information about the application's current health status", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HealthStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HealthStatus"), }, }, "history": { @@ -2381,8 +2381,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RevisionHistory"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RevisionHistory"), }, }, }, @@ -2395,8 +2395,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationCondition"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationCondition"), }, }, }, @@ -2411,7 +2411,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference "operationState": { SchemaProps: spec.SchemaProps{ Description: "OperationState contains information about any ongoing operations, such as a sync", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OperationState"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OperationState"), }, }, "observedAt": { @@ -2430,8 +2430,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference "summary": { SchemaProps: spec.SchemaProps{ Description: "Summary contains a list of URLs and container images used by this application", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSummary"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSummary"), }, }, "resourceHealthSource": { @@ -2466,15 +2466,15 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference "sourceHydrator": { SchemaProps: spec.SchemaProps{ Description: "SourceHydrator stores information about the current state of source hydration", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SourceHydratorStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydratorStatus"), }, }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationCondition", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSummary", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HealthStatus", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OperationState", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceStatus", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RevisionHistory", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SourceHydratorStatus", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationCondition", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSummary", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HealthStatus", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OperationState", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceStatus", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RevisionHistory", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydratorStatus", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } @@ -2535,8 +2535,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationTree(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceNode"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceNode"), }, }, }, @@ -2549,8 +2549,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationTree(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceNode"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceNode"), }, }, }, @@ -2563,8 +2563,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationTree(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HostInfo"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HostInfo"), }, }, }, @@ -2574,7 +2574,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationTree(ref common.ReferenceCa }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HostInfo", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceNode"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HostInfo", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceNode"}, } } @@ -2595,8 +2595,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationWatchEvent(ref common.Refer "application": { SchemaProps: spec.SchemaProps{ Description: "Application is:\n * If Type is Added or Modified: the new state of the object.\n * If Type is Deleted: the state of the object immediately before deletion.\n * If Type is Error: *api.Status is recommended; other types may make sense\n depending on context.", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Application"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Application"), }, }, }, @@ -2604,7 +2604,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationWatchEvent(ref common.Refer }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Application"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Application"}, } } @@ -2660,7 +2660,7 @@ func schema_pkg_apis_application_v1alpha1_BasicAuthBitbucketServer(ref common.Re "passwordRef": { SchemaProps: spec.SchemaProps{ Description: "Password (or personal access token) reference.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), }, }, }, @@ -2668,7 +2668,7 @@ func schema_pkg_apis_application_v1alpha1_BasicAuthBitbucketServer(ref common.Re }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, } } @@ -2682,7 +2682,7 @@ func schema_pkg_apis_application_v1alpha1_BearerTokenBitbucket(ref common.Refere "tokenRef": { SchemaProps: spec.SchemaProps{ Description: "Password (or personal access token) reference.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), }, }, }, @@ -2690,7 +2690,7 @@ func schema_pkg_apis_application_v1alpha1_BearerTokenBitbucket(ref common.Refere }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, } } @@ -2704,7 +2704,7 @@ func schema_pkg_apis_application_v1alpha1_BearerTokenBitbucketCloud(ref common.R "tokenRef": { SchemaProps: spec.SchemaProps{ Description: "Password (or personal access token) reference.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), }, }, }, @@ -2712,7 +2712,7 @@ func schema_pkg_apis_application_v1alpha1_BearerTokenBitbucketCloud(ref common.R }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, } } @@ -2783,15 +2783,15 @@ func schema_pkg_apis_application_v1alpha1_Cluster(ref common.ReferenceCallback) "config": { SchemaProps: spec.SchemaProps{ Description: "Config holds cluster information for connecting to a cluster", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterConfig"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterConfig"), }, }, "connectionState": { SchemaProps: spec.SchemaProps{ Description: "Deprecated: use Info.ConnectionState field instead. ConnectionState contains information about cluster connection state", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConnectionState"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConnectionState"), }, }, "serverVersion": { @@ -2825,8 +2825,8 @@ func schema_pkg_apis_application_v1alpha1_Cluster(ref common.ReferenceCallback) "info": { SchemaProps: spec.SchemaProps{ Description: "Info holds information about cluster cache and state", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterInfo"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterInfo"), }, }, "shard": { @@ -2887,7 +2887,7 @@ func schema_pkg_apis_application_v1alpha1_Cluster(ref common.ReferenceCallback) }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterConfig", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterInfo", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConnectionState", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterConfig", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterInfo", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConnectionState", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } @@ -2956,20 +2956,20 @@ func schema_pkg_apis_application_v1alpha1_ClusterConfig(ref common.ReferenceCall "tlsClientConfig": { SchemaProps: spec.SchemaProps{ Description: "TLSClientConfig contains settings to enable transport layer security", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.TLSClientConfig"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.TLSClientConfig"), }, }, "awsAuthConfig": { SchemaProps: spec.SchemaProps{ Description: "AWSAuthConfig contains IAM authentication configuration", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AWSAuthConfig"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AWSAuthConfig"), }, }, "execProviderConfig": { SchemaProps: spec.SchemaProps{ Description: "ExecProviderConfig contains configuration for an exec provider", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ExecProviderConfig"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ExecProviderConfig"), }, }, }, @@ -2977,7 +2977,7 @@ func schema_pkg_apis_application_v1alpha1_ClusterConfig(ref common.ReferenceCall }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.AWSAuthConfig", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ExecProviderConfig", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.TLSClientConfig"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.AWSAuthConfig", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ExecProviderConfig", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.TLSClientConfig"}, } } @@ -2991,14 +2991,14 @@ func schema_pkg_apis_application_v1alpha1_ClusterGenerator(ref common.ReferenceC "selector": { SchemaProps: spec.SchemaProps{ Description: "Selector defines a label selector to match against all clusters registered with ArgoCD. Clusters today are stored as Kubernetes Secrets, thus the Secret labels will be used for matching the selector.", - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"), }, }, "template": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), }, }, "values": { @@ -3028,7 +3028,7 @@ func schema_pkg_apis_application_v1alpha1_ClusterGenerator(ref common.ReferenceC }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, } } @@ -3042,8 +3042,8 @@ func schema_pkg_apis_application_v1alpha1_ClusterInfo(ref common.ReferenceCallba "connectionState": { SchemaProps: spec.SchemaProps{ Description: "ConnectionState contains information about the connection to the cluster", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConnectionState"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConnectionState"), }, }, "serverVersion": { @@ -3056,8 +3056,8 @@ func schema_pkg_apis_application_v1alpha1_ClusterInfo(ref common.ReferenceCallba "cacheInfo": { SchemaProps: spec.SchemaProps{ Description: "CacheInfo contains information about the cluster cache", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterCacheInfo"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterCacheInfo"), }, }, "applicationsCount": { @@ -3088,7 +3088,7 @@ func schema_pkg_apis_application_v1alpha1_ClusterInfo(ref common.ReferenceCallba }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ClusterCacheInfo", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConnectionState"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ClusterCacheInfo", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConnectionState"}, } } @@ -3101,7 +3101,7 @@ func schema_pkg_apis_application_v1alpha1_ClusterList(ref common.ReferenceCallba Properties: map[string]spec.Schema{ "metadata": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), }, }, @@ -3111,8 +3111,8 @@ func schema_pkg_apis_application_v1alpha1_ClusterList(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Cluster"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Cluster"), }, }, }, @@ -3123,7 +3123,7 @@ func schema_pkg_apis_application_v1alpha1_ClusterList(ref common.ReferenceCallba }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Cluster", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Cluster", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, } } @@ -3178,15 +3178,15 @@ func schema_pkg_apis_application_v1alpha1_ComparedTo(ref common.ReferenceCallbac "source": { SchemaProps: spec.SchemaProps{ Description: "Source is a reference to the application's source used for comparison", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), }, }, "destination": { SchemaProps: spec.SchemaProps{ Description: "Destination is a reference to the application's destination used for comparison", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationDestination"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestination"), }, }, "sources": { @@ -3196,8 +3196,8 @@ func schema_pkg_apis_application_v1alpha1_ComparedTo(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), }, }, }, @@ -3210,8 +3210,8 @@ func schema_pkg_apis_application_v1alpha1_ComparedTo(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences"), }, }, }, @@ -3222,7 +3222,7 @@ func schema_pkg_apis_application_v1alpha1_ComparedTo(ref common.ReferenceCallbac }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationDestination", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestination", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences"}, } } @@ -3276,13 +3276,13 @@ func schema_pkg_apis_application_v1alpha1_ConfigManagementPlugin(ref common.Refe }, "init": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Command"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Command"), }, }, "generate": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Command"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Command"), }, }, "lockRepo": { @@ -3296,7 +3296,7 @@ func schema_pkg_apis_application_v1alpha1_ConfigManagementPlugin(ref common.Refe }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Command"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Command"}, } } @@ -3433,14 +3433,14 @@ func schema_pkg_apis_application_v1alpha1_DuckTypeGenerator(ref common.Reference }, "labelSelector": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"), }, }, "template": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), }, }, "values": { @@ -3464,7 +3464,7 @@ func schema_pkg_apis_application_v1alpha1_DuckTypeGenerator(ref common.Reference }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, } } @@ -3662,8 +3662,8 @@ func schema_pkg_apis_application_v1alpha1_GitGenerator(ref common.ReferenceCallb Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitDirectoryGeneratorItem"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitDirectoryGeneratorItem"), }, }, }, @@ -3675,8 +3675,8 @@ func schema_pkg_apis_application_v1alpha1_GitGenerator(ref common.ReferenceCallb Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitFileGeneratorItem"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitFileGeneratorItem"), }, }, }, @@ -3697,8 +3697,8 @@ func schema_pkg_apis_application_v1alpha1_GitGenerator(ref common.ReferenceCallb }, "template": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), }, }, "pathParamPrefix": { @@ -3728,7 +3728,7 @@ func schema_pkg_apis_application_v1alpha1_GitGenerator(ref common.ReferenceCallb }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitDirectoryGeneratorItem", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GitFileGeneratorItem"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitDirectoryGeneratorItem", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitFileGeneratorItem"}, } } @@ -3798,7 +3798,7 @@ func schema_pkg_apis_application_v1alpha1_GnuPGPublicKeyList(ref common.Referenc Properties: map[string]spec.Schema{ "metadata": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), }, }, @@ -3808,8 +3808,8 @@ func schema_pkg_apis_application_v1alpha1_GnuPGPublicKeyList(ref common.Referenc Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GnuPGPublicKey"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GnuPGPublicKey"), }, }, }, @@ -3820,7 +3820,7 @@ func schema_pkg_apis_application_v1alpha1_GnuPGPublicKeyList(ref common.Referenc }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.GnuPGPublicKey", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GnuPGPublicKey", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, } } @@ -3967,8 +3967,8 @@ func schema_pkg_apis_application_v1alpha1_HostInfo(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HostResourceInfo"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HostResourceInfo"), }, }, }, @@ -3976,7 +3976,7 @@ func schema_pkg_apis_application_v1alpha1_HostInfo(ref common.ReferenceCallback) }, "systemInfo": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/api/core/v1.NodeSystemInfo"), }, }, @@ -3984,7 +3984,7 @@ func schema_pkg_apis_application_v1alpha1_HostInfo(ref common.ReferenceCallback) }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HostResourceInfo", "k8s.io/api/core/v1.NodeSystemInfo"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HostResourceInfo", "k8s.io/api/core/v1.NodeSystemInfo"}, } } @@ -4076,8 +4076,8 @@ func schema_pkg_apis_application_v1alpha1_HydrateOperation(ref common.ReferenceC "sourceHydrator": { SchemaProps: spec.SchemaProps{ Description: "SourceHydrator holds the hydrator config used for the hydrate operation", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SourceHydrator"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator"), }, }, }, @@ -4085,7 +4085,7 @@ func schema_pkg_apis_application_v1alpha1_HydrateOperation(ref common.ReferenceC }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SourceHydrator", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } @@ -4211,8 +4211,8 @@ func schema_pkg_apis_application_v1alpha1_JWTTokens(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.JWTToken"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JWTToken"), }, }, }, @@ -4222,7 +4222,7 @@ func schema_pkg_apis_application_v1alpha1_JWTTokens(ref common.ReferenceCallback }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.JWTToken"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JWTToken"}, } } @@ -4365,7 +4365,7 @@ func schema_pkg_apis_application_v1alpha1_KustomizePatch(ref common.ReferenceCal }, "target": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KustomizeSelector"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KustomizeSelector"), }, }, "options": { @@ -4387,7 +4387,7 @@ func schema_pkg_apis_application_v1alpha1_KustomizePatch(ref common.ReferenceCal }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KustomizeSelector"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KustomizeSelector"}, } } @@ -4537,8 +4537,8 @@ func schema_pkg_apis_application_v1alpha1_ListGenerator(ref common.ReferenceCall }, "template": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), }, }, "elementsYaml": { @@ -4552,7 +4552,7 @@ func schema_pkg_apis_application_v1alpha1_ListGenerator(ref common.ReferenceCall }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON"}, } } @@ -4611,8 +4611,8 @@ func schema_pkg_apis_application_v1alpha1_MatrixGenerator(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetNestedGenerator"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetNestedGenerator"), }, }, }, @@ -4620,8 +4620,8 @@ func schema_pkg_apis_application_v1alpha1_MatrixGenerator(ref common.ReferenceCa }, "template": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), }, }, }, @@ -4629,7 +4629,7 @@ func schema_pkg_apis_application_v1alpha1_MatrixGenerator(ref common.ReferenceCa }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetNestedGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetNestedGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"}, } } @@ -4646,8 +4646,8 @@ func schema_pkg_apis_application_v1alpha1_MergeGenerator(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetNestedGenerator"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetNestedGenerator"), }, }, }, @@ -4669,8 +4669,8 @@ func schema_pkg_apis_application_v1alpha1_MergeGenerator(ref common.ReferenceCal }, "template": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), }, }, }, @@ -4678,7 +4678,7 @@ func schema_pkg_apis_application_v1alpha1_MergeGenerator(ref common.ReferenceCal }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetNestedGenerator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetNestedGenerator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"}, } } @@ -4695,8 +4695,8 @@ func schema_pkg_apis_application_v1alpha1_NestedMatrixGenerator(ref common.Refer Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTerminalGenerator"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTerminalGenerator"), }, }, }, @@ -4707,7 +4707,7 @@ func schema_pkg_apis_application_v1alpha1_NestedMatrixGenerator(ref common.Refer }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTerminalGenerator"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTerminalGenerator"}, } } @@ -4724,8 +4724,8 @@ func schema_pkg_apis_application_v1alpha1_NestedMergeGenerator(ref common.Refere Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTerminalGenerator"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTerminalGenerator"), }, }, }, @@ -4750,7 +4750,7 @@ func schema_pkg_apis_application_v1alpha1_NestedMergeGenerator(ref common.Refere }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTerminalGenerator"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTerminalGenerator"}, } } @@ -4764,14 +4764,14 @@ func schema_pkg_apis_application_v1alpha1_Operation(ref common.ReferenceCallback "sync": { SchemaProps: spec.SchemaProps{ Description: "Sync contains parameters for the operation", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncOperation"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncOperation"), }, }, "initiatedBy": { SchemaProps: spec.SchemaProps{ Description: "InitiatedBy contains information about who initiated the operations", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OperationInitiator"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OperationInitiator"), }, }, "info": { @@ -4781,7 +4781,7 @@ func schema_pkg_apis_application_v1alpha1_Operation(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Info"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Info"), }, }, }, @@ -4790,15 +4790,15 @@ func schema_pkg_apis_application_v1alpha1_Operation(ref common.ReferenceCallback "retry": { SchemaProps: spec.SchemaProps{ Description: "Retry controls the strategy to apply if a sync fails", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RetryStrategy"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RetryStrategy"), }, }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Info", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OperationInitiator", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RetryStrategy", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncOperation"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Info", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OperationInitiator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RetryStrategy", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncOperation"}, } } @@ -4839,8 +4839,8 @@ func schema_pkg_apis_application_v1alpha1_OperationState(ref common.ReferenceCal "operation": { SchemaProps: spec.SchemaProps{ Description: "Operation is the original requested operation", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Operation"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Operation"), }, }, "phase": { @@ -4861,7 +4861,7 @@ func schema_pkg_apis_application_v1alpha1_OperationState(ref common.ReferenceCal "syncResult": { SchemaProps: spec.SchemaProps{ Description: "SyncResult is the result of a Sync operation", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncOperationResult"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncOperationResult"), }, }, "startedAt": { @@ -4888,7 +4888,7 @@ func schema_pkg_apis_application_v1alpha1_OperationState(ref common.ReferenceCal }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Operation", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncOperationResult", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Operation", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncOperationResult", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } @@ -4999,8 +4999,8 @@ func schema_pkg_apis_application_v1alpha1_OrphanedResourcesMonitorSettings(ref c Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OrphanedResourceKey"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OrphanedResourceKey"), }, }, }, @@ -5010,7 +5010,7 @@ func schema_pkg_apis_application_v1alpha1_OrphanedResourcesMonitorSettings(ref c }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OrphanedResourceKey"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OrphanedResourceKey"}, } } @@ -5103,14 +5103,14 @@ func schema_pkg_apis_application_v1alpha1_PluginGenerator(ref common.ReferenceCa Properties: map[string]spec.Schema{ "configMapRef": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginConfigMapRef"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginConfigMapRef"), }, }, "input": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginInput"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginInput"), }, }, "requeueAfterSeconds": { @@ -5122,8 +5122,8 @@ func schema_pkg_apis_application_v1alpha1_PluginGenerator(ref common.ReferenceCa }, "template": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), }, }, "values": { @@ -5147,7 +5147,7 @@ func schema_pkg_apis_application_v1alpha1_PluginGenerator(ref common.ReferenceCa }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginConfigMapRef", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PluginInput"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginConfigMapRef", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PluginInput"}, } } @@ -5223,8 +5223,8 @@ func schema_pkg_apis_application_v1alpha1_ProjectRole(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.JWTToken"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JWTToken"), }, }, }, @@ -5250,7 +5250,7 @@ func schema_pkg_apis_application_v1alpha1_ProjectRole(ref common.ReferenceCallba }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.JWTToken"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JWTToken"}, } } @@ -5264,22 +5264,22 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGenerator(ref common.Refere "github": { SchemaProps: spec.SchemaProps{ Description: "Which provider to use and config for it.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorGithub"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorGithub"), }, }, "gitlab": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorGitLab"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorGitLab"), }, }, "gitea": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorGitea"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorGitea"), }, }, "bitbucketServer": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorBitbucketServer"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorBitbucketServer"), }, }, "filters": { @@ -5289,8 +5289,8 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGenerator(ref common.Refere Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorFilter"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorFilter"), }, }, }, @@ -5305,26 +5305,26 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGenerator(ref common.Refere }, "template": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), }, }, "bitbucket": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorBitbucket"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorBitbucket"), }, }, "azuredevops": { SchemaProps: spec.SchemaProps{ Description: "Additional provider to use and config for it.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorAzureDevOps"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorAzureDevOps"), }, }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorAzureDevOps", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorBitbucket", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorBitbucketServer", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorFilter", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorGitLab", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorGitea", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.PullRequestGeneratorGithub"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorAzureDevOps", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorBitbucket", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorBitbucketServer", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorFilter", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorGitLab", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorGitea", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorGithub"}, } } @@ -5369,7 +5369,7 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorAzureDevOps(ref co "tokenRef": { SchemaProps: spec.SchemaProps{ Description: "Authentication token reference.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), }, }, "labels": { @@ -5392,7 +5392,7 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorAzureDevOps(ref co }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, } } @@ -5429,13 +5429,13 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorBitbucket(ref comm "basicAuth": { SchemaProps: spec.SchemaProps{ Description: "Credentials for Basic auth", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer"), }, }, "bearerToken": { SchemaProps: spec.SchemaProps{ Description: "Credentials for AppToken (Bearer auth)", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BearerTokenBitbucketCloud"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BearerTokenBitbucketCloud"), }, }, }, @@ -5443,7 +5443,7 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorBitbucket(ref comm }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BearerTokenBitbucketCloud"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BearerTokenBitbucketCloud"}, } } @@ -5481,13 +5481,13 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorBitbucketServer(re "basicAuth": { SchemaProps: spec.SchemaProps{ Description: "Credentials for Basic auth", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer"), }, }, "bearerToken": { SchemaProps: spec.SchemaProps{ Description: "Credentials for AccessToken (Bearer auth)", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BearerTokenBitbucket"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BearerTokenBitbucket"), }, }, "insecure": { @@ -5500,7 +5500,7 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorBitbucketServer(re "caRef": { SchemaProps: spec.SchemaProps{ Description: "ConfigMap key holding the trusted certificates", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConfigMapKeyRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef"), }, }, }, @@ -5508,7 +5508,7 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorBitbucketServer(re }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BearerTokenBitbucket", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConfigMapKeyRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BearerTokenBitbucket", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef"}, } } @@ -5562,7 +5562,7 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGitLab(ref common. "tokenRef": { SchemaProps: spec.SchemaProps{ Description: "Authentication token reference.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), }, }, "labels": { @@ -5597,7 +5597,7 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGitLab(ref common. "caRef": { SchemaProps: spec.SchemaProps{ Description: "ConfigMap key holding the trusted certificates", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConfigMapKeyRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef"), }, }, }, @@ -5605,7 +5605,7 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGitLab(ref common. }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConfigMapKeyRef", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, } } @@ -5643,7 +5643,7 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGitea(ref common.R "tokenRef": { SchemaProps: spec.SchemaProps{ Description: "Authentication token reference.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), }, }, "insecure": { @@ -5658,7 +5658,7 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGitea(ref common.R }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, } } @@ -5695,7 +5695,7 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGithub(ref common. "tokenRef": { SchemaProps: spec.SchemaProps{ Description: "Authentication token reference.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), }, }, "appSecretName": { @@ -5725,7 +5725,7 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGithub(ref common. }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, } } @@ -5737,8 +5737,8 @@ func schema_pkg_apis_application_v1alpha1_RefTarget(ref common.ReferenceCallback Properties: map[string]spec.Schema{ "Repo": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Repository"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Repository"), }, }, "TargetRevision": { @@ -5760,7 +5760,7 @@ func schema_pkg_apis_application_v1alpha1_RefTarget(ref common.ReferenceCallback }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Repository"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Repository"}, } } @@ -5900,7 +5900,7 @@ func schema_pkg_apis_application_v1alpha1_RepoCredsList(ref common.ReferenceCall Properties: map[string]spec.Schema{ "metadata": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), }, }, @@ -5910,8 +5910,8 @@ func schema_pkg_apis_application_v1alpha1_RepoCredsList(ref common.ReferenceCall Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RepoCreds"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RepoCreds"), }, }, }, @@ -5922,7 +5922,7 @@ func schema_pkg_apis_application_v1alpha1_RepoCredsList(ref common.ReferenceCall }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RepoCreds", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RepoCreds", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, } } @@ -5965,8 +5965,8 @@ func schema_pkg_apis_application_v1alpha1_Repository(ref common.ReferenceCallbac "connectionState": { SchemaProps: spec.SchemaProps{ Description: "ConnectionState contains information about the current state of connection to the repository server", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConnectionState"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConnectionState"), }, }, "insecureIgnoreHostKey": { @@ -6100,7 +6100,7 @@ func schema_pkg_apis_application_v1alpha1_Repository(ref common.ReferenceCallbac }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConnectionState"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConnectionState"}, } } @@ -6166,7 +6166,7 @@ func schema_pkg_apis_application_v1alpha1_RepositoryCertificateList(ref common.R Properties: map[string]spec.Schema{ "metadata": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), }, }, @@ -6177,8 +6177,8 @@ func schema_pkg_apis_application_v1alpha1_RepositoryCertificateList(ref common.R Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RepositoryCertificate"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RepositoryCertificate"), }, }, }, @@ -6189,7 +6189,7 @@ func schema_pkg_apis_application_v1alpha1_RepositoryCertificateList(ref common.R }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RepositoryCertificate", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RepositoryCertificate", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, } } @@ -6202,7 +6202,7 @@ func schema_pkg_apis_application_v1alpha1_RepositoryList(ref common.ReferenceCal Properties: map[string]spec.Schema{ "metadata": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), }, }, @@ -6212,7 +6212,7 @@ func schema_pkg_apis_application_v1alpha1_RepositoryList(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Repository"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Repository"), }, }, }, @@ -6223,7 +6223,7 @@ func schema_pkg_apis_application_v1alpha1_RepositoryList(ref common.ReferenceCal }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Repository", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Repository", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, } } @@ -6245,8 +6245,8 @@ func schema_pkg_apis_application_v1alpha1_ResourceAction(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceActionParam"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceActionParam"), }, }, }, @@ -6270,35 +6270,11 @@ func schema_pkg_apis_application_v1alpha1_ResourceAction(ref common.ReferenceCal Format: "", }, }, - "defaultValue": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "hasParameters": { - SchemaProps: spec.SchemaProps{ - Type: []string{"boolean"}, - Format: "", - }, - }, - "regexp": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "errorMessage": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceActionParam"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceActionParam"}, } } @@ -6383,8 +6359,8 @@ func schema_pkg_apis_application_v1alpha1_ResourceActions(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceActionDefinition"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceActionDefinition"), }, }, }, @@ -6394,7 +6370,7 @@ func schema_pkg_apis_application_v1alpha1_ResourceActions(ref common.ReferenceCa }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceActionDefinition"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceActionDefinition"}, } } @@ -6598,8 +6574,8 @@ func schema_pkg_apis_application_v1alpha1_ResourceNetworkingInfo(ref common.Refe Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceRef"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceRef"), }, }, }, @@ -6626,7 +6602,7 @@ func schema_pkg_apis_application_v1alpha1_ResourceNetworkingInfo(ref common.Refe Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, + Default: map[string]interface{}{}, Ref: ref("k8s.io/api/core/v1.LoadBalancerIngress"), }, }, @@ -6652,7 +6628,7 @@ func schema_pkg_apis_application_v1alpha1_ResourceNetworkingInfo(ref common.Refe }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceRef", "k8s.io/api/core/v1.LoadBalancerIngress"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceRef", "k8s.io/api/core/v1.LoadBalancerIngress"}, } } @@ -6705,8 +6681,8 @@ func schema_pkg_apis_application_v1alpha1_ResourceNode(ref common.ReferenceCallb Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceRef"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceRef"), }, }, }, @@ -6718,8 +6694,8 @@ func schema_pkg_apis_application_v1alpha1_ResourceNode(ref common.ReferenceCallb Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.InfoItem"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.InfoItem"), }, }, }, @@ -6727,7 +6703,7 @@ func schema_pkg_apis_application_v1alpha1_ResourceNode(ref common.ReferenceCallb }, "networkingInfo": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceNetworkingInfo"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceNetworkingInfo"), }, }, "resourceVersion": { @@ -6752,7 +6728,7 @@ func schema_pkg_apis_application_v1alpha1_ResourceNode(ref common.ReferenceCallb }, "health": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HealthStatus"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HealthStatus"), }, }, "createdAt": { @@ -6764,7 +6740,7 @@ func schema_pkg_apis_application_v1alpha1_ResourceNode(ref common.ReferenceCallb }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HealthStatus", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.InfoItem", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceNetworkingInfo", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceRef", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HealthStatus", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.InfoItem", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceNetworkingInfo", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceRef", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } @@ -6798,14 +6774,14 @@ func schema_pkg_apis_application_v1alpha1_ResourceOverride(ref common.ReferenceC }, "IgnoreDifferences": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OverrideIgnoreDiff"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OverrideIgnoreDiff"), }, }, "IgnoreResourceUpdates": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OverrideIgnoreDiff"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OverrideIgnoreDiff"), }, }, "KnownTypeFields": { @@ -6814,8 +6790,8 @@ func schema_pkg_apis_application_v1alpha1_ResourceOverride(ref common.ReferenceC Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KnownTypeField"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KnownTypeField"), }, }, }, @@ -6826,7 +6802,7 @@ func schema_pkg_apis_application_v1alpha1_ResourceOverride(ref common.ReferenceC }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KnownTypeField", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OverrideIgnoreDiff"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KnownTypeField", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OverrideIgnoreDiff"}, } } @@ -7013,7 +6989,7 @@ func schema_pkg_apis_application_v1alpha1_ResourceStatus(ref common.ReferenceCal }, "health": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HealthStatus"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HealthStatus"), }, }, "hook": { @@ -7038,7 +7014,7 @@ func schema_pkg_apis_application_v1alpha1_ResourceStatus(ref common.ReferenceCal }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HealthStatus"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HealthStatus"}, } } @@ -7059,14 +7035,14 @@ func schema_pkg_apis_application_v1alpha1_RetryStrategy(ref common.ReferenceCall "backoff": { SchemaProps: spec.SchemaProps{ Description: "Backoff controls how to backoff on subsequent retries of failed syncs", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Backoff"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Backoff"), }, }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.Backoff"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Backoff"}, } } @@ -7101,8 +7077,8 @@ func schema_pkg_apis_application_v1alpha1_RevisionHistory(ref common.ReferenceCa "source": { SchemaProps: spec.SchemaProps{ Description: "Source is a reference to the application source used for the sync operation", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), }, }, "deployStartedAt": { @@ -7118,8 +7094,8 @@ func schema_pkg_apis_application_v1alpha1_RevisionHistory(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), }, }, }, @@ -7143,8 +7119,8 @@ func schema_pkg_apis_application_v1alpha1_RevisionHistory(ref common.ReferenceCa "initiatedBy": { SchemaProps: spec.SchemaProps{ Description: "InitiatedBy contains information about who initiated the operations", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OperationInitiator"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OperationInitiator"), }, }, }, @@ -7152,7 +7128,7 @@ func schema_pkg_apis_application_v1alpha1_RevisionHistory(ref common.ReferenceCa }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.OperationInitiator", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OperationInitiator", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } @@ -7224,32 +7200,32 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGenerator(ref common.Refere "github": { SchemaProps: spec.SchemaProps{ Description: "Which provider to use and config for it.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorGithub"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorGithub"), }, }, "gitlab": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitlab"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitlab"), }, }, "bitbucket": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorBitbucket"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorBitbucket"), }, }, "bitbucketServer": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorBitbucketServer"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorBitbucketServer"), }, }, "gitea": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitea"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitea"), }, }, "azureDevOps": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorAzureDevOps"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorAzureDevOps"), }, }, "filters": { @@ -7259,8 +7235,8 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGenerator(ref common.Refere Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorFilter"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorFilter"), }, }, }, @@ -7282,8 +7258,8 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGenerator(ref common.Refere }, "template": { SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate"), }, }, "values": { @@ -7304,14 +7280,14 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGenerator(ref common.Refere }, "awsCodeCommit": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorAWSCodeCommit"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorAWSCodeCommit"), }, }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorAWSCodeCommit", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorAzureDevOps", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorBitbucket", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorBitbucketServer", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorFilter", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitea", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorGithub", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitlab"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSetTemplate", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorAWSCodeCommit", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorAzureDevOps", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorBitbucket", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorBitbucketServer", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorFilter", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitea", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorGithub", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitlab"}, } } @@ -7329,7 +7305,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorAWSCodeCommit(ref Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.TagFilter"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.TagFilter"), }, }, }, @@ -7360,7 +7336,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorAWSCodeCommit(ref }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.TagFilter"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.TagFilter"}, } } @@ -7397,7 +7373,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorAzureDevOps(ref co "accessTokenRef": { SchemaProps: spec.SchemaProps{ Description: "The Personal Access Token (PAT) to use when connecting. Required.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), }, }, "allBranches": { @@ -7412,7 +7388,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorAzureDevOps(ref co }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, } } @@ -7442,7 +7418,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorBitbucket(ref comm "appPasswordRef": { SchemaProps: spec.SchemaProps{ Description: "The app password to use for the user. Required. See: https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), }, }, "allBranches": { @@ -7457,7 +7433,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorBitbucket(ref comm }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, } } @@ -7487,7 +7463,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorBitbucketServer(re "basicAuth": { SchemaProps: spec.SchemaProps{ Description: "Credentials for Basic auth", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer"), }, }, "allBranches": { @@ -7500,7 +7476,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorBitbucketServer(re "bearerToken": { SchemaProps: spec.SchemaProps{ Description: "Credentials for AccessToken (Bearer auth)", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BearerTokenBitbucket"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BearerTokenBitbucket"), }, }, "insecure": { @@ -7513,7 +7489,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorBitbucketServer(re "caRef": { SchemaProps: spec.SchemaProps{ Description: "ConfigMap key holding the trusted certificates", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConfigMapKeyRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef"), }, }, }, @@ -7521,7 +7497,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorBitbucketServer(re }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.BearerTokenBitbucket", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConfigMapKeyRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BearerTokenBitbucket", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef"}, } } @@ -7615,7 +7591,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGitea(ref common.R "tokenRef": { SchemaProps: spec.SchemaProps{ Description: "Authentication token reference.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), }, }, "allBranches": { @@ -7637,7 +7613,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGitea(ref common.R }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, } } @@ -7666,7 +7642,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGithub(ref common. "tokenRef": { SchemaProps: spec.SchemaProps{ Description: "Authentication token reference.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), }, }, "appSecretName": { @@ -7688,7 +7664,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGithub(ref common. }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, } } @@ -7724,7 +7700,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGitlab(ref common. "tokenRef": { SchemaProps: spec.SchemaProps{ Description: "Authentication token reference.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), }, }, "allBranches": { @@ -7758,7 +7734,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGitlab(ref common. "caRef": { SchemaProps: spec.SchemaProps{ Description: "ConfigMap key holding the trusted certificates", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConfigMapKeyRef"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef"), }, }, }, @@ -7766,7 +7742,7 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGitlab(ref common. }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ConfigMapKeyRef", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SecretRef"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, } } @@ -7830,21 +7806,21 @@ func schema_pkg_apis_application_v1alpha1_SourceHydrator(ref common.ReferenceCal "drySource": { SchemaProps: spec.SchemaProps{ Description: "DrySource specifies where the dry \"don't repeat yourself\" manifest source lives.", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.DrySource"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DrySource"), }, }, "syncSource": { SchemaProps: spec.SchemaProps{ Description: "SyncSource specifies where to sync hydrated manifests from.", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncSource"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncSource"), }, }, "hydrateTo": { SchemaProps: spec.SchemaProps{ Description: "HydrateTo specifies an optional \"staging\" location to push hydrated manifests to. An external system would then have to move manifests to the SyncSource, e.g. by pull request.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HydrateTo"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HydrateTo"), }, }, }, @@ -7852,7 +7828,7 @@ func schema_pkg_apis_application_v1alpha1_SourceHydrator(ref common.ReferenceCal }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.DrySource", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HydrateTo", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncSource"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DrySource", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HydrateTo", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncSource"}, } } @@ -7866,20 +7842,20 @@ func schema_pkg_apis_application_v1alpha1_SourceHydratorStatus(ref common.Refere "lastSuccessfulOperation": { SchemaProps: spec.SchemaProps{ Description: "LastSuccessfulOperation holds info about the most recent successful hydration", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SuccessfulHydrateOperation"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SuccessfulHydrateOperation"), }, }, "currentOperation": { SchemaProps: spec.SchemaProps{ Description: "CurrentOperation holds the status of the hydrate operation", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HydrateOperation"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HydrateOperation"), }, }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.HydrateOperation", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SuccessfulHydrateOperation"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HydrateOperation", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SuccessfulHydrateOperation"}, } } @@ -7907,15 +7883,15 @@ func schema_pkg_apis_application_v1alpha1_SuccessfulHydrateOperation(ref common. "sourceHydrator": { SchemaProps: spec.SchemaProps{ Description: "SourceHydrator holds the hydrator config used for the hydrate operation", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SourceHydrator"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator"), }, }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SourceHydrator"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator"}, } } @@ -7950,7 +7926,7 @@ func schema_pkg_apis_application_v1alpha1_SyncOperation(ref common.ReferenceCall "syncStrategy": { SchemaProps: spec.SchemaProps{ Description: "SyncStrategy describes how to perform the sync", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncStrategy"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStrategy"), }, }, "resources": { @@ -7960,8 +7936,8 @@ func schema_pkg_apis_application_v1alpha1_SyncOperation(ref common.ReferenceCall Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncOperationResource"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncOperationResource"), }, }, }, @@ -7970,7 +7946,7 @@ func schema_pkg_apis_application_v1alpha1_SyncOperation(ref common.ReferenceCall "source": { SchemaProps: spec.SchemaProps{ Description: "Source overrides the source definition set in the application. This is typically set in a Rollback operation and is nil during a Sync operation", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), }, }, "manifests": { @@ -8010,8 +7986,8 @@ func schema_pkg_apis_application_v1alpha1_SyncOperation(ref common.ReferenceCall Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), }, }, }, @@ -8036,7 +8012,7 @@ func schema_pkg_apis_application_v1alpha1_SyncOperation(ref common.ReferenceCall }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncOperationResource", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncStrategy"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncOperationResource", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStrategy"}, } } @@ -8094,7 +8070,7 @@ func schema_pkg_apis_application_v1alpha1_SyncOperationResult(ref common.Referen Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceResult"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceResult"), }, }, }, @@ -8111,8 +8087,8 @@ func schema_pkg_apis_application_v1alpha1_SyncOperationResult(ref common.Referen "source": { SchemaProps: spec.SchemaProps{ Description: "Source records the application source information of the sync, used for comparing auto-sync", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), }, }, "sources": { @@ -8122,8 +8098,8 @@ func schema_pkg_apis_application_v1alpha1_SyncOperationResult(ref common.Referen Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), }, }, }, @@ -8147,7 +8123,7 @@ func schema_pkg_apis_application_v1alpha1_SyncOperationResult(ref common.Referen "managedNamespaceMetadata": { SchemaProps: spec.SchemaProps{ Description: "ManagedNamespaceMetadata contains the current sync state of managed namespace metadata", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ManagedNamespaceMetadata"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ManagedNamespaceMetadata"), }, }, }, @@ -8155,7 +8131,7 @@ func schema_pkg_apis_application_v1alpha1_SyncOperationResult(ref common.Referen }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ManagedNamespaceMetadata", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ResourceResult"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ManagedNamespaceMetadata", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceResult"}, } } @@ -8169,7 +8145,7 @@ func schema_pkg_apis_application_v1alpha1_SyncPolicy(ref common.ReferenceCallbac "automated": { SchemaProps: spec.SchemaProps{ Description: "Automated will keep an application synced to the target revision", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncPolicyAutomated"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncPolicyAutomated"), }, }, "syncOptions": { @@ -8190,20 +8166,20 @@ func schema_pkg_apis_application_v1alpha1_SyncPolicy(ref common.ReferenceCallbac "retry": { SchemaProps: spec.SchemaProps{ Description: "Retry controls failed sync retry behavior", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RetryStrategy"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RetryStrategy"), }, }, "managedNamespaceMetadata": { SchemaProps: spec.SchemaProps{ Description: "ManagedNamespaceMetadata controls metadata in the given namespace (if CreateNamespace=true)", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ManagedNamespaceMetadata"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ManagedNamespaceMetadata"), }, }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ManagedNamespaceMetadata", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.RetryStrategy", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncPolicyAutomated"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ManagedNamespaceMetadata", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RetryStrategy", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncPolicyAutomated"}, } } @@ -8289,8 +8265,8 @@ func schema_pkg_apis_application_v1alpha1_SyncStatus(ref common.ReferenceCallbac "comparedTo": { SchemaProps: spec.SchemaProps{ Description: "ComparedTo contains information about what has been compared", - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ComparedTo"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ComparedTo"), }, }, "revision": { @@ -8320,7 +8296,7 @@ func schema_pkg_apis_application_v1alpha1_SyncStatus(ref common.ReferenceCallbac }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.ComparedTo"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ComparedTo"}, } } @@ -8334,20 +8310,20 @@ func schema_pkg_apis_application_v1alpha1_SyncStrategy(ref common.ReferenceCallb "apply": { SchemaProps: spec.SchemaProps{ Description: "Apply will perform a `kubectl apply` to perform the sync.", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncStrategyApply"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStrategyApply"), }, }, "hook": { SchemaProps: spec.SchemaProps{ Description: "Hook will submit any referenced resources to perform the sync. This is the default strategy", - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncStrategyHook"), + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStrategyHook"), }, }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncStrategyApply", "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.SyncStrategyHook"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStrategyApply", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStrategyHook"}, } } @@ -8478,13 +8454,6 @@ func schema_pkg_apis_application_v1alpha1_SyncWindow(ref common.ReferenceCallbac Format: "", }, }, - "andOperator": { - SchemaProps: spec.SchemaProps{ - Description: "UseAndOperator use AND operator for matching applications, namespaces and clusters instead of the default OR operator", - Type: []string{"boolean"}, - Format: "", - }, - }, }, }, }, @@ -8629,8 +8598,8 @@ func schema_pkg_apis_application_v1alpha1_rawResourceOverride(ref common.Referen Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]any{}, - Ref: ref("github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KnownTypeField"), + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KnownTypeField"), }, }, }, @@ -8640,6 +8609,6 @@ func schema_pkg_apis_application_v1alpha1_rawResourceOverride(ref common.Referen }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1.KnownTypeField"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.KnownTypeField"}, } } diff --git a/pkg/apis/application/v1alpha1/register.go b/pkg/apis/application/v1alpha1/register.go index fbb251c06e..beeb03b437 100644 --- a/pkg/apis/application/v1alpha1/register.go +++ b/pkg/apis/application/v1alpha1/register.go @@ -1,7 +1,7 @@ package v1alpha1 import ( - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/apis/application/v1alpha1/repository_types.go b/pkg/apis/application/v1alpha1/repository_types.go index 373fd2c137..047ae14b1a 100644 --- a/pkg/apis/application/v1alpha1/repository_types.go +++ b/pkg/apis/application/v1alpha1/repository_types.go @@ -5,11 +5,10 @@ import ( "net/url" "strings" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/cert" - "github.com/argoproj/argo-cd/v3/util/git" - "github.com/argoproj/argo-cd/v3/util/helm" - "github.com/argoproj/argo-cd/v3/util/workloadidentity" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/cert" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/helm" log "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -46,13 +45,9 @@ type RepoCreds struct { // Proxy specifies the HTTP/HTTPS proxy used to access repos at the repo server Proxy string `json:"proxy,omitempty" protobuf:"bytes,19,opt,name=proxy"` // ForceHttpBasicAuth specifies whether Argo CD should attempt to force basic auth for HTTP connections - ForceHttpBasicAuth bool `json:"forceHttpBasicAuth,omitempty" protobuf:"bytes,20,opt,name=forceHttpBasicAuth"` //nolint:revive //FIXME(var-naming) + ForceHttpBasicAuth bool `json:"forceHttpBasicAuth,omitempty" protobuf:"bytes,20,opt,name=forceHttpBasicAuth"` // NoProxy specifies a list of targets where the proxy isn't used, applies only in cases where the proxy is applied NoProxy string `json:"noProxy,omitempty" protobuf:"bytes,23,opt,name=noProxy"` - // UseAzureWorkloadIdentity specifies whether to use Azure Workload Identity for authentication - UseAzureWorkloadIdentity bool `json:"useAzureWorkloadIdentity,omitempty" protobuf:"bytes,24,opt,name=useAzureWorkloadIdentity"` - // BearerToken contains the bearer token used for Git BitBucket Data Center auth at the repo server - BearerToken string `json:"bearerToken,omitempty" protobuf:"bytes,25,opt,name=bearerToken"` } // Repository is a repository holding application configurations @@ -101,13 +96,9 @@ type Repository struct { // GCPServiceAccountKey specifies the service account key in JSON format to be used for getting credentials to Google Cloud Source repos GCPServiceAccountKey string `json:"gcpServiceAccountKey,omitempty" protobuf:"bytes,21,opt,name=gcpServiceAccountKey"` // ForceHttpBasicAuth specifies whether Argo CD should attempt to force basic auth for HTTP connections - ForceHttpBasicAuth bool `json:"forceHttpBasicAuth,omitempty" protobuf:"bytes,22,opt,name=forceHttpBasicAuth"` //nolint:revive //FIXME(var-naming) + ForceHttpBasicAuth bool `json:"forceHttpBasicAuth,omitempty" protobuf:"bytes,22,opt,name=forceHttpBasicAuth"` // NoProxy specifies a list of targets where the proxy isn't used, applies only in cases where the proxy is applied NoProxy string `json:"noProxy,omitempty" protobuf:"bytes,23,opt,name=noProxy"` - // UseAzureWorkloadIdentity specifies whether to use Azure Workload Identity for authentication - UseAzureWorkloadIdentity bool `json:"useAzureWorkloadIdentity,omitempty" protobuf:"bytes,24,opt,name=useAzureWorkloadIdentity"` - // BearerToken contains the bearer token used for Git BitBucket Data Center auth at the repo server - BearerToken string `json:"bearerToken,omitempty" protobuf:"bytes,25,opt,name=bearerToken"` } // IsInsecure returns true if the repository has been configured to skip server verification @@ -121,8 +112,8 @@ func (repo *Repository) IsLFSEnabled() bool { } // HasCredentials returns true when the repository has been configured with any credentials -func (repo *Repository) HasCredentials() bool { - return repo.Username != "" || repo.Password != "" || repo.BearerToken != "" || repo.SSHPrivateKey != "" || repo.TLSClientCertData != "" || repo.GithubAppPrivateKey != "" || repo.UseAzureWorkloadIdentity +func (m *Repository) HasCredentials() bool { + return m.Username != "" || m.Password != "" || m.SSHPrivateKey != "" || m.TLSClientCertData != "" || m.GithubAppPrivateKey != "" } // CopyCredentialsFromRepo copies all credential information from source repository to receiving repository @@ -134,9 +125,6 @@ func (repo *Repository) CopyCredentialsFromRepo(source *Repository) { if repo.Password == "" { repo.Password = source.Password } - if repo.BearerToken == "" { - repo.BearerToken = source.BearerToken - } if repo.SSHPrivateKey == "" { repo.SSHPrivateKey = source.SSHPrivateKey } @@ -162,7 +150,6 @@ func (repo *Repository) CopyCredentialsFromRepo(source *Repository) { repo.GCPServiceAccountKey = source.GCPServiceAccountKey } repo.ForceHttpBasicAuth = source.ForceHttpBasicAuth - repo.UseAzureWorkloadIdentity = source.UseAzureWorkloadIdentity } } @@ -175,9 +162,6 @@ func (repo *Repository) CopyCredentialsFrom(source *RepoCreds) { if repo.Password == "" { repo.Password = source.Password } - if repo.BearerToken == "" { - repo.BearerToken = source.BearerToken - } if repo.SSHPrivateKey == "" { repo.SSHPrivateKey = source.SSHPrivateKey } @@ -209,7 +193,6 @@ func (repo *Repository) CopyCredentialsFrom(source *RepoCreds) { repo.NoProxy = source.NoProxy } repo.ForceHttpBasicAuth = source.ForceHttpBasicAuth - repo.UseAzureWorkloadIdentity = source.UseAzureWorkloadIdentity } } @@ -218,8 +201,8 @@ func (repo *Repository) GetGitCreds(store git.CredsStore) git.Creds { if repo == nil { return git.NopCreds{} } - if repo.Password != "" || repo.BearerToken != "" { - return git.NewHTTPSCreds(repo.Username, repo.Password, repo.BearerToken, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure(), repo.Proxy, repo.NoProxy, store, repo.ForceHttpBasicAuth) + if repo.Password != "" { + return git.NewHTTPSCreds(repo.Username, repo.Password, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure(), repo.Proxy, repo.NoProxy, store, repo.ForceHttpBasicAuth) } if repo.SSHPrivateKey != "" { return git.NewSSHCreds(repo.SSHPrivateKey, getCAPath(repo.Repo), repo.IsInsecure(), store, repo.Proxy, repo.NoProxy) @@ -230,26 +213,12 @@ func (repo *Repository) GetGitCreds(store git.CredsStore) git.Creds { if repo.GCPServiceAccountKey != "" { return git.NewGoogleCloudCreds(repo.GCPServiceAccountKey, store) } - if repo.UseAzureWorkloadIdentity { - return git.NewAzureWorkloadIdentityCreds(store, workloadidentity.NewWorkloadIdentityTokenProvider()) - } return git.NopCreds{} } // GetHelmCreds returns the credentials from a repository configuration used to authenticate at a Helm repository func (repo *Repository) GetHelmCreds() helm.Creds { - if repo.UseAzureWorkloadIdentity { - return helm.NewAzureWorkloadIdentityCreds( - repo.Repo, - getCAPath(repo.Repo), - []byte(repo.TLSClientCertData), - []byte(repo.TLSClientCertKey), - repo.Insecure, - workloadidentity.NewWorkloadIdentityTokenProvider(), - ) - } - - return helm.HelmCreds{ + return helm.Creds{ Username: repo.Username, Password: repo.Password, CAPath: getCAPath(repo.Repo), @@ -298,50 +267,49 @@ func getCAPath(repoURL string) string { } // CopySettingsFrom copies all repository settings from source to receiver -func (repo *Repository) CopySettingsFrom(source *Repository) { +func (m *Repository) CopySettingsFrom(source *Repository) { if source != nil { - repo.EnableLFS = source.EnableLFS - repo.InsecureIgnoreHostKey = source.InsecureIgnoreHostKey - repo.Insecure = source.Insecure - repo.InheritedCreds = source.InheritedCreds + m.EnableLFS = source.EnableLFS + m.InsecureIgnoreHostKey = source.InsecureIgnoreHostKey + m.Insecure = source.Insecure + m.InheritedCreds = source.InheritedCreds } } // StringForLogging gets a string representation of the Repository which is safe to log or return to the user. -func (repo *Repository) StringForLogging() string { - if repo == nil { +func (m *Repository) StringForLogging() string { + if m == nil { return "" } - return fmt.Sprintf("&Repository{Repo: %q, Type: %q, Name: %q, Project: %q}", repo.Repo, repo.Type, repo.Name, repo.Project) + return fmt.Sprintf("&Repository{Repo: %q, Type: %q, Name: %q, Project: %q}", m.Repo, m.Type, m.Name, m.Project) } // Sanitized returns a copy of the Repository with sensitive information removed. -func (repo *Repository) Sanitized() *Repository { +func (m *Repository) Sanitized() *Repository { return &Repository{ - Repo: repo.Repo, - Type: repo.Type, - Name: repo.Name, - Username: repo.Username, - Insecure: repo.IsInsecure(), - EnableLFS: repo.EnableLFS, - EnableOCI: repo.EnableOCI, - Proxy: repo.Proxy, - NoProxy: repo.NoProxy, - Project: repo.Project, - ForceHttpBasicAuth: repo.ForceHttpBasicAuth, - InheritedCreds: repo.InheritedCreds, - GithubAppId: repo.GithubAppId, - GithubAppInstallationId: repo.GithubAppInstallationId, - GitHubAppEnterpriseBaseURL: repo.GitHubAppEnterpriseBaseURL, - UseAzureWorkloadIdentity: repo.UseAzureWorkloadIdentity, + Repo: m.Repo, + Type: m.Type, + Name: m.Name, + Username: m.Username, + Insecure: m.IsInsecure(), + EnableLFS: m.EnableLFS, + EnableOCI: m.EnableOCI, + Proxy: m.Proxy, + NoProxy: m.NoProxy, + Project: m.Project, + ForceHttpBasicAuth: m.ForceHttpBasicAuth, + InheritedCreds: m.InheritedCreds, + GithubAppId: m.GithubAppId, + GithubAppInstallationId: m.GithubAppInstallationId, + GitHubAppEnterpriseBaseURL: m.GitHubAppEnterpriseBaseURL, } } -func (repo *Repository) Normalize() *Repository { - if repo.Type == "" { - repo.Type = common.DefaultRepoType +func (m *Repository) Normalize() *Repository { + if m.Type == "" { + m.Type = common.DefaultRepoType } - return repo + return m } // Repositories defines a list of Repository configurations diff --git a/pkg/apis/application/v1alpha1/repository_types_test.go b/pkg/apis/application/v1alpha1/repository_types_test.go deleted file mode 100644 index 4d20bf1de9..0000000000 --- a/pkg/apis/application/v1alpha1/repository_types_test.go +++ /dev/null @@ -1,102 +0,0 @@ -package v1alpha1 - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/argoproj/argo-cd/v3/util/git" - "github.com/argoproj/argo-cd/v3/util/helm" -) - -func TestGetGitCredsShouldReturnAzureWorkloadIdentityCredsIfSpecified(t *testing.T) { - repository := Repository{UseAzureWorkloadIdentity: true} - - creds := repository.GetGitCreds(git.NoopCredsStore{}) - - _, ok := creds.(git.AzureWorkloadIdentityCreds) - require.Truef(t, ok, "expected AzureWorkloadIdentityCreds but got %T", creds) -} - -func TestGetHelmCredsShouldReturnAzureWorkloadIdentityCredsIfSpecified(t *testing.T) { - repository := Repository{UseAzureWorkloadIdentity: true} - - creds := repository.GetHelmCreds() - - _, ok := creds.(helm.AzureWorkloadIdentityCreds) - require.Truef(t, ok, "expected AzureWorkloadIdentityCreds but got %T", creds) -} - -func TestGetHelmCredsShouldReturnHelmCredsIfAzureWorkloadIdentityNotSpecified(t *testing.T) { - repository := Repository{} - - creds := repository.GetHelmCreds() - - _, ok := creds.(helm.HelmCreds) - require.Truef(t, ok, "expected HelmCreds but got %T", creds) -} - -func TestGetGitCreds(t *testing.T) { - tests := []struct { - name string - repo *Repository - expected git.Creds - }{ - { - name: "nil repository", - repo: nil, - expected: git.NopCreds{}, - }, - { - name: "HTTPS credentials", - repo: &Repository{ - Username: "user", - Password: "pass", - }, - expected: git.NewHTTPSCreds("user", "pass", "", "", "", false, "", "", nil, false), - }, - { - name: "Bearer token credentials", - repo: &Repository{ - BearerToken: "token", - }, - expected: git.NewHTTPSCreds("", "", "token", "", "", false, "", "", nil, false), - }, - { - name: "SSH credentials", - repo: &Repository{ - SSHPrivateKey: "ssh-key", - }, - expected: git.NewSSHCreds("ssh-key", "", false, nil, "", ""), - }, - { - name: "GitHub App credentials", - repo: &Repository{ - GithubAppPrivateKey: "github-key", - GithubAppId: 123, - GithubAppInstallationId: 456, - }, - expected: git.NewGitHubAppCreds(123, 456, "github-key", "", "", "", "", false, "", "", nil), - }, - { - name: "Google Cloud credentials", - repo: &Repository{ - GCPServiceAccountKey: "gcp-key", - }, - expected: git.NewGoogleCloudCreds("gcp-key", nil), - }, - { - name: "No credentials", - repo: &Repository{}, - expected: git.NopCreds{}, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - creds := tt.repo.GetGitCreds(nil) - assert.Equal(t, tt.expected, creds) - }) - } -} diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index c47007334c..524f574f88 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -39,13 +39,13 @@ import ( "k8s.io/client-go/tools/clientcmd/api" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/util/rbac" + "github.com/argoproj/argo-cd/v2/util/rbac" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/helm" - utilhttp "github.com/argoproj/argo-cd/v3/util/http" - "github.com/argoproj/argo-cd/v3/util/security" + "github.com/argoproj/argo-cd/v2/common" + "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" + "github.com/argoproj/argo-cd/v2/util/security" ) // Application is a definition of Application resource. @@ -102,12 +102,6 @@ func (id IgnoreDifferences) Equals(other IgnoreDifferences) bool { type TrackingMethod string -const ( - TrackingMethodAnnotation TrackingMethod = "annotation" - TrackingMethodLabel TrackingMethod = "label" - TrackingMethodAnnotationAndLabel TrackingMethod = "annotation+label" -) - // ResourceIgnoreDifferences contains resource filter and list of json paths which should be ignored during comparison with live state. type ResourceIgnoreDifferences struct { Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` @@ -138,7 +132,7 @@ func (a *EnvEntry) IsZero() bool { func NewEnvEntry(text string) (*EnvEntry, error) { parts := strings.SplitN(text, "=", 2) if len(parts) != 2 { - return nil, fmt.Errorf("expected env entry of the form: param=value but received: %s", text) + return nil, fmt.Errorf("Expected env entry of the form: param=value. Received: %s", text) } return &EnvEntry{ Name: parts[0], @@ -548,7 +542,7 @@ var helmParameterRx = regexp.MustCompile(`([^\\]),`) func NewHelmParameter(text string, forceString bool) (*HelmParameter, error) { parts := strings.SplitN(text, "=", 2) if len(parts) != 2 { - return nil, fmt.Errorf("expected helm parameter of the form param=value but received: %s", text) + return nil, fmt.Errorf("Expected helm parameter of the form: param=value. Received: %s", text) } return &HelmParameter{ Name: parts[0], @@ -561,7 +555,7 @@ func NewHelmParameter(text string, forceString bool) (*HelmParameter, error) { func NewHelmFileParameter(text string) (*HelmFileParameter, error) { parts := strings.SplitN(text, "=", 2) if len(parts) != 2 { - return nil, fmt.Errorf("expected helm file parameter of the form param=path but received: %s", text) + return nil, fmt.Errorf("Expected helm file parameter of the form: param=path. Received: %s", text) } return &HelmFileParameter{ Name: parts[0], @@ -621,9 +615,10 @@ func (i KustomizeImage) delim() string { // Match returns true if the image name matches (i.e. up to the first delimiter) func (i KustomizeImage) Match(j KustomizeImage) bool { delim := j.delim() - imageName, _, _ := strings.Cut(string(i), delim) - otherImageName, _, _ := strings.Cut(string(j), delim) - return imageName == otherImageName + if !strings.Contains(string(j), delim) { + return false + } + return strings.HasPrefix(string(i), strings.Split(string(j), delim)[0]) } // KustomizeImages is a list of Kustomize images @@ -667,8 +662,6 @@ type ApplicationSourceKustomize struct { Patches KustomizePatches `json:"patches,omitempty" protobuf:"bytes,12,opt,name=patches"` // Components specifies a list of kustomize components to add to the kustomization before building Components []string `json:"components,omitempty" protobuf:"bytes,13,rep,name=components"` - // IgnoreMissingComponents prevents kustomize from failing when components do not exist locally by not appending them to kustomization file - IgnoreMissingComponents bool `json:"ignoreMissingComponents,omitempty" protobuf:"bytes,17,opt,name=ignoreMissingComponents"` // LabelWithoutSelector specifies whether to apply common labels to resource selectors or not LabelWithoutSelector bool `json:"labelWithoutSelector,omitempty" protobuf:"bytes,14,opt,name=labelWithoutSelector"` // KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD @@ -677,8 +670,6 @@ type ApplicationSourceKustomize 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,16,opt,name=apiVersions"` - // LabelIncludeTemplates specifies whether to apply common labels to resource templates or not - LabelIncludeTemplates bool `json:"labelIncludeTemplates,omitempty" protobuf:"bytes,18,opt,name=labelIncludeTemplates"` } type KustomizeReplica struct { @@ -785,8 +776,7 @@ func (k *ApplicationSourceKustomize) IsZero() bool { len(k.Patches) == 0 && len(k.Components) == 0 && k.KubeVersion == "" && - len(k.APIVersions) == 0 && - !k.IgnoreMissingComponents + len(k.APIVersions) == 0 } // MergeImage merges a new Kustomize image identifier in to a list of images @@ -974,21 +964,21 @@ func (p ApplicationSourcePluginParameter) MarshalJSON() ([]byte, error) { out["string"] = p.String_ } if p.OptionalMap != nil { - if p.Map == nil { + if p.OptionalMap.Map == nil { // Nil is not the same as a nil map. Nil means the field was not set, while a nil map means the field was set to an empty map. // Either way, we want to marshal it as "{}". out["map"] = map[string]string{} } else { - out["map"] = p.Map + out["map"] = p.OptionalMap.Map } } if p.OptionalArray != nil { - if p.Array == nil { + if p.OptionalArray.Array == nil { // Nil is not the same as a nil array. Nil means the field was not set, while a nil array means the field was set to an empty array. // Either way, we want to marshal it as "[]". out["array"] = []string{} } else { - out["array"] = p.Array + out["array"] = p.OptionalArray.Array } } bytes, err := json.Marshal(out) @@ -1035,12 +1025,12 @@ func (p ApplicationSourcePluginParameters) Environ() ([]string, error) { env = append(env, fmt.Sprintf("%s=%s", envBaseName, *param.String_)) } if param.OptionalMap != nil { - for key, value := range param.Map { + for key, value := range param.OptionalMap.Map { env = append(env, fmt.Sprintf("%s_%s=%s", envBaseName, escaped(key), value)) } } if param.OptionalArray != nil { - for i, value := range param.Array { + for i, value := range param.OptionalArray.Array { env = append(env, fmt.Sprintf("%s_%d=%s", envBaseName, i, value)) } } @@ -1123,12 +1113,23 @@ type ApplicationDestination struct { Namespace string `json:"namespace,omitempty" protobuf:"bytes,2,opt,name=namespace"` // Name is an alternate way of specifying the target cluster by its symbolic name. This must be set if Server is not set. Name string `json:"name,omitempty" protobuf:"bytes,3,opt,name=name"` + + // nolint:govet + isServerInferred bool `json:"-"` + // nolint:govet + isNameInferred bool `json:"-"` +} + +// SetIsServerInferred sets the isServerInferred flag. This is used to allow comparison between two destinations where +// one server is inferred and the other is not. +func (d *ApplicationDestination) SetIsServerInferred(inferred bool) { + d.isServerInferred = inferred } type ResourceHealthLocation string var ( - ResourceHealthLocationInline ResourceHealthLocation + ResourceHealthLocationInline ResourceHealthLocation = "" ResourceHealthLocationAppTree ResourceHealthLocation = "appTree" ) @@ -1139,7 +1140,7 @@ type ApplicationStatus struct { // Sync contains information about the application's current sync status Sync SyncStatus `json:"sync,omitempty" protobuf:"bytes,2,opt,name=sync"` // Health contains information about the application's current health status - Health AppHealthStatus `json:"health,omitempty" protobuf:"bytes,3,opt,name=health"` + Health HealthStatus `json:"health,omitempty" protobuf:"bytes,3,opt,name=health"` // History contains information about the application's sync history History RevisionHistories `json:"history,omitempty" protobuf:"bytes,4,opt,name=history"` // Conditions is a list of currently observed application conditions @@ -1289,7 +1290,8 @@ type SyncOperationResource struct { Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` Name string `json:"name" protobuf:"bytes,3,opt,name=name"` Namespace string `json:"namespace,omitempty" protobuf:"bytes,4,opt,name=namespace"` - Exclude bool `json:"-"` + // nolint:govet + Exclude bool `json:"-"` } // RevisionHistories is a array of history, oldest first and newest last @@ -1302,9 +1304,6 @@ func (in RevisionHistories) LastRevisionHistory() RevisionHistory { // Trunc truncates the list of history items to size n func (in RevisionHistories) Trunc(n int) RevisionHistories { - if n < 0 { - n = 0 - } i := len(in) - n if i > 0 { in = in[i:] @@ -1441,14 +1440,6 @@ type SyncPolicy struct { // If you add a field here, be sure to update IsZero. } -// IsAutomatedSyncEnabled checks if the automated sync is enabled or disabled -func (p *SyncPolicy) IsAutomatedSyncEnabled() bool { - if p.Automated != nil && (p.Automated.Enabled == nil || *p.Automated.Enabled) { - return true - } - return false -} - // IsZero returns true if the sync policy is empty func (p *SyncPolicy) IsZero() bool { return p == nil || (p.Automated == nil && len(p.SyncOptions) == 0 && p.Retry == nil && p.ManagedNamespaceMetadata == nil) @@ -1524,8 +1515,6 @@ type SyncPolicyAutomated struct { SelfHeal bool `json:"selfHeal,omitempty" protobuf:"bytes,2,opt,name=selfHeal"` // AllowEmpty allows apps have zero live resources (default: false) AllowEmpty bool `json:"allowEmpty,omitempty" protobuf:"bytes,3,opt,name=allowEmpty"` - // Enable allows apps to explicitly control automated sync - Enabled *bool `json:"enabled,omitempty" protobuf:"bytes,4,opt,name=enable"` } // SyncStrategy controls the manner in which a sync is performed @@ -1657,8 +1646,7 @@ func (r ResourceResults) Find(group string, kind string, namespace string, name // PruningRequired returns a positive integer containing the number of resources that require pruning after an operation has been completed func (r ResourceResults) PruningRequired() (num int) { for _, res := range r { - // find all resources that require pruning but ignore resources marked for no pruning using sync-option Prune=false - if res.Status == synccommon.ResultCodePruneSkipped && !strings.Contains(res.Message, "no prune") { + if res.Status == synccommon.ResultCodePruneSkipped { num++ } } @@ -1786,27 +1774,13 @@ type SyncStatus struct { Revisions []string `json:"revisions,omitempty" protobuf:"bytes,4,opt,name=revisions"` } -// AppHealthStatus contains information about the currently observed health state of an application -type AppHealthStatus struct { - // Status holds the status code of the application - Status health.HealthStatusCode `json:"status,omitempty" protobuf:"bytes,1,opt,name=status"` - // Message is a human-readable informational message describing the health status - // - // Deprecated: this field is not used and will be removed in a future release. - Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"` - // LastTransitionTime is the time the HealthStatus was set or updated - LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` -} - -// HealthStatus contains information about the currently observed health state of a resource +// HealthStatus contains information about the currently observed health state of an application or resource type HealthStatus struct { - // Status holds the status code of the resource + // Status holds the status code of the application or resource Status health.HealthStatusCode `json:"status,omitempty" protobuf:"bytes,1,opt,name=status"` // Message is a human-readable informational message describing the health status Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"` // LastTransitionTime is the time the HealthStatus was set or updated - // - // Deprecated: this field is not used and will be removed in a future release. LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` } @@ -1818,56 +1792,44 @@ type InfoItem struct { Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` } -// ResourceNetworkingInfo holds networking-related information for a resource. +// ResourceNetworkingInfo holds networking resource related information +// TODO: describe members of this type type ResourceNetworkingInfo struct { - // TargetLabels represents labels associated with the target resources that this resource communicates with. - TargetLabels map[string]string `json:"targetLabels,omitempty" protobuf:"bytes,1,opt,name=targetLabels"` - // TargetRefs contains references to other resources that this resource interacts with, such as Services or Pods. - TargetRefs []ResourceRef `json:"targetRefs,omitempty" protobuf:"bytes,2,opt,name=targetRefs"` - // Labels holds the labels associated with this networking resource. - Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,3,opt,name=labels"` - // Ingress provides information about external access points (e.g., load balancer ingress) for this resource. - Ingress []corev1.LoadBalancerIngress `json:"ingress,omitempty" protobuf:"bytes,4,opt,name=ingress"` - // ExternalURLs holds a list of URLs that should be accessible externally. - // This field is typically populated for Ingress resources based on their hostname rules. + TargetLabels map[string]string `json:"targetLabels,omitempty" protobuf:"bytes,1,opt,name=targetLabels"` + TargetRefs []ResourceRef `json:"targetRefs,omitempty" protobuf:"bytes,2,opt,name=targetRefs"` + Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,3,opt,name=labels"` + Ingress []corev1.LoadBalancerIngress `json:"ingress,omitempty" protobuf:"bytes,4,opt,name=ingress"` + // ExternalURLs holds list of URLs which should be available externally. List is populated for ingress resources using rules hostnames. ExternalURLs []string `json:"externalURLs,omitempty" protobuf:"bytes,5,opt,name=externalURLs"` } -// HostResourceInfo represents resource usage details for a specific resource type on a host. +// TODO: describe this type type HostResourceInfo struct { - // ResourceName specifies the type of resource (e.g., CPU, memory, storage). - ResourceName corev1.ResourceName `json:"resourceName,omitempty" protobuf:"bytes,1,name=resourceName"` - // RequestedByApp indicates the total amount of this resource requested by the application running on the host. - RequestedByApp int64 `json:"requestedByApp,omitempty" protobuf:"bytes,2,name=requestedByApp"` - // RequestedByNeighbors indicates the total amount of this resource requested by other workloads on the same host. - RequestedByNeighbors int64 `json:"requestedByNeighbors,omitempty" protobuf:"bytes,3,name=requestedByNeighbors"` - // Capacity represents the total available capacity of this resource on the host. - Capacity int64 `json:"capacity,omitempty" protobuf:"bytes,4,name=capacity"` + ResourceName corev1.ResourceName `json:"resourceName,omitempty" protobuf:"bytes,1,name=resourceName"` + RequestedByApp int64 `json:"requestedByApp,omitempty" protobuf:"bytes,2,name=requestedByApp"` + RequestedByNeighbors int64 `json:"requestedByNeighbors,omitempty" protobuf:"bytes,3,name=requestedByNeighbors"` + Capacity int64 `json:"capacity,omitempty" protobuf:"bytes,4,name=capacity"` } -// HostInfo holds metadata and resource usage metrics for a specific host in the cluster. +// HostInfo holds host name and resources metrics +// TODO: describe purpose of this type +// TODO: describe members of this type type HostInfo struct { - // Name is the hostname or node name in the Kubernetes cluster. - Name string `json:"name,omitempty" protobuf:"bytes,1,name=name"` - // ResourcesInfo provides a list of resource usage details for different resource types on this host. - ResourcesInfo []HostResourceInfo `json:"resourcesInfo,omitempty" protobuf:"bytes,2,name=resourcesInfo"` - // SystemInfo contains detailed system-level information about the host, such as OS, kernel version, and architecture. - SystemInfo corev1.NodeSystemInfo `json:"systemInfo,omitempty" protobuf:"bytes,3,opt,name=systemInfo"` + Name string `json:"name,omitempty" protobuf:"bytes,1,name=name"` + ResourcesInfo []HostResourceInfo `json:"resourcesInfo,omitempty" protobuf:"bytes,2,name=resourcesInfo"` + SystemInfo corev1.NodeSystemInfo `json:"systemInfo,omitempty" protobuf:"bytes,3,opt,name=systemInfo"` } -// ApplicationTree represents the hierarchical structure of resources associated with an Argo CD application. +// ApplicationTree holds nodes which belongs to the application +// TODO: describe purpose of this type type ApplicationTree struct { - // Nodes contains a list of resources that are either directly managed by the application - // or are children of directly managed resources. + // Nodes contains list of nodes which either directly managed by the application and children of directly managed nodes. Nodes []ResourceNode `json:"nodes,omitempty" protobuf:"bytes,1,rep,name=nodes"` - // OrphanedNodes contains resources that exist in the same namespace as the application - // but are not managed by it. This list is populated only if orphaned resource tracking - // is enabled in the application's project settings. + // OrphanedNodes contains if or orphaned nodes: nodes which are not managed by the app but in the same namespace. List is populated only if orphaned resources enabled in app project. OrphanedNodes []ResourceNode `json:"orphanedNodes,omitempty" protobuf:"bytes,2,rep,name=orphanedNodes"` - // Hosts provides a list of Kubernetes nodes that are running pods related to the application. + // Hosts holds list of Kubernetes nodes that run application related pods Hosts []HostInfo `json:"hosts,omitempty" protobuf:"bytes,3,rep,name=hosts"` - // ShardsCount represents the total number of shards the application tree is split into. - // This is used to distribute resource processing across multiple shards. + // ShardsCount contains total number of shards the application tree is split into ShardsCount int64 `json:"shardsCount,omitempty" protobuf:"bytes,4,opt,name=shardsCount"` } @@ -1945,10 +1907,7 @@ type ApplicationSummary struct { Images []string `json:"images,omitempty" protobuf:"bytes,2,opt,name=images"` } -// FindNode searches for a resource node in the application tree. -// It looks for a node that matches the given group, kind, namespace, and name. -// The search includes both directly managed nodes (`Nodes`) and orphaned nodes (`OrphanedNodes`). -// Returns a pointer to the found node, or nil if no matching node is found. +// TODO: Document purpose of this method func (t *ApplicationTree) FindNode(group string, kind string, namespace string, name string) *ResourceNode { for _, n := range append(t.Nodes, t.OrphanedNodes...) { if n.Group == group && n.Kind == kind && n.Namespace == namespace && n.Name == name { @@ -1958,20 +1917,10 @@ func (t *ApplicationTree) FindNode(group string, kind string, namespace string, return nil } -// GetSummary generates a summary of the application by extracting external URLs and container images -// used within the application's resources. -// -// - It collects external URLs from the networking information of all resource nodes. -// - It extracts container images referenced in the application's resources. -// - Additionally, it includes links from application annotations that start with `common.AnnotationKeyLinkPrefix`. -// - The collected URLs and images are sorted alphabetically before being returned. -// -// Returns an `ApplicationSummary` containing a list of unique external URLs and container images. +// TODO: Document purpose of this method func (t *ApplicationTree) GetSummary(app *Application) ApplicationSummary { urlsSet := make(map[string]bool) imagesSet := make(map[string]bool) - - // Collect external URLs and container images from application nodes for _, node := range t.Nodes { if node.NetworkingInfo != nil { for _, url := range node.NetworkingInfo.ExternalURLs { @@ -1982,8 +1931,7 @@ func (t *ApplicationTree) GetSummary(app *Application) ApplicationSummary { imagesSet[image] = true } } - - // Include application-specific links from annotations + // also add Application's own links for k, v := range app.GetAnnotations() { if strings.HasPrefix(k, common.AnnotationKeyLinkPrefix) { urlsSet[v] = true @@ -1994,14 +1942,16 @@ func (t *ApplicationTree) GetSummary(app *Application) ApplicationSummary { for url := range urlsSet { urls = append(urls, url) } - sort.Strings(urls) - - images := make([]string, 0, len(imagesSet)) + sort.Slice(urls, func(i, j int) bool { + return urls[i] < urls[j] + }) + images := make([]string, 0) for image := range imagesSet { images = append(images, image) } - sort.Strings(images) - + sort.Slice(images, func(i, j int) bool { + return images[i] < images[j] + }) return ApplicationSummary{ExternalURLs: urls, Images: images} } @@ -2015,27 +1965,17 @@ type ResourceRef struct { UID string `json:"uid,omitempty" protobuf:"bytes,6,opt,name=uid"` } -// ResourceNode contains information about a live Kubernetes resource and its relationships with other resources. +// ResourceNode contains information about live resource and its children +// TODO: describe members of this type type ResourceNode struct { - // ResourceRef uniquely identifies the resource using its group, kind, namespace, and name. - ResourceRef `json:",inline" protobuf:"bytes,1,opt,name=resourceRef"` - // ParentRefs lists the parent resources that reference this resource. - // This helps in understanding ownership and hierarchical relationships. - ParentRefs []ResourceRef `json:"parentRefs,omitempty" protobuf:"bytes,2,opt,name=parentRefs"` - // Info provides additional metadata or annotations about the resource. - Info []InfoItem `json:"info,omitempty" protobuf:"bytes,3,opt,name=info"` - // NetworkingInfo contains details about the resource's networking attributes, - // such as ingress information and external URLs. - NetworkingInfo *ResourceNetworkingInfo `json:"networkingInfo,omitempty" protobuf:"bytes,4,opt,name=networkingInfo"` - // ResourceVersion indicates the version of the resource, used to track changes. - ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,5,opt,name=resourceVersion"` - // Images lists container images associated with the resource. - // This is primarily useful for pods and other workload resources. - Images []string `json:"images,omitempty" protobuf:"bytes,6,opt,name=images"` - // Health represents the health status of the resource (e.g., Healthy, Degraded, Progressing). - Health *HealthStatus `json:"health,omitempty" protobuf:"bytes,7,opt,name=health"` - // CreatedAt records the timestamp when the resource was created. - CreatedAt *metav1.Time `json:"createdAt,omitempty" protobuf:"bytes,8,opt,name=createdAt"` + ResourceRef `json:",inline" protobuf:"bytes,1,opt,name=resourceRef"` + ParentRefs []ResourceRef `json:"parentRefs,omitempty" protobuf:"bytes,2,opt,name=parentRefs"` + Info []InfoItem `json:"info,omitempty" protobuf:"bytes,3,opt,name=info"` + NetworkingInfo *ResourceNetworkingInfo `json:"networkingInfo,omitempty" protobuf:"bytes,4,opt,name=networkingInfo"` + ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,5,opt,name=resourceVersion"` + Images []string `json:"images,omitempty" protobuf:"bytes,6,opt,name=images"` + Health *HealthStatus `json:"health,omitempty" protobuf:"bytes,7,opt,name=health"` + CreatedAt *metav1.Time `json:"createdAt,omitempty" protobuf:"bytes,8,opt,name=createdAt"` } // FullName returns a resource node's full name in the format "group/kind/namespace/name" @@ -2053,31 +1993,20 @@ func (n *ResourceNode) GroupKindVersion() schema.GroupVersionKind { } } -// ResourceStatus holds the current synchronization and health status of a Kubernetes resource. +// ResourceStatus holds the current sync and health status of a resource +// TODO: describe members of this type type ResourceStatus struct { - // Group represents the API group of the resource (e.g., "apps" for Deployments). - Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` - // Version indicates the API version of the resource (e.g., "v1", "v1beta1"). - Version string `json:"version,omitempty" protobuf:"bytes,2,opt,name=version"` - // Kind specifies the type of the resource (e.g., "Deployment", "Service"). - Kind string `json:"kind,omitempty" protobuf:"bytes,3,opt,name=kind"` - // Namespace defines the Kubernetes namespace where the resource is located. - Namespace string `json:"namespace,omitempty" protobuf:"bytes,4,opt,name=namespace"` - // Name is the unique name of the resource within the namespace. - Name string `json:"name,omitempty" protobuf:"bytes,5,opt,name=name"` - // Status represents the synchronization state of the resource (e.g., Synced, OutOfSync). - Status SyncStatusCode `json:"status,omitempty" protobuf:"bytes,6,opt,name=status"` - // Health indicates the health status of the resource (e.g., Healthy, Degraded, Progressing). - Health *HealthStatus `json:"health,omitempty" protobuf:"bytes,7,opt,name=health"` - // Hook is true if the resource is used as a lifecycle hook in an Argo CD application. - Hook bool `json:"hook,omitempty" protobuf:"bytes,8,opt,name=hook"` - // RequiresPruning is true if the resource needs to be pruned (deleted) as part of synchronization. - RequiresPruning bool `json:"requiresPruning,omitempty" protobuf:"bytes,9,opt,name=requiresPruning"` - // SyncWave determines the order in which resources are applied during a sync operation. - // Lower values are applied first. - SyncWave int64 `json:"syncWave,omitempty" protobuf:"bytes,10,opt,name=syncWave"` - // RequiresDeletionConfirmation is true if the resource requires explicit user confirmation before deletion. - RequiresDeletionConfirmation bool `json:"requiresDeletionConfirmation,omitempty" protobuf:"bytes,11,opt,name=requiresDeletionConfirmation"` + 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 @@ -2085,36 +2014,27 @@ func (r *ResourceStatus) GroupVersionKind() schema.GroupVersionKind { return schema.GroupVersionKind{Group: r.Group, Version: r.Version, Kind: r.Kind} } -// ResourceDiff holds the diff between a live and target resource object in Argo CD. -// It is used to compare the desired state (from Git/Helm) with the actual state in the cluster. +// ResourceDiff holds the diff of a live and target resource object +// TODO: describe members of this type type ResourceDiff struct { - // Group represents the API group of the resource (e.g., "apps" for Deployments). - Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` - // Kind represents the Kubernetes resource kind (e.g., "Deployment", "Service"). - Kind string `json:"kind,omitempty" protobuf:"bytes,2,opt,name=kind"` - // Namespace specifies the namespace where the resource exists. + Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` + Kind string `json:"kind,omitempty" protobuf:"bytes,2,opt,name=kind"` Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"` - // Name is the name of the resource. - Name string `json:"name,omitempty" protobuf:"bytes,4,opt,name=name"` - // TargetState contains the JSON-serialized resource manifest as defined in the Git/Helm repository. + Name string `json:"name,omitempty" protobuf:"bytes,4,opt,name=name"` + // TargetState contains the JSON serialized resource manifest defined in the Git/Helm TargetState string `json:"targetState,omitempty" protobuf:"bytes,5,opt,name=targetState"` - // LiveState contains the JSON-serialized resource manifest of the resource currently running in the cluster. + // TargetState contains the JSON live resource manifest LiveState string `json:"liveState,omitempty" protobuf:"bytes,6,opt,name=liveState"` - // Diff contains the JSON patch representing the difference between the live and target resource. - // Deprecated: Use NormalizedLiveState and PredictedLiveState instead to compute differences. + // Diff contains the JSON patch between target and live resource + // Deprecated: use NormalizedLiveState and PredictedLiveState to render the difference Diff string `json:"diff,omitempty" protobuf:"bytes,7,opt,name=diff"` - // Hook indicates whether this resource is a hook resource (e.g., pre-sync or post-sync hooks). - Hook bool `json:"hook,omitempty" protobuf:"bytes,8,opt,name=hook"` - // NormalizedLiveState contains the JSON-serialized live resource state after applying normalizations. - // Normalizations may include ignoring irrelevant fields like timestamps or defaults applied by Kubernetes. + Hook bool `json:"hook,omitempty" protobuf:"bytes,8,opt,name=hook"` + // NormalizedLiveState contains JSON serialized live resource state with applied normalizations NormalizedLiveState string `json:"normalizedLiveState,omitempty" protobuf:"bytes,9,opt,name=normalizedLiveState"` - // PredictedLiveState contains the JSON-serialized resource state that Argo CD predicts based on the - // combination of the normalized live state and the desired target state. + // PredictedLiveState contains JSON serialized resource state that is calculated based on normalized and target resource state PredictedLiveState string `json:"predictedLiveState,omitempty" protobuf:"bytes,10,opt,name=predictedLiveState"` - // ResourceVersion is the Kubernetes resource version, which helps in tracking changes. - ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,11,opt,name=resourceVersion"` - // Modified indicates whether the live resource has changes compared to the target resource. - Modified bool `json:"modified,omitempty" protobuf:"bytes,12,opt,name=modified"` + ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,11,opt,name=resourceVersion"` + Modified bool `json:"modified,omitempty" protobuf:"bytes,12,opt,name=modified"` } // FullName returns full name of a node that was used for diffing in the format "group/kind/namespace/name" @@ -2333,16 +2253,12 @@ type TLSClientConfig struct { CAData []byte `json:"caData,omitempty" protobuf:"bytes,5,opt,name=caData"` } -// KnownTypeField contains a mapping between a Custom Resource Definition (CRD) field -// and a well-known Kubernetes type. This mapping is primarily used for unit conversions -// in resources where the type is not explicitly defined (e.g., converting "0.1" to "100m" for CPU requests). +// KnownTypeField contains mapping between CRD field and known Kubernetes type. +// This is mainly used for unit conversion in unknown resources (e.g. 0.1 == 100mi) +// TODO: Describe the members of this type type KnownTypeField struct { - // Field represents the JSON path to the specific field in the CRD that requires type conversion. - // Example: "spec.resources.requests.cpu" Field string `json:"field,omitempty" protobuf:"bytes,1,opt,name=field"` - // Type specifies the expected Kubernetes type for the field, such as "cpu" or "memory". - // This helps in converting values between different formats (e.g., "0.1" to "100m" for CPU). - Type string `json:"type,omitempty" protobuf:"bytes,2,opt,name=type"` + Type string `json:"type,omitempty" protobuf:"bytes,2,opt,name=type"` } // OverrideIgnoreDiff contains configurations about how fields should be ignored during diffs between @@ -2367,19 +2283,14 @@ type rawResourceOverride struct { } // ResourceOverride holds configuration to customize resource diffing and health assessment +// TODO: describe the members of this type type ResourceOverride struct { - // HealthLua contains a Lua script that defines custom health checks for the resource. - HealthLua string `protobuf:"bytes,1,opt,name=healthLua"` - // UseOpenLibs indicates whether to use open-source libraries for the resource. - UseOpenLibs bool `protobuf:"bytes,5,opt,name=useOpenLibs"` - // Actions defines the set of actions that can be performed on the resource, as a Lua script. - Actions string `protobuf:"bytes,3,opt,name=actions"` - // IgnoreDifferences contains configuration for which differences should be ignored during the resource diffing. - IgnoreDifferences OverrideIgnoreDiff `protobuf:"bytes,2,opt,name=ignoreDifferences"` - // IgnoreResourceUpdates holds configuration for ignoring updates to specific resource fields. + HealthLua string `protobuf:"bytes,1,opt,name=healthLua"` + UseOpenLibs bool `protobuf:"bytes,5,opt,name=useOpenLibs"` + Actions string `protobuf:"bytes,3,opt,name=actions"` + IgnoreDifferences OverrideIgnoreDiff `protobuf:"bytes,2,opt,name=ignoreDifferences"` IgnoreResourceUpdates OverrideIgnoreDiff `protobuf:"bytes,6,opt,name=ignoreResourceUpdates"` - // KnownTypeFields lists fields for which unit conversions should be applied. - KnownTypeFields []KnownTypeField `protobuf:"bytes,4,opt,name=knownTypeFields"` + KnownTypeFields []KnownTypeField `protobuf:"bytes,4,opt,name=knownTypeFields"` } // UnmarshalJSON unmarshals a JSON byte slice into a ResourceOverride object. @@ -2405,78 +2316,61 @@ func (ro *ResourceOverride) UnmarshalJSON(data []byte) error { return nil } -// MarshalJSON marshals a ResourceOverride object into a JSON byte slice. -// It converts `IgnoreDifferences` and `IgnoreResourceUpdates` fields to YAML format before marshaling. -func (ro ResourceOverride) MarshalJSON() ([]byte, error) { - ignoreDifferencesData, err := yaml.Marshal(ro.IgnoreDifferences) +// TODO: describe this method +func (s ResourceOverride) MarshalJSON() ([]byte, error) { + ignoreDifferencesData, err := yaml.Marshal(s.IgnoreDifferences) if err != nil { return nil, err } - ignoreResourceUpdatesData, err := yaml.Marshal(ro.IgnoreResourceUpdates) + ignoreResourceUpdatesData, err := yaml.Marshal(s.IgnoreResourceUpdates) if err != nil { return nil, err } - raw := &rawResourceOverride{ro.HealthLua, ro.UseOpenLibs, ro.Actions, string(ignoreDifferencesData), string(ignoreResourceUpdatesData), ro.KnownTypeFields} + raw := &rawResourceOverride{s.HealthLua, s.UseOpenLibs, s.Actions, string(ignoreDifferencesData), string(ignoreResourceUpdatesData), s.KnownTypeFields} return json.Marshal(raw) } -// GetActions parses and returns the actions defined for the resource. -// It unmarshals the `Actions` field (a Lua script) into a ResourceActions object. -func (ro *ResourceOverride) GetActions() (ResourceActions, error) { +// TODO: describe this method +func (o *ResourceOverride) GetActions() (ResourceActions, error) { var actions ResourceActions - err := yaml.Unmarshal([]byte(ro.Actions), &actions) + err := yaml.Unmarshal([]byte(o.Actions), &actions) if err != nil { return actions, err } return actions, nil } -// ResourceActions holds the set of actions that can be applied to a resource. -// It defines custom Lua scripts for discovery and action execution, as well as options -// for merging built-in actions with custom ones. +// TODO: describe this type +// TODO: describe members of this type type ResourceActions struct { - // ActionDiscoveryLua contains a Lua script for discovering actions. - ActionDiscoveryLua string `json:"discovery.lua,omitempty" yaml:"discovery.lua,omitempty" protobuf:"bytes,1,opt,name=actionDiscoveryLua"` - // Definitions holds the list of action definitions available for the resource. - Definitions []ResourceActionDefinition `json:"definitions,omitempty" protobuf:"bytes,2,rep,name=definitions"` - // MergeBuiltinActions indicates whether built-in actions should be merged with custom actions. - MergeBuiltinActions bool `json:"mergeBuiltinActions,omitempty" yaml:"mergeBuiltinActions,omitempty" protobuf:"bytes,3,opt,name=mergeBuiltinActions"` + ActionDiscoveryLua string `json:"discovery.lua,omitempty" yaml:"discovery.lua,omitempty" protobuf:"bytes,1,opt,name=actionDiscoveryLua"` + Definitions []ResourceActionDefinition `json:"definitions,omitempty" protobuf:"bytes,2,rep,name=definitions"` + MergeBuiltinActions bool `json:"mergeBuiltinActions,omitempty" yaml:"mergeBuiltinActions,omitempty" protobuf:"bytes,3,opt,name=mergeBuiltinActions"` } -// ResourceActionDefinition defines an individual action that can be executed on a resource. -// It includes a name for the action and a Lua script that defines the action's behavior. +// TODO: describe this type +// TODO: describe members of this type type ResourceActionDefinition struct { - // Name is the identifier for the action. - Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // ActionLua contains the Lua script that defines the behavior of the action. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` ActionLua string `json:"action.lua" yaml:"action.lua" protobuf:"bytes,2,opt,name=actionLua"` } -// ResourceAction represents an individual action that can be performed on a resource. -// It includes parameters, an optional disabled flag, an icon for display, and a name for the action. +// TODO: describe this type +// TODO: describe members of this type type ResourceAction struct { - // Name is the name or identifier for the action. - Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` - // Params contains the parameters required to execute the action. - Params []ResourceActionParam `json:"params,omitempty" protobuf:"bytes,2,rep,name=params"` - // Disabled indicates whether the action is disabled. - Disabled bool `json:"disabled,omitempty" protobuf:"varint,3,opt,name=disabled"` - // IconClass specifies the CSS class for the action's icon. - IconClass string `json:"iconClass,omitempty" protobuf:"bytes,4,opt,name=iconClass"` - // DisplayName provides a user-friendly name for the action. - DisplayName string `json:"displayName,omitempty" protobuf:"bytes,5,opt,name=displayName"` + Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` + Params []ResourceActionParam `json:"params,omitempty" protobuf:"bytes,2,rep,name=params"` + Disabled bool `json:"disabled,omitempty" protobuf:"varint,3,opt,name=disabled"` + IconClass string `json:"iconClass,omitempty" protobuf:"bytes,4,opt,name=iconClass"` + DisplayName string `json:"displayName,omitempty" protobuf:"bytes,5,opt,name=displayName"` } -// ResourceActionParam represents a parameter for a resource action. -// It includes a name, value, type, and an optional default value for the parameter. +// TODO: describe this type +// TODO: describe members of this type type ResourceActionParam struct { - // Name is the name of the parameter. - Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` - // Value is the value of the parameter. - Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` - // Type is the type of the parameter (e.g., string, integer). - Type string `json:"type,omitempty" protobuf:"bytes,3,opt,name=type"` - // Default is the default value of the parameter, if any. + Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` + Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` + Type string `json:"type,omitempty" protobuf:"bytes,3,opt,name=type"` Default string `json:"default,omitempty" protobuf:"bytes,4,opt,name=default"` } @@ -2617,7 +2511,6 @@ type AppProjectSpec struct { // Destinations contains list of destinations available for deployment Destinations []ApplicationDestination `json:"destinations,omitempty" protobuf:"bytes,2,name=destination"` // Description contains optional project description - // +kubebuilder:validation:MaxLength=255 Description string `json:"description,omitempty" protobuf:"bytes,3,opt,name=description"` // Roles are user defined RBAC roles associated with this project Roles []ProjectRole `json:"roles,omitempty" protobuf:"bytes,4,rep,name=roles"` @@ -2664,10 +2557,6 @@ type SyncWindow struct { ManualSync bool `json:"manualSync,omitempty" protobuf:"bytes,7,opt,name=manualSync"` // TimeZone of the sync that will be applied to the schedule TimeZone string `json:"timeZone,omitempty" protobuf:"bytes,8,opt,name=timeZone"` - // UseAndOperator use AND operator for matching applications, namespaces and clusters instead of the default OR operator - UseAndOperator bool `json:"andOperator,omitempty" protobuf:"bytes,9,opt,name=andOperator"` - // Description of the sync that will be applied to the schedule, can be used to add any information such as a ticket number for example - Description string `json:"description,omitempty" protobuf:"bytes,10,opt,name=description"` } // HasWindows returns true if SyncWindows has one or more SyncWindow @@ -2764,19 +2653,17 @@ func (w *SyncWindow) scheduleOffsetByTimeZone() time.Duration { } // AddWindow adds a sync window with the given parameters to the AppProject -func (spec *AppProjectSpec) AddWindow(knd string, sch string, dur string, app []string, ns []string, cl []string, ms bool, timeZone string, andOperator bool, description string) error { +func (spec *AppProjectSpec) AddWindow(knd string, sch string, dur string, app []string, ns []string, cl []string, ms bool, timeZone string) error { if len(knd) == 0 || len(sch) == 0 || len(dur) == 0 { return errors.New("cannot create window: require kind, schedule, duration and one or more of applications, namespaces and clusters") } window := &SyncWindow{ - Kind: knd, - Schedule: sch, - Duration: dur, - ManualSync: ms, - TimeZone: timeZone, - UseAndOperator: andOperator, - Description: description, + Kind: knd, + Schedule: sch, + Duration: dur, + ManualSync: ms, + TimeZone: timeZone, } if len(app) > 0 { @@ -2816,73 +2703,37 @@ func (spec *AppProjectSpec) DeleteWindow(id int) error { } // Matches returns a list of sync windows that are defined for a given application -// It will use the AND operator if the UseAndOperator is set to true otherwise will default to the OR operator func (w *SyncWindows) Matches(app *Application) *SyncWindows { if w.HasWindows() { var matchingWindows SyncWindows - var matched, isSet bool - - for _, window := range *w { - matched = false - isSet = false - - // First check if any applications are configured for the window - if len(window.Applications) > 0 { - isSet = true - for _, a := range window.Applications { + for _, w := range *w { + if len(w.Applications) > 0 { + for _, a := range w.Applications { if globMatch(a, app.Name, false) { - matched = true + matchingWindows = append(matchingWindows, w) break } } } - - // If using the AND operator and window applications were set but did not match, break out of the loop earlier - if window.UseAndOperator && !matched && isSet { - continue - } else if !window.UseAndOperator && matched { - matchingWindows = append(matchingWindows, window) - continue - } - - // Second check if any clusters are configured for the window - if len(window.Clusters) > 0 { - // check next for cluster matching - matched = false - isSet = true - for _, c := range window.Clusters { + if len(w.Clusters) > 0 { + for _, c := range w.Clusters { dst := app.Spec.Destination dstNameMatched := dst.Name != "" && globMatch(c, dst.Name, false) dstServerMatched := dst.Server != "" && globMatch(c, dst.Server, false) if dstNameMatched || dstServerMatched { - matched = true + matchingWindows = append(matchingWindows, w) break } } } - - // If using the AND operator and window clusters were set but did not match, break out of the loop earlier - if isSet && window.UseAndOperator && !matched { - continue - } else if !window.UseAndOperator && matched { - matchingWindows = append(matchingWindows, window) - continue - } - - // Last check if any namespaces are configured for the window - if len(window.Namespaces) > 0 { - matched = false - // If the window clusters matched or if the window clusters were not set check next for namespace matching - for _, n := range window.Namespaces { + if len(w.Namespaces) > 0 { + for _, n := range w.Namespaces { if globMatch(n, app.Spec.Destination.Namespace, false) { - matched = true + matchingWindows = append(matchingWindows, w) break } } } - if matched { - matchingWindows = append(matchingWindows, window) - } } if len(matchingWindows) > 0 { return &matchingWindows @@ -3007,9 +2858,9 @@ func (w SyncWindow) active(currentTime time.Time) (bool, error) { } // Update updates a sync window's settings with the given parameter -func (w *SyncWindow) Update(s string, d string, a []string, n []string, c []string, tz string, description string) error { - if len(s) == 0 && len(d) == 0 && len(a) == 0 && len(n) == 0 && len(c) == 0 && len(description) == 0 { - return errors.New("cannot update: require one or more of schedule, duration, application, namespace, cluster or description") +func (w *SyncWindow) Update(s string, d string, a []string, n []string, c []string, tz string) error { + if len(s) == 0 && len(d) == 0 && len(a) == 0 && len(n) == 0 && len(c) == 0 { + return errors.New("cannot update: require one or more of schedule, duration, application, namespace, or cluster") } if len(s) > 0 { @@ -3023,19 +2874,12 @@ func (w *SyncWindow) Update(s string, d string, a []string, n []string, c []stri if len(a) > 0 { w.Applications = a } - if len(n) > 0 { w.Namespaces = n } - if len(c) > 0 { w.Clusters = c } - - if len(description) > 0 { - w.Description = description - } - if tz == "" { tz = "UTC" } @@ -3066,11 +2910,6 @@ func (w *SyncWindow) Validate() error { if err != nil { return fmt.Errorf("cannot parse duration '%s': %w", w.Duration, err) } - - if len(w.Description) > 255 { - return errors.New("description must not exceed 255 characters") - } - return nil } @@ -3145,7 +2984,7 @@ type ApplicationDestinationServiceAccount struct { // CascadedDeletion indicates if the deletion finalizer is set and controller should delete the application and it's cascaded resources func (app *Application) CascadedDeletion() bool { - for _, finalizer := range app.Finalizers { + for _, finalizer := range app.ObjectMeta.Finalizers { if isPropagationPolicyFinalizer(finalizer) { return true } @@ -3233,7 +3072,7 @@ func isPropagationPolicyFinalizer(finalizer string) bool { // GetPropagationPolicy returns the value of propagation policy finalizer func (app *Application) GetPropagationPolicy() string { - for _, finalizer := range app.Finalizers { + for _, finalizer := range app.ObjectMeta.Finalizers { if isPropagationPolicyFinalizer(finalizer) { return finalizer } @@ -3367,6 +3206,33 @@ func (source *ApplicationSource) ExplicitType() (*ApplicationSourceType, error) return &appType, nil } +// Equals compares two instances of ApplicationDestination and returns true if instances are equal. +func (dest ApplicationDestination) Equals(other ApplicationDestination) bool { + // ignore destination cluster name and isServerInferred fields during comparison + // since server URL is inferred from cluster name + if dest.isServerInferred { + dest.Server = "" + dest.isServerInferred = false + } + + if other.isServerInferred { + other.Server = "" + other.isServerInferred = false + } + + if dest.isNameInferred { + dest.Name = "" + dest.isNameInferred = false + } + + if other.isNameInferred { + other.Name = "" + other.isNameInferred = false + } + + return reflect.DeepEqual(dest, other) +} + // GetProject returns the application's project. This is preferred over spec.Project which may be empty func (spec ApplicationSpec) GetProject() string { if spec.Project == "" { @@ -3478,7 +3344,7 @@ func ParseProxyUrl(proxyUrl string) (*url.URL, error) { //nolint:revive //FIXME( 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 nil, fmt.Errorf("Failed to parse proxy url, unsupported scheme %q, must be http, https, or socks5", u.Scheme) } return u, nil } @@ -3513,11 +3379,11 @@ func (c *Cluster) RawRestConfig() (*rest.Config, error) { } default: tlsClientConfig := rest.TLSClientConfig{ - Insecure: c.Config.Insecure, - ServerName: c.Config.ServerName, - CertData: c.Config.CertData, - KeyData: c.Config.KeyData, - CAData: c.Config.CAData, + Insecure: c.Config.TLSClientConfig.Insecure, + ServerName: c.Config.TLSClientConfig.ServerName, + CertData: c.Config.TLSClientConfig.CertData, + KeyData: c.Config.TLSClientConfig.KeyData, + CAData: c.Config.TLSClientConfig.CAData, } switch { case c.Config.AWSAuthConfig != nil: @@ -3571,12 +3437,12 @@ func (c *Cluster) RawRestConfig() (*rest.Config, error) { } } if err != nil { - return nil, fmt.Errorf("unable to create K8s REST config: %w", 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) + return nil, fmt.Errorf("Unable to create K8s REST config, can`t parse proxy url: %w", err) } config.Proxy = http.ProxyURL(u) } @@ -3591,11 +3457,11 @@ func (c *Cluster) RawRestConfig() (*rest.Config, error) { 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) + return nil, fmt.Errorf("Unable to get K8s RAW REST config: %w", err) } err = SetK8SConfigDefaults(config) if err != nil { - return nil, fmt.Errorf("unable to apply K8s REST config defaults: %w", err) + return nil, fmt.Errorf("Unable to apply K8s REST config defaults: %w", err) } return config, nil } @@ -3613,24 +3479,54 @@ func UnmarshalToUnstructured(resource string) (*unstructured.Unstructured, error return &obj, nil } -// LiveObject returns the live object representation of the resource by unmarshalling the -// `LiveState` field into an unstructured.Unstructured object. This object represents the current -// live state of the resource in the cluster. +// TODO: document this method func (r ResourceDiff) LiveObject() (*unstructured.Unstructured, error) { return UnmarshalToUnstructured(r.LiveState) } -// TargetObject returns the target object representation of the resource by unmarshalling the -// `TargetState` field into an unstructured.Unstructured object. This object represents the desired -// state of the resource, as defined in the target configuration. +// TODO: document this method func (r ResourceDiff) TargetObject() (*unstructured.Unstructured, error) { return UnmarshalToUnstructured(r.TargetState) } +// SetInferredServer sets the Server field of the destination. See IsServerInferred() for details. +func (d *ApplicationDestination) SetInferredServer(server string) { + d.isServerInferred = true + d.Server = server +} + +// SetInferredName sets the Name field of the destination. See IsNameInferred() for details. +func (d *ApplicationDestination) SetInferredName(name string) { + d.isNameInferred = true + d.Name = name +} + +// An ApplicationDestination has an 'inferred server' if the ApplicationDestination +// contains a Name, but not a Server URL. In this case it is necessary to retrieve +// the Server URL by looking up the cluster name. +// +// As of this writing, looking up the cluster name, and setting the URL, is +// performed by 'utils.ValidateDestination(...)', which then calls SetInferredServer. +func (d *ApplicationDestination) IsServerInferred() bool { + return d.isServerInferred +} + +func (d *ApplicationDestination) IsNameInferred() bool { + return d.isNameInferred +} + // MarshalJSON marshals an application destination to JSON format func (d *ApplicationDestination) MarshalJSON() ([]byte, error) { type Alias ApplicationDestination dest := d + if d.isServerInferred { + dest = dest.DeepCopy() + dest.Server = "" + } + if d.isNameInferred { + dest = dest.DeepCopy() + dest.Name = "" + } return json.Marshal(&struct{ *Alias }{Alias: (*Alias)(dest)}) } @@ -3676,12 +3572,8 @@ func (app *Application) GetAnnotation(annotation string) string { return v } -// IsDeletionConfirmed checks whether the application has been approved for deletion. -// It compares the timestamp stored in the `AnnotationDeletionApproved` annotation -// with the provided 'since' time. If the annotation is missing or has an invalid -// timestamp format, it returns false. -func (app *Application) IsDeletionConfirmed(since time.Time) bool { - val := app.GetAnnotation(synccommon.AnnotationDeletionApproved) +func (a *Application) IsDeletionConfirmed(since time.Time) bool { + val := a.GetAnnotation(synccommon.AnnotationDeletionApproved) if val == "" { return false } diff --git a/pkg/apis/application/v1alpha1/types_test.go b/pkg/apis/application/v1alpha1/types_test.go index 9a00c75f72..8993fd23ed 100644 --- a/pkg/apis/application/v1alpha1/types_test.go +++ b/pkg/apis/application/v1alpha1/types_test.go @@ -6,13 +6,14 @@ import ( "fmt" "os" "path" + "reflect" "testing" "time" "github.com/stretchr/testify/require" "k8s.io/utils/ptr" - argocdcommon "github.com/argoproj/argo-cd/v3/common" + argocdcommon "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/stretchr/testify/assert" @@ -235,11 +236,7 @@ func TestAppProject_IsDestinationPermitted(t *testing.T) { Destinations: data.projDest, }, } - destCluster := &Cluster{ - Server: data.appDest.Server, - Name: data.appDest.Name, - } - permitted, _ := proj.IsDestinationPermitted(destCluster, data.appDest.Namespace, func(_ string) ([]*Cluster, error) { + permitted, _ := proj.IsDestinationPermitted(data.appDest, func(project string) ([]*Cluster, error) { return []*Cluster{}, nil }) assert.Equal(t, data.isPermitted, permitted) @@ -406,11 +403,7 @@ func TestAppProject_IsNegatedDestinationPermitted(t *testing.T) { Destinations: data.projDest, }, } - destCluster := &Cluster{ - Server: data.appDest.Server, - Name: data.appDest.Name, - } - permitted, _ := proj.IsDestinationPermitted(destCluster, data.appDest.Namespace, func(_ string) ([]*Cluster, error) { + permitted, _ := proj.IsDestinationPermitted(data.appDest, func(project string) ([]*Cluster, error) { return []*Cluster{}, nil }) assert.Equalf(t, data.isPermitted, permitted, "appDest mismatch for %+v with project destinations %+v", data.appDest, data.projDest) @@ -482,11 +475,8 @@ func TestAppProject_IsDestinationPermitted_PermitOnlyProjectScopedClusters(t *te Destinations: data.projDest, }, } - destCluster := &Cluster{ - Server: data.appDest.Server, - Name: data.appDest.Name, - } - permitted, _ := proj.IsDestinationPermitted(destCluster, data.appDest.Namespace, func(_ string) ([]*Cluster, error) { + + permitted, _ := proj.IsDestinationPermitted(data.appDest, func(_ string) ([]*Cluster, error) { return data.clusters, nil }) assert.Equal(t, data.isPermitted, permitted) @@ -500,7 +490,8 @@ func TestAppProject_IsDestinationPermitted_PermitOnlyProjectScopedClusters(t *te }}, }, } - _, err := proj.IsDestinationPermitted(&Cluster{Server: "https://my-cluster.123.com"}, "default", func(_ string) ([]*Cluster, error) { + + _, err := proj.IsDestinationPermitted(ApplicationDestination{Server: "https://my-cluster.123.com", Namespace: "default"}, func(_ string) ([]*Cluster, error) { return nil, errors.New("some error") }) assert.ErrorContains(t, err, "could not retrieve project clusters") @@ -1093,6 +1084,32 @@ func TestAppSource_GetNamespaceOrDefault(t *testing.T) { } } +func TestAppDestinationEquality(t *testing.T) { + left := &ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "default", + } + right := left.DeepCopy() + assert.True(t, left.Equals(*right)) + right.Namespace = "kube-system" + assert.False(t, left.Equals(*right)) +} + +func TestAppDestinationEquality_InferredServerURL(t *testing.T) { + left := ApplicationDestination{ + Name: "in-cluster", + Namespace: "default", + } + right := ApplicationDestination{ + Name: "in-cluster", + Server: "https://kubernetes.default.svc", + Namespace: "default", + isServerInferred: true, + } + assert.True(t, left.Equals(right)) + assert.True(t, right.Equals(left)) +} + func TestAppProjectSpec_DestinationClusters(t *testing.T) { tests := []struct { name string @@ -1113,7 +1130,9 @@ func TestAppProjectSpec_DestinationClusters(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { d := AppProjectSpec{Destinations: tt.destinations} - require.Equal(t, tt.want, d.DestinationClusters(), "AppProjectSpec.DestinationClusters()") + if got := d.DestinationClusters(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("AppProjectSpec.DestinationClusters() = %v, want %v", got, tt.want) + } }) } } @@ -1139,11 +1158,6 @@ func TestRepository_HasCredentials(t *testing.T) { repo: Repository{Password: "foo"}, want: true, }, - { - name: "TestHasBearerToken", - repo: Repository{BearerToken: "foo"}, - want: true, - }, { name: "TestHasSSHPrivateKey", repo: Repository{SSHPrivateKey: "foo"}, @@ -1162,7 +1176,9 @@ func TestRepository_HasCredentials(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equalf(t, tt.want, tt.repo.HasCredentials(), "Repository.HasCredentials()") + if got := tt.repo.HasCredentials(); got != tt.want { + t.Errorf("Repository.HasCredentials() = %v, want %v", got, tt.want) + } }) } } @@ -1201,7 +1217,9 @@ func TestRepository_IsInsecure(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equalf(t, tt.want, tt.repo.IsInsecure(), "Repository.IsInsecure()") + if got := tt.repo.IsInsecure(); got != tt.want { + t.Errorf("Repository.IsInsecure() = %v, want %v", got, tt.want) + } }) } } @@ -1240,7 +1258,9 @@ func TestRepository_IsLFSEnabled(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equalf(t, tt.want, tt.repo.IsLFSEnabled(), "Repository.IsLFSEnabled()") + if got := tt.repo.IsLFSEnabled(); got != tt.want { + t.Errorf("Repository.IsLFSEnabled() = %v, want %v", got, tt.want) + } }) } } @@ -1254,7 +1274,6 @@ func TestRepository_CopyCredentialsFromRepo(t *testing.T) { }{ {"Username", &Repository{Username: "foo"}, &Repository{}, Repository{Username: "foo"}}, {"Password", &Repository{Password: "foo"}, &Repository{}, Repository{Password: "foo"}}, - {"BearerToken", &Repository{BearerToken: "foo"}, &Repository{}, Repository{BearerToken: "foo"}}, {"SSHPrivateKey", &Repository{SSHPrivateKey: "foo"}, &Repository{}, Repository{SSHPrivateKey: "foo"}}, {"InsecureHostKey", &Repository{InsecureIgnoreHostKey: true}, &Repository{}, Repository{InsecureIgnoreHostKey: true}}, {"Insecure", &Repository{Insecure: true}, &Repository{}, Repository{Insecure: true}}, @@ -1265,7 +1284,6 @@ func TestRepository_CopyCredentialsFromRepo(t *testing.T) { {"SourceUsername", &Repository{}, &Repository{Username: "foo"}, Repository{Username: "foo"}}, {"SourcePassword", &Repository{}, &Repository{Password: "foo"}, Repository{Password: "foo"}}, - {"SourcePassword", &Repository{}, &Repository{BearerToken: "foo"}, Repository{BearerToken: "foo"}}, {"SourceSSHPrivateKey", &Repository{}, &Repository{SSHPrivateKey: "foo"}, Repository{SSHPrivateKey: "foo"}}, {"SourceInsecureHostKey", &Repository{}, &Repository{InsecureIgnoreHostKey: true}, Repository{InsecureIgnoreHostKey: false}}, {"SourceInsecure", &Repository{}, &Repository{Insecure: true}, Repository{Insecure: false}}, @@ -1291,7 +1309,6 @@ func TestRepository_CopyCredentialsFrom(t *testing.T) { }{ {"Username", &Repository{Username: "foo"}, &RepoCreds{}, Repository{Username: "foo"}}, {"Password", &Repository{Password: "foo"}, &RepoCreds{}, Repository{Password: "foo"}}, - {"BearerToken", &Repository{BearerToken: "foo"}, &RepoCreds{}, Repository{BearerToken: "foo"}}, {"SSHPrivateKey", &Repository{SSHPrivateKey: "foo"}, &RepoCreds{}, Repository{SSHPrivateKey: "foo"}}, {"InsecureHostKey", &Repository{InsecureIgnoreHostKey: true}, &RepoCreds{}, Repository{InsecureIgnoreHostKey: true}}, {"Insecure", &Repository{Insecure: true}, &RepoCreds{}, Repository{Insecure: true}}, @@ -1302,7 +1319,6 @@ func TestRepository_CopyCredentialsFrom(t *testing.T) { {"SourceUsername", &Repository{}, &RepoCreds{Username: "foo"}, Repository{Username: "foo"}}, {"SourcePassword", &Repository{}, &RepoCreds{Password: "foo"}, Repository{Password: "foo"}}, - {"SourceBearerToken", &Repository{}, &RepoCreds{BearerToken: "foo"}, Repository{BearerToken: "foo"}}, {"SourceSSHPrivateKey", &Repository{}, &RepoCreds{SSHPrivateKey: "foo"}, Repository{SSHPrivateKey: "foo"}}, {"SourceTLSClientCertData", &Repository{}, &RepoCreds{TLSClientCertData: "foo"}, Repository{TLSClientCertData: "foo"}}, {"SourceTLSClientCertKey", &Repository{}, &RepoCreds{TLSClientCertKey: "foo"}, Repository{TLSClientCertKey: "foo"}}, @@ -1360,7 +1376,9 @@ func TestSyncStrategy_Force(t *testing.T) { Apply: tt.fields.Apply, Hook: tt.fields.Hook, } - assert.Equalf(t, tt.want, m.Force(), "SyncStrategy.Force()") + if got := m.Force(); got != tt.want { + t.Errorf("SyncStrategy.Force() = %v, want %v", got, tt.want) + } }) } } @@ -1383,7 +1401,9 @@ func TestSyncOperation_IsApplyStrategy(t *testing.T) { o := &SyncOperation{ SyncStrategy: tt.fields.SyncStrategy, } - assert.Equalf(t, tt.want, o.IsApplyStrategy(), "SyncOperation.IsApplyStrategy()") + if got := o.IsApplyStrategy(); got != tt.want { + t.Errorf("SyncOperation.IsApplyStrategy() = %v, want %v", got, tt.want) + } }) } } @@ -1415,15 +1435,18 @@ func TestResourceResults_Find(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, got1 := tt.r.Find(tt.args.group, tt.args.kind, tt.args.namespace, tt.args.name, tt.args.phase) - assert.Equal(t, tt.want, got, "ResourceResults.Find()") - assert.Equal(t, tt.want1, got1, "ResourceResults.Find()") + if got != tt.want { + t.Errorf("ResourceResults.Find() got = %v, want %v", got, tt.want) + } + if !reflect.DeepEqual(got1, tt.want1) { + t.Errorf("ResourceResults.Find() got1 = %v, want %v", got1, tt.want1) + } }) } } func TestResourceResults_PruningRequired(t *testing.T) { needsPruning := &ResourceResult{Status: common.ResultCodePruneSkipped} - pruneSkippedButNoPruneMessage := &ResourceResult{Status: common.ResultCodePruneSkipped, Message: "ignored (no prune)"} tests := []struct { name string r ResourceResults @@ -1432,12 +1455,12 @@ func TestResourceResults_PruningRequired(t *testing.T) { {"TestNil", ResourceResults{}, 0}, {"TestOne", ResourceResults{needsPruning}, 1}, {"TestTwo", ResourceResults{needsPruning, needsPruning}, 2}, - {"TestPruneSkippedButNoPruneMessage", ResourceResults{pruneSkippedButNoPruneMessage}, 0}, - {"TestPruneSkippedButNoPruneMessage_and_OnePrune", ResourceResults{needsPruning, pruneSkippedButNoPruneMessage}, 1}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equalf(t, tt.wantNum, tt.r.PruningRequired(), "ResourceResults.PruningRequired()") + if gotNum := tt.r.PruningRequired(); gotNum != tt.wantNum { + t.Errorf("ResourceResults.PruningRequired() = %v, want %v", gotNum, tt.wantNum) + } }) } } @@ -1492,7 +1515,7 @@ func TestApplicationSourceHelm_AddFileParameter(t *testing.T) { func TestNewHelmParameter(t *testing.T) { t.Run("Invalid", func(t *testing.T) { _, err := NewHelmParameter("garbage", false) - require.EqualError(t, err, "expected helm parameter of the form param=value but received: garbage") + require.EqualError(t, err, "Expected helm parameter of the form: param=value. Received: garbage") }) t.Run("NonString", func(t *testing.T) { p, err := NewHelmParameter("foo=bar", false) @@ -1729,12 +1752,12 @@ func TestEnv_IsZero(t *testing.T) { func TestEnv_Envsubst(t *testing.T) { env := Env{&EnvEntry{"FOO", "bar"}} - assert.Empty(t, env.Envsubst("")) + assert.Equal(t, "", env.Envsubst("")) assert.Equal(t, "bar", env.Envsubst("$FOO")) assert.Equal(t, "bar", env.Envsubst("${FOO}")) assert.Equal(t, "FOO", env.Envsubst("${FOO")) - assert.Empty(t, env.Envsubst("$BAR")) - assert.Empty(t, env.Envsubst("${BAR}")) + assert.Equal(t, "", env.Envsubst("$BAR")) + assert.Equal(t, "", env.Envsubst("${BAR}")) assert.Equal(t, "echo bar; echo ; echo bar; echo ; echo FOO", env.Envsubst("echo $FOO; echo $BAR; echo ${FOO}; echo ${BAR}; echo ${FOO"), @@ -1774,13 +1797,10 @@ func TestKustomizeImage_Match(t *testing.T) { // mismatched delimiter assert.False(t, KustomizeImage("foo=1").Match("bar:1")) assert.False(t, KustomizeImage("foo:1").Match("bar=1")) - assert.False(t, KustomizeImage("foobar:2").Match("foo:2")) - assert.False(t, KustomizeImage("foobar@2").Match("foo@2")) // matches assert.True(t, KustomizeImage("foo=1").Match("foo=2")) assert.True(t, KustomizeImage("foo:1").Match("foo:2")) assert.True(t, KustomizeImage("foo@1").Match("foo@2")) - assert.True(t, KustomizeImage("nginx").Match("nginx")) } func TestApplicationSourceKustomize_MergeImage(t *testing.T) { @@ -2193,53 +2213,39 @@ func TestSyncWindows_InactiveAllows(t *testing.T) { func TestAppProjectSpec_AddWindow(t *testing.T) { proj := newTestProjectWithSyncWindows() tests := []struct { - name string - p *AppProject - k string - s string - d string - a []string - n []string - c []string - m bool - t string - o bool - description string - want string + name string + p *AppProject + k string + s string + d string + a []string + n []string + c []string + m bool + t string + want string }{ - {"MissingKind", proj, "", "* * * * *", "11", []string{"app1"}, []string{}, []string{}, false, "error", false, "", ""}, - {"MissingSchedule", proj, "allow", "", "", []string{"app1"}, []string{}, []string{}, false, "error", false, "", ""}, - {"MissingDuration", proj, "allow", "* * * * *", "", []string{"app1"}, []string{}, []string{}, false, "error", false, "", ""}, - {"BadSchedule", proj, "allow", "* * *", "1h", []string{"app1"}, []string{}, []string{}, false, "error", false, "", ""}, - {"BadDuration", proj, "deny", "* * * * *", "33mm", []string{"app1"}, []string{}, []string{}, false, "error", false, "", ""}, - {"WorkingApplication", proj, "allow", "1 * * * *", "1h", []string{"app1"}, []string{}, []string{}, false, "noError", false, "", ""}, - {"WorkingNamespace", proj, "deny", "3 * * * *", "1h", []string{}, []string{}, []string{"cluster"}, false, "noError", false, "", ""}, - {"WorkeringDescription", proj, "deny", "3 * * * *", "1h", []string{}, []string{}, []string{"cluster"}, false, "noError", false, "description", ""}, + {"MissingKind", proj, "", "* * * * *", "11", []string{"app1"}, []string{}, []string{}, false, "error", ""}, + {"MissingSchedule", proj, "allow", "", "", []string{"app1"}, []string{}, []string{}, false, "error", ""}, + {"MissingDuration", proj, "allow", "* * * * *", "", []string{"app1"}, []string{}, []string{}, false, "error", ""}, + {"BadSchedule", proj, "allow", "* * *", "1h", []string{"app1"}, []string{}, []string{}, false, "error", ""}, + {"BadDuration", proj, "deny", "* * * * *", "33mm", []string{"app1"}, []string{}, []string{}, false, "error", ""}, + {"WorkingApplication", proj, "allow", "1 * * * *", "1h", []string{"app1"}, []string{}, []string{}, false, "noError", ""}, + {"WorkingNamespace", proj, "deny", "3 * * * *", "1h", []string{}, []string{}, []string{"cluster"}, false, "noError", ""}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { switch tt.want { case "error": - require.Error(t, tt.p.Spec.AddWindow(tt.k, tt.s, tt.d, tt.a, tt.n, tt.c, tt.m, tt.t, tt.o, tt.description)) + require.Error(t, tt.p.Spec.AddWindow(tt.k, tt.s, tt.d, tt.a, tt.n, tt.c, tt.m, tt.t)) case "noError": - require.NoError(t, tt.p.Spec.AddWindow(tt.k, tt.s, tt.d, tt.a, tt.n, tt.c, tt.m, tt.t, tt.o, tt.description)) + require.NoError(t, tt.p.Spec.AddWindow(tt.k, tt.s, tt.d, tt.a, tt.n, tt.c, tt.m, tt.t)) require.NoError(t, tt.p.Spec.DeleteWindow(0)) } }) } } -func TestAppProjectSpecWindowWithDescription(t *testing.T) { - proj := newTestProjectWithSyncWindows() - require.NoError(t, proj.Spec.AddWindow("allow", "* * * * *", "1h", []string{"app1"}, []string{}, []string{}, false, "error", false, "Ticket AAAAA")) - require.Equal(t, "Ticket AAAAA", proj.Spec.SyncWindows[1].Description) - - require.NoError(t, proj.Spec.SyncWindows[1].Update("", "", []string{}, []string{}, []string{}, "", "Ticket BBBBB")) - require.Equal(t, "Ticket BBBBB", proj.Spec.SyncWindows[1].Description) - - require.Error(t, proj.Spec.SyncWindows[1].Update("", "", []string{}, []string{}, []string{}, "", "")) -} - func TestAppProjectSpec_DeleteWindow(t *testing.T) { proj := newTestProjectWithSyncWindows() window2 := &SyncWindow{Schedule: "1 * * * *", Duration: "2h"} @@ -2261,203 +2267,34 @@ func TestSyncWindows_Matches(t *testing.T) { app := newTestApp() t.Run("MatchNamespace", func(t *testing.T) { proj.Spec.SyncWindows[0].Namespaces = []string{"default"} - proj.Spec.SyncWindows[0].Clusters = nil - proj.Spec.SyncWindows[0].Applications = nil windows := proj.Spec.SyncWindows.Matches(app) assert.Len(t, *windows, 1) proj.Spec.SyncWindows[0].Namespaces = nil }) t.Run("MatchCluster", func(t *testing.T) { proj.Spec.SyncWindows[0].Clusters = []string{"cluster1"} - proj.Spec.SyncWindows[0].Namespaces = nil - proj.Spec.SyncWindows[0].Applications = nil windows := proj.Spec.SyncWindows.Matches(app) assert.Len(t, *windows, 1) proj.Spec.SyncWindows[0].Clusters = nil }) t.Run("MatchClusterName", func(t *testing.T) { proj.Spec.SyncWindows[0].Clusters = []string{"clusterName"} - proj.Spec.SyncWindows[0].Namespaces = nil - proj.Spec.SyncWindows[0].Applications = nil windows := proj.Spec.SyncWindows.Matches(app) assert.Len(t, *windows, 1) proj.Spec.SyncWindows[0].Clusters = nil }) t.Run("MatchAppName", func(t *testing.T) { proj.Spec.SyncWindows[0].Applications = []string{"test-app"} - proj.Spec.SyncWindows[0].Namespaces = nil - proj.Spec.SyncWindows[0].Clusters = nil windows := proj.Spec.SyncWindows.Matches(app) assert.Len(t, *windows, 1) proj.Spec.SyncWindows[0].Applications = nil }) - t.Run("MatchAppNameAndNamespace", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-app"} - proj.Spec.SyncWindows[0].Namespaces = []string{"default"} - proj.Spec.SyncWindows[0].Clusters = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Applications = nil - proj.Spec.SyncWindows[0].Namespaces = nil - }) - t.Run("MatchAppNameAndClusterName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-app"} - proj.Spec.SyncWindows[0].Clusters = []string{"clusterName"} - proj.Spec.SyncWindows[0].Namespaces = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Applications = nil - proj.Spec.SyncWindows[0].Clusters = nil - }) - t.Run("MatchNamespaceAndClusterName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Namespaces = []string{"default"} - proj.Spec.SyncWindows[0].Clusters = []string{"clusterName"} - proj.Spec.SyncWindows[0].Applications = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Namespaces = nil - proj.Spec.SyncWindows[0].Clusters = nil - }) - t.Run("MatchAppNameAndNamespaceAndClusterName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-app"} - proj.Spec.SyncWindows[0].Namespaces = []string{"default"} - proj.Spec.SyncWindows[0].Clusters = []string{"clusterName"} - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Applications = nil - proj.Spec.SyncWindows[0].Namespaces = nil - proj.Spec.SyncWindows[0].Clusters = nil - }) t.Run("MatchWildcardAppName", func(t *testing.T) { proj.Spec.SyncWindows[0].Applications = []string{"test-*"} - proj.Spec.SyncWindows[0].Clusters = nil - proj.Spec.SyncWindows[0].Namespaces = nil windows := proj.Spec.SyncWindows.Matches(app) assert.Len(t, *windows, 1) proj.Spec.SyncWindows[0].Applications = nil }) - t.Run("MatchWildcardAppNameAndNamespace", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-*"} - proj.Spec.SyncWindows[0].Namespaces = []string{"default"} - proj.Spec.SyncWindows[0].Clusters = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Applications = nil - proj.Spec.SyncWindows[0].Namespaces = nil - }) - t.Run("MatchWildcardAppNameAndWildcardClusterName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-*"} - proj.Spec.SyncWindows[0].Clusters = []string{"clusterN*"} - proj.Spec.SyncWindows[0].Namespaces = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Applications = nil - proj.Spec.SyncWindows[0].Clusters = nil - }) - t.Run("NoMatch", func(t *testing.T) { - windows := proj.Spec.SyncWindows.Matches(app) - assert.Nil(t, windows) - }) -} - -func TestSyncWindows_Matches_AND_Operator(t *testing.T) { - proj := newTestProjectWithSyncWindowsAndOperator() - app := newTestApp() - t.Run("MatchNamespace", func(t *testing.T) { - proj.Spec.SyncWindows[0].Namespaces = []string{"default"} - proj.Spec.SyncWindows[0].Clusters = nil - proj.Spec.SyncWindows[0].Applications = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Namespaces = nil - }) - t.Run("MatchCluster", func(t *testing.T) { - proj.Spec.SyncWindows[0].Clusters = []string{"cluster1"} - proj.Spec.SyncWindows[0].Namespaces = nil - proj.Spec.SyncWindows[0].Applications = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Clusters = nil - }) - t.Run("MatchClusterName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Clusters = []string{"clusterName"} - proj.Spec.SyncWindows[0].Namespaces = nil - proj.Spec.SyncWindows[0].Applications = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Clusters = nil - }) - t.Run("MatchAppName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-app"} - proj.Spec.SyncWindows[0].Namespaces = nil - proj.Spec.SyncWindows[0].Clusters = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Applications = nil - }) - t.Run("MatchAppNameAndNamespace", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-app"} - proj.Spec.SyncWindows[0].Namespaces = []string{"default"} - proj.Spec.SyncWindows[0].Clusters = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Applications = nil - proj.Spec.SyncWindows[0].Namespaces = nil - }) - t.Run("MatchAppNameAndClusterName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-app"} - proj.Spec.SyncWindows[0].Clusters = []string{"clusterName"} - proj.Spec.SyncWindows[0].Namespaces = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Applications = nil - proj.Spec.SyncWindows[0].Clusters = nil - }) - t.Run("MatchNamespaceAndClusterName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Namespaces = []string{"default"} - proj.Spec.SyncWindows[0].Clusters = []string{"clusterName"} - proj.Spec.SyncWindows[0].Applications = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Namespaces = nil - proj.Spec.SyncWindows[0].Clusters = nil - }) - t.Run("MatchAppNameAndNamespaceAndClusterName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-app"} - proj.Spec.SyncWindows[0].Namespaces = []string{"default"} - proj.Spec.SyncWindows[0].Clusters = []string{"clusterName"} - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Applications = nil - proj.Spec.SyncWindows[0].Namespaces = nil - proj.Spec.SyncWindows[0].Clusters = nil - }) - t.Run("MatchWildcardAppName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-*"} - proj.Spec.SyncWindows[0].Clusters = nil - proj.Spec.SyncWindows[0].Namespaces = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Applications = nil - }) - t.Run("MatchWildcardAppNameAndNamespace", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-*"} - proj.Spec.SyncWindows[0].Namespaces = []string{"default"} - proj.Spec.SyncWindows[0].Clusters = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Applications = nil - proj.Spec.SyncWindows[0].Namespaces = nil - }) - t.Run("MatchWildcardAppNameAndWildcardClusterName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-*"} - proj.Spec.SyncWindows[0].Clusters = []string{"clusterN*"} - proj.Spec.SyncWindows[0].Namespaces = nil - windows := proj.Spec.SyncWindows.Matches(app) - assert.Len(t, *windows, 1) - proj.Spec.SyncWindows[0].Applications = nil - proj.Spec.SyncWindows[0].Clusters = nil - }) t.Run("NoMatch", func(t *testing.T) { windows := proj.Spec.SyncWindows.Matches(app) assert.Nil(t, windows) @@ -2996,39 +2833,34 @@ func TestSyncWindow_Active(t *testing.T) { func TestSyncWindow_Update(t *testing.T) { e := SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h", Applications: []string{"app1"}} t.Run("AddApplication", func(t *testing.T) { - err := e.Update("", "", []string{"app1", "app2"}, []string{}, []string{}, "", "") + err := e.Update("", "", []string{"app1", "app2"}, []string{}, []string{}, "") require.NoError(t, err) assert.Equal(t, []string{"app1", "app2"}, e.Applications) }) t.Run("AddNamespace", func(t *testing.T) { - err := e.Update("", "", []string{}, []string{"namespace1"}, []string{}, "", "") + err := e.Update("", "", []string{}, []string{"namespace1"}, []string{}, "") require.NoError(t, err) assert.Equal(t, []string{"namespace1"}, e.Namespaces) }) t.Run("AddCluster", func(t *testing.T) { - err := e.Update("", "", []string{}, []string{}, []string{"cluster1"}, "", "") + err := e.Update("", "", []string{}, []string{}, []string{"cluster1"}, "") require.NoError(t, err) assert.Equal(t, []string{"cluster1"}, e.Clusters) }) t.Run("MissingConfig", func(t *testing.T) { - err := e.Update("", "", []string{}, []string{}, []string{}, "", "") - require.EqualError(t, err, "cannot update: require one or more of schedule, duration, application, namespace, cluster or description") + err := e.Update("", "", []string{}, []string{}, []string{}, "") + require.EqualError(t, err, "cannot update: require one or more of schedule, duration, application, namespace, or cluster") }) t.Run("ChangeDuration", func(t *testing.T) { - err := e.Update("", "10h", []string{}, []string{}, []string{}, "", "") + err := e.Update("", "10h", []string{}, []string{}, []string{}, "") require.NoError(t, err) assert.Equal(t, "10h", e.Duration) }) t.Run("ChangeSchedule", func(t *testing.T) { - err := e.Update("* 1 0 0 *", "", []string{}, []string{}, []string{}, "", "") + err := e.Update("* 1 0 0 *", "", []string{}, []string{}, []string{}, "") require.NoError(t, err) assert.Equal(t, "* 1 0 0 *", e.Schedule) }) - t.Run("AddDescription", func(t *testing.T) { - err := e.Update("", "", []string{}, []string{}, []string{}, "", "Ticket 123") - require.NoError(t, err) - assert.Equal(t, "Ticket 123", e.Description) - }) } func TestSyncWindow_Validate(t *testing.T) { @@ -3063,7 +2895,7 @@ func TestApplicationStatus_GetConditions(t *testing.T) { conditions := status.GetConditions(map[ApplicationConditionType]bool{ ApplicationConditionInvalidSpecError: true, }) - assert.Equal(t, []ApplicationCondition{{Type: ApplicationConditionInvalidSpecError}}, conditions) + assert.EqualValues(t, []ApplicationCondition{{Type: ApplicationConditionInvalidSpecError}}, conditions) } type projectBuilder struct { @@ -3081,41 +2913,35 @@ func (b *projectBuilder) build() *AppProject { } func (b *projectBuilder) withActiveAllowWindow(allowManual bool) *projectBuilder { - window := newSyncWindow("allow", "* * * * *", allowManual, false) - b.proj.Spec.SyncWindows = append(b.proj.Spec.SyncWindows, window) - return b -} - -func (b *projectBuilder) withActiveAllowWindowAndOperator(allowManual bool, andOperator bool) *projectBuilder { - window := newSyncWindow("allow", "* * * * *", allowManual, andOperator) + window := newSyncWindow("allow", "* * * * *", allowManual) b.proj.Spec.SyncWindows = append(b.proj.Spec.SyncWindows, window) return b } func (b *projectBuilder) withInactiveAllowWindow(allowManual bool) *projectBuilder { - window := newSyncWindow("allow", inactiveCronSchedule(), allowManual, false) + window := newSyncWindow("allow", inactiveCronSchedule(), allowManual) b.proj.Spec.SyncWindows = append(b.proj.Spec.SyncWindows, window) return b } func (b *projectBuilder) withActiveDenyWindow(allowManual bool) *projectBuilder { - window := newSyncWindow("deny", "* * * * *", allowManual, false) + window := newSyncWindow("deny", "* * * * *", allowManual) b.proj.Spec.SyncWindows = append(b.proj.Spec.SyncWindows, window) return b } func (b *projectBuilder) withInactiveDenyWindow(allowManual bool) *projectBuilder { - window := newSyncWindow("deny", inactiveCronSchedule(), allowManual, false) + window := newSyncWindow("deny", inactiveCronSchedule(), allowManual) b.proj.Spec.SyncWindows = append(b.proj.Spec.SyncWindows, window) return b } func (b *projectBuilder) withInvalidWindows() *projectBuilder { b.proj.Spec.SyncWindows = append(b.proj.Spec.SyncWindows, - newSyncWindow("allow", "* 10 * * 7", false, false), - newSyncWindow("deny", "* 10 * * 7", false, false), - newSyncWindow("allow", "* 10 * * 7", true, false), - newSyncWindow("deny", "* 10 * * 7", true, false), + newSyncWindow("allow", "* 10 * * 7", false), + newSyncWindow("deny", "* 10 * * 7", false), + newSyncWindow("allow", "* 10 * * 7", true), + newSyncWindow("deny", "* 10 * * 7", true), ) return b } @@ -3125,15 +2951,14 @@ func inactiveCronSchedule() string { return fmt.Sprintf("0 %d * * *", hourPlus10) } -func newSyncWindow(kind, schedule string, allowManual bool, andOperator bool) *SyncWindow { +func newSyncWindow(kind, schedule string, allowManual bool) *SyncWindow { return &SyncWindow{ - Kind: kind, - Schedule: schedule, - Duration: "1h", - Applications: []string{"app1"}, - Namespaces: []string{"public"}, - ManualSync: allowManual, - UseAndOperator: andOperator, + Kind: kind, + Schedule: schedule, + Duration: "1h", + Applications: []string{"app1"}, + Namespaces: []string{"public"}, + ManualSync: allowManual, } } @@ -3141,10 +2966,6 @@ func newTestProjectWithSyncWindows() *AppProject { return newProjectBuilder().withActiveAllowWindow(false).build() } -func newTestProjectWithSyncWindowsAndOperator() *AppProject { - return newProjectBuilder().withActiveAllowWindowAndOperator(false, true).build() -} - func newTestApp() *Application { a := &Application{ ObjectMeta: metav1.ObjectMeta{Name: "test-app"}, @@ -3224,8 +3045,8 @@ func TestSetConditions(t *testing.T) { validate: func(t *testing.T, a *Application) { t.Helper() // SetConditions should add timestamps for new conditions. - assert.True(t, a.Status.Conditions[0].LastTransitionTime.After(fiveMinsAgo.Time)) - assert.True(t, a.Status.Conditions[1].LastTransitionTime.After(fiveMinsAgo.Time)) + assert.True(t, a.Status.Conditions[0].LastTransitionTime.Time.After(fiveMinsAgo.Time)) + assert.True(t, a.Status.Conditions[1].LastTransitionTime.Time.After(fiveMinsAgo.Time)) }, }, { @@ -3347,7 +3168,7 @@ func TestSetConditions(t *testing.T) { // to match positions. func assertConditions(t *testing.T, expected []ApplicationCondition, actual []ApplicationCondition) { t.Helper() - assert.Len(t, actual, len(expected)) + assert.Equal(t, len(expected), len(actual)) for i := range expected { assert.Equal(t, expected[i].Type, actual[i].Type) assert.Equal(t, expected[i].Message, actual[i].Message) @@ -3388,8 +3209,6 @@ func TestRevisionHistories_Trunc(t *testing.T) { assert.Len(t, RevisionHistories{{}, {}}.Trunc(1), 1) // keep the last element, even with longer list assert.Equal(t, RevisionHistories{{Revision: "my-revision"}}, RevisionHistories{{}, {}, {Revision: "my-revision"}}.Trunc(1)) - // negative limit to 0 - assert.Empty(t, RevisionHistories{}.Trunc(-1)) } func TestApplicationSpec_GetRevisionHistoryLimit(t *testing.T) { @@ -3983,9 +3802,9 @@ func TestApplicationSourcePluginParameters_Environ_string(t *testing.T) { require.NoError(t, err) assert.Len(t, environ, 2) assert.Contains(t, environ, "PARAM_VERSION=1.2.3") - paramsJSON, err := json.Marshal(params) + paramsJson, err := json.Marshal(params) require.NoError(t, err) - assert.Contains(t, environ, fmt.Sprintf("ARGOCD_APP_PARAMETERS=%s", paramsJSON)) + assert.Contains(t, environ, fmt.Sprintf("ARGOCD_APP_PARAMETERS=%s", paramsJson)) } func TestApplicationSourcePluginParameters_Environ_array(t *testing.T) { @@ -4000,9 +3819,9 @@ func TestApplicationSourcePluginParameters_Environ_array(t *testing.T) { assert.Len(t, environ, 3) assert.Contains(t, environ, "PARAM_DEPENDENCIES_0=redis") assert.Contains(t, environ, "PARAM_DEPENDENCIES_1=minio") - paramsJSON, err := json.Marshal(params) + paramsJson, err := json.Marshal(params) require.NoError(t, err) - assert.Contains(t, environ, fmt.Sprintf("ARGOCD_APP_PARAMETERS=%s", paramsJSON)) + assert.Contains(t, environ, fmt.Sprintf("ARGOCD_APP_PARAMETERS=%s", paramsJson)) } func TestApplicationSourcePluginParameters_Environ_map(t *testing.T) { @@ -4022,9 +3841,9 @@ func TestApplicationSourcePluginParameters_Environ_map(t *testing.T) { assert.Len(t, environ, 3) assert.Contains(t, environ, "PARAM_HELM_PARAMETERS_IMAGE_REPO=quay.io/argoproj/argo-cd") assert.Contains(t, environ, "PARAM_HELM_PARAMETERS_IMAGE_TAG=v2.4.0") - paramsJSON, err := json.Marshal(params) + paramsJson, err := json.Marshal(params) require.NoError(t, err) - assert.Contains(t, environ, fmt.Sprintf("ARGOCD_APP_PARAMETERS=%s", paramsJSON)) + assert.Contains(t, environ, fmt.Sprintf("ARGOCD_APP_PARAMETERS=%s", paramsJson)) } func TestApplicationSourcePluginParameters_Environ_all(t *testing.T) { @@ -4053,9 +3872,9 @@ func TestApplicationSourcePluginParameters_Environ_all(t *testing.T) { assert.Contains(t, environ, "PARAM_SOME_NAME_1=minio") assert.Contains(t, environ, "PARAM_SOME_NAME_IMAGE_REPO=quay.io/argoproj/argo-cd") assert.Contains(t, environ, "PARAM_SOME_NAME_IMAGE_TAG=v2.4.0") - paramsJSON, err := json.Marshal(params) + paramsJson, err := json.Marshal(params) require.NoError(t, err) - assert.Contains(t, environ, fmt.Sprintf("ARGOCD_APP_PARAMETERS=%s", paramsJSON)) + assert.Contains(t, environ, fmt.Sprintf("ARGOCD_APP_PARAMETERS=%s", paramsJson)) } func getApplicationSpec() *ApplicationSpec { @@ -4146,6 +3965,7 @@ func TestOptionalArrayEquality(t *testing.T) { err := json.Unmarshal([]byte(presentButEmpty), ¶m) require.NoError(t, err) jsonPresentButEmpty := param.OptionalArray + // nolint:testifylint require.Equal(t, &OptionalArray{Array: []string{}}, jsonPresentButEmpty) // We won't simulate the protobuf unmarshalling of an empty array parameter. By experimentation, this is how it's @@ -4189,6 +4009,7 @@ func TestOptionalMapEquality(t *testing.T) { err := json.Unmarshal([]byte(presentButEmpty), ¶m) require.NoError(t, err) jsonPresentButEmpty := param.OptionalMap + // nolint:testifylint require.Equal(t, &OptionalMap{Map: map[string]string{}}, jsonPresentButEmpty) // We won't simulate the protobuf unmarshalling of an empty map parameter. By experimentation, this is how it's @@ -4507,7 +4328,7 @@ func TestCluster_ParseProxyUrl(t *testing.T) { }, { url: "test://!abc", - expectedErrMsg: "failed to parse proxy url, unsupported scheme \"test\", must be http, https, or socks5", + expectedErrMsg: "Failed to parse proxy url, unsupported scheme \"test\", must be http, https, or socks5", }, { url: "http://192.168.99.100:8443", diff --git a/pkg/apis/application/v1alpha1/values.go b/pkg/apis/application/v1alpha1/values.go index e900a5d3d6..1c0d6b76de 100644 --- a/pkg/apis/application/v1alpha1/values.go +++ b/pkg/apis/application/v1alpha1/values.go @@ -3,10 +3,10 @@ package v1alpha1 import ( "encoding/json" "fmt" - "reflect" + reflect "reflect" "strings" - "k8s.io/apimachinery/pkg/runtime" + runtime "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/yaml" ) @@ -21,13 +21,13 @@ func (h *ApplicationSourceHelm) SetValuesString(value string) error { if err != nil { return fmt.Errorf("failed converting yaml to json: %w", err) } - var v any + var v interface{} if err := json.Unmarshal(data, &v); err != nil { return fmt.Errorf("failed to unmarshal json: %w", err) } switch v.(type) { case string: - case map[string]any: + case map[string]interface{}: default: return fmt.Errorf("invalid type %q", reflect.TypeOf(v)) } diff --git a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go index 7992eaa4cb..9faf5d3a73 100644 --- a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go @@ -42,26 +42,6 @@ func (in *AWSAuthConfig) DeepCopy() *AWSAuthConfig { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AppHealthStatus) DeepCopyInto(out *AppHealthStatus) { - *out = *in - if in.LastTransitionTime != nil { - in, out := &in.LastTransitionTime, &out.LastTransitionTime - *out = (*in).DeepCopy() - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppHealthStatus. -func (in *AppHealthStatus) DeepCopy() *AppHealthStatus { - if in == nil { - return nil - } - out := new(AppHealthStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AppProject) DeepCopyInto(out *AppProject) { *out = *in @@ -3139,13 +3119,6 @@ func (in *PullRequestGenerator) DeepCopyInto(out *PullRequestGenerator) { *out = new(PullRequestGeneratorAzureDevOps) (*in).DeepCopyInto(*out) } - if in.Values != nil { - in, out := &in.Values, &out.Values - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } return } @@ -3307,11 +3280,6 @@ func (in *PullRequestGeneratorGitea) DeepCopyInto(out *PullRequestGeneratorGitea *out = new(SecretRef) **out = **in } - if in.Labels != nil { - in, out := &in.Labels, &out.Labels - *out = make([]string, len(*in)) - copy(*out, *in) - } return } @@ -4491,7 +4459,7 @@ func (in *SyncPolicy) DeepCopyInto(out *SyncPolicy) { if in.Automated != nil { in, out := &in.Automated, &out.Automated *out = new(SyncPolicyAutomated) - (*in).DeepCopyInto(*out) + **out = **in } if in.SyncOptions != nil { in, out := &in.SyncOptions, &out.SyncOptions @@ -4524,11 +4492,6 @@ func (in *SyncPolicy) DeepCopy() *SyncPolicy { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SyncPolicyAutomated) DeepCopyInto(out *SyncPolicyAutomated) { *out = *in - if in.Enabled != nil { - in, out := &in.Enabled, &out.Enabled - *out = new(bool) - **out = **in - } return } diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index cbabdf3737..869b10d0f8 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -3,10 +3,10 @@ package versioned import ( - fmt "fmt" - http "net/http" + "fmt" + "net/http" - argoprojv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1" + argoprojv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index 9e144e2a9f..fe6096b4ca 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -3,9 +3,9 @@ package fake import ( - clientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - argoprojv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1" - fakeargoprojv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1/fake" + clientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + argoprojv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1" + fakeargoprojv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1/fake" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/discovery" diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index a359fc50b6..5773b75ce6 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -3,7 +3,7 @@ package fake import ( - argoprojv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index 00498c3d9c..46f64a49e4 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -3,7 +3,7 @@ package scheme import ( - argoprojv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoprojv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/application.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/application.go index dbcdd097fe..69546f4441 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/application.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/application.go @@ -3,10 +3,10 @@ package v1alpha1 import ( - context "context" + "context" - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - scheme "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/scheme" + 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" @@ -21,32 +21,31 @@ type ApplicationsGetter interface { // ApplicationInterface has methods to work with Application resources. type ApplicationInterface interface { - Create(ctx context.Context, application *applicationv1alpha1.Application, opts v1.CreateOptions) (*applicationv1alpha1.Application, error) - Update(ctx context.Context, application *applicationv1alpha1.Application, opts v1.UpdateOptions) (*applicationv1alpha1.Application, error) + Create(ctx context.Context, application *v1alpha1.Application, opts v1.CreateOptions) (*v1alpha1.Application, error) + Update(ctx context.Context, application *v1alpha1.Application, opts v1.UpdateOptions) (*v1alpha1.Application, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*applicationv1alpha1.Application, error) - List(ctx context.Context, opts v1.ListOptions) (*applicationv1alpha1.ApplicationList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.Application, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ApplicationList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *applicationv1alpha1.Application, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.Application, err error) ApplicationExpansion } // applications implements ApplicationInterface type applications struct { - *gentype.ClientWithList[*applicationv1alpha1.Application, *applicationv1alpha1.ApplicationList] + *gentype.ClientWithList[*v1alpha1.Application, *v1alpha1.ApplicationList] } // newApplications returns a Applications func newApplications(c *ArgoprojV1alpha1Client, namespace string) *applications { return &applications{ - gentype.NewClientWithList[*applicationv1alpha1.Application, *applicationv1alpha1.ApplicationList]( + gentype.NewClientWithList[*v1alpha1.Application, *v1alpha1.ApplicationList]( "applications", c.RESTClient(), scheme.ParameterCodec, namespace, - func() *applicationv1alpha1.Application { return &applicationv1alpha1.Application{} }, - func() *applicationv1alpha1.ApplicationList { return &applicationv1alpha1.ApplicationList{} }, - ), + func() *v1alpha1.Application { return &v1alpha1.Application{} }, + func() *v1alpha1.ApplicationList { return &v1alpha1.ApplicationList{} }), } } diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/application_client.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/application_client.go index 7f959111c7..51994c674f 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/application_client.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/application_client.go @@ -3,10 +3,10 @@ package v1alpha1 import ( - http "net/http" + "net/http" - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - scheme "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/scheme" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/scheme" rest "k8s.io/client-go/rest" ) @@ -79,10 +79,10 @@ func New(c rest.Interface) *ArgoprojV1alpha1Client { } func setConfigDefaults(config *rest.Config) error { - gv := applicationv1alpha1.SchemeGroupVersion + gv := v1alpha1.SchemeGroupVersion config.GroupVersion = &gv config.APIPath = "/apis" - config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion() + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() if config.UserAgent == "" { config.UserAgent = rest.DefaultKubernetesUserAgent() diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/applicationset.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/applicationset.go index e1d66f3b60..9fadaabc0d 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/applicationset.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/applicationset.go @@ -3,10 +3,10 @@ package v1alpha1 import ( - context "context" + "context" - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - scheme "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/scheme" + 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" @@ -21,32 +21,31 @@ type ApplicationSetsGetter interface { // ApplicationSetInterface has methods to work with ApplicationSet resources. type ApplicationSetInterface interface { - Create(ctx context.Context, applicationSet *applicationv1alpha1.ApplicationSet, opts v1.CreateOptions) (*applicationv1alpha1.ApplicationSet, error) - Update(ctx context.Context, applicationSet *applicationv1alpha1.ApplicationSet, opts v1.UpdateOptions) (*applicationv1alpha1.ApplicationSet, error) + Create(ctx context.Context, applicationSet *v1alpha1.ApplicationSet, opts v1.CreateOptions) (*v1alpha1.ApplicationSet, error) + Update(ctx context.Context, applicationSet *v1alpha1.ApplicationSet, opts v1.UpdateOptions) (*v1alpha1.ApplicationSet, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*applicationv1alpha1.ApplicationSet, error) - List(ctx context.Context, opts v1.ListOptions) (*applicationv1alpha1.ApplicationSetList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ApplicationSet, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ApplicationSetList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *applicationv1alpha1.ApplicationSet, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ApplicationSet, err error) ApplicationSetExpansion } // applicationSets implements ApplicationSetInterface type applicationSets struct { - *gentype.ClientWithList[*applicationv1alpha1.ApplicationSet, *applicationv1alpha1.ApplicationSetList] + *gentype.ClientWithList[*v1alpha1.ApplicationSet, *v1alpha1.ApplicationSetList] } // newApplicationSets returns a ApplicationSets func newApplicationSets(c *ArgoprojV1alpha1Client, namespace string) *applicationSets { return &applicationSets{ - gentype.NewClientWithList[*applicationv1alpha1.ApplicationSet, *applicationv1alpha1.ApplicationSetList]( + gentype.NewClientWithList[*v1alpha1.ApplicationSet, *v1alpha1.ApplicationSetList]( "applicationsets", c.RESTClient(), scheme.ParameterCodec, namespace, - func() *applicationv1alpha1.ApplicationSet { return &applicationv1alpha1.ApplicationSet{} }, - func() *applicationv1alpha1.ApplicationSetList { return &applicationv1alpha1.ApplicationSetList{} }, - ), + func() *v1alpha1.ApplicationSet { return &v1alpha1.ApplicationSet{} }, + func() *v1alpha1.ApplicationSetList { return &v1alpha1.ApplicationSetList{} }), } } diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/appproject.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/appproject.go index 78aa5e5549..a20ec8041d 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/appproject.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/appproject.go @@ -3,10 +3,10 @@ package v1alpha1 import ( - context "context" + "context" - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - scheme "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/scheme" + 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" @@ -21,32 +21,31 @@ type AppProjectsGetter interface { // AppProjectInterface has methods to work with AppProject resources. type AppProjectInterface interface { - Create(ctx context.Context, appProject *applicationv1alpha1.AppProject, opts v1.CreateOptions) (*applicationv1alpha1.AppProject, error) - Update(ctx context.Context, appProject *applicationv1alpha1.AppProject, opts v1.UpdateOptions) (*applicationv1alpha1.AppProject, error) + Create(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.CreateOptions) (*v1alpha1.AppProject, error) + Update(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.UpdateOptions) (*v1alpha1.AppProject, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*applicationv1alpha1.AppProject, error) - List(ctx context.Context, opts v1.ListOptions) (*applicationv1alpha1.AppProjectList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.AppProject, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.AppProjectList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *applicationv1alpha1.AppProject, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.AppProject, err error) AppProjectExpansion } // appProjects implements AppProjectInterface type appProjects struct { - *gentype.ClientWithList[*applicationv1alpha1.AppProject, *applicationv1alpha1.AppProjectList] + *gentype.ClientWithList[*v1alpha1.AppProject, *v1alpha1.AppProjectList] } // newAppProjects returns a AppProjects func newAppProjects(c *ArgoprojV1alpha1Client, namespace string) *appProjects { return &appProjects{ - gentype.NewClientWithList[*applicationv1alpha1.AppProject, *applicationv1alpha1.AppProjectList]( + gentype.NewClientWithList[*v1alpha1.AppProject, *v1alpha1.AppProjectList]( "appprojects", c.RESTClient(), scheme.ParameterCodec, namespace, - func() *applicationv1alpha1.AppProject { return &applicationv1alpha1.AppProject{} }, - func() *applicationv1alpha1.AppProjectList { return &applicationv1alpha1.AppProjectList{} }, - ), + func() *v1alpha1.AppProject { return &v1alpha1.AppProject{} }, + func() *v1alpha1.AppProjectList { return &v1alpha1.AppProjectList{} }), } } 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 158ad086af..4a6cb8f9ea 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 @@ -3,34 +3,116 @@ package fake import ( - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1" - gentype "k8s.io/client-go/gentype" + "context" + + 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" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" ) -// fakeApplications implements ApplicationInterface -type fakeApplications struct { - *gentype.FakeClientWithList[*v1alpha1.Application, *v1alpha1.ApplicationList] +// FakeApplications implements ApplicationInterface +type FakeApplications struct { Fake *FakeArgoprojV1alpha1 + ns string } -func newFakeApplications(fake *FakeArgoprojV1alpha1, namespace string) applicationv1alpha1.ApplicationInterface { - return &fakeApplications{ - gentype.NewFakeClientWithList[*v1alpha1.Application, *v1alpha1.ApplicationList]( - fake.Fake, - namespace, - v1alpha1.SchemeGroupVersion.WithResource("applications"), - v1alpha1.SchemeGroupVersion.WithKind("Application"), - func() *v1alpha1.Application { return &v1alpha1.Application{} }, - func() *v1alpha1.ApplicationList { return &v1alpha1.ApplicationList{} }, - func(dst, src *v1alpha1.ApplicationList) { dst.ListMeta = src.ListMeta }, - func(list *v1alpha1.ApplicationList) []*v1alpha1.Application { - return gentype.ToPointerSlice(list.Items) - }, - func(list *v1alpha1.ApplicationList, items []*v1alpha1.Application) { - list.Items = gentype.FromPointerSlice(items) - }, - ), - fake, +var applicationsResource = v1alpha1.SchemeGroupVersion.WithResource("applications") + +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.NewGetActionWithOptions(applicationsResource, c.ns, name, options), emptyResult) + + if obj == nil { + 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.NewListActionWithOptions(applicationsResource, applicationsKind, c.ns, opts), emptyResult) + + if obj == nil { + return emptyResult, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.ApplicationList{ListMeta: obj.(*v1alpha1.ApplicationList).ListMeta} + for _, item := range obj.(*v1alpha1.ApplicationList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// 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.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.NewCreateActionWithOptions(applicationsResource, c.ns, application, opts), emptyResult) + + if obj == nil { + 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.NewUpdateActionWithOptions(applicationsResource, c.ns, application, opts), emptyResult) + + if obj == nil { + return emptyResult, err + } + return obj.(*v1alpha1.Application), err +} + +// Delete takes name of the application and deletes it. Returns an error if one occurs. +func (c *FakeApplications) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(applicationsResource, c.ns, name, opts), &v1alpha1.Application{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeApplications) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionActionWithOptions(applicationsResource, c.ns, opts, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.ApplicationList{}) + return err +} + +// 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.NewPatchSubresourceActionWithOptions(applicationsResource, c.ns, name, pt, data, opts, subresources...), emptyResult) + + if obj == nil { + return emptyResult, err + } + return obj.(*v1alpha1.Application), err } diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application_client.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application_client.go index d3dd218fbd..af74100b97 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application_client.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application_client.go @@ -3,7 +3,7 @@ package fake import ( - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1" rest "k8s.io/client-go/rest" testing "k8s.io/client-go/testing" ) @@ -13,15 +13,15 @@ type FakeArgoprojV1alpha1 struct { } func (c *FakeArgoprojV1alpha1) AppProjects(namespace string) v1alpha1.AppProjectInterface { - return newFakeAppProjects(c, namespace) + return &FakeAppProjects{c, namespace} } func (c *FakeArgoprojV1alpha1) Applications(namespace string) v1alpha1.ApplicationInterface { - return newFakeApplications(c, namespace) + return &FakeApplications{c, namespace} } func (c *FakeArgoprojV1alpha1) ApplicationSets(namespace string) v1alpha1.ApplicationSetInterface { - return newFakeApplicationSets(c, namespace) + return &FakeApplicationSets{c, namespace} } // RESTClient returns a RESTClient that is used to communicate 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 bc0cdd82dc..04157e3d04 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 @@ -3,34 +3,116 @@ package fake import ( - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1" - gentype "k8s.io/client-go/gentype" + "context" + + 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" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" ) -// fakeApplicationSets implements ApplicationSetInterface -type fakeApplicationSets struct { - *gentype.FakeClientWithList[*v1alpha1.ApplicationSet, *v1alpha1.ApplicationSetList] +// FakeApplicationSets implements ApplicationSetInterface +type FakeApplicationSets struct { Fake *FakeArgoprojV1alpha1 + ns string } -func newFakeApplicationSets(fake *FakeArgoprojV1alpha1, namespace string) applicationv1alpha1.ApplicationSetInterface { - return &fakeApplicationSets{ - gentype.NewFakeClientWithList[*v1alpha1.ApplicationSet, *v1alpha1.ApplicationSetList]( - fake.Fake, - namespace, - v1alpha1.SchemeGroupVersion.WithResource("applicationsets"), - v1alpha1.SchemeGroupVersion.WithKind("ApplicationSet"), - func() *v1alpha1.ApplicationSet { return &v1alpha1.ApplicationSet{} }, - func() *v1alpha1.ApplicationSetList { return &v1alpha1.ApplicationSetList{} }, - func(dst, src *v1alpha1.ApplicationSetList) { dst.ListMeta = src.ListMeta }, - func(list *v1alpha1.ApplicationSetList) []*v1alpha1.ApplicationSet { - return gentype.ToPointerSlice(list.Items) - }, - func(list *v1alpha1.ApplicationSetList, items []*v1alpha1.ApplicationSet) { - list.Items = gentype.FromPointerSlice(items) - }, - ), - fake, +var applicationsetsResource = v1alpha1.SchemeGroupVersion.WithResource("applicationsets") + +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.NewGetActionWithOptions(applicationsetsResource, c.ns, name, options), emptyResult) + + if obj == nil { + 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.NewListActionWithOptions(applicationsetsResource, applicationsetsKind, c.ns, opts), emptyResult) + + if obj == nil { + return emptyResult, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.ApplicationSetList{ListMeta: obj.(*v1alpha1.ApplicationSetList).ListMeta} + for _, item := range obj.(*v1alpha1.ApplicationSetList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// 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.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.NewCreateActionWithOptions(applicationsetsResource, c.ns, applicationSet, opts), emptyResult) + + if obj == nil { + 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.NewUpdateActionWithOptions(applicationsetsResource, c.ns, applicationSet, opts), emptyResult) + + if obj == nil { + return emptyResult, err + } + return obj.(*v1alpha1.ApplicationSet), err +} + +// Delete takes name of the applicationSet and deletes it. Returns an error if one occurs. +func (c *FakeApplicationSets) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(applicationsetsResource, c.ns, name, opts), &v1alpha1.ApplicationSet{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeApplicationSets) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionActionWithOptions(applicationsetsResource, c.ns, opts, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.ApplicationSetList{}) + return err +} + +// 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.NewPatchSubresourceActionWithOptions(applicationsetsResource, c.ns, name, pt, data, opts, subresources...), emptyResult) + + if obj == nil { + 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 e5cdf593a5..d510e445a5 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 @@ -3,32 +3,116 @@ package fake import ( - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1" - gentype "k8s.io/client-go/gentype" + "context" + + 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" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" ) -// fakeAppProjects implements AppProjectInterface -type fakeAppProjects struct { - *gentype.FakeClientWithList[*v1alpha1.AppProject, *v1alpha1.AppProjectList] +// FakeAppProjects implements AppProjectInterface +type FakeAppProjects struct { Fake *FakeArgoprojV1alpha1 + ns string } -func newFakeAppProjects(fake *FakeArgoprojV1alpha1, namespace string) applicationv1alpha1.AppProjectInterface { - return &fakeAppProjects{ - gentype.NewFakeClientWithList[*v1alpha1.AppProject, *v1alpha1.AppProjectList]( - fake.Fake, - namespace, - v1alpha1.SchemeGroupVersion.WithResource("appprojects"), - v1alpha1.SchemeGroupVersion.WithKind("AppProject"), - func() *v1alpha1.AppProject { return &v1alpha1.AppProject{} }, - func() *v1alpha1.AppProjectList { return &v1alpha1.AppProjectList{} }, - func(dst, src *v1alpha1.AppProjectList) { dst.ListMeta = src.ListMeta }, - func(list *v1alpha1.AppProjectList) []*v1alpha1.AppProject { return gentype.ToPointerSlice(list.Items) }, - func(list *v1alpha1.AppProjectList, items []*v1alpha1.AppProject) { - list.Items = gentype.FromPointerSlice(items) - }, - ), - fake, +var appprojectsResource = v1alpha1.SchemeGroupVersion.WithResource("appprojects") + +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.NewGetActionWithOptions(appprojectsResource, c.ns, name, options), emptyResult) + + if obj == nil { + 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.NewListActionWithOptions(appprojectsResource, appprojectsKind, c.ns, opts), emptyResult) + + if obj == nil { + return emptyResult, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.AppProjectList{ListMeta: obj.(*v1alpha1.AppProjectList).ListMeta} + for _, item := range obj.(*v1alpha1.AppProjectList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// 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.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.NewCreateActionWithOptions(appprojectsResource, c.ns, appProject, opts), emptyResult) + + if obj == nil { + 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.NewUpdateActionWithOptions(appprojectsResource, c.ns, appProject, opts), emptyResult) + + if obj == nil { + return emptyResult, err + } + return obj.(*v1alpha1.AppProject), err +} + +// Delete takes name of the appProject and deletes it. Returns an error if one occurs. +func (c *FakeAppProjects) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(appprojectsResource, c.ns, name, opts), &v1alpha1.AppProject{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeAppProjects) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionActionWithOptions(appprojectsResource, c.ns, opts, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.AppProjectList{}) + return err +} + +// 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.NewPatchSubresourceActionWithOptions(appprojectsResource, c.ns, name, pt, data, opts, subresources...), emptyResult) + + if obj == nil { + return emptyResult, err + } + return obj.(*v1alpha1.AppProject), err } diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/mocks/AppProjectInterface.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/mocks/AppProjectInterface.go index 97a5cf4179..f386a04143 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/mocks/AppProjectInterface.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/mocks/AppProjectInterface.go @@ -1,19 +1,248 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" + context "context" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" mock "github.com/stretchr/testify/mock" - "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/watch" + types "k8s.io/apimachinery/pkg/types" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + + watch "k8s.io/apimachinery/pkg/watch" ) +// AppProjectInterface is an autogenerated mock type for the AppProjectInterface type +type AppProjectInterface struct { + mock.Mock +} + +// Create provides a mock function with given fields: ctx, appProject, opts +func (_m *AppProjectInterface) Create(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.CreateOptions) (*v1alpha1.AppProject, error) { + ret := _m.Called(ctx, appProject, opts) + + if len(ret) == 0 { + panic("no return value specified for Create") + } + + var r0 *v1alpha1.AppProject + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.AppProject, v1.CreateOptions) (*v1alpha1.AppProject, error)); ok { + return rf(ctx, appProject, opts) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.AppProject, v1.CreateOptions) *v1alpha1.AppProject); ok { + r0 = rf(ctx, appProject, opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.AppProject) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.AppProject, v1.CreateOptions) error); ok { + r1 = rf(ctx, appProject, opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Delete provides a mock function with given fields: ctx, name, opts +func (_m *AppProjectInterface) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + ret := _m.Called(ctx, name, opts) + + if len(ret) == 0 { + panic("no return value specified for Delete") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string, v1.DeleteOptions) error); ok { + r0 = rf(ctx, name, opts) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteCollection provides a mock function with given fields: ctx, opts, listOpts +func (_m *AppProjectInterface) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + ret := _m.Called(ctx, opts, listOpts) + + if len(ret) == 0 { + panic("no return value specified for DeleteCollection") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, v1.DeleteOptions, v1.ListOptions) error); ok { + r0 = rf(ctx, opts, listOpts) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Get provides a mock function with given fields: ctx, name, opts +func (_m *AppProjectInterface) Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.AppProject, error) { + ret := _m.Called(ctx, name, opts) + + if len(ret) == 0 { + panic("no return value specified for Get") + } + + var r0 *v1alpha1.AppProject + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, v1.GetOptions) (*v1alpha1.AppProject, error)); ok { + return rf(ctx, name, opts) + } + if rf, ok := ret.Get(0).(func(context.Context, string, v1.GetOptions) *v1alpha1.AppProject); ok { + r0 = rf(ctx, name, opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.AppProject) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, v1.GetOptions) error); ok { + r1 = rf(ctx, name, opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// List provides a mock function with given fields: ctx, opts +func (_m *AppProjectInterface) List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.AppProjectList, error) { + ret := _m.Called(ctx, opts) + + if len(ret) == 0 { + panic("no return value specified for List") + } + + var r0 *v1alpha1.AppProjectList + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, v1.ListOptions) (*v1alpha1.AppProjectList, error)); ok { + return rf(ctx, opts) + } + if rf, ok := ret.Get(0).(func(context.Context, v1.ListOptions) *v1alpha1.AppProjectList); ok { + r0 = rf(ctx, opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.AppProjectList) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, v1.ListOptions) error); ok { + r1 = rf(ctx, opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Patch provides a mock function with given fields: ctx, name, pt, data, opts, subresources +func (_m *AppProjectInterface) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (*v1alpha1.AppProject, error) { + _va := make([]interface{}, len(subresources)) + for _i := range subresources { + _va[_i] = subresources[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, name, pt, data, opts) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for Patch") + } + + var r0 *v1alpha1.AppProject + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, types.PatchType, []byte, v1.PatchOptions, ...string) (*v1alpha1.AppProject, error)); ok { + return rf(ctx, name, pt, data, opts, subresources...) + } + if rf, ok := ret.Get(0).(func(context.Context, string, types.PatchType, []byte, v1.PatchOptions, ...string) *v1alpha1.AppProject); ok { + r0 = rf(ctx, name, pt, data, opts, subresources...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.AppProject) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, types.PatchType, []byte, v1.PatchOptions, ...string) error); ok { + r1 = rf(ctx, name, pt, data, opts, subresources...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Update provides a mock function with given fields: ctx, appProject, opts +func (_m *AppProjectInterface) Update(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.UpdateOptions) (*v1alpha1.AppProject, error) { + ret := _m.Called(ctx, appProject, opts) + + if len(ret) == 0 { + panic("no return value specified for Update") + } + + var r0 *v1alpha1.AppProject + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.AppProject, v1.UpdateOptions) (*v1alpha1.AppProject, error)); ok { + return rf(ctx, appProject, opts) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.AppProject, v1.UpdateOptions) *v1alpha1.AppProject); ok { + r0 = rf(ctx, appProject, opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.AppProject) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.AppProject, v1.UpdateOptions) error); ok { + r1 = rf(ctx, appProject, opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Watch provides a mock function with given fields: ctx, opts +func (_m *AppProjectInterface) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + ret := _m.Called(ctx, opts) + + if len(ret) == 0 { + panic("no return value specified for Watch") + } + + var r0 watch.Interface + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, v1.ListOptions) (watch.Interface, error)); ok { + return rf(ctx, opts) + } + if rf, ok := ret.Get(0).(func(context.Context, v1.ListOptions) watch.Interface); ok { + r0 = rf(ctx, opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(watch.Interface) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, v1.ListOptions) error); ok { + r1 = rf(ctx, opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewAppProjectInterface creates a new instance of AppProjectInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewAppProjectInterface(t interface { @@ -27,474 +256,3 @@ func NewAppProjectInterface(t interface { return mock } - -// AppProjectInterface is an autogenerated mock type for the AppProjectInterface type -type AppProjectInterface struct { - mock.Mock -} - -type AppProjectInterface_Expecter struct { - mock *mock.Mock -} - -func (_m *AppProjectInterface) EXPECT() *AppProjectInterface_Expecter { - return &AppProjectInterface_Expecter{mock: &_m.Mock} -} - -// Create provides a mock function for the type AppProjectInterface -func (_mock *AppProjectInterface) Create(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.CreateOptions) (*v1alpha1.AppProject, error) { - ret := _mock.Called(ctx, appProject, opts) - - if len(ret) == 0 { - panic("no return value specified for Create") - } - - var r0 *v1alpha1.AppProject - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.AppProject, v1.CreateOptions) (*v1alpha1.AppProject, error)); ok { - return returnFunc(ctx, appProject, opts) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.AppProject, v1.CreateOptions) *v1alpha1.AppProject); ok { - r0 = returnFunc(ctx, appProject, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.AppProject) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.AppProject, v1.CreateOptions) error); ok { - r1 = returnFunc(ctx, appProject, opts) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// AppProjectInterface_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' -type AppProjectInterface_Create_Call struct { - *mock.Call -} - -// Create is a helper method to define mock.On call -// - ctx -// - appProject -// - opts -func (_e *AppProjectInterface_Expecter) Create(ctx interface{}, appProject interface{}, opts interface{}) *AppProjectInterface_Create_Call { - return &AppProjectInterface_Create_Call{Call: _e.mock.On("Create", ctx, appProject, opts)} -} - -func (_c *AppProjectInterface_Create_Call) Run(run func(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.CreateOptions)) *AppProjectInterface_Create_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.AppProject), args[2].(v1.CreateOptions)) - }) - return _c -} - -func (_c *AppProjectInterface_Create_Call) Return(appProject1 *v1alpha1.AppProject, err error) *AppProjectInterface_Create_Call { - _c.Call.Return(appProject1, err) - return _c -} - -func (_c *AppProjectInterface_Create_Call) RunAndReturn(run func(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.CreateOptions) (*v1alpha1.AppProject, error)) *AppProjectInterface_Create_Call { - _c.Call.Return(run) - return _c -} - -// Delete provides a mock function for the type AppProjectInterface -func (_mock *AppProjectInterface) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - ret := _mock.Called(ctx, name, opts) - - if len(ret) == 0 { - panic("no return value specified for Delete") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, v1.DeleteOptions) error); ok { - r0 = returnFunc(ctx, name, opts) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// AppProjectInterface_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' -type AppProjectInterface_Delete_Call struct { - *mock.Call -} - -// Delete is a helper method to define mock.On call -// - ctx -// - name -// - opts -func (_e *AppProjectInterface_Expecter) Delete(ctx interface{}, name interface{}, opts interface{}) *AppProjectInterface_Delete_Call { - return &AppProjectInterface_Delete_Call{Call: _e.mock.On("Delete", ctx, name, opts)} -} - -func (_c *AppProjectInterface_Delete_Call) Run(run func(ctx context.Context, name string, opts v1.DeleteOptions)) *AppProjectInterface_Delete_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(v1.DeleteOptions)) - }) - return _c -} - -func (_c *AppProjectInterface_Delete_Call) Return(err error) *AppProjectInterface_Delete_Call { - _c.Call.Return(err) - return _c -} - -func (_c *AppProjectInterface_Delete_Call) RunAndReturn(run func(ctx context.Context, name string, opts v1.DeleteOptions) error) *AppProjectInterface_Delete_Call { - _c.Call.Return(run) - return _c -} - -// DeleteCollection provides a mock function for the type AppProjectInterface -func (_mock *AppProjectInterface) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - ret := _mock.Called(ctx, opts, listOpts) - - if len(ret) == 0 { - panic("no return value specified for DeleteCollection") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, v1.DeleteOptions, v1.ListOptions) error); ok { - r0 = returnFunc(ctx, opts, listOpts) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// AppProjectInterface_DeleteCollection_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteCollection' -type AppProjectInterface_DeleteCollection_Call struct { - *mock.Call -} - -// DeleteCollection is a helper method to define mock.On call -// - ctx -// - opts -// - listOpts -func (_e *AppProjectInterface_Expecter) DeleteCollection(ctx interface{}, opts interface{}, listOpts interface{}) *AppProjectInterface_DeleteCollection_Call { - return &AppProjectInterface_DeleteCollection_Call{Call: _e.mock.On("DeleteCollection", ctx, opts, listOpts)} -} - -func (_c *AppProjectInterface_DeleteCollection_Call) Run(run func(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions)) *AppProjectInterface_DeleteCollection_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(v1.DeleteOptions), args[2].(v1.ListOptions)) - }) - return _c -} - -func (_c *AppProjectInterface_DeleteCollection_Call) Return(err error) *AppProjectInterface_DeleteCollection_Call { - _c.Call.Return(err) - return _c -} - -func (_c *AppProjectInterface_DeleteCollection_Call) RunAndReturn(run func(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error) *AppProjectInterface_DeleteCollection_Call { - _c.Call.Return(run) - return _c -} - -// Get provides a mock function for the type AppProjectInterface -func (_mock *AppProjectInterface) Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.AppProject, error) { - ret := _mock.Called(ctx, name, opts) - - if len(ret) == 0 { - panic("no return value specified for Get") - } - - var r0 *v1alpha1.AppProject - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, v1.GetOptions) (*v1alpha1.AppProject, error)); ok { - return returnFunc(ctx, name, opts) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string, v1.GetOptions) *v1alpha1.AppProject); ok { - r0 = returnFunc(ctx, name, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.AppProject) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string, v1.GetOptions) error); ok { - r1 = returnFunc(ctx, name, opts) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// AppProjectInterface_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' -type AppProjectInterface_Get_Call struct { - *mock.Call -} - -// Get is a helper method to define mock.On call -// - ctx -// - name -// - opts -func (_e *AppProjectInterface_Expecter) Get(ctx interface{}, name interface{}, opts interface{}) *AppProjectInterface_Get_Call { - return &AppProjectInterface_Get_Call{Call: _e.mock.On("Get", ctx, name, opts)} -} - -func (_c *AppProjectInterface_Get_Call) Run(run func(ctx context.Context, name string, opts v1.GetOptions)) *AppProjectInterface_Get_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(v1.GetOptions)) - }) - return _c -} - -func (_c *AppProjectInterface_Get_Call) Return(appProject *v1alpha1.AppProject, err error) *AppProjectInterface_Get_Call { - _c.Call.Return(appProject, err) - return _c -} - -func (_c *AppProjectInterface_Get_Call) RunAndReturn(run func(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.AppProject, error)) *AppProjectInterface_Get_Call { - _c.Call.Return(run) - return _c -} - -// List provides a mock function for the type AppProjectInterface -func (_mock *AppProjectInterface) List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.AppProjectList, error) { - ret := _mock.Called(ctx, opts) - - if len(ret) == 0 { - panic("no return value specified for List") - } - - var r0 *v1alpha1.AppProjectList - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, v1.ListOptions) (*v1alpha1.AppProjectList, error)); ok { - return returnFunc(ctx, opts) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, v1.ListOptions) *v1alpha1.AppProjectList); ok { - r0 = returnFunc(ctx, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.AppProjectList) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, v1.ListOptions) error); ok { - r1 = returnFunc(ctx, opts) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// AppProjectInterface_List_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'List' -type AppProjectInterface_List_Call struct { - *mock.Call -} - -// List is a helper method to define mock.On call -// - ctx -// - opts -func (_e *AppProjectInterface_Expecter) List(ctx interface{}, opts interface{}) *AppProjectInterface_List_Call { - return &AppProjectInterface_List_Call{Call: _e.mock.On("List", ctx, opts)} -} - -func (_c *AppProjectInterface_List_Call) Run(run func(ctx context.Context, opts v1.ListOptions)) *AppProjectInterface_List_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(v1.ListOptions)) - }) - return _c -} - -func (_c *AppProjectInterface_List_Call) Return(appProjectList *v1alpha1.AppProjectList, err error) *AppProjectInterface_List_Call { - _c.Call.Return(appProjectList, err) - return _c -} - -func (_c *AppProjectInterface_List_Call) RunAndReturn(run func(ctx context.Context, opts v1.ListOptions) (*v1alpha1.AppProjectList, error)) *AppProjectInterface_List_Call { - _c.Call.Return(run) - return _c -} - -// Patch provides a mock function for the type AppProjectInterface -func (_mock *AppProjectInterface) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (*v1alpha1.AppProject, error) { - // string - _va := make([]interface{}, len(subresources)) - for _i := range subresources { - _va[_i] = subresources[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, name, pt, data, opts) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for Patch") - } - - var r0 *v1alpha1.AppProject - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, types.PatchType, []byte, v1.PatchOptions, ...string) (*v1alpha1.AppProject, error)); ok { - return returnFunc(ctx, name, pt, data, opts, subresources...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string, types.PatchType, []byte, v1.PatchOptions, ...string) *v1alpha1.AppProject); ok { - r0 = returnFunc(ctx, name, pt, data, opts, subresources...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.AppProject) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string, types.PatchType, []byte, v1.PatchOptions, ...string) error); ok { - r1 = returnFunc(ctx, name, pt, data, opts, subresources...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// AppProjectInterface_Patch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Patch' -type AppProjectInterface_Patch_Call struct { - *mock.Call -} - -// Patch is a helper method to define mock.On call -// - ctx -// - name -// - pt -// - data -// - opts -// - subresources -func (_e *AppProjectInterface_Expecter) Patch(ctx interface{}, name interface{}, pt interface{}, data interface{}, opts interface{}, subresources ...interface{}) *AppProjectInterface_Patch_Call { - return &AppProjectInterface_Patch_Call{Call: _e.mock.On("Patch", - append([]interface{}{ctx, name, pt, data, opts}, subresources...)...)} -} - -func (_c *AppProjectInterface_Patch_Call) Run(run func(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string)) *AppProjectInterface_Patch_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]string, len(args)-5) - for i, a := range args[5:] { - if a != nil { - variadicArgs[i] = a.(string) - } - } - run(args[0].(context.Context), args[1].(string), args[2].(types.PatchType), args[3].([]byte), args[4].(v1.PatchOptions), variadicArgs...) - }) - return _c -} - -func (_c *AppProjectInterface_Patch_Call) Return(result *v1alpha1.AppProject, err error) *AppProjectInterface_Patch_Call { - _c.Call.Return(result, err) - return _c -} - -func (_c *AppProjectInterface_Patch_Call) RunAndReturn(run func(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (*v1alpha1.AppProject, error)) *AppProjectInterface_Patch_Call { - _c.Call.Return(run) - return _c -} - -// Update provides a mock function for the type AppProjectInterface -func (_mock *AppProjectInterface) Update(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.UpdateOptions) (*v1alpha1.AppProject, error) { - ret := _mock.Called(ctx, appProject, opts) - - if len(ret) == 0 { - panic("no return value specified for Update") - } - - var r0 *v1alpha1.AppProject - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.AppProject, v1.UpdateOptions) (*v1alpha1.AppProject, error)); ok { - return returnFunc(ctx, appProject, opts) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.AppProject, v1.UpdateOptions) *v1alpha1.AppProject); ok { - r0 = returnFunc(ctx, appProject, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.AppProject) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.AppProject, v1.UpdateOptions) error); ok { - r1 = returnFunc(ctx, appProject, opts) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// AppProjectInterface_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update' -type AppProjectInterface_Update_Call struct { - *mock.Call -} - -// Update is a helper method to define mock.On call -// - ctx -// - appProject -// - opts -func (_e *AppProjectInterface_Expecter) Update(ctx interface{}, appProject interface{}, opts interface{}) *AppProjectInterface_Update_Call { - return &AppProjectInterface_Update_Call{Call: _e.mock.On("Update", ctx, appProject, opts)} -} - -func (_c *AppProjectInterface_Update_Call) Run(run func(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.UpdateOptions)) *AppProjectInterface_Update_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.AppProject), args[2].(v1.UpdateOptions)) - }) - return _c -} - -func (_c *AppProjectInterface_Update_Call) Return(appProject1 *v1alpha1.AppProject, err error) *AppProjectInterface_Update_Call { - _c.Call.Return(appProject1, err) - return _c -} - -func (_c *AppProjectInterface_Update_Call) RunAndReturn(run func(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.UpdateOptions) (*v1alpha1.AppProject, error)) *AppProjectInterface_Update_Call { - _c.Call.Return(run) - return _c -} - -// Watch provides a mock function for the type AppProjectInterface -func (_mock *AppProjectInterface) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - ret := _mock.Called(ctx, opts) - - if len(ret) == 0 { - panic("no return value specified for Watch") - } - - var r0 watch.Interface - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, v1.ListOptions) (watch.Interface, error)); ok { - return returnFunc(ctx, opts) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, v1.ListOptions) watch.Interface); ok { - r0 = returnFunc(ctx, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(watch.Interface) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, v1.ListOptions) error); ok { - r1 = returnFunc(ctx, opts) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// AppProjectInterface_Watch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Watch' -type AppProjectInterface_Watch_Call struct { - *mock.Call -} - -// Watch is a helper method to define mock.On call -// - ctx -// - opts -func (_e *AppProjectInterface_Expecter) Watch(ctx interface{}, opts interface{}) *AppProjectInterface_Watch_Call { - return &AppProjectInterface_Watch_Call{Call: _e.mock.On("Watch", ctx, opts)} -} - -func (_c *AppProjectInterface_Watch_Call) Run(run func(ctx context.Context, opts v1.ListOptions)) *AppProjectInterface_Watch_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(v1.ListOptions)) - }) - return _c -} - -func (_c *AppProjectInterface_Watch_Call) Return(interfaceParam watch.Interface, err error) *AppProjectInterface_Watch_Call { - _c.Call.Return(interfaceParam, err) - return _c -} - -func (_c *AppProjectInterface_Watch_Call) RunAndReturn(run func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)) *AppProjectInterface_Watch_Call { - _c.Call.Return(run) - return _c -} diff --git a/pkg/client/informers/externalversions/application/interface.go b/pkg/client/informers/externalversions/application/interface.go index 1a858f86b0..e5345a18cb 100644 --- a/pkg/client/informers/externalversions/application/interface.go +++ b/pkg/client/informers/externalversions/application/interface.go @@ -3,8 +3,8 @@ package application import ( - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions/application/v1alpha1" - internalinterfaces "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions/application/v1alpha1" + internalinterfaces "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions/internalinterfaces" ) // Interface provides access to each of this group's versions. diff --git a/pkg/client/informers/externalversions/application/v1alpha1/application.go b/pkg/client/informers/externalversions/application/v1alpha1/application.go index 7e119c0342..e29ec65c8d 100644 --- a/pkg/client/informers/externalversions/application/v1alpha1/application.go +++ b/pkg/client/informers/externalversions/application/v1alpha1/application.go @@ -3,13 +3,13 @@ package v1alpha1 import ( - context "context" + "context" time "time" - apisapplicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - versioned "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - internalinterfaces "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions/internalinterfaces" - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" + applicationv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + versioned "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + internalinterfaces "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -20,7 +20,7 @@ import ( // Applications. type ApplicationInformer interface { Informer() cache.SharedIndexInformer - Lister() applicationv1alpha1.ApplicationLister + Lister() v1alpha1.ApplicationLister } type applicationInformer struct { @@ -55,7 +55,7 @@ func NewFilteredApplicationInformer(client versioned.Interface, namespace string return client.ArgoprojV1alpha1().Applications(namespace).Watch(context.TODO(), options) }, }, - &apisapplicationv1alpha1.Application{}, + &applicationv1alpha1.Application{}, resyncPeriod, indexers, ) @@ -66,9 +66,9 @@ func (f *applicationInformer) defaultInformer(client versioned.Interface, resync } func (f *applicationInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&apisapplicationv1alpha1.Application{}, f.defaultInformer) + return f.factory.InformerFor(&applicationv1alpha1.Application{}, f.defaultInformer) } -func (f *applicationInformer) Lister() applicationv1alpha1.ApplicationLister { - return applicationv1alpha1.NewApplicationLister(f.Informer().GetIndexer()) +func (f *applicationInformer) Lister() v1alpha1.ApplicationLister { + return v1alpha1.NewApplicationLister(f.Informer().GetIndexer()) } diff --git a/pkg/client/informers/externalversions/application/v1alpha1/applicationset.go b/pkg/client/informers/externalversions/application/v1alpha1/applicationset.go index 13e35525d0..7ef5c1dc9e 100644 --- a/pkg/client/informers/externalversions/application/v1alpha1/applicationset.go +++ b/pkg/client/informers/externalversions/application/v1alpha1/applicationset.go @@ -3,13 +3,13 @@ package v1alpha1 import ( - context "context" + "context" time "time" - apisapplicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - versioned "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - internalinterfaces "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions/internalinterfaces" - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" + applicationv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + versioned "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + internalinterfaces "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -20,7 +20,7 @@ import ( // ApplicationSets. type ApplicationSetInformer interface { Informer() cache.SharedIndexInformer - Lister() applicationv1alpha1.ApplicationSetLister + Lister() v1alpha1.ApplicationSetLister } type applicationSetInformer struct { @@ -55,7 +55,7 @@ func NewFilteredApplicationSetInformer(client versioned.Interface, namespace str return client.ArgoprojV1alpha1().ApplicationSets(namespace).Watch(context.TODO(), options) }, }, - &apisapplicationv1alpha1.ApplicationSet{}, + &applicationv1alpha1.ApplicationSet{}, resyncPeriod, indexers, ) @@ -66,9 +66,9 @@ func (f *applicationSetInformer) defaultInformer(client versioned.Interface, res } func (f *applicationSetInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&apisapplicationv1alpha1.ApplicationSet{}, f.defaultInformer) + return f.factory.InformerFor(&applicationv1alpha1.ApplicationSet{}, f.defaultInformer) } -func (f *applicationSetInformer) Lister() applicationv1alpha1.ApplicationSetLister { - return applicationv1alpha1.NewApplicationSetLister(f.Informer().GetIndexer()) +func (f *applicationSetInformer) Lister() v1alpha1.ApplicationSetLister { + return v1alpha1.NewApplicationSetLister(f.Informer().GetIndexer()) } diff --git a/pkg/client/informers/externalversions/application/v1alpha1/appproject.go b/pkg/client/informers/externalversions/application/v1alpha1/appproject.go index 7f77aa75c2..234e3053bd 100644 --- a/pkg/client/informers/externalversions/application/v1alpha1/appproject.go +++ b/pkg/client/informers/externalversions/application/v1alpha1/appproject.go @@ -3,13 +3,13 @@ package v1alpha1 import ( - context "context" + "context" time "time" - apisapplicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - versioned "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - internalinterfaces "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions/internalinterfaces" - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" + applicationv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + versioned "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + internalinterfaces "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -20,7 +20,7 @@ import ( // AppProjects. type AppProjectInformer interface { Informer() cache.SharedIndexInformer - Lister() applicationv1alpha1.AppProjectLister + Lister() v1alpha1.AppProjectLister } type appProjectInformer struct { @@ -55,7 +55,7 @@ func NewFilteredAppProjectInformer(client versioned.Interface, namespace string, return client.ArgoprojV1alpha1().AppProjects(namespace).Watch(context.TODO(), options) }, }, - &apisapplicationv1alpha1.AppProject{}, + &applicationv1alpha1.AppProject{}, resyncPeriod, indexers, ) @@ -66,9 +66,9 @@ func (f *appProjectInformer) defaultInformer(client versioned.Interface, resyncP } func (f *appProjectInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&apisapplicationv1alpha1.AppProject{}, f.defaultInformer) + return f.factory.InformerFor(&applicationv1alpha1.AppProject{}, f.defaultInformer) } -func (f *appProjectInformer) Lister() applicationv1alpha1.AppProjectLister { - return applicationv1alpha1.NewAppProjectLister(f.Informer().GetIndexer()) +func (f *appProjectInformer) Lister() v1alpha1.AppProjectLister { + return v1alpha1.NewAppProjectLister(f.Informer().GetIndexer()) } diff --git a/pkg/client/informers/externalversions/application/v1alpha1/interface.go b/pkg/client/informers/externalversions/application/v1alpha1/interface.go index aec79bb1b6..26990ee5ef 100644 --- a/pkg/client/informers/externalversions/application/v1alpha1/interface.go +++ b/pkg/client/informers/externalversions/application/v1alpha1/interface.go @@ -3,7 +3,7 @@ package v1alpha1 import ( - internalinterfaces "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions/internalinterfaces" + internalinterfaces "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions/internalinterfaces" ) // Interface provides access to all the informers in this group version. diff --git a/pkg/client/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go index edfc23afe5..d2ace1f120 100644 --- a/pkg/client/informers/externalversions/factory.go +++ b/pkg/client/informers/externalversions/factory.go @@ -7,9 +7,9 @@ import ( sync "sync" time "time" - versioned "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - application "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions/application" - internalinterfaces "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions/internalinterfaces" + versioned "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + application "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions/application" + internalinterfaces "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions/internalinterfaces" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index ecc96d1ff0..476f3ab890 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -3,9 +3,9 @@ package externalversions import ( - fmt "fmt" + "fmt" - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" ) diff --git a/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go b/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go index 4e1703fd42..710dda8e37 100644 --- a/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -5,7 +5,7 @@ package internalinterfaces import ( time "time" - versioned "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" + versioned "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" cache "k8s.io/client-go/tools/cache" diff --git a/pkg/client/listers/application/v1alpha1/application.go b/pkg/client/listers/application/v1alpha1/application.go index f679550837..a58173cccf 100644 --- a/pkg/client/listers/application/v1alpha1/application.go +++ b/pkg/client/listers/application/v1alpha1/application.go @@ -3,10 +3,10 @@ package v1alpha1 import ( - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - labels "k8s.io/apimachinery/pkg/labels" - listers "k8s.io/client-go/listers" - cache "k8s.io/client-go/tools/cache" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/listers" + "k8s.io/client-go/tools/cache" ) // ApplicationLister helps list Applications. @@ -14,7 +14,7 @@ import ( type ApplicationLister interface { // List lists all Applications in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*applicationv1alpha1.Application, err error) + List(selector labels.Selector) (ret []*v1alpha1.Application, err error) // Applications returns an object that can list and get Applications. Applications(namespace string) ApplicationNamespaceLister ApplicationListerExpansion @@ -22,17 +22,17 @@ type ApplicationLister interface { // applicationLister implements the ApplicationLister interface. type applicationLister struct { - listers.ResourceIndexer[*applicationv1alpha1.Application] + listers.ResourceIndexer[*v1alpha1.Application] } // NewApplicationLister returns a new ApplicationLister. func NewApplicationLister(indexer cache.Indexer) ApplicationLister { - return &applicationLister{listers.New[*applicationv1alpha1.Application](indexer, applicationv1alpha1.Resource("application"))} + 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{listers.NewNamespaced[*applicationv1alpha1.Application](s.ResourceIndexer, namespace)} + return applicationNamespaceLister{listers.NewNamespaced[*v1alpha1.Application](s.ResourceIndexer, namespace)} } // ApplicationNamespaceLister helps list and get Applications. @@ -40,15 +40,15 @@ func (s *applicationLister) Applications(namespace string) ApplicationNamespaceL type ApplicationNamespaceLister interface { // List lists all Applications in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*applicationv1alpha1.Application, err error) + List(selector labels.Selector) (ret []*v1alpha1.Application, err error) // Get retrieves the Application from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*applicationv1alpha1.Application, error) + Get(name string) (*v1alpha1.Application, error) ApplicationNamespaceListerExpansion } // applicationNamespaceLister implements the ApplicationNamespaceLister // interface. type applicationNamespaceLister struct { - listers.ResourceIndexer[*applicationv1alpha1.Application] + listers.ResourceIndexer[*v1alpha1.Application] } diff --git a/pkg/client/listers/application/v1alpha1/applicationset.go b/pkg/client/listers/application/v1alpha1/applicationset.go index 33106af9a3..0f87e40e04 100644 --- a/pkg/client/listers/application/v1alpha1/applicationset.go +++ b/pkg/client/listers/application/v1alpha1/applicationset.go @@ -3,10 +3,10 @@ package v1alpha1 import ( - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - labels "k8s.io/apimachinery/pkg/labels" - listers "k8s.io/client-go/listers" - cache "k8s.io/client-go/tools/cache" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/listers" + "k8s.io/client-go/tools/cache" ) // ApplicationSetLister helps list ApplicationSets. @@ -14,7 +14,7 @@ import ( type ApplicationSetLister interface { // List lists all ApplicationSets in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*applicationv1alpha1.ApplicationSet, err error) + List(selector labels.Selector) (ret []*v1alpha1.ApplicationSet, err error) // ApplicationSets returns an object that can list and get ApplicationSets. ApplicationSets(namespace string) ApplicationSetNamespaceLister ApplicationSetListerExpansion @@ -22,17 +22,17 @@ type ApplicationSetLister interface { // applicationSetLister implements the ApplicationSetLister interface. type applicationSetLister struct { - listers.ResourceIndexer[*applicationv1alpha1.ApplicationSet] + listers.ResourceIndexer[*v1alpha1.ApplicationSet] } // NewApplicationSetLister returns a new ApplicationSetLister. func NewApplicationSetLister(indexer cache.Indexer) ApplicationSetLister { - return &applicationSetLister{listers.New[*applicationv1alpha1.ApplicationSet](indexer, applicationv1alpha1.Resource("applicationset"))} + 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{listers.NewNamespaced[*applicationv1alpha1.ApplicationSet](s.ResourceIndexer, namespace)} + return applicationSetNamespaceLister{listers.NewNamespaced[*v1alpha1.ApplicationSet](s.ResourceIndexer, namespace)} } // ApplicationSetNamespaceLister helps list and get ApplicationSets. @@ -40,15 +40,15 @@ func (s *applicationSetLister) ApplicationSets(namespace string) ApplicationSetN type ApplicationSetNamespaceLister interface { // List lists all ApplicationSets in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*applicationv1alpha1.ApplicationSet, err error) + List(selector labels.Selector) (ret []*v1alpha1.ApplicationSet, err error) // Get retrieves the ApplicationSet from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*applicationv1alpha1.ApplicationSet, error) + Get(name string) (*v1alpha1.ApplicationSet, error) ApplicationSetNamespaceListerExpansion } // applicationSetNamespaceLister implements the ApplicationSetNamespaceLister // interface. type applicationSetNamespaceLister struct { - listers.ResourceIndexer[*applicationv1alpha1.ApplicationSet] + listers.ResourceIndexer[*v1alpha1.ApplicationSet] } diff --git a/pkg/client/listers/application/v1alpha1/appproject.go b/pkg/client/listers/application/v1alpha1/appproject.go index 76ca5d9e0e..21697453c9 100644 --- a/pkg/client/listers/application/v1alpha1/appproject.go +++ b/pkg/client/listers/application/v1alpha1/appproject.go @@ -3,10 +3,10 @@ package v1alpha1 import ( - applicationv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - labels "k8s.io/apimachinery/pkg/labels" - listers "k8s.io/client-go/listers" - cache "k8s.io/client-go/tools/cache" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/listers" + "k8s.io/client-go/tools/cache" ) // AppProjectLister helps list AppProjects. @@ -14,7 +14,7 @@ import ( type AppProjectLister interface { // List lists all AppProjects in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*applicationv1alpha1.AppProject, err error) + List(selector labels.Selector) (ret []*v1alpha1.AppProject, err error) // AppProjects returns an object that can list and get AppProjects. AppProjects(namespace string) AppProjectNamespaceLister AppProjectListerExpansion @@ -22,17 +22,17 @@ type AppProjectLister interface { // appProjectLister implements the AppProjectLister interface. type appProjectLister struct { - listers.ResourceIndexer[*applicationv1alpha1.AppProject] + listers.ResourceIndexer[*v1alpha1.AppProject] } // NewAppProjectLister returns a new AppProjectLister. func NewAppProjectLister(indexer cache.Indexer) AppProjectLister { - return &appProjectLister{listers.New[*applicationv1alpha1.AppProject](indexer, applicationv1alpha1.Resource("appproject"))} + 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{listers.NewNamespaced[*applicationv1alpha1.AppProject](s.ResourceIndexer, namespace)} + return appProjectNamespaceLister{listers.NewNamespaced[*v1alpha1.AppProject](s.ResourceIndexer, namespace)} } // AppProjectNamespaceLister helps list and get AppProjects. @@ -40,15 +40,15 @@ func (s *appProjectLister) AppProjects(namespace string) AppProjectNamespaceList type AppProjectNamespaceLister interface { // List lists all AppProjects in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*applicationv1alpha1.AppProject, err error) + List(selector labels.Selector) (ret []*v1alpha1.AppProject, err error) // Get retrieves the AppProject from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*applicationv1alpha1.AppProject, error) + Get(name string) (*v1alpha1.AppProject, error) AppProjectNamespaceListerExpansion } // appProjectNamespaceLister implements the AppProjectNamespaceLister // interface. type appProjectNamespaceLister struct { - listers.ResourceIndexer[*applicationv1alpha1.AppProject] + listers.ResourceIndexer[*v1alpha1.AppProject] } diff --git a/pkg/ratelimiter/ratelimiter.go b/pkg/ratelimiter/ratelimiter.go index 7da3573bbf..b9f0f4a19f 100644 --- a/pkg/ratelimiter/ratelimiter.go +++ b/pkg/ratelimiter/ratelimiter.go @@ -51,7 +51,7 @@ type failureData struct { // dealing with max failures and expiration/resets are up dependent on the cooldown period type ItemExponentialRateLimiterWithAutoReset[T comparable] struct { failuresLock sync.Mutex - failures map[any]failureData + failures map[interface{}]failureData baseDelay time.Duration maxDelay time.Duration @@ -63,7 +63,7 @@ var _ workqueue.TypedRateLimiter[string] = &ItemExponentialRateLimiterWithAutoRe func NewItemExponentialRateLimiterWithAutoReset[T comparable](baseDelay, maxDelay, failureCoolDown time.Duration, backoffFactor float64) workqueue.TypedRateLimiter[T] { return &ItemExponentialRateLimiterWithAutoReset[T]{ - failures: map[any]failureData{}, + failures: map[interface{}]failureData{}, baseDelay: baseDelay, maxDelay: maxDelay, coolDown: failureCoolDown, diff --git a/renovate-presets/devtool.json5 b/renovate-presets/devtool.json5 index 1ac93539c1..96ad51d380 100644 --- a/renovate-presets/devtool.json5 +++ b/renovate-presets/devtool.json5 @@ -20,16 +20,6 @@ ], "enabled": true }, - { - "description": "Enable updates from specified github releases", - "matchDatasources": [ - "github-releases" - ], - "matchPackageNames": [ - "gotestyourself/gotestsum" - ], - "enabled": true - }, { "description": "Enable updates from specified docker images", "matchDatasources": [ @@ -79,4 +69,4 @@ "automerge": false } ] -} +} \ No newline at end of file diff --git a/reposerver/apiclient/clientset.go b/reposerver/apiclient/clientset.go index 2243caf45e..11bccf5502 100644 --- a/reposerver/apiclient/clientset.go +++ b/reposerver/apiclient/clientset.go @@ -7,18 +7,18 @@ import ( "math" "time" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/env" - grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/retry" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/timeout" + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry" log "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" - argogrpc "github.com/argoproj/argo-cd/v3/util/grpc" - utilio "github.com/argoproj/argo-cd/v3/util/io" + argogrpc "github.com/argoproj/argo-cd/v2/util/grpc" + "github.com/argoproj/argo-cd/v2/util/io" ) // MaxGRPCMessageSize contains max grpc message size @@ -36,7 +36,7 @@ type TLSConfiguration struct { // Clientset represents repository server api clients type Clientset interface { - NewRepoServerClient() (utilio.Closer, RepoServerServiceClient, error) + NewRepoServerClient() (io.Closer, RepoServerServiceClient, error) } type clientSet struct { @@ -45,7 +45,7 @@ type clientSet struct { tlsConfig TLSConfiguration } -func (c *clientSet) NewRepoServerClient() (utilio.Closer, RepoServerServiceClient, error) { +func (c *clientSet) NewRepoServerClient() (io.Closer, RepoServerServiceClient, error) { conn, err := NewConnection(c.address, c.timeoutSeconds, &c.tlsConfig) if err != nil { return nil, nil, fmt.Errorf("failed to open a new connection to repo server: %w", err) @@ -60,11 +60,11 @@ func NewConnection(address string, timeoutSeconds int, tlsConfig *TLSConfigurati } unaryInterceptors := []grpc.UnaryClientInterceptor{grpc_retry.UnaryClientInterceptor(retryOpts...)} if timeoutSeconds > 0 { - unaryInterceptors = append(unaryInterceptors, timeout.UnaryClientInterceptor(time.Duration(timeoutSeconds)*time.Second)) + unaryInterceptors = append(unaryInterceptors, argogrpc.WithTimeout(time.Duration(timeoutSeconds)*time.Second)) } opts := []grpc.DialOption{ grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(retryOpts...)), - grpc.WithChainUnaryInterceptor(unaryInterceptors...), + grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(unaryInterceptors...)), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(MaxGRPCMessageSize), grpc.MaxCallSendMsgSize(MaxGRPCMessageSize)), grpc.WithUnaryInterceptor(argogrpc.OTELUnaryClientInterceptor()), grpc.WithStreamInterceptor(argogrpc.OTELStreamClientInterceptor()), @@ -82,7 +82,7 @@ func NewConnection(address string, timeoutSeconds int, tlsConfig *TLSConfigurati opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) } - //nolint:staticcheck + // nolint:staticcheck conn, err := grpc.Dial(address, opts...) if err != nil { log.Errorf("Unable to connect to repository service with address %s", address) diff --git a/reposerver/apiclient/clientset_test.go b/reposerver/apiclient/clientset_test.go index bf943aaf07..c0966b799d 100644 --- a/reposerver/apiclient/clientset_test.go +++ b/reposerver/apiclient/clientset_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient/mocks" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" ) func TestNewRepoServerClient_CorrectClientReturned(t *testing.T) { diff --git a/reposerver/apiclient/mocks/Clientset.go b/reposerver/apiclient/mocks/Clientset.go index 4c727b8d2a..292b0de5d3 100644 --- a/reposerver/apiclient/mocks/Clientset.go +++ b/reposerver/apiclient/mocks/Clientset.go @@ -1,14 +1,15 @@ package mocks import ( - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - utilio "github.com/argoproj/argo-cd/v3/util/io" + apiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + + io "github.com/argoproj/argo-cd/v2/util/io" ) type Clientset struct { RepoServerServiceClient apiclient.RepoServerServiceClient } -func (c *Clientset) NewRepoServerClient() (utilio.Closer, apiclient.RepoServerServiceClient, error) { - return utilio.NopCloser, c.RepoServerServiceClient, nil +func (c *Clientset) NewRepoServerClient() (io.Closer, apiclient.RepoServerServiceClient, error) { + return io.NopCloser, c.RepoServerServiceClient, nil } diff --git a/reposerver/apiclient/mocks/RepoServerServiceClient.go b/reposerver/apiclient/mocks/RepoServerServiceClient.go index f12c683b3f..af428eaea3 100644 --- a/reposerver/apiclient/mocks/RepoServerServiceClient.go +++ b/reposerver/apiclient/mocks/RepoServerServiceClient.go @@ -1,19 +1,544 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" + context "context" + + apiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + + emptypb "google.golang.org/protobuf/types/known/emptypb" + + grpc "google.golang.org/grpc" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" mock "github.com/stretchr/testify/mock" - "google.golang.org/grpc" - "google.golang.org/protobuf/types/known/emptypb" + + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) +// RepoServerServiceClient is an autogenerated mock type for the RepoServerServiceClient type +type RepoServerServiceClient struct { + mock.Mock +} + +// GenerateManifest provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) GenerateManifest(ctx context.Context, in *apiclient.ManifestRequest, opts ...grpc.CallOption) (*apiclient.ManifestResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GenerateManifest") + } + + var r0 *apiclient.ManifestResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.ManifestRequest, ...grpc.CallOption) (*apiclient.ManifestResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.ManifestRequest, ...grpc.CallOption) *apiclient.ManifestResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.ManifestResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.ManifestRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GenerateManifestWithFiles provides a mock function with given fields: ctx, opts +func (_m *RepoServerServiceClient) GenerateManifestWithFiles(ctx context.Context, opts ...grpc.CallOption) (apiclient.RepoServerService_GenerateManifestWithFilesClient, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GenerateManifestWithFiles") + } + + var r0 apiclient.RepoServerService_GenerateManifestWithFilesClient + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ...grpc.CallOption) (apiclient.RepoServerService_GenerateManifestWithFilesClient, error)); ok { + return rf(ctx, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, ...grpc.CallOption) apiclient.RepoServerService_GenerateManifestWithFilesClient); ok { + r0 = rf(ctx, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(apiclient.RepoServerService_GenerateManifestWithFilesClient) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, ...grpc.CallOption) error); ok { + r1 = rf(ctx, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAppDetails provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) GetAppDetails(ctx context.Context, in *apiclient.RepoServerAppDetailsQuery, opts ...grpc.CallOption) (*apiclient.RepoAppDetailsResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetAppDetails") + } + + var r0 *apiclient.RepoAppDetailsResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.RepoServerAppDetailsQuery, ...grpc.CallOption) (*apiclient.RepoAppDetailsResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.RepoServerAppDetailsQuery, ...grpc.CallOption) *apiclient.RepoAppDetailsResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.RepoAppDetailsResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.RepoServerAppDetailsQuery, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetGitDirectories provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) GetGitDirectories(ctx context.Context, in *apiclient.GitDirectoriesRequest, opts ...grpc.CallOption) (*apiclient.GitDirectoriesResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetGitDirectories") + } + + var r0 *apiclient.GitDirectoriesResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.GitDirectoriesRequest, ...grpc.CallOption) (*apiclient.GitDirectoriesResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.GitDirectoriesRequest, ...grpc.CallOption) *apiclient.GitDirectoriesResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.GitDirectoriesResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.GitDirectoriesRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetGitFiles provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) GetGitFiles(ctx context.Context, in *apiclient.GitFilesRequest, opts ...grpc.CallOption) (*apiclient.GitFilesResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetGitFiles") + } + + var r0 *apiclient.GitFilesResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.GitFilesRequest, ...grpc.CallOption) (*apiclient.GitFilesResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.GitFilesRequest, ...grpc.CallOption) *apiclient.GitFilesResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.GitFilesResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.GitFilesRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetHelmCharts provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) GetHelmCharts(ctx context.Context, in *apiclient.HelmChartsRequest, opts ...grpc.CallOption) (*apiclient.HelmChartsResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetHelmCharts") + } + + var r0 *apiclient.HelmChartsResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.HelmChartsRequest, ...grpc.CallOption) (*apiclient.HelmChartsResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.HelmChartsRequest, ...grpc.CallOption) *apiclient.HelmChartsResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.HelmChartsResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.HelmChartsRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRevisionChartDetails provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) GetRevisionChartDetails(ctx context.Context, in *apiclient.RepoServerRevisionChartDetailsRequest, opts ...grpc.CallOption) (*v1alpha1.ChartDetails, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetRevisionChartDetails") + } + + var r0 *v1alpha1.ChartDetails + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.RepoServerRevisionChartDetailsRequest, ...grpc.CallOption) (*v1alpha1.ChartDetails, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.RepoServerRevisionChartDetailsRequest, ...grpc.CallOption) *v1alpha1.ChartDetails); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.ChartDetails) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.RepoServerRevisionChartDetailsRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRevisionMetadata provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) GetRevisionMetadata(ctx context.Context, in *apiclient.RepoServerRevisionMetadataRequest, opts ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetRevisionMetadata") + } + + var r0 *v1alpha1.RevisionMetadata + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.RepoServerRevisionMetadataRequest, ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.RepoServerRevisionMetadataRequest, ...grpc.CallOption) *v1alpha1.RevisionMetadata); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RevisionMetadata) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.RepoServerRevisionMetadataRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListApps provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) ListApps(ctx context.Context, in *apiclient.ListAppsRequest, opts ...grpc.CallOption) (*apiclient.AppList, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for ListApps") + } + + var r0 *apiclient.AppList + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.ListAppsRequest, ...grpc.CallOption) (*apiclient.AppList, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.ListAppsRequest, ...grpc.CallOption) *apiclient.AppList); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.AppList) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.ListAppsRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListPlugins provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) ListPlugins(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*apiclient.PluginList, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for ListPlugins") + } + + var r0 *apiclient.PluginList + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *emptypb.Empty, ...grpc.CallOption) (*apiclient.PluginList, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *emptypb.Empty, ...grpc.CallOption) *apiclient.PluginList); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.PluginList) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *emptypb.Empty, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListRefs provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) ListRefs(ctx context.Context, in *apiclient.ListRefsRequest, opts ...grpc.CallOption) (*apiclient.Refs, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for ListRefs") + } + + var r0 *apiclient.Refs + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.ListRefsRequest, ...grpc.CallOption) (*apiclient.Refs, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.ListRefsRequest, ...grpc.CallOption) *apiclient.Refs); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.Refs) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.ListRefsRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ResolveRevision provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) ResolveRevision(ctx context.Context, in *apiclient.ResolveRevisionRequest, opts ...grpc.CallOption) (*apiclient.ResolveRevisionResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for ResolveRevision") + } + + var r0 *apiclient.ResolveRevisionResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.ResolveRevisionRequest, ...grpc.CallOption) (*apiclient.ResolveRevisionResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.ResolveRevisionRequest, ...grpc.CallOption) *apiclient.ResolveRevisionResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.ResolveRevisionResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.ResolveRevisionRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// TestRepository provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) TestRepository(ctx context.Context, in *apiclient.TestRepositoryRequest, opts ...grpc.CallOption) (*apiclient.TestRepositoryResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for TestRepository") + } + + var r0 *apiclient.TestRepositoryResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.TestRepositoryRequest, ...grpc.CallOption) (*apiclient.TestRepositoryResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.TestRepositoryRequest, ...grpc.CallOption) *apiclient.TestRepositoryResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.TestRepositoryResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.TestRepositoryRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateRevisionForPaths provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) UpdateRevisionForPaths(ctx context.Context, in *apiclient.UpdateRevisionForPathsRequest, opts ...grpc.CallOption) (*apiclient.UpdateRevisionForPathsResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for UpdateRevisionForPaths") + } + + var r0 *apiclient.UpdateRevisionForPathsResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.UpdateRevisionForPathsRequest, ...grpc.CallOption) (*apiclient.UpdateRevisionForPathsResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.UpdateRevisionForPathsRequest, ...grpc.CallOption) *apiclient.UpdateRevisionForPathsResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.UpdateRevisionForPathsResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.UpdateRevisionForPathsRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewRepoServerServiceClient creates a new instance of RepoServerServiceClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewRepoServerServiceClient(t interface { @@ -27,1037 +552,3 @@ func NewRepoServerServiceClient(t interface { return mock } - -// RepoServerServiceClient is an autogenerated mock type for the RepoServerServiceClient type -type RepoServerServiceClient struct { - mock.Mock -} - -type RepoServerServiceClient_Expecter struct { - mock *mock.Mock -} - -func (_m *RepoServerServiceClient) EXPECT() *RepoServerServiceClient_Expecter { - return &RepoServerServiceClient_Expecter{mock: &_m.Mock} -} - -// GenerateManifest provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) GenerateManifest(ctx context.Context, in *apiclient.ManifestRequest, opts ...grpc.CallOption) (*apiclient.ManifestResponse, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GenerateManifest") - } - - var r0 *apiclient.ManifestResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.ManifestRequest, ...grpc.CallOption) (*apiclient.ManifestResponse, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.ManifestRequest, ...grpc.CallOption) *apiclient.ManifestResponse); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.ManifestResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.ManifestRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_GenerateManifest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GenerateManifest' -type RepoServerServiceClient_GenerateManifest_Call struct { - *mock.Call -} - -// GenerateManifest is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) GenerateManifest(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_GenerateManifest_Call { - return &RepoServerServiceClient_GenerateManifest_Call{Call: _e.mock.On("GenerateManifest", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_GenerateManifest_Call) Run(run func(ctx context.Context, in *apiclient.ManifestRequest, opts ...grpc.CallOption)) *RepoServerServiceClient_GenerateManifest_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.ManifestRequest), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_GenerateManifest_Call) Return(manifestResponse *apiclient.ManifestResponse, err error) *RepoServerServiceClient_GenerateManifest_Call { - _c.Call.Return(manifestResponse, err) - return _c -} - -func (_c *RepoServerServiceClient_GenerateManifest_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.ManifestRequest, opts ...grpc.CallOption) (*apiclient.ManifestResponse, error)) *RepoServerServiceClient_GenerateManifest_Call { - _c.Call.Return(run) - return _c -} - -// GenerateManifestWithFiles provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) GenerateManifestWithFiles(ctx context.Context, opts ...grpc.CallOption) (apiclient.RepoServerService_GenerateManifestWithFilesClient, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GenerateManifestWithFiles") - } - - var r0 apiclient.RepoServerService_GenerateManifestWithFilesClient - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, ...grpc.CallOption) (apiclient.RepoServerService_GenerateManifestWithFilesClient, error)); ok { - return returnFunc(ctx, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, ...grpc.CallOption) apiclient.RepoServerService_GenerateManifestWithFilesClient); ok { - r0 = returnFunc(ctx, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(apiclient.RepoServerService_GenerateManifestWithFilesClient) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_GenerateManifestWithFiles_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GenerateManifestWithFiles' -type RepoServerServiceClient_GenerateManifestWithFiles_Call struct { - *mock.Call -} - -// GenerateManifestWithFiles is a helper method to define mock.On call -// - ctx -// - opts -func (_e *RepoServerServiceClient_Expecter) GenerateManifestWithFiles(ctx interface{}, opts ...interface{}) *RepoServerServiceClient_GenerateManifestWithFiles_Call { - return &RepoServerServiceClient_GenerateManifestWithFiles_Call{Call: _e.mock.On("GenerateManifestWithFiles", - append([]interface{}{ctx}, opts...)...)} -} - -func (_c *RepoServerServiceClient_GenerateManifestWithFiles_Call) Run(run func(ctx context.Context, opts ...grpc.CallOption)) *RepoServerServiceClient_GenerateManifestWithFiles_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_GenerateManifestWithFiles_Call) Return(repoServerService_GenerateManifestWithFilesClient apiclient.RepoServerService_GenerateManifestWithFilesClient, err error) *RepoServerServiceClient_GenerateManifestWithFiles_Call { - _c.Call.Return(repoServerService_GenerateManifestWithFilesClient, err) - return _c -} - -func (_c *RepoServerServiceClient_GenerateManifestWithFiles_Call) RunAndReturn(run func(ctx context.Context, opts ...grpc.CallOption) (apiclient.RepoServerService_GenerateManifestWithFilesClient, error)) *RepoServerServiceClient_GenerateManifestWithFiles_Call { - _c.Call.Return(run) - return _c -} - -// GetAppDetails provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) GetAppDetails(ctx context.Context, in *apiclient.RepoServerAppDetailsQuery, opts ...grpc.CallOption) (*apiclient.RepoAppDetailsResponse, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GetAppDetails") - } - - var r0 *apiclient.RepoAppDetailsResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.RepoServerAppDetailsQuery, ...grpc.CallOption) (*apiclient.RepoAppDetailsResponse, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.RepoServerAppDetailsQuery, ...grpc.CallOption) *apiclient.RepoAppDetailsResponse); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.RepoAppDetailsResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.RepoServerAppDetailsQuery, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_GetAppDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAppDetails' -type RepoServerServiceClient_GetAppDetails_Call struct { - *mock.Call -} - -// GetAppDetails is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) GetAppDetails(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_GetAppDetails_Call { - return &RepoServerServiceClient_GetAppDetails_Call{Call: _e.mock.On("GetAppDetails", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_GetAppDetails_Call) Run(run func(ctx context.Context, in *apiclient.RepoServerAppDetailsQuery, opts ...grpc.CallOption)) *RepoServerServiceClient_GetAppDetails_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.RepoServerAppDetailsQuery), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_GetAppDetails_Call) Return(repoAppDetailsResponse *apiclient.RepoAppDetailsResponse, err error) *RepoServerServiceClient_GetAppDetails_Call { - _c.Call.Return(repoAppDetailsResponse, err) - return _c -} - -func (_c *RepoServerServiceClient_GetAppDetails_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.RepoServerAppDetailsQuery, opts ...grpc.CallOption) (*apiclient.RepoAppDetailsResponse, error)) *RepoServerServiceClient_GetAppDetails_Call { - _c.Call.Return(run) - return _c -} - -// GetGitDirectories provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) GetGitDirectories(ctx context.Context, in *apiclient.GitDirectoriesRequest, opts ...grpc.CallOption) (*apiclient.GitDirectoriesResponse, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GetGitDirectories") - } - - var r0 *apiclient.GitDirectoriesResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.GitDirectoriesRequest, ...grpc.CallOption) (*apiclient.GitDirectoriesResponse, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.GitDirectoriesRequest, ...grpc.CallOption) *apiclient.GitDirectoriesResponse); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.GitDirectoriesResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.GitDirectoriesRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_GetGitDirectories_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGitDirectories' -type RepoServerServiceClient_GetGitDirectories_Call struct { - *mock.Call -} - -// GetGitDirectories is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) GetGitDirectories(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_GetGitDirectories_Call { - return &RepoServerServiceClient_GetGitDirectories_Call{Call: _e.mock.On("GetGitDirectories", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_GetGitDirectories_Call) Run(run func(ctx context.Context, in *apiclient.GitDirectoriesRequest, opts ...grpc.CallOption)) *RepoServerServiceClient_GetGitDirectories_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.GitDirectoriesRequest), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_GetGitDirectories_Call) Return(gitDirectoriesResponse *apiclient.GitDirectoriesResponse, err error) *RepoServerServiceClient_GetGitDirectories_Call { - _c.Call.Return(gitDirectoriesResponse, err) - return _c -} - -func (_c *RepoServerServiceClient_GetGitDirectories_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.GitDirectoriesRequest, opts ...grpc.CallOption) (*apiclient.GitDirectoriesResponse, error)) *RepoServerServiceClient_GetGitDirectories_Call { - _c.Call.Return(run) - return _c -} - -// GetGitFiles provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) GetGitFiles(ctx context.Context, in *apiclient.GitFilesRequest, opts ...grpc.CallOption) (*apiclient.GitFilesResponse, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GetGitFiles") - } - - var r0 *apiclient.GitFilesResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.GitFilesRequest, ...grpc.CallOption) (*apiclient.GitFilesResponse, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.GitFilesRequest, ...grpc.CallOption) *apiclient.GitFilesResponse); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.GitFilesResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.GitFilesRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_GetGitFiles_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGitFiles' -type RepoServerServiceClient_GetGitFiles_Call struct { - *mock.Call -} - -// GetGitFiles is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) GetGitFiles(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_GetGitFiles_Call { - return &RepoServerServiceClient_GetGitFiles_Call{Call: _e.mock.On("GetGitFiles", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_GetGitFiles_Call) Run(run func(ctx context.Context, in *apiclient.GitFilesRequest, opts ...grpc.CallOption)) *RepoServerServiceClient_GetGitFiles_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.GitFilesRequest), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_GetGitFiles_Call) Return(gitFilesResponse *apiclient.GitFilesResponse, err error) *RepoServerServiceClient_GetGitFiles_Call { - _c.Call.Return(gitFilesResponse, err) - return _c -} - -func (_c *RepoServerServiceClient_GetGitFiles_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.GitFilesRequest, opts ...grpc.CallOption) (*apiclient.GitFilesResponse, error)) *RepoServerServiceClient_GetGitFiles_Call { - _c.Call.Return(run) - return _c -} - -// GetHelmCharts provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) GetHelmCharts(ctx context.Context, in *apiclient.HelmChartsRequest, opts ...grpc.CallOption) (*apiclient.HelmChartsResponse, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GetHelmCharts") - } - - var r0 *apiclient.HelmChartsResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.HelmChartsRequest, ...grpc.CallOption) (*apiclient.HelmChartsResponse, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.HelmChartsRequest, ...grpc.CallOption) *apiclient.HelmChartsResponse); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.HelmChartsResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.HelmChartsRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_GetHelmCharts_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetHelmCharts' -type RepoServerServiceClient_GetHelmCharts_Call struct { - *mock.Call -} - -// GetHelmCharts is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) GetHelmCharts(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_GetHelmCharts_Call { - return &RepoServerServiceClient_GetHelmCharts_Call{Call: _e.mock.On("GetHelmCharts", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_GetHelmCharts_Call) Run(run func(ctx context.Context, in *apiclient.HelmChartsRequest, opts ...grpc.CallOption)) *RepoServerServiceClient_GetHelmCharts_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.HelmChartsRequest), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_GetHelmCharts_Call) Return(helmChartsResponse *apiclient.HelmChartsResponse, err error) *RepoServerServiceClient_GetHelmCharts_Call { - _c.Call.Return(helmChartsResponse, err) - return _c -} - -func (_c *RepoServerServiceClient_GetHelmCharts_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.HelmChartsRequest, opts ...grpc.CallOption) (*apiclient.HelmChartsResponse, error)) *RepoServerServiceClient_GetHelmCharts_Call { - _c.Call.Return(run) - return _c -} - -// GetRevisionChartDetails provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) GetRevisionChartDetails(ctx context.Context, in *apiclient.RepoServerRevisionChartDetailsRequest, opts ...grpc.CallOption) (*v1alpha1.ChartDetails, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GetRevisionChartDetails") - } - - var r0 *v1alpha1.ChartDetails - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.RepoServerRevisionChartDetailsRequest, ...grpc.CallOption) (*v1alpha1.ChartDetails, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.RepoServerRevisionChartDetailsRequest, ...grpc.CallOption) *v1alpha1.ChartDetails); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.ChartDetails) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.RepoServerRevisionChartDetailsRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_GetRevisionChartDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRevisionChartDetails' -type RepoServerServiceClient_GetRevisionChartDetails_Call struct { - *mock.Call -} - -// GetRevisionChartDetails is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) GetRevisionChartDetails(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_GetRevisionChartDetails_Call { - return &RepoServerServiceClient_GetRevisionChartDetails_Call{Call: _e.mock.On("GetRevisionChartDetails", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_GetRevisionChartDetails_Call) Run(run func(ctx context.Context, in *apiclient.RepoServerRevisionChartDetailsRequest, opts ...grpc.CallOption)) *RepoServerServiceClient_GetRevisionChartDetails_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.RepoServerRevisionChartDetailsRequest), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_GetRevisionChartDetails_Call) Return(chartDetails *v1alpha1.ChartDetails, err error) *RepoServerServiceClient_GetRevisionChartDetails_Call { - _c.Call.Return(chartDetails, err) - return _c -} - -func (_c *RepoServerServiceClient_GetRevisionChartDetails_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.RepoServerRevisionChartDetailsRequest, opts ...grpc.CallOption) (*v1alpha1.ChartDetails, error)) *RepoServerServiceClient_GetRevisionChartDetails_Call { - _c.Call.Return(run) - return _c -} - -// GetRevisionMetadata provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) GetRevisionMetadata(ctx context.Context, in *apiclient.RepoServerRevisionMetadataRequest, opts ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GetRevisionMetadata") - } - - var r0 *v1alpha1.RevisionMetadata - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.RepoServerRevisionMetadataRequest, ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.RepoServerRevisionMetadataRequest, ...grpc.CallOption) *v1alpha1.RevisionMetadata); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.RevisionMetadata) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.RepoServerRevisionMetadataRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_GetRevisionMetadata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRevisionMetadata' -type RepoServerServiceClient_GetRevisionMetadata_Call struct { - *mock.Call -} - -// GetRevisionMetadata is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) GetRevisionMetadata(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_GetRevisionMetadata_Call { - return &RepoServerServiceClient_GetRevisionMetadata_Call{Call: _e.mock.On("GetRevisionMetadata", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_GetRevisionMetadata_Call) Run(run func(ctx context.Context, in *apiclient.RepoServerRevisionMetadataRequest, opts ...grpc.CallOption)) *RepoServerServiceClient_GetRevisionMetadata_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.RepoServerRevisionMetadataRequest), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_GetRevisionMetadata_Call) Return(revisionMetadata *v1alpha1.RevisionMetadata, err error) *RepoServerServiceClient_GetRevisionMetadata_Call { - _c.Call.Return(revisionMetadata, err) - return _c -} - -func (_c *RepoServerServiceClient_GetRevisionMetadata_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.RepoServerRevisionMetadataRequest, opts ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error)) *RepoServerServiceClient_GetRevisionMetadata_Call { - _c.Call.Return(run) - return _c -} - -// ListApps provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) ListApps(ctx context.Context, in *apiclient.ListAppsRequest, opts ...grpc.CallOption) (*apiclient.AppList, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for ListApps") - } - - var r0 *apiclient.AppList - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.ListAppsRequest, ...grpc.CallOption) (*apiclient.AppList, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.ListAppsRequest, ...grpc.CallOption) *apiclient.AppList); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.AppList) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.ListAppsRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_ListApps_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListApps' -type RepoServerServiceClient_ListApps_Call struct { - *mock.Call -} - -// ListApps is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) ListApps(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_ListApps_Call { - return &RepoServerServiceClient_ListApps_Call{Call: _e.mock.On("ListApps", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_ListApps_Call) Run(run func(ctx context.Context, in *apiclient.ListAppsRequest, opts ...grpc.CallOption)) *RepoServerServiceClient_ListApps_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.ListAppsRequest), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_ListApps_Call) Return(appList *apiclient.AppList, err error) *RepoServerServiceClient_ListApps_Call { - _c.Call.Return(appList, err) - return _c -} - -func (_c *RepoServerServiceClient_ListApps_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.ListAppsRequest, opts ...grpc.CallOption) (*apiclient.AppList, error)) *RepoServerServiceClient_ListApps_Call { - _c.Call.Return(run) - return _c -} - -// ListPlugins provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) ListPlugins(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*apiclient.PluginList, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for ListPlugins") - } - - var r0 *apiclient.PluginList - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *emptypb.Empty, ...grpc.CallOption) (*apiclient.PluginList, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *emptypb.Empty, ...grpc.CallOption) *apiclient.PluginList); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.PluginList) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *emptypb.Empty, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_ListPlugins_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListPlugins' -type RepoServerServiceClient_ListPlugins_Call struct { - *mock.Call -} - -// ListPlugins is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) ListPlugins(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_ListPlugins_Call { - return &RepoServerServiceClient_ListPlugins_Call{Call: _e.mock.On("ListPlugins", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_ListPlugins_Call) Run(run func(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption)) *RepoServerServiceClient_ListPlugins_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*emptypb.Empty), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_ListPlugins_Call) Return(pluginList *apiclient.PluginList, err error) *RepoServerServiceClient_ListPlugins_Call { - _c.Call.Return(pluginList, err) - return _c -} - -func (_c *RepoServerServiceClient_ListPlugins_Call) RunAndReturn(run func(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*apiclient.PluginList, error)) *RepoServerServiceClient_ListPlugins_Call { - _c.Call.Return(run) - return _c -} - -// ListRefs provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) ListRefs(ctx context.Context, in *apiclient.ListRefsRequest, opts ...grpc.CallOption) (*apiclient.Refs, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for ListRefs") - } - - var r0 *apiclient.Refs - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.ListRefsRequest, ...grpc.CallOption) (*apiclient.Refs, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.ListRefsRequest, ...grpc.CallOption) *apiclient.Refs); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.Refs) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.ListRefsRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_ListRefs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListRefs' -type RepoServerServiceClient_ListRefs_Call struct { - *mock.Call -} - -// ListRefs is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) ListRefs(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_ListRefs_Call { - return &RepoServerServiceClient_ListRefs_Call{Call: _e.mock.On("ListRefs", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_ListRefs_Call) Run(run func(ctx context.Context, in *apiclient.ListRefsRequest, opts ...grpc.CallOption)) *RepoServerServiceClient_ListRefs_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.ListRefsRequest), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_ListRefs_Call) Return(refs *apiclient.Refs, err error) *RepoServerServiceClient_ListRefs_Call { - _c.Call.Return(refs, err) - return _c -} - -func (_c *RepoServerServiceClient_ListRefs_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.ListRefsRequest, opts ...grpc.CallOption) (*apiclient.Refs, error)) *RepoServerServiceClient_ListRefs_Call { - _c.Call.Return(run) - return _c -} - -// ResolveRevision provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) ResolveRevision(ctx context.Context, in *apiclient.ResolveRevisionRequest, opts ...grpc.CallOption) (*apiclient.ResolveRevisionResponse, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for ResolveRevision") - } - - var r0 *apiclient.ResolveRevisionResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.ResolveRevisionRequest, ...grpc.CallOption) (*apiclient.ResolveRevisionResponse, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.ResolveRevisionRequest, ...grpc.CallOption) *apiclient.ResolveRevisionResponse); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.ResolveRevisionResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.ResolveRevisionRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_ResolveRevision_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ResolveRevision' -type RepoServerServiceClient_ResolveRevision_Call struct { - *mock.Call -} - -// ResolveRevision is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) ResolveRevision(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_ResolveRevision_Call { - return &RepoServerServiceClient_ResolveRevision_Call{Call: _e.mock.On("ResolveRevision", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_ResolveRevision_Call) Run(run func(ctx context.Context, in *apiclient.ResolveRevisionRequest, opts ...grpc.CallOption)) *RepoServerServiceClient_ResolveRevision_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.ResolveRevisionRequest), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_ResolveRevision_Call) Return(resolveRevisionResponse *apiclient.ResolveRevisionResponse, err error) *RepoServerServiceClient_ResolveRevision_Call { - _c.Call.Return(resolveRevisionResponse, err) - return _c -} - -func (_c *RepoServerServiceClient_ResolveRevision_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.ResolveRevisionRequest, opts ...grpc.CallOption) (*apiclient.ResolveRevisionResponse, error)) *RepoServerServiceClient_ResolveRevision_Call { - _c.Call.Return(run) - return _c -} - -// TestRepository provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) TestRepository(ctx context.Context, in *apiclient.TestRepositoryRequest, opts ...grpc.CallOption) (*apiclient.TestRepositoryResponse, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for TestRepository") - } - - var r0 *apiclient.TestRepositoryResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.TestRepositoryRequest, ...grpc.CallOption) (*apiclient.TestRepositoryResponse, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.TestRepositoryRequest, ...grpc.CallOption) *apiclient.TestRepositoryResponse); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.TestRepositoryResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.TestRepositoryRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_TestRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TestRepository' -type RepoServerServiceClient_TestRepository_Call struct { - *mock.Call -} - -// TestRepository is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) TestRepository(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_TestRepository_Call { - return &RepoServerServiceClient_TestRepository_Call{Call: _e.mock.On("TestRepository", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_TestRepository_Call) Run(run func(ctx context.Context, in *apiclient.TestRepositoryRequest, opts ...grpc.CallOption)) *RepoServerServiceClient_TestRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.TestRepositoryRequest), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_TestRepository_Call) Return(testRepositoryResponse *apiclient.TestRepositoryResponse, err error) *RepoServerServiceClient_TestRepository_Call { - _c.Call.Return(testRepositoryResponse, err) - return _c -} - -func (_c *RepoServerServiceClient_TestRepository_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.TestRepositoryRequest, opts ...grpc.CallOption) (*apiclient.TestRepositoryResponse, error)) *RepoServerServiceClient_TestRepository_Call { - _c.Call.Return(run) - return _c -} - -// UpdateRevisionForPaths provides a mock function for the type RepoServerServiceClient -func (_mock *RepoServerServiceClient) UpdateRevisionForPaths(ctx context.Context, in *apiclient.UpdateRevisionForPathsRequest, opts ...grpc.CallOption) (*apiclient.UpdateRevisionForPathsResponse, error) { - // grpc.CallOption - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for UpdateRevisionForPaths") - } - - var r0 *apiclient.UpdateRevisionForPathsResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.UpdateRevisionForPathsRequest, ...grpc.CallOption) (*apiclient.UpdateRevisionForPathsResponse, error)); ok { - return returnFunc(ctx, in, opts...) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *apiclient.UpdateRevisionForPathsRequest, ...grpc.CallOption) *apiclient.UpdateRevisionForPathsResponse); ok { - r0 = returnFunc(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.UpdateRevisionForPathsResponse) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *apiclient.UpdateRevisionForPathsRequest, ...grpc.CallOption) error); ok { - r1 = returnFunc(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerServiceClient_UpdateRevisionForPaths_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateRevisionForPaths' -type RepoServerServiceClient_UpdateRevisionForPaths_Call struct { - *mock.Call -} - -// UpdateRevisionForPaths is a helper method to define mock.On call -// - ctx -// - in -// - opts -func (_e *RepoServerServiceClient_Expecter) UpdateRevisionForPaths(ctx interface{}, in interface{}, opts ...interface{}) *RepoServerServiceClient_UpdateRevisionForPaths_Call { - return &RepoServerServiceClient_UpdateRevisionForPaths_Call{Call: _e.mock.On("UpdateRevisionForPaths", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *RepoServerServiceClient_UpdateRevisionForPaths_Call) Run(run func(ctx context.Context, in *apiclient.UpdateRevisionForPathsRequest, opts ...grpc.CallOption)) *RepoServerServiceClient_UpdateRevisionForPaths_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*apiclient.UpdateRevisionForPathsRequest), variadicArgs...) - }) - return _c -} - -func (_c *RepoServerServiceClient_UpdateRevisionForPaths_Call) Return(updateRevisionForPathsResponse *apiclient.UpdateRevisionForPathsResponse, err error) *RepoServerServiceClient_UpdateRevisionForPaths_Call { - _c.Call.Return(updateRevisionForPathsResponse, err) - return _c -} - -func (_c *RepoServerServiceClient_UpdateRevisionForPaths_Call) RunAndReturn(run func(ctx context.Context, in *apiclient.UpdateRevisionForPathsRequest, opts ...grpc.CallOption) (*apiclient.UpdateRevisionForPathsResponse, error)) *RepoServerServiceClient_UpdateRevisionForPaths_Call { - _c.Call.Return(run) - return _c -} diff --git a/reposerver/apiclient/mocks/RepoServerService_GenerateManifestWithFilesClient.go b/reposerver/apiclient/mocks/RepoServerService_GenerateManifestWithFilesClient.go index 5e6a0daba2..beba722564 100644 --- a/reposerver/apiclient/mocks/RepoServerService_GenerateManifestWithFilesClient.go +++ b/reposerver/apiclient/mocks/RepoServerService_GenerateManifestWithFilesClient.go @@ -1,17 +1,194 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" + context "context" + + apiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + + metadata "google.golang.org/grpc/metadata" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" mock "github.com/stretchr/testify/mock" - "google.golang.org/grpc/metadata" ) +// RepoServerService_GenerateManifestWithFilesClient is an autogenerated mock type for the RepoServerService_GenerateManifestWithFilesClient type +type RepoServerService_GenerateManifestWithFilesClient struct { + mock.Mock +} + +// CloseAndRecv provides a mock function with no fields +func (_m *RepoServerService_GenerateManifestWithFilesClient) CloseAndRecv() (*apiclient.ManifestResponse, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for CloseAndRecv") + } + + var r0 *apiclient.ManifestResponse + var r1 error + if rf, ok := ret.Get(0).(func() (*apiclient.ManifestResponse, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() *apiclient.ManifestResponse); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.ManifestResponse) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CloseSend provides a mock function with no fields +func (_m *RepoServerService_GenerateManifestWithFilesClient) CloseSend() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for CloseSend") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Context provides a mock function with no fields +func (_m *RepoServerService_GenerateManifestWithFilesClient) Context() context.Context { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Context") + } + + var r0 context.Context + if rf, ok := ret.Get(0).(func() context.Context); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(context.Context) + } + } + + return r0 +} + +// Header provides a mock function with no fields +func (_m *RepoServerService_GenerateManifestWithFilesClient) Header() (metadata.MD, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Header") + } + + var r0 metadata.MD + var r1 error + if rf, ok := ret.Get(0).(func() (metadata.MD, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() metadata.MD); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(metadata.MD) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RecvMsg provides a mock function with given fields: m +func (_m *RepoServerService_GenerateManifestWithFilesClient) RecvMsg(m interface{}) error { + ret := _m.Called(m) + + if len(ret) == 0 { + panic("no return value specified for RecvMsg") + } + + var r0 error + if rf, ok := ret.Get(0).(func(interface{}) error); ok { + r0 = rf(m) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Send provides a mock function with given fields: _a0 +func (_m *RepoServerService_GenerateManifestWithFilesClient) Send(_a0 *apiclient.ManifestRequestWithFiles) error { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for Send") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*apiclient.ManifestRequestWithFiles) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SendMsg provides a mock function with given fields: m +func (_m *RepoServerService_GenerateManifestWithFilesClient) SendMsg(m interface{}) error { + ret := _m.Called(m) + + if len(ret) == 0 { + panic("no return value specified for SendMsg") + } + + var r0 error + if rf, ok := ret.Get(0).(func(interface{}) error); ok { + r0 = rf(m) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Trailer provides a mock function with no fields +func (_m *RepoServerService_GenerateManifestWithFilesClient) Trailer() metadata.MD { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Trailer") + } + + var r0 metadata.MD + if rf, ok := ret.Get(0).(func() metadata.MD); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(metadata.MD) + } + } + + return r0 +} + // NewRepoServerService_GenerateManifestWithFilesClient creates a new instance of RepoServerService_GenerateManifestWithFilesClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewRepoServerService_GenerateManifestWithFilesClient(t interface { @@ -25,397 +202,3 @@ func NewRepoServerService_GenerateManifestWithFilesClient(t interface { return mock } - -// RepoServerService_GenerateManifestWithFilesClient is an autogenerated mock type for the RepoServerService_GenerateManifestWithFilesClient type -type RepoServerService_GenerateManifestWithFilesClient struct { - mock.Mock -} - -type RepoServerService_GenerateManifestWithFilesClient_Expecter struct { - mock *mock.Mock -} - -func (_m *RepoServerService_GenerateManifestWithFilesClient) EXPECT() *RepoServerService_GenerateManifestWithFilesClient_Expecter { - return &RepoServerService_GenerateManifestWithFilesClient_Expecter{mock: &_m.Mock} -} - -// CloseAndRecv provides a mock function for the type RepoServerService_GenerateManifestWithFilesClient -func (_mock *RepoServerService_GenerateManifestWithFilesClient) CloseAndRecv() (*apiclient.ManifestResponse, error) { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for CloseAndRecv") - } - - var r0 *apiclient.ManifestResponse - var r1 error - if returnFunc, ok := ret.Get(0).(func() (*apiclient.ManifestResponse, error)); ok { - return returnFunc() - } - if returnFunc, ok := ret.Get(0).(func() *apiclient.ManifestResponse); ok { - r0 = returnFunc() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*apiclient.ManifestResponse) - } - } - if returnFunc, ok := ret.Get(1).(func() error); ok { - r1 = returnFunc() - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerService_GenerateManifestWithFilesClient_CloseAndRecv_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CloseAndRecv' -type RepoServerService_GenerateManifestWithFilesClient_CloseAndRecv_Call struct { - *mock.Call -} - -// CloseAndRecv is a helper method to define mock.On call -func (_e *RepoServerService_GenerateManifestWithFilesClient_Expecter) CloseAndRecv() *RepoServerService_GenerateManifestWithFilesClient_CloseAndRecv_Call { - return &RepoServerService_GenerateManifestWithFilesClient_CloseAndRecv_Call{Call: _e.mock.On("CloseAndRecv")} -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_CloseAndRecv_Call) Run(run func()) *RepoServerService_GenerateManifestWithFilesClient_CloseAndRecv_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_CloseAndRecv_Call) Return(manifestResponse *apiclient.ManifestResponse, err error) *RepoServerService_GenerateManifestWithFilesClient_CloseAndRecv_Call { - _c.Call.Return(manifestResponse, err) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_CloseAndRecv_Call) RunAndReturn(run func() (*apiclient.ManifestResponse, error)) *RepoServerService_GenerateManifestWithFilesClient_CloseAndRecv_Call { - _c.Call.Return(run) - return _c -} - -// CloseSend provides a mock function for the type RepoServerService_GenerateManifestWithFilesClient -func (_mock *RepoServerService_GenerateManifestWithFilesClient) CloseSend() error { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for CloseSend") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func() error); ok { - r0 = returnFunc() - } else { - r0 = ret.Error(0) - } - return r0 -} - -// RepoServerService_GenerateManifestWithFilesClient_CloseSend_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CloseSend' -type RepoServerService_GenerateManifestWithFilesClient_CloseSend_Call struct { - *mock.Call -} - -// CloseSend is a helper method to define mock.On call -func (_e *RepoServerService_GenerateManifestWithFilesClient_Expecter) CloseSend() *RepoServerService_GenerateManifestWithFilesClient_CloseSend_Call { - return &RepoServerService_GenerateManifestWithFilesClient_CloseSend_Call{Call: _e.mock.On("CloseSend")} -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_CloseSend_Call) Run(run func()) *RepoServerService_GenerateManifestWithFilesClient_CloseSend_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_CloseSend_Call) Return(err error) *RepoServerService_GenerateManifestWithFilesClient_CloseSend_Call { - _c.Call.Return(err) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_CloseSend_Call) RunAndReturn(run func() error) *RepoServerService_GenerateManifestWithFilesClient_CloseSend_Call { - _c.Call.Return(run) - return _c -} - -// Context provides a mock function for the type RepoServerService_GenerateManifestWithFilesClient -func (_mock *RepoServerService_GenerateManifestWithFilesClient) Context() context.Context { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for Context") - } - - var r0 context.Context - if returnFunc, ok := ret.Get(0).(func() context.Context); ok { - r0 = returnFunc() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(context.Context) - } - } - return r0 -} - -// RepoServerService_GenerateManifestWithFilesClient_Context_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Context' -type RepoServerService_GenerateManifestWithFilesClient_Context_Call struct { - *mock.Call -} - -// Context is a helper method to define mock.On call -func (_e *RepoServerService_GenerateManifestWithFilesClient_Expecter) Context() *RepoServerService_GenerateManifestWithFilesClient_Context_Call { - return &RepoServerService_GenerateManifestWithFilesClient_Context_Call{Call: _e.mock.On("Context")} -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_Context_Call) Run(run func()) *RepoServerService_GenerateManifestWithFilesClient_Context_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_Context_Call) Return(context1 context.Context) *RepoServerService_GenerateManifestWithFilesClient_Context_Call { - _c.Call.Return(context1) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_Context_Call) RunAndReturn(run func() context.Context) *RepoServerService_GenerateManifestWithFilesClient_Context_Call { - _c.Call.Return(run) - return _c -} - -// Header provides a mock function for the type RepoServerService_GenerateManifestWithFilesClient -func (_mock *RepoServerService_GenerateManifestWithFilesClient) Header() (metadata.MD, error) { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for Header") - } - - var r0 metadata.MD - var r1 error - if returnFunc, ok := ret.Get(0).(func() (metadata.MD, error)); ok { - return returnFunc() - } - if returnFunc, ok := ret.Get(0).(func() metadata.MD); ok { - r0 = returnFunc() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(metadata.MD) - } - } - if returnFunc, ok := ret.Get(1).(func() error); ok { - r1 = returnFunc() - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// RepoServerService_GenerateManifestWithFilesClient_Header_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Header' -type RepoServerService_GenerateManifestWithFilesClient_Header_Call struct { - *mock.Call -} - -// Header is a helper method to define mock.On call -func (_e *RepoServerService_GenerateManifestWithFilesClient_Expecter) Header() *RepoServerService_GenerateManifestWithFilesClient_Header_Call { - return &RepoServerService_GenerateManifestWithFilesClient_Header_Call{Call: _e.mock.On("Header")} -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_Header_Call) Run(run func()) *RepoServerService_GenerateManifestWithFilesClient_Header_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_Header_Call) Return(mD metadata.MD, err error) *RepoServerService_GenerateManifestWithFilesClient_Header_Call { - _c.Call.Return(mD, err) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_Header_Call) RunAndReturn(run func() (metadata.MD, error)) *RepoServerService_GenerateManifestWithFilesClient_Header_Call { - _c.Call.Return(run) - return _c -} - -// RecvMsg provides a mock function for the type RepoServerService_GenerateManifestWithFilesClient -func (_mock *RepoServerService_GenerateManifestWithFilesClient) RecvMsg(m any) error { - ret := _mock.Called(m) - - if len(ret) == 0 { - panic("no return value specified for RecvMsg") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(any) error); ok { - r0 = returnFunc(m) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// RepoServerService_GenerateManifestWithFilesClient_RecvMsg_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RecvMsg' -type RepoServerService_GenerateManifestWithFilesClient_RecvMsg_Call struct { - *mock.Call -} - -// RecvMsg is a helper method to define mock.On call -// - m -func (_e *RepoServerService_GenerateManifestWithFilesClient_Expecter) RecvMsg(m interface{}) *RepoServerService_GenerateManifestWithFilesClient_RecvMsg_Call { - return &RepoServerService_GenerateManifestWithFilesClient_RecvMsg_Call{Call: _e.mock.On("RecvMsg", m)} -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_RecvMsg_Call) Run(run func(m any)) *RepoServerService_GenerateManifestWithFilesClient_RecvMsg_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(any)) - }) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_RecvMsg_Call) Return(err error) *RepoServerService_GenerateManifestWithFilesClient_RecvMsg_Call { - _c.Call.Return(err) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_RecvMsg_Call) RunAndReturn(run func(m any) error) *RepoServerService_GenerateManifestWithFilesClient_RecvMsg_Call { - _c.Call.Return(run) - return _c -} - -// Send provides a mock function for the type RepoServerService_GenerateManifestWithFilesClient -func (_mock *RepoServerService_GenerateManifestWithFilesClient) Send(manifestRequestWithFiles *apiclient.ManifestRequestWithFiles) error { - ret := _mock.Called(manifestRequestWithFiles) - - if len(ret) == 0 { - panic("no return value specified for Send") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(*apiclient.ManifestRequestWithFiles) error); ok { - r0 = returnFunc(manifestRequestWithFiles) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// RepoServerService_GenerateManifestWithFilesClient_Send_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Send' -type RepoServerService_GenerateManifestWithFilesClient_Send_Call struct { - *mock.Call -} - -// Send is a helper method to define mock.On call -// - manifestRequestWithFiles -func (_e *RepoServerService_GenerateManifestWithFilesClient_Expecter) Send(manifestRequestWithFiles interface{}) *RepoServerService_GenerateManifestWithFilesClient_Send_Call { - return &RepoServerService_GenerateManifestWithFilesClient_Send_Call{Call: _e.mock.On("Send", manifestRequestWithFiles)} -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_Send_Call) Run(run func(manifestRequestWithFiles *apiclient.ManifestRequestWithFiles)) *RepoServerService_GenerateManifestWithFilesClient_Send_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*apiclient.ManifestRequestWithFiles)) - }) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_Send_Call) Return(err error) *RepoServerService_GenerateManifestWithFilesClient_Send_Call { - _c.Call.Return(err) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_Send_Call) RunAndReturn(run func(manifestRequestWithFiles *apiclient.ManifestRequestWithFiles) error) *RepoServerService_GenerateManifestWithFilesClient_Send_Call { - _c.Call.Return(run) - return _c -} - -// SendMsg provides a mock function for the type RepoServerService_GenerateManifestWithFilesClient -func (_mock *RepoServerService_GenerateManifestWithFilesClient) SendMsg(m any) error { - ret := _mock.Called(m) - - if len(ret) == 0 { - panic("no return value specified for SendMsg") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(any) error); ok { - r0 = returnFunc(m) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// RepoServerService_GenerateManifestWithFilesClient_SendMsg_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendMsg' -type RepoServerService_GenerateManifestWithFilesClient_SendMsg_Call struct { - *mock.Call -} - -// SendMsg is a helper method to define mock.On call -// - m -func (_e *RepoServerService_GenerateManifestWithFilesClient_Expecter) SendMsg(m interface{}) *RepoServerService_GenerateManifestWithFilesClient_SendMsg_Call { - return &RepoServerService_GenerateManifestWithFilesClient_SendMsg_Call{Call: _e.mock.On("SendMsg", m)} -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_SendMsg_Call) Run(run func(m any)) *RepoServerService_GenerateManifestWithFilesClient_SendMsg_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(any)) - }) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_SendMsg_Call) Return(err error) *RepoServerService_GenerateManifestWithFilesClient_SendMsg_Call { - _c.Call.Return(err) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_SendMsg_Call) RunAndReturn(run func(m any) error) *RepoServerService_GenerateManifestWithFilesClient_SendMsg_Call { - _c.Call.Return(run) - return _c -} - -// Trailer provides a mock function for the type RepoServerService_GenerateManifestWithFilesClient -func (_mock *RepoServerService_GenerateManifestWithFilesClient) Trailer() metadata.MD { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for Trailer") - } - - var r0 metadata.MD - if returnFunc, ok := ret.Get(0).(func() metadata.MD); ok { - r0 = returnFunc() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(metadata.MD) - } - } - return r0 -} - -// RepoServerService_GenerateManifestWithFilesClient_Trailer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Trailer' -type RepoServerService_GenerateManifestWithFilesClient_Trailer_Call struct { - *mock.Call -} - -// Trailer is a helper method to define mock.On call -func (_e *RepoServerService_GenerateManifestWithFilesClient_Expecter) Trailer() *RepoServerService_GenerateManifestWithFilesClient_Trailer_Call { - return &RepoServerService_GenerateManifestWithFilesClient_Trailer_Call{Call: _e.mock.On("Trailer")} -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_Trailer_Call) Run(run func()) *RepoServerService_GenerateManifestWithFilesClient_Trailer_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_Trailer_Call) Return(mD metadata.MD) *RepoServerService_GenerateManifestWithFilesClient_Trailer_Call { - _c.Call.Return(mD) - return _c -} - -func (_c *RepoServerService_GenerateManifestWithFilesClient_Trailer_Call) RunAndReturn(run func() metadata.MD) *RepoServerService_GenerateManifestWithFilesClient_Trailer_Call { - _c.Call.Return(run) - return _c -} diff --git a/reposerver/apiclient/repository.pb.go b/reposerver/apiclient/repository.pb.go index 548318db01..34adb3bc07 100644 --- a/reposerver/apiclient/repository.pb.go +++ b/reposerver/apiclient/repository.pb.go @@ -6,7 +6,7 @@ package apiclient import ( context "context" fmt "fmt" - v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" proto "github.com/gogo/protobuf/proto" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -2478,156 +2478,156 @@ func init() { } var fileDescriptor_dd8723cfcc820480 = []byte{ - // 2377 bytes of a gzipped FileDescriptorProto + // 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, 0x6c, 0x57, 0x62, 0x70, 0x42, 0x28, 0x45, 0xb6, 0x25, 0xc7, 0x96, 0x2d, 0xc6, + 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, 0x65, 0x05, + 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, 0xfb, 0x24, 0x58, 0x93, 0x9f, 0x94, 0xfb, 0xc1, 0x41, 0xe6, 0xb3, 0xc3, 0x02, - 0x9f, 0xfb, 0x08, 0x52, 0x48, 0xfb, 0x51, 0x9f, 0xf2, 0x41, 0xd4, 0xed, 0xd8, 0xbe, 0xbb, 0x86, - 0x83, 0xbe, 0xcf, 0x02, 0xff, 0x73, 0xf9, 0xf1, 0xae, 0xdd, 0x5b, 0xdb, 0xbf, 0xb5, 0xc6, 0xf6, - 0xfa, 0x6b, 0x98, 0xd1, 0x70, 0x0d, 0x33, 0xe6, 0x50, 0x1b, 0x73, 0xea, 0x7b, 0x6b, 0xfb, 0x37, - 0xb0, 0xc3, 0x06, 0xf8, 0xc6, 0x5a, 0x9f, 0x78, 0x24, 0xc0, 0x9c, 0xf4, 0x14, 0xe5, 0xf6, 0x85, - 0xbe, 0xef, 0xf7, 0x1d, 0xb2, 0x26, 0x47, 0xdd, 0x68, 0x77, 0x8d, 0xb8, 0x8c, 0x6b, 0xb6, 0xe6, - 0x3f, 0xe6, 0x60, 0x61, 0x1b, 0x7b, 0x74, 0x97, 0x84, 0xdc, 0x22, 0x2f, 0x23, 0x12, 0x72, 0xf4, - 0x02, 0xea, 0x42, 0x18, 0xa3, 0xb2, 0x5a, 0xb9, 0x3a, 0x7b, 0x73, 0xab, 0x93, 0x4a, 0xd3, 0x89, - 0xa5, 0x91, 0x1f, 0x3f, 0xb6, 0x7b, 0x9d, 0xfd, 0x5b, 0x1d, 0xb6, 0xd7, 0xef, 0x08, 0x69, 0x3a, - 0x19, 0x69, 0x3a, 0xb1, 0x34, 0x1d, 0x2b, 0xd9, 0x96, 0x25, 0xa9, 0xa2, 0x36, 0x34, 0x03, 0xb2, - 0x4f, 0x43, 0xea, 0x7b, 0x46, 0x75, 0xb5, 0x72, 0xb5, 0x65, 0x25, 0x63, 0x64, 0xc0, 0x8c, 0xe7, - 0x6f, 0x60, 0x7b, 0x40, 0x8c, 0xda, 0x6a, 0xe5, 0x6a, 0xd3, 0x8a, 0x87, 0x68, 0x15, 0x66, 0x31, - 0x63, 0x8f, 0x70, 0x97, 0x38, 0x0f, 0xc9, 0x81, 0x51, 0x97, 0x0b, 0xb3, 0x20, 0xb1, 0x16, 0x33, - 0xf6, 0x18, 0xbb, 0xc4, 0x68, 0xc8, 0xd9, 0x78, 0x88, 0x2e, 0x42, 0xcb, 0xc3, 0x2e, 0x09, 0x19, - 0xb6, 0x89, 0xd1, 0x94, 0x73, 0x29, 0x00, 0xfd, 0x14, 0x96, 0x32, 0x82, 0x3f, 0xf5, 0xa3, 0xc0, - 0x26, 0x06, 0xc8, 0xad, 0x3f, 0x99, 0x6c, 0xeb, 0xeb, 0x45, 0xb2, 0xd6, 0x30, 0x27, 0xf4, 0x23, - 0x68, 0x48, 0xcb, 0x1b, 0xb3, 0xab, 0xb5, 0x63, 0xd5, 0xb6, 0x22, 0x8b, 0x3c, 0x98, 0x61, 0x4e, - 0xd4, 0xa7, 0x5e, 0x68, 0x9c, 0x92, 0x1c, 0x9e, 0x4d, 0xc6, 0x61, 0xc3, 0xf7, 0x76, 0x69, 0x7f, - 0x1b, 0x7b, 0xb8, 0x4f, 0x5c, 0xe2, 0xf1, 0x1d, 0x49, 0xdc, 0x8a, 0x99, 0xa0, 0x57, 0xb0, 0xb8, - 0x17, 0x85, 0xdc, 0x77, 0xe9, 0x2b, 0xf2, 0x84, 0x89, 0xb5, 0xa1, 0x31, 0x27, 0xb5, 0xf9, 0x78, - 0x32, 0xc6, 0x0f, 0x0b, 0x54, 0xad, 0x21, 0x3e, 0xc2, 0x49, 0xf6, 0xa2, 0x2e, 0xf9, 0x8c, 0x04, - 0xd2, 0xbb, 0xe6, 0x95, 0x93, 0x64, 0x40, 0xca, 0x8d, 0xa8, 0x1e, 0x85, 0xc6, 0xc2, 0x6a, 0x4d, - 0xb9, 0x51, 0x02, 0x42, 0x57, 0x61, 0x61, 0x9f, 0x04, 0x74, 0xf7, 0xe0, 0x29, 0xed, 0x7b, 0x98, - 0x47, 0x01, 0x31, 0x16, 0xa5, 0x2b, 0x16, 0xc1, 0xc8, 0x85, 0xb9, 0x01, 0x71, 0x5c, 0xa1, 0xf2, - 0x8d, 0x80, 0xf4, 0x42, 0x63, 0x49, 0xea, 0x77, 0x73, 0x72, 0x0b, 0x4a, 0x72, 0x56, 0x9e, 0xba, - 0x10, 0xcc, 0xf3, 0x2d, 0x1d, 0x29, 0x2a, 0x46, 0x90, 0x12, 0xac, 0x00, 0x46, 0x57, 0x60, 0x9e, - 0x07, 0xd8, 0xde, 0xa3, 0x5e, 0x7f, 0x9b, 0xf0, 0x81, 0xdf, 0x33, 0x4e, 0x4b, 0x4d, 0x14, 0xa0, - 0xc8, 0x06, 0x44, 0x3c, 0xdc, 0x75, 0x48, 0x4f, 0xf9, 0xe2, 0xb3, 0x03, 0x46, 0x42, 0xe3, 0x8c, - 0xdc, 0xc5, 0xad, 0x4e, 0x26, 0x43, 0x15, 0x12, 0x44, 0xe7, 0xde, 0xd0, 0xaa, 0x7b, 0x1e, 0x0f, - 0x0e, 0xac, 0x12, 0x72, 0x68, 0x0f, 0x66, 0xc5, 0x3e, 0x62, 0x57, 0x38, 0x2b, 0x5d, 0xe1, 0xc1, - 0x64, 0x3a, 0xda, 0x4a, 0x09, 0x5a, 0x59, 0xea, 0xa8, 0x03, 0x68, 0x80, 0xc3, 0xed, 0xc8, 0xe1, - 0x94, 0x39, 0x44, 0x89, 0x11, 0x1a, 0xcb, 0x52, 0x4d, 0x25, 0x33, 0xe8, 0x21, 0x40, 0x40, 0x76, - 0x63, 0xbc, 0x73, 0x72, 0xe7, 0xd7, 0xc7, 0xed, 0xdc, 0x4a, 0xb0, 0xd5, 0x8e, 0x33, 0xcb, 0x05, - 0x73, 0xb1, 0x0d, 0x62, 0x73, 0x1d, 0xed, 0x32, 0xac, 0x0d, 0xe9, 0x62, 0x25, 0x33, 0xc2, 0x17, - 0x35, 0x54, 0x26, 0xad, 0xf3, 0xca, 0x5b, 0x33, 0x20, 0xb4, 0x05, 0x5f, 0xc3, 0x9e, 0xe7, 0x73, - 0xb9, 0xfd, 0x58, 0x94, 0x4d, 0x9d, 0xde, 0x77, 0x30, 0x1f, 0x84, 0x46, 0x5b, 0xae, 0x3a, 0x0c, - 0x4d, 0xb8, 0x04, 0xf5, 0x42, 0x8e, 0x1d, 0x47, 0x22, 0x3d, 0xb8, 0x6b, 0x5c, 0x50, 0x2e, 0x91, - 0x87, 0xb6, 0xef, 0xc1, 0xb9, 0x11, 0xc6, 0x45, 0x8b, 0x50, 0xdb, 0x23, 0x07, 0xf2, 0x50, 0x68, - 0x59, 0xe2, 0x13, 0x9d, 0x81, 0xc6, 0x3e, 0x76, 0x22, 0x22, 0xd3, 0x78, 0xd3, 0x52, 0x83, 0x3b, - 0xd5, 0x6f, 0x56, 0xda, 0xbf, 0xac, 0xc0, 0x42, 0x41, 0x55, 0x25, 0xeb, 0x7f, 0x98, 0x5d, 0x7f, - 0x0c, 0x81, 0xb3, 0xfb, 0x0c, 0x07, 0x7d, 0xc2, 0x33, 0x82, 0x98, 0x7f, 0xab, 0x80, 0x51, 0xb0, - 0xe1, 0xf7, 0x28, 0x1f, 0xdc, 0xa7, 0x0e, 0x09, 0xd1, 0x6d, 0x98, 0x09, 0x14, 0x4c, 0x1f, 0x75, - 0x17, 0xc6, 0x98, 0x7e, 0x6b, 0xca, 0x8a, 0xb1, 0xd1, 0x47, 0xd0, 0x74, 0x09, 0xc7, 0x3d, 0xcc, - 0xb1, 0x96, 0x7d, 0xb5, 0x6c, 0xa5, 0xe0, 0xb2, 0xad, 0xf1, 0xb6, 0xa6, 0xac, 0x64, 0x0d, 0x7a, - 0x0f, 0x1a, 0xf6, 0x20, 0xf2, 0xf6, 0xe4, 0x21, 0x37, 0x7b, 0xf3, 0xd2, 0xa8, 0xc5, 0x1b, 0x02, - 0x69, 0x6b, 0xca, 0x52, 0xd8, 0x1f, 0x4f, 0x43, 0x9d, 0xe1, 0x80, 0x9b, 0xf7, 0xe1, 0x4c, 0x19, - 0x0b, 0x71, 0xb2, 0xda, 0x03, 0x62, 0xef, 0x85, 0x91, 0xab, 0xd5, 0x9c, 0x8c, 0x11, 0x82, 0x7a, - 0x48, 0x5f, 0x29, 0x55, 0xd7, 0x2c, 0xf9, 0x6d, 0xbe, 0x0d, 0x4b, 0x43, 0xdc, 0x84, 0x51, 0x95, - 0x6c, 0x82, 0xc2, 0x29, 0xcd, 0xda, 0x8c, 0xe0, 0xec, 0x33, 0xa9, 0x8b, 0xe4, 0x78, 0x39, 0x89, - 0x5a, 0xc1, 0xdc, 0x82, 0xe5, 0x22, 0xdb, 0x90, 0xf9, 0x5e, 0x48, 0x44, 0xb0, 0xc9, 0x7c, 0x4c, - 0x49, 0x2f, 0x9d, 0x95, 0x52, 0x34, 0xad, 0x92, 0x19, 0xf3, 0xb7, 0x55, 0x58, 0xb6, 0x48, 0xe8, - 0x3b, 0xfb, 0x24, 0x4e, 0x96, 0x27, 0x53, 0xee, 0xfc, 0x00, 0x6a, 0x98, 0x31, 0xed, 0x26, 0x0f, - 0x8e, 0xad, 0xa0, 0xb0, 0x04, 0x55, 0xf4, 0x0e, 0x2c, 0x61, 0xb7, 0x4b, 0xfb, 0x91, 0x1f, 0x85, - 0xf1, 0xb6, 0xa4, 0x53, 0xb5, 0xac, 0xe1, 0x09, 0x91, 0x70, 0x42, 0x19, 0x91, 0x0f, 0xbc, 0x1e, - 0xf9, 0x89, 0xac, 0xa1, 0x6a, 0x56, 0x16, 0x64, 0xda, 0x70, 0x6e, 0x48, 0x49, 0x5a, 0xe1, 0xd9, - 0xb2, 0xad, 0x52, 0x28, 0xdb, 0x4a, 0xc5, 0xa8, 0x8e, 0x10, 0xc3, 0x7c, 0x5d, 0x81, 0xc5, 0x34, - 0xb8, 0x34, 0xf9, 0x8b, 0xd0, 0x72, 0x35, 0x2c, 0x34, 0x2a, 0x32, 0x67, 0xa6, 0x80, 0x7c, 0x05, - 0x57, 0x2d, 0x56, 0x70, 0xcb, 0x30, 0xad, 0x0a, 0x6c, 0xbd, 0x75, 0x3d, 0xca, 0x89, 0x5c, 0x2f, - 0x88, 0xbc, 0x02, 0x10, 0x26, 0x19, 0xce, 0x98, 0x96, 0xb3, 0x19, 0x08, 0x32, 0xe1, 0x94, 0x3a, - 0xef, 0x2d, 0x12, 0x46, 0x0e, 0x37, 0x66, 0x24, 0x46, 0x0e, 0x26, 0xe3, 0xcd, 0x77, 0x5d, 0xec, - 0xf5, 0x42, 0xa3, 0x29, 0x45, 0x4e, 0xc6, 0xa6, 0x0f, 0x0b, 0x8f, 0xa8, 0xd8, 0xdf, 0x6e, 0x78, - 0x32, 0xa1, 0xf2, 0x3e, 0xd4, 0x05, 0x33, 0x21, 0x54, 0x37, 0xc0, 0x9e, 0x3d, 0x20, 0xb1, 0x1e, - 0x93, 0xb1, 0x48, 0x02, 0x1c, 0xf7, 0x43, 0xa3, 0x2a, 0xe1, 0xf2, 0xdb, 0xfc, 0x7d, 0x55, 0x49, - 0xba, 0xce, 0x58, 0xf8, 0xd5, 0x37, 0x00, 0xe5, 0x25, 0x49, 0x6d, 0xb8, 0x24, 0x29, 0x88, 0xfc, - 0x65, 0x4a, 0x92, 0x63, 0x3a, 0xe4, 0xcc, 0x08, 0x66, 0xd6, 0x19, 0x13, 0x82, 0xa0, 0x1b, 0x50, - 0xc7, 0x8c, 0x29, 0x85, 0x17, 0xf2, 0xb9, 0x46, 0x11, 0xff, 0xb5, 0x48, 0x12, 0xb5, 0x7d, 0x1b, - 0x5a, 0x09, 0xe8, 0x30, 0xb6, 0xad, 0x2c, 0xdb, 0x55, 0x00, 0x55, 0x73, 0x3f, 0xf0, 0x76, 0x7d, - 0x61, 0x52, 0x11, 0x08, 0x7a, 0xa9, 0xfc, 0x36, 0xef, 0xc4, 0x18, 0x52, 0xb6, 0x77, 0xa0, 0x41, + 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, 0xca, 0x10, 0x5a, 0x67, 0xec, 0x2e, 0xe1, 0x98, 0x3a, 0xe1, 0x77, 0x23, 0x12, - 0x1c, 0xbc, 0x61, 0xc7, 0xe8, 0xc3, 0xb4, 0x8a, 0x40, 0x9d, 0x2d, 0x8f, 0xbd, 0xfd, 0xd2, 0xe4, - 0xd3, 0x9e, 0xab, 0xf6, 0x66, 0x7a, 0xae, 0xb2, 0x1e, 0xa8, 0x7e, 0x42, 0x3d, 0xd0, 0xe8, 0x36, - 0x38, 0xd3, 0x5c, 0x4f, 0xe7, 0x9b, 0xeb, 0x92, 0xd6, 0x62, 0xe6, 0xa8, 0xad, 0x45, 0xb3, 0xb4, - 0xb5, 0x70, 0x4b, 0xe3, 0xb8, 0x25, 0xd5, 0xfd, 0xed, 0xac, 0x07, 0x8e, 0xf4, 0xb5, 0x49, 0x9a, - 0x0c, 0x78, 0xa3, 0x4d, 0xc6, 0xa7, 0xb9, 0xa6, 0x41, 0xb5, 0xed, 0xef, 0x1d, 0x6d, 0x4f, 0x63, - 0xda, 0x87, 0xff, 0xbb, 0xd2, 0xfb, 0x17, 0xb2, 0xe2, 0x62, 0x7e, 0xaa, 0x83, 0xe4, 0xb0, 0x17, - 0xe7, 0x90, 0x38, 0x76, 0x75, 0xd2, 0x12, 0xdf, 0xe8, 0x3a, 0xd4, 0x85, 0x92, 0x75, 0x49, 0x7c, - 0x2e, 0xab, 0x4f, 0x61, 0x89, 0x75, 0xc6, 0x9e, 0x32, 0x62, 0x5b, 0x12, 0x09, 0xdd, 0x81, 0x56, - 0xe2, 0xf8, 0x3a, 0xb2, 0x2e, 0x66, 0x57, 0x24, 0x71, 0x12, 0x2f, 0x4b, 0xd1, 0xc5, 0xda, 0x1e, - 0x0d, 0x88, 0x2d, 0x0b, 0xc6, 0xc6, 0xf0, 0xda, 0xbb, 0xf1, 0x64, 0xb2, 0x36, 0x41, 0x47, 0x37, - 0x60, 0x5a, 0xdd, 0x73, 0xc8, 0x08, 0x9a, 0xbd, 0x79, 0x7e, 0x38, 0x99, 0xc6, 0xab, 0x34, 0xa2, + 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, 0x06, 0x38, 0xe0, 0x89, 0x79, 0x4f, 0x62, 0x2f, 0xf1, 0x81, 0x57, 0x4d, 0x0f, + 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, 0x00, 0x18, - 0x0e, 0xb0, 0x4b, 0x38, 0x09, 0x44, 0x26, 0x17, 0x11, 0xff, 0x70, 0xf2, 0xec, 0xb2, 0x13, 0xd3, - 0xb4, 0x32, 0xe4, 0x45, 0x35, 0x2b, 0x59, 0x87, 0x3a, 0x7f, 0xeb, 0x11, 0xfa, 0x02, 0xe6, 0x77, - 0xa9, 0x43, 0x76, 0x52, 0x41, 0xa6, 0xa5, 0x20, 0x4f, 0x26, 0x17, 0xe4, 0x7e, 0x96, 0xae, 0x55, + 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, 0x5b, 0xf7, 0x3c, 0x3f, 0xf2, + 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, 0xcb, 0x88, 0x06, 0xa4, + 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, 0x40, 0x57, 0xfe, 0x6a, 0x80, - 0x3e, 0x84, 0x9a, 0x8b, 0x99, 0x3e, 0xe8, 0xae, 0xe5, 0xb2, 0x43, 0x99, 0x06, 0x3a, 0xdb, 0x98, + 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, 0x73, 0x58, 0x4e, 0x3d, 0x2a, 0xcb, 0x50, 0x17, 0x81, 0x6f, 0x1d, 0x2a, 0x99, - 0x35, 0x82, 0x80, 0xf9, 0x12, 0x96, 0x84, 0xcb, 0xc8, 0xc0, 0x3f, 0xa1, 0xd6, 0xe6, 0x03, 0x68, - 0x25, 0x2c, 0x4b, 0x7d, 0xa6, 0x0d, 0xcd, 0xfd, 0xf8, 0x4a, 0x57, 0xf5, 0x36, 0xc9, 0xd8, 0x5c, - 0x07, 0x94, 0x95, 0x57, 0x9f, 0x40, 0xd7, 0xf3, 0x45, 0xf1, 0xd9, 0xe2, 0x71, 0x23, 0xd1, 0xe3, - 0x9a, 0xf8, 0xef, 0x55, 0x58, 0xd8, 0xa4, 0xf2, 0x8e, 0xe4, 0x84, 0x92, 0xdc, 0x35, 0x58, 0x0c, + 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, 0xc7, 0xe4, 0x0b, 0xbd, - 0x9f, 0x4d, 0xc7, 0xef, 0x76, 0xa9, 0xd7, 0x8f, 0x99, 0x34, 0x24, 0x93, 0xd1, 0x08, 0x65, 0xa5, - 0xe2, 0x74, 0x79, 0xa9, 0x98, 0x74, 0xd0, 0x1b, 0xbe, 0xeb, 0x52, 0xae, 0x2b, 0xca, 0x1c, 0xcc, - 0xfc, 0x79, 0x05, 0x16, 0x53, 0xcd, 0x6a, 0xdb, 0xdc, 0x56, 0x31, 0xa4, 0x2c, 0x73, 0x39, 0x6b, - 0x99, 0x22, 0xea, 0x7f, 0x1e, 0x3e, 0xa7, 0xb2, 0xe1, 0xf3, 0xab, 0x2a, 0x9c, 0xdd, 0xa4, 0x3c, - 0x4e, 0x5c, 0xf4, 0x7f, 0xcd, 0xca, 0x25, 0x36, 0xa9, 0x1f, 0xcd, 0x26, 0x8d, 0x12, 0x9b, 0x74, + 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, 0xf7, 0x03, 0x79, 0xeb, + 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, - 0xf4, 0x32, 0xd8, 0x38, 0xb1, 0x97, 0xc1, 0xe1, 0x5e, 0x6b, 0xba, 0xb4, 0xd7, 0x7a, 0x9e, 0xeb, + 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, 0xf4, 0x41, 0xad, 0x35, 0xfc, 0xa0, 0x56, 0xfe, 0x26, 0x03, 0x23, 0xdf, 0x64, 0xae, - 0xc0, 0x7c, 0x78, 0xe0, 0xd9, 0xa4, 0x97, 0xdc, 0x24, 0xce, 0xaa, 0x6d, 0xe7, 0xa1, 0xb9, 0x88, + 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, 0xb8, 0xf9, 0x47, 0x80, 0xa5, 0xb4, 0xea, 0x17, 0x7f, 0xa9, 0x4d, 0xd0, 0x13, 0x58, 0x8c, - 0x9f, 0x97, 0xe2, 0x8b, 0x5c, 0x34, 0xee, 0xed, 0xa4, 0x7d, 0xb1, 0x7c, 0x52, 0x89, 0x66, 0x4e, - 0x21, 0x1b, 0xce, 0x17, 0x09, 0xa6, 0xcf, 0x34, 0xdf, 0x18, 0x43, 0x39, 0xc1, 0x3a, 0x8c, 0xc5, - 0xd5, 0x0a, 0x7a, 0x0e, 0xf3, 0xf9, 0xc7, 0x04, 0x94, 0x2b, 0x83, 0x4a, 0xdf, 0x37, 0xda, 0xe6, - 0x38, 0x94, 0x44, 0xfe, 0x17, 0xc2, 0x0d, 0x72, 0xf7, 0xe6, 0xc8, 0xcc, 0xdf, 0x08, 0x94, 0xbd, - 0x3c, 0xb4, 0xbf, 0x3e, 0x16, 0x27, 0xa1, 0xfe, 0x01, 0x34, 0xe3, 0xbb, 0xe4, 0xbc, 0x9a, 0x0b, - 0x37, 0xcc, 0xed, 0xc5, 0x3c, 0xbd, 0xdd, 0xd0, 0x9c, 0x42, 0x1f, 0xa9, 0xc5, 0xeb, 0x8c, 0x95, - 0x2c, 0xce, 0xdc, 0xa0, 0xb6, 0x4f, 0x97, 0xdc, 0x5a, 0x9a, 0x53, 0xe8, 0x3b, 0x30, 0x2b, 0xbe, - 0x76, 0xf4, 0xf3, 0xfe, 0x72, 0x47, 0xfd, 0x9a, 0xa4, 0x13, 0xff, 0x9a, 0xa4, 0x73, 0xcf, 0x65, - 0xfc, 0xa0, 0x5d, 0x72, 0xad, 0xa8, 0x09, 0xbc, 0x80, 0xb9, 0x4d, 0xc2, 0xd3, 0x5b, 0x00, 0x74, - 0xf9, 0x48, 0x77, 0x25, 0x6d, 0xb3, 0x88, 0x36, 0x7c, 0x91, 0x60, 0x4e, 0xa1, 0x5f, 0x57, 0xe0, - 0xf4, 0x26, 0xe1, 0xc5, 0xbe, 0x1a, 0xbd, 0x5b, 0xce, 0x64, 0x44, 0xff, 0xdd, 0x7e, 0x3c, 0x69, - 0x4c, 0xe6, 0xc9, 0x9a, 0x53, 0xe8, 0x37, 0x15, 0x38, 0x97, 0x11, 0x2c, 0xdb, 0x28, 0xa3, 0x1b, - 0xe3, 0x85, 0x2b, 0x69, 0xaa, 0xdb, 0x9f, 0x4c, 0xf8, 0xab, 0x8d, 0x0c, 0x49, 0x73, 0x0a, 0xed, - 0x48, 0x9b, 0xa4, 0x75, 0x31, 0xba, 0x54, 0x5a, 0x00, 0x27, 0xdc, 0x57, 0x46, 0x4d, 0x27, 0x76, - 0xf8, 0x04, 0x66, 0x37, 0x09, 0x8f, 0x0b, 0xb4, 0xbc, 0xa7, 0x15, 0x6a, 0xe7, 0x7c, 0xa8, 0x16, - 0x6b, 0x3a, 0xe9, 0x31, 0x4b, 0x8a, 0x56, 0xa6, 0x08, 0xc9, 0xc7, 0x6a, 0x69, 0xb5, 0x96, 0xf7, - 0x98, 0xf2, 0x1a, 0xc6, 0x9c, 0x42, 0x2f, 0x61, 0xb9, 0x3c, 0x55, 0xa2, 0xb7, 0x8f, 0x7c, 0x68, - 0xb6, 0xaf, 0x1d, 0x05, 0x35, 0x66, 0xf9, 0xf1, 0xfa, 0x5f, 0x5e, 0xaf, 0x54, 0xfe, 0xfa, 0x7a, - 0xa5, 0xf2, 0xaf, 0xd7, 0x2b, 0x95, 0xef, 0xdf, 0x3a, 0xe4, 0xd7, 0x5d, 0x99, 0x1f, 0x8c, 0x61, - 0x46, 0x6d, 0x87, 0x12, 0x8f, 0x77, 0xa7, 0x65, 0xbc, 0xdd, 0xfa, 0x77, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x17, 0x3e, 0x16, 0x5a, 0x4f, 0x26, 0x00, 0x00, + 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. diff --git a/reposerver/cache/cache.go b/reposerver/cache/cache.go index 212d040d81..cdc16ea4eb 100644 --- a/reposerver/cache/cache.go +++ b/reposerver/cache/cache.go @@ -16,11 +16,12 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/hash" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/argo" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/hash" ) var ( @@ -144,15 +145,15 @@ func listApps(repoURL, revision string) string { return fmt.Sprintf("ldir|%s|%s", repoURL, revision) } -func (c *Cache) ListApps(repoURL, revision string) (map[string]string, error) { +func (c *Cache) ListApps(repoUrl, revision string) (map[string]string, error) { res := make(map[string]string) - err := c.cache.GetItem(listApps(repoURL, revision), &res) + err := c.cache.GetItem(listApps(repoUrl, revision), &res) return res, err } -func (c *Cache) SetApps(repoURL, revision string, apps map[string]string) error { +func (c *Cache) SetApps(repoUrl, revision string, apps map[string]string) error { return c.cache.SetItem( - listApps(repoURL, revision), + listApps(repoUrl, revision), apps, &cacheutil.CacheActionOpts{ Expiration: c.repoCacheExpiration, @@ -161,14 +162,14 @@ func (c *Cache) SetApps(repoURL, revision string, apps map[string]string) error } func helmIndexRefsKey(repo string) string { - return "helm-index|" + repo + return fmt.Sprintf("helm-index|%s", repo) } // SetHelmIndex stores helm repository index.yaml content to cache func (c *Cache) SetHelmIndex(repo string, indexData []byte) error { if indexData == nil { // Logged as warning upstream - return errors.New("helm index data is nil, skipping cache") + return fmt.Errorf("helm index data is nil, skipping cache") } return c.cache.SetItem( helmIndexRefsKey(repo), @@ -182,7 +183,7 @@ func (c *Cache) GetHelmIndex(repo string, indexData *[]byte) error { } func gitRefsKey(repo string) string { - return "git-refs|" + repo + return fmt.Sprintf("git-refs|%s", repo) } // SetGitReferences saves resolved Git repository references to cache @@ -304,7 +305,7 @@ func manifestCacheKey(revision string, appSrc *appv1.ApplicationSource, srcRefs func trackingKey(appLabelKey string, trackingMethod string) string { trackingKey := appLabelKey - if text.FirstNonEmpty(trackingMethod, string(appv1.TrackingMethodLabel)) != string(appv1.TrackingMethodLabel) { + if text.FirstNonEmpty(trackingMethod, string(argo.TrackingMethodLabel)) != string(argo.TrackingMethodLabel) { trackingKey = trackingMethod + ":" + trackingKey } return trackingKey @@ -340,7 +341,7 @@ func (c *Cache) GetManifests(revision string, appSrc *appv1.ApplicationSource, s hash, err := res.generateCacheEntryHash() if err != nil { - return fmt.Errorf("unable to generate hash value: %w", err) + return fmt.Errorf("Unable to generate hash value: %w", err) } // If cached result does not have manifests or the expected hash of the cache entry does not match the actual hash value... @@ -351,7 +352,7 @@ func (c *Cache) GetManifests(revision string, appSrc *appv1.ApplicationSource, s 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) + return fmt.Errorf("Unable to delete manifest after hash mismatch, %w", err) } // Treat hash mismatches as cache misses, so that the underlying resource is reacquired @@ -375,7 +376,7 @@ func (c *Cache) SetManifests(revision string, appSrc *appv1.ApplicationSource, s res = res.shallowCopy() hash, err := res.generateCacheEntryHash() if err != nil { - return fmt.Errorf("unable to generate hash value: %w", err) + return fmt.Errorf("Unable to generate hash value: %w", err) } res.CacheEntryHash = hash } @@ -398,7 +399,7 @@ func (c *Cache) DeleteManifests(revision string, appSrc *appv1.ApplicationSource func appDetailsCacheKey(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, trackingMethod appv1.TrackingMethod, refSourceCommitSHAs ResolvedRevisions) string { if trackingMethod == "" { - trackingMethod = appv1.TrackingMethodLabel + trackingMethod = argo.TrackingMethodLabel } return fmt.Sprintf("appdetails|%s|%d|%s", revision, appSourceKey(appSrc, srcRefs, refSourceCommitSHAs), trackingMethod) } diff --git a/reposerver/cache/cache_test.go b/reposerver/cache/cache_test.go index a96ba55652..a42ac0a513 100644 --- a/reposerver/cache/cache_test.go +++ b/reposerver/cache/cache_test.go @@ -3,6 +3,7 @@ package cache import ( "encoding/json" "errors" + "fmt" "testing" "time" @@ -12,10 +13,11 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/reposerver/cache/mocks" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/reposerver/cache/mocks" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" ) type MockedCache struct { @@ -42,21 +44,21 @@ func TestCache_GetRevisionMetadata(t *testing.T) { mockCache := fixtures.mockCache // cache miss _, err := cache.GetRevisionMetadata("my-repo-url", "my-revision") - require.ErrorIs(t, err, ErrCacheMiss) + assert.Equal(t, ErrCacheMiss, err) mockCache.RedisClient.AssertCalled(t, "Get", mock.Anything, mock.Anything) // populate cache - err = cache.SetRevisionMetadata("my-repo-url", "my-revision", &v1alpha1.RevisionMetadata{Message: "my-message"}) + err = cache.SetRevisionMetadata("my-repo-url", "my-revision", &RevisionMetadata{Message: "my-message"}) require.NoError(t, err) // cache miss _, err = cache.GetRevisionMetadata("other-repo-url", "my-revision") - require.ErrorIs(t, err, ErrCacheMiss) + assert.Equal(t, ErrCacheMiss, err) // cache miss _, err = cache.GetRevisionMetadata("my-repo-url", "other-revision") - require.ErrorIs(t, err, ErrCacheMiss) + assert.Equal(t, ErrCacheMiss, err) // cache hit value, err := cache.GetRevisionMetadata("my-repo-url", "my-revision") require.NoError(t, err) - assert.Equal(t, &v1alpha1.RevisionMetadata{Message: "my-message"}, value) + assert.Equal(t, &RevisionMetadata{Message: "my-message"}, value) mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 4}) } @@ -67,16 +69,16 @@ func TestCache_ListApps(t *testing.T) { mockCache := fixtures.mockCache // cache miss _, err := cache.ListApps("my-repo-url", "my-revision") - require.ErrorIs(t, err, ErrCacheMiss) + assert.Equal(t, ErrCacheMiss, err) // populate cache err = cache.SetApps("my-repo-url", "my-revision", map[string]string{"foo": "bar"}) require.NoError(t, err) // cache miss _, err = cache.ListApps("other-repo-url", "my-revision") - require.ErrorIs(t, err, ErrCacheMiss) + assert.Equal(t, ErrCacheMiss, err) // cache miss _, err = cache.ListApps("my-repo-url", "other-revision") - require.ErrorIs(t, err, ErrCacheMiss) + assert.Equal(t, ErrCacheMiss, err) // cache hit value, err := cache.ListApps("my-repo-url", "my-revision") require.NoError(t, err) @@ -92,43 +94,43 @@ func TestCache_GetManifests(t *testing.T) { // cache miss q := &apiclient.ManifestRequest{} value := &CachedManifestResponse{} - err := cache.GetManifests("my-revision", &v1alpha1.ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil, "") - require.ErrorIs(t, err, ErrCacheMiss) + 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", &v1alpha1.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", &v1alpha1.ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil, "") - require.ErrorIs(t, err, ErrCacheMiss) + 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", &v1alpha1.ApplicationSource{Path: "other-path"}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil, "") - require.ErrorIs(t, err, ErrCacheMiss) + 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", &v1alpha1.ApplicationSource{}, q.RefSources, q, "other-namespace", "", "my-app-label-key", "my-app-label-value", value, nil, "") - require.ErrorIs(t, err, ErrCacheMiss) + 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", &v1alpha1.ApplicationSource{}, q.RefSources, q, "my-namespace", "", "other-app-label-key", "my-app-label-value", value, nil, "") - require.ErrorIs(t, err, ErrCacheMiss) + 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", &v1alpha1.ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "other-app-label-value", value, nil, "") - require.ErrorIs(t, err, ErrCacheMiss) + 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", &v1alpha1.ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "other-app-label-value", value, map[string]string{"my-referenced-source": "my-referenced-revision"}, "") - require.ErrorIs(t, err, ErrCacheMiss) + 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", &v1alpha1.ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", + "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, "") require.NoError(t, err) - err = cache.GetManifests("my-revision1", &v1alpha1.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) @@ -144,20 +146,20 @@ func TestCache_GetAppDetails(t *testing.T) { mockCache := fixtures.mockCache // cache miss value := &apiclient.RepoAppDetailsResponse{} - emptyRefSources := map[string]*v1alpha1.RefTarget{} - err := cache.GetAppDetails("my-revision", &v1alpha1.ApplicationSource{}, emptyRefSources, value, "", nil) - require.ErrorIs(t, err, ErrCacheMiss) + emptyRefSources := map[string]*RefTarget{} + err := cache.GetAppDetails("my-revision", &ApplicationSource{}, emptyRefSources, value, "", nil) + assert.Equal(t, ErrCacheMiss, err) res := &apiclient.RepoAppDetailsResponse{Type: "my-type"} - err = cache.SetAppDetails("my-revision", &v1alpha1.ApplicationSource{}, emptyRefSources, res, "", nil) + err = cache.SetAppDetails("my-revision", &ApplicationSource{}, emptyRefSources, res, "", nil) require.NoError(t, err) // cache miss - err = cache.GetAppDetails("other-revision", &v1alpha1.ApplicationSource{}, emptyRefSources, value, "", nil) - require.ErrorIs(t, err, ErrCacheMiss) + err = cache.GetAppDetails("other-revision", &ApplicationSource{}, emptyRefSources, value, "", nil) + assert.Equal(t, ErrCacheMiss, err) // cache miss - err = cache.GetAppDetails("my-revision", &v1alpha1.ApplicationSource{Path: "other-path"}, emptyRefSources, value, "", nil) - require.ErrorIs(t, err, ErrCacheMiss) + err = cache.GetAppDetails("my-revision", &ApplicationSource{Path: "other-path"}, emptyRefSources, value, "", nil) + assert.Equal(t, ErrCacheMiss, err) // cache hit - err = cache.GetAppDetails("my-revision", &v1alpha1.ApplicationSource{}, emptyRefSources, value, "", nil) + err = cache.GetAppDetails("my-revision", &ApplicationSource{}, emptyRefSources, value, "", nil) require.NoError(t, err) assert.Equal(t, &apiclient.RepoAppDetailsResponse{Type: "my-type"}, value) mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 4}) @@ -184,7 +186,7 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { Revision: "revision", Manifests: []string{"sample-text"}, } - appSrc := &v1alpha1.ApplicationSource{} + appSrc := &ApplicationSource{} appKey := "key" appValue := "value" @@ -198,7 +200,9 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { } q := &apiclient.ManifestRequest{} err := repoCache.SetManifests(response.Revision, appSrc, q.RefSources, q, response.Namespace, "", appKey, appValue, store, nil, "") - require.NoError(t, err) + if err != nil { + t.Fatal(err) + } // Get the cache entry of the set value directly from the in memory cache, and check the values var cacheKey string @@ -217,14 +221,18 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { assert.Equal(t, cmr.ManifestResponse, store.ManifestResponse) regeneratedHash, err := cmr.generateCacheEntryHash() - require.NoError(t, err) + if err != nil { + t.Fatal(err) + } assert.Equal(t, cmr.CacheEntryHash, regeneratedHash) } // 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, "") - require.NoError(t, err) + if err != nil { + t.Fatal(err) + } assert.Equal(t, retrievedVal, store) // Corrupt the hash so that it doesn't match @@ -236,7 +244,9 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { Key: cacheKey, Object: &newCmr, }) - require.NoError(t, err) + if err != nil { + t.Fatal(err) + } } // Retrieve the value using GetManifests and confirm it returns a cache miss @@ -252,13 +262,17 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { func getInMemoryCacheContents(t *testing.T, inMemCache *cacheutil.InMemoryCache) map[string]*CachedManifestResponse { t.Helper() - items, err := inMemCache.Items(func() any { return &CachedManifestResponse{} }) - require.NoError(t, err) + items, err := inMemCache.Items(func() interface{} { return &CachedManifestResponse{} }) + if err != nil { + t.Fatal(err) + } result := map[string]*CachedManifestResponse{} for key, val := range items { obj, ok := val.(*CachedManifestResponse) - require.True(t, ok, "Unexpected type in cache") + if !ok { + t.Fatal(errors.New("Unexpected type in cache")) + } result[key] = obj } @@ -305,7 +319,7 @@ func TestCachedManifestResponse_ShallowCopyExpectedFields(t *testing.T) { return } - jsonMap := map[string]any{} + jsonMap := map[string]interface{}{} err = json.Unmarshal(str, &jsonMap) if err != nil { assert.FailNow(t, "Unable to unmarshal", err) @@ -317,7 +331,7 @@ func TestCachedManifestResponse_ShallowCopyExpectedFields(t *testing.T) { "numberOfConsecutiveFailures", "numberOfCachedResponsesReturned", } - assert.Len(t, jsonMap, len(expectedFields)) + assert.Equal(t, len(jsonMap), len(expectedFields)) // If this test failed, you probably also forgot to update CachedManifestResponse.shallowCopy(), so // go do that first :) @@ -335,7 +349,7 @@ func TestGetGitReferences(t *testing.T) { var references []*plumbing.Reference lockOwner, err := cache.GetGitReferences("test-repo", &references) require.NoError(t, err, "Error is cache miss handled inside function") - assert.Empty(t, lockOwner, "Lock owner should be empty") + assert.Equal(t, "", lockOwner, "Lock owner should be empty") assert.Nil(t, references) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1}) }) @@ -347,7 +361,7 @@ func TestGetGitReferences(t *testing.T) { var references []*plumbing.Reference lockOwner, err := cache.GetGitReferences("test-repo", &references) require.NoError(t, err, "Error is cache miss handled inside function") - assert.Empty(t, lockOwner, "Lock owner should be empty") + assert.Equal(t, "", lockOwner, "Lock owner should be empty") assert.Nil(t, references) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1}) }) @@ -361,7 +375,7 @@ func TestGetGitReferences(t *testing.T) { var references []*plumbing.Reference lockOwner, err := cache.GetGitReferences("test-repo", &references) require.NoError(t, err) - assert.Empty(t, lockOwner, "Lock owner should be empty") + assert.Equal(t, "", lockOwner, "Lock owner should be empty") assert.Len(t, references, 1) assert.Equal(t, "test", (references)[0].Target().String()) assert.Equal(t, "test-repo", (references)[0].Name().String()) @@ -377,7 +391,7 @@ func TestGetGitReferences(t *testing.T) { var references []*plumbing.Reference lockOwner, err := cache.GetGitReferences("test-repo", &references) require.ErrorContains(t, err, "test cache error", "Error should be propagated") - assert.Empty(t, lockOwner, "Lock owner should be empty") + assert.Equal(t, "", lockOwner, "Lock owner should be empty") assert.Nil(t, references) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1}) }) @@ -417,7 +431,7 @@ func TestTryLockGitRefCache_OwnershipFlows(t *testing.T) { fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 1}) require.NoError(t, err) var output [][2]string - key := "git-refs|" + "my-repo-url" + key := fmt.Sprintf("git-refs|%s", "my-repo-url") err = utilCache.GetItem(key, &output) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 2}) require.NoError(t, err) @@ -455,7 +469,7 @@ func TestGetOrLockGitReferences(t *testing.T) { lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) require.NoError(t, err) assert.Equal(t, "test-lock-id", lockId) - assert.NotEmpty(t, lockId, "Lock id should be set") + assert.NotEqual(t, "", lockId, "Lock id should be set") fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 2}) }) @@ -469,7 +483,7 @@ func TestGetOrLockGitReferences(t *testing.T) { lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) require.NoError(t, err) assert.NotEqual(t, "test-lock-id", lockId) - assert.Empty(t, lockId, "Lock id should not be set") + assert.Equal(t, "", lockId, "Lock id should not be set") assert.Equal(t, "test-repo", references[0].Name().String()) assert.Equal(t, "test", references[0].Target().String()) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 1}) @@ -490,7 +504,7 @@ func TestGetOrLockGitReferences(t *testing.T) { lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) require.NoError(t, err) assert.NotEqual(t, "test-lock-id", lockId) - assert.Empty(t, lockId, "Lock id should not be set") + assert.Equal(t, "", lockId, "Lock id should not be set") assert.Equal(t, "test-repo", references[0].Name().String()) assert.Equal(t, "test", references[0].Target().String()) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 1}) @@ -503,7 +517,7 @@ func TestGetOrLockGitReferences(t *testing.T) { t.Cleanup(fixtures.mockCache.StopRedisCallback) cache := fixtures.cache fixtures.mockCache.RedisClient.On("Get", mock.Anything, mock.Anything).Unset() - fixtures.mockCache.RedisClient.On("Get", mock.Anything, mock.Anything).Return(cacheutil.ErrCacheMiss).Once().Run(func(_ mock.Arguments) { + fixtures.mockCache.RedisClient.On("Get", mock.Anything, mock.Anything).Return(cacheutil.ErrCacheMiss).Once().Run(func(args mock.Arguments) { err := cache.SetGitReferences("test-repo", *GitRefCacheItemToReferences([][2]string{{"test-repo", "ref: test"}})) require.NoError(t, err) }).On("Get", mock.Anything, mock.Anything).Return(nil) @@ -511,7 +525,7 @@ func TestGetOrLockGitReferences(t *testing.T) { lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) require.NoError(t, err) assert.NotEqual(t, "test-lock-id", lockId) - assert.Empty(t, lockId, "Lock id should not be set") + assert.Equal(t, "", lockId, "Lock id should not be set") fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 2, ExternalGets: 2}) }) @@ -527,7 +541,7 @@ func TestGetOrLockGitReferences(t *testing.T) { lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) require.NoError(t, err) assert.Equal(t, "test-lock-id", lockId) - assert.NotEmpty(t, lockId, "Lock id should be set") + assert.NotEqual(t, "", lockId, "Lock id should be set") cache.revisionCacheLockTimeout = 10 * time.Second fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1}) }) @@ -544,7 +558,7 @@ func TestGetOrLockGitReferences(t *testing.T) { lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) require.NoError(t, err) assert.Equal(t, "test-lock-id", lockId) - assert.NotEmpty(t, lockId, "Lock id should be set") + assert.NotEqual(t, "", lockId, "Lock id should be set") fixtures.mockCache.RedisClient.AssertNumberOfCalls(t, "Set", 2) fixtures.mockCache.RedisClient.AssertNumberOfCalls(t, "Get", 4) }) @@ -566,7 +580,7 @@ func TestUnlockGitReferences(t *testing.T) { lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) require.NoError(t, err) assert.Equal(t, "test-lock-id", lockId) - assert.NotEmpty(t, lockId, "Lock id should be set") + assert.NotEqual(t, "", lockId, "Lock id should be set") // Release lock err = cache.UnlockGitReferences("test-repo", lockId) require.NoError(t, err) @@ -599,14 +613,14 @@ func TestRevisionChartDetails(t *testing.T) { t.Cleanup(fixtures.mockCache.StopRedisCallback) details, err := fixtures.cache.GetRevisionChartDetails("test-repo", "test-revision", "v1.0.0") require.ErrorIs(t, err, ErrCacheMiss) - assert.Equal(t, &v1alpha1.ChartDetails{}, details) + assert.Equal(t, &appv1.ChartDetails{}, details) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1}) }) t.Run("GetRevisionChartDetails cache miss local", func(t *testing.T) { fixtures := newFixtures() t.Cleanup(fixtures.mockCache.StopRedisCallback) cache := fixtures.cache - expectedItem := &v1alpha1.ChartDetails{ + expectedItem := &appv1.ChartDetails{ Description: "test-chart", Home: "v1.0.0", Maintainers: []string{"test-maintainer"}, @@ -626,7 +640,7 @@ func TestRevisionChartDetails(t *testing.T) { fixtures := newFixtures() t.Cleanup(fixtures.mockCache.StopRedisCallback) cache := fixtures.cache - expectedItem := &v1alpha1.ChartDetails{ + expectedItem := &appv1.ChartDetails{ Description: "test-chart", Home: "v1.0.0", Maintainers: []string{"test-maintainer"}, @@ -645,7 +659,7 @@ func TestRevisionChartDetails(t *testing.T) { t.Run("SetRevisionChartDetails", func(t *testing.T) { fixtures := newFixtures() t.Cleanup(fixtures.mockCache.StopRedisCallback) - expectedItem := &v1alpha1.ChartDetails{ + expectedItem := &appv1.ChartDetails{ Description: "test-chart", Home: "v1.0.0", Maintainers: []string{"test-maintainer"}, diff --git a/reposerver/cache/mocks/reposervercache.go b/reposerver/cache/mocks/reposervercache.go index d96557c856..ddc71510e7 100644 --- a/reposerver/cache/mocks/reposervercache.go +++ b/reposerver/cache/mocks/reposervercache.go @@ -8,8 +8,8 @@ import ( "github.com/redis/go-redis/v9" "github.com/stretchr/testify/mock" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - cacheutilmocks "github.com/argoproj/argo-cd/v3/util/cache/mocks" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + cacheutilmocks "github.com/argoproj/argo-cd/v2/util/cache/mocks" ) type MockCacheType int diff --git a/reposerver/gpgwatcher.go b/reposerver/gpgwatcher.go index 6d0215843e..5b43d6a24a 100644 --- a/reposerver/gpgwatcher.go +++ b/reposerver/gpgwatcher.go @@ -1,7 +1,6 @@ package reposerver import ( - "errors" "fmt" "path" "time" @@ -9,7 +8,7 @@ import ( "github.com/fsnotify/fsnotify" log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/util/gpg" + "github.com/argoproj/argo-cd/v2/util/gpg" ) const maxRecreateRetries = 5 @@ -47,14 +46,15 @@ func StartGPGWatcher(sourcePath string) error { if err != nil { log.Errorf("Error re-creating watcher on %s: %v", sourcePath, err) if attempt < maxRecreateRetries { - attempt++ + attempt += 1 log.Infof("Retrying to re-create watcher, attempt %d of %d", attempt, maxRecreateRetries) time.Sleep(1 * time.Second) continue + } else { + log.Errorf("Maximum retries exceeded.") + close(done) + return } - log.Errorf("Maximum retries exceeded.") - close(done) - return } break } @@ -86,5 +86,5 @@ func StartGPGWatcher(sourcePath string) error { return fmt.Errorf("failed to add a new source to the watcher: %w", err) } <-done - return errors.New("abnormal termination of GPG watcher, refusing to continue") + return fmt.Errorf("Abnormal termination of GPG watcher, refusing to continue.") } diff --git a/reposerver/metrics/githandlers.go b/reposerver/metrics/githandlers.go index b226f3f2a1..09a0591002 100644 --- a/reposerver/metrics/githandlers.go +++ b/reposerver/metrics/githandlers.go @@ -7,8 +7,8 @@ import ( "golang.org/x/sync/semaphore" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/git" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/git" ) var ( diff --git a/reposerver/metrics/githandlers_test.go b/reposerver/metrics/githandlers_test.go index c59b050970..e2eb03dca1 100644 --- a/reposerver/metrics/githandlers_test.go +++ b/reposerver/metrics/githandlers_test.go @@ -74,7 +74,7 @@ func TestEdgeCasesAndErrorHandling(t *testing.T) { } func TestSemaphoreFunctionality(t *testing.T) { - t.Setenv("ARGOCD_GIT_LSREMOTE_PARALLELISM_LIMIT", "1") + os.Setenv("ARGOCD_GIT_LSREMOTE_PARALLELISM_LIMIT", "1") tests := []struct { name string diff --git a/reposerver/repository/chart.go b/reposerver/repository/chart.go index cf81388904..3424db4b51 100644 --- a/reposerver/repository/chart.go +++ b/reposerver/repository/chart.go @@ -6,7 +6,7 @@ import ( "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func getChartDetails(chartYAML string) (*v1alpha1.ChartDetails, error) { diff --git a/reposerver/repository/chart_test.go b/reposerver/repository/chart_test.go index 6424d1bfa8..3e1bccfa46 100644 --- a/reposerver/repository/chart_test.go +++ b/reposerver/repository/chart_test.go @@ -14,9 +14,9 @@ version: 0.0.0` cd, err := getChartDetails(chart1) require.NoError(t, err) - assert.Empty(t, cd.Description) + assert.Equal(t, "", cd.Description) assert.Equal(t, cd.Maintainers, []string(nil)) - assert.Empty(t, cd.Home) + assert.Equal(t, "", cd.Home) } func Test_getChartDetailsSet(t *testing.T) { diff --git a/reposerver/repository/lock.go b/reposerver/repository/lock.go index e180773023..fa8da9c3e5 100644 --- a/reposerver/repository/lock.go +++ b/reposerver/repository/lock.go @@ -5,7 +5,7 @@ import ( "io" "sync" - utilio "github.com/argoproj/argo-cd/v3/util/io" + ioutil "github.com/argoproj/argo-cd/v2/util/io" ) func NewRepositoryLock() *repositoryLock { @@ -27,7 +27,7 @@ func (r *repositoryLock) Lock(path string, revision string, allowConcurrent bool } r.lock.Unlock() - closer := utilio.NewCloser(func() error { + closer := ioutil.NewCloser(func() error { state.cond.L.Lock() notify := false state.processCount-- @@ -68,10 +68,11 @@ func (r *repositoryLock) Lock(path string, revision string, allowConcurrent bool state.processCount++ state.cond.L.Unlock() return closer, nil + } else { + state.cond.Wait() + // wait when all in-flight processes of this revision complete and try again + state.cond.L.Unlock() } - state.cond.Wait() - // wait when all in-flight processes of this revision complete and try again - state.cond.L.Unlock() } } diff --git a/reposerver/repository/lock_test.go b/reposerver/repository/lock_test.go index 799476eaac..db2bf2558a 100644 --- a/reposerver/repository/lock_test.go +++ b/reposerver/repository/lock_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" - utilio "github.com/argoproj/argo-cd/v3/util/io" + util "github.com/argoproj/argo-cd/v2/util/io" ) // execute given action and return false if action have not completed within 1 second @@ -29,7 +29,7 @@ func lockQuickly(action func() (io.Closer, error)) (io.Closer, bool) { func numberOfInits(initializedTimes *int) func() (io.Closer, error) { return func() (io.Closer, error) { *initializedTimes++ - return utilio.NopCloser, nil + return util.NopCloser, nil } } @@ -55,9 +55,9 @@ func TestLock_SameRevision(t *testing.T) { assert.Equal(t, 1, initializedTimes) - utilio.Close(closer1) + util.Close(closer1) - utilio.Close(closer2) + util.Close(closer2) } func TestLock_DifferentRevisions(t *testing.T) { @@ -81,7 +81,7 @@ func TestLock_DifferentRevisions(t *testing.T) { return } - utilio.Close(closer1) + util.Close(closer1) _, done = lockQuickly(func() (io.Closer, error) { return lock.Lock("myRepo", "2", true, init) @@ -113,7 +113,7 @@ func TestLock_NoConcurrentWithSameRevision(t *testing.T) { return } - utilio.Close(closer1) + util.Close(closer1) } func TestLock_FailedInitialization(t *testing.T) { @@ -121,7 +121,7 @@ func TestLock_FailedInitialization(t *testing.T) { closer1, done := lockQuickly(func() (io.Closer, error) { return lock.Lock("myRepo", "1", true, func() (io.Closer, error) { - return utilio.NopCloser, errors.New("failed") + return util.NopCloser, errors.New("failed") }) }) @@ -133,7 +133,7 @@ func TestLock_FailedInitialization(t *testing.T) { closer2, done := lockQuickly(func() (io.Closer, error) { return lock.Lock("myRepo", "1", true, func() (io.Closer, error) { - return utilio.NopCloser, nil + return util.NopCloser, nil }) }) @@ -141,7 +141,7 @@ func TestLock_FailedInitialization(t *testing.T) { return } - utilio.Close(closer2) + util.Close(closer2) } func TestLock_SameRevisionFirstNotConcurrent(t *testing.T) { @@ -166,5 +166,5 @@ func TestLock_SameRevisionFirstNotConcurrent(t *testing.T) { assert.Equal(t, 1, initializedTimes) - utilio.Close(closer1) + util.Close(closer1) } diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index 0ec90e19c6..c579eeb5b6 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -16,21 +16,23 @@ import ( "strings" "time" + "github.com/Masterminds/semver/v3" "github.com/TomOnTime/utfutil" "github.com/argoproj/gitops-engine/pkg/utils/kube" textutils "github.com/argoproj/gitops-engine/pkg/utils/text" - "github.com/argoproj/pkg/v2/sync" + "github.com/argoproj/pkg/sync" jsonpatch "github.com/evanphx/json-patch" gogit "github.com/go-git/go-git/v5" "github.com/golang/protobuf/ptypes/empty" "github.com/google/go-jsonnet" "github.com/google/uuid" - grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/retry" + grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry" log "github.com/sirupsen/logrus" "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" @@ -38,46 +40,53 @@ import ( kubeyaml "k8s.io/apimachinery/pkg/util/yaml" "sigs.k8s.io/yaml" - pluginclient "github.com/argoproj/argo-cd/v3/cmpserver/apiclient" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/reposerver/cache" - "github.com/argoproj/argo-cd/v3/reposerver/metrics" - "github.com/argoproj/argo-cd/v3/util/app/discovery" - apppathutil "github.com/argoproj/argo-cd/v3/util/app/path" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/cmp" - "github.com/argoproj/argo-cd/v3/util/git" - "github.com/argoproj/argo-cd/v3/util/glob" - "github.com/argoproj/argo-cd/v3/util/gpg" - "github.com/argoproj/argo-cd/v3/util/grpc" - "github.com/argoproj/argo-cd/v3/util/helm" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/io/files" - pathutil "github.com/argoproj/argo-cd/v3/util/io/path" - "github.com/argoproj/argo-cd/v3/util/kustomize" - "github.com/argoproj/argo-cd/v3/util/manifeststream" - "github.com/argoproj/argo-cd/v3/util/text" - "github.com/argoproj/argo-cd/v3/util/versions" + pluginclient "github.com/argoproj/argo-cd/v2/cmpserver/apiclient" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/reposerver/cache" + "github.com/argoproj/argo-cd/v2/reposerver/metrics" + "github.com/argoproj/argo-cd/v2/util/app/discovery" + apppathutil "github.com/argoproj/argo-cd/v2/util/app/path" + argopath "github.com/argoproj/argo-cd/v2/util/app/path" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/cmp" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/glob" + "github.com/argoproj/argo-cd/v2/util/gpg" + "github.com/argoproj/argo-cd/v2/util/grpc" + "github.com/argoproj/argo-cd/v2/util/helm" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/io/files" + pathutil "github.com/argoproj/argo-cd/v2/util/io/path" + "github.com/argoproj/argo-cd/v2/util/kustomize" + "github.com/argoproj/argo-cd/v2/util/manifeststream" + "github.com/argoproj/argo-cd/v2/util/text" ) const ( cachedManifestGenerationPrefix = "Manifest generation error (cached)" helmDepUpMarkerFile = ".argocd-helm-dep-up" + allowConcurrencyFile = ".argocd-allow-concurrency" repoSourceFile = ".argocd-source.yaml" appSourceFile = ".argocd-source-%s.yaml" ociPrefix = "oci://" ) -var ErrExceededMaxCombinedManifestFileSize = errors.New("exceeded max combined manifest file size") +var ( + ErrExceededMaxCombinedManifestFileSize = errors.New("exceeded max combined manifest file size") + // helmConcurrencyDefault if true then helm concurrent manifest generation is enabled + // TODO: remove env variable and usage of .argocd-allow-concurrency once we are sure that it is safe to enable it by default + helmConcurrencyDefault = env.ParseBoolFromEnv("ARGOCD_HELM_ALLOW_CONCURRENCY", false) +) // Service implements ManifestService interface type Service struct { gitCredsStore git.CredsStore rootDir string - gitRepoPaths utilio.TempPaths - chartPaths utilio.TempPaths + gitRepoPaths io.TempPaths + chartPaths io.TempPaths gitRepoInitializer func(rootPath string) goio.Closer repoLock *repositoryLock cache *cache.Cache @@ -109,8 +118,6 @@ type RepoServerInitConstants struct { CMPUseManifestGeneratePaths bool } -var manifestGenerateLock = sync.NewKeyLock() - // NewService returns a new instance of the Manifest service func NewService(metricsServer *metrics.MetricsServer, cache *cache.Cache, initConstants RepoServerInitConstants, resourceTracking argo.ResourceTracking, gitCredsStore git.CredsStore, rootDir string) *Service { var parallelismLimitSemaphore *semaphore.Weighted @@ -118,8 +125,8 @@ func NewService(metricsServer *metrics.MetricsServer, cache *cache.Cache, initCo parallelismLimitSemaphore = semaphore.NewWeighted(initConstants.ParallelismLimit) } repoLock := NewRepositoryLock() - gitRandomizedPaths := utilio.NewRandomizedTempPaths(rootDir) - helmRandomizedPaths := utilio.NewRandomizedTempPaths(rootDir) + gitRandomizedPaths := io.NewRandomizedTempPaths(rootDir) + helmRandomizedPaths := io.NewRandomizedTempPaths(rootDir) return &Service{ parallelismLimitSemaphore: parallelismLimitSemaphore, repoLock: repoLock, @@ -169,14 +176,14 @@ func (s *Service) Init() error { s.gitRepoPaths.Add(git.NormalizeGitURL(remotes[0].Config().URLs[0]), fullPath) } } - utilio.Close(closer) + io.Close(closer) } // remove read permissions since no-one should be able to list the directories return os.Chmod(s.rootDir, 0o300) } // ListRefs List a subset of the refs (currently, branches and tags) of a git repo -func (s *Service) ListRefs(_ context.Context, q *apiclient.ListRefsRequest) (*apiclient.Refs, error) { +func (s *Service) ListRefs(ctx context.Context, q *apiclient.ListRefsRequest) (*apiclient.Refs, error) { gitClient, err := s.newClient(q.Repo) if err != nil { return nil, fmt.Errorf("error creating git client: %w", err) @@ -219,7 +226,7 @@ func (s *Service) ListApps(ctx context.Context, q *apiclient.ListAppsRequest) (* return nil, fmt.Errorf("error acquiring repository lock: %w", err) } - defer utilio.Close(closer) + defer io.Close(closer) apps, err := discovery.Discover(ctx, gitClient.Root(), gitClient.Root(), q.EnabledSourceTypes, s.initConstants.CMPTarExcludedGlobs, []string{}) if err != nil { return nil, fmt.Errorf("error discovering applications: %w", err) @@ -233,7 +240,7 @@ func (s *Service) ListApps(ctx context.Context, q *apiclient.ListAppsRequest) (* } // ListPlugins lists the contents of a GitHub repo -func (s *Service) ListPlugins(_ context.Context, _ *empty.Empty) (*apiclient.PluginList, error) { +func (s *Service) ListPlugins(ctx context.Context, _ *empty.Empty) (*apiclient.PluginList, error) { pluginSockFilePath := common.GetPluginSockFilePath() sockFiles, err := os.ReadDir(pluginSockFilePath) @@ -351,11 +358,11 @@ func (s *Service) runRepoOperation( if err != nil { return err } - defer utilio.Close(closer) + defer io.Close(closer) if !s.initConstants.AllowOutOfBoundsSymlinks { - err := apppathutil.CheckOutOfBoundsSymlinks(chartPath) + err := argopath.CheckOutOfBoundsSymlinks(chartPath) if err != nil { - oobError := &apppathutil.OutOfBoundsSymlinkError{} + oobError := &argopath.OutOfBoundsSymlinkError{} if errors.As(err, &oobError) { log.WithFields(log.Fields{ common.SecurityField: common.SecurityHigh, @@ -364,83 +371,86 @@ func (s *Service) runRepoOperation( "file": oobError.File, }).Warn("chart contains out-of-bounds symlink") return fmt.Errorf("chart contains out-of-bounds symlinks. file: %s", oobError.File) + } else { + return err } - return err } } return operation(chartPath, revision, revision, func() (*operationContext, error) { return &operationContext{chartPath, ""}, nil }) - } - closer, err := s.repoLock.Lock(gitClient.Root(), revision, settings.allowConcurrent, func() (goio.Closer, error) { - return s.checkoutRevision(gitClient, revision, s.initConstants.SubmoduleEnabled) - }) - if err != nil { - return err - } - - defer utilio.Close(closer) - - if !s.initConstants.AllowOutOfBoundsSymlinks { - err := apppathutil.CheckOutOfBoundsSymlinks(gitClient.Root()) - if err != nil { - oobError := &apppathutil.OutOfBoundsSymlinkError{} - if errors.As(err, &oobError) { - log.WithFields(log.Fields{ - common.SecurityField: common.SecurityHigh, - "repo": repo.Repo, - "revision": revision, - "file": oobError.File, - }).Warn("repository contains out-of-bounds symlink") - return fmt.Errorf("repository contains out-of-bounds symlinks. file: %s", oobError.File) - } - return err - } - } - - var commitSHA string - if hasMultipleSources { - commitSHA = revision } else { - commit, err := gitClient.CommitSHA() + closer, err := s.repoLock.Lock(gitClient.Root(), revision, settings.allowConcurrent, func() (goio.Closer, error) { + return s.checkoutRevision(gitClient, revision, s.initConstants.SubmoduleEnabled) + }) if err != nil { - return fmt.Errorf("failed to get commit SHA: %w", err) - } - commitSHA = commit - } - - // double-check locking - if !settings.noCache { - if ok, err := cacheFn(revision, repoRefs, false); ok { return err } - } - // Here commitSHA refers to the SHA of the actual commit, whereas revision refers to the branch/tag name etc - // We use the commitSHA to generate manifests and store them in cache, and revision to retrieve them from cache - return operation(gitClient.Root(), commitSHA, revision, func() (*operationContext, error) { - var signature string - if verifyCommit { - // When the revision is an annotated tag, we need to pass the unresolved revision (i.e. the tag name) - // to the verification routine. For everything else, we work with the SHA that the target revision is - // pointing to (i.e. the resolved revision). - var rev string - if gitClient.IsAnnotatedTag(revision) { - rev = unresolvedRevision - } else { - rev = revision + defer io.Close(closer) + + if !s.initConstants.AllowOutOfBoundsSymlinks { + err := argopath.CheckOutOfBoundsSymlinks(gitClient.Root()) + if err != nil { + oobError := &argopath.OutOfBoundsSymlinkError{} + if errors.As(err, &oobError) { + log.WithFields(log.Fields{ + common.SecurityField: common.SecurityHigh, + "repo": repo.Repo, + "revision": revision, + "file": oobError.File, + }).Warn("repository contains out-of-bounds symlink") + return fmt.Errorf("repository contains out-of-bounds symlinks. file: %s", oobError.File) + } else { + return err + } } - signature, err = gitClient.VerifyCommitSignature(rev) + } + + var commitSHA string + if hasMultipleSources { + commitSHA = revision + } else { + commit, err := gitClient.CommitSHA() + if err != nil { + return fmt.Errorf("failed to get commit SHA: %w", err) + } + commitSHA = commit + } + + // double-check locking + if !settings.noCache { + if ok, err := cacheFn(revision, repoRefs, false); ok { + return err + } + } + + // Here commitSHA refers to the SHA of the actual commit, whereas revision refers to the branch/tag name etc + // We use the commitSHA to generate manifests and store them in cache, and revision to retrieve them from cache + return operation(gitClient.Root(), commitSHA, revision, func() (*operationContext, error) { + var signature string + if verifyCommit { + // When the revision is an annotated tag, we need to pass the unresolved revision (i.e. the tag name) + // to the verification routine. For everything else, we work with the SHA that the target revision is + // pointing to (i.e. the resolved revision). + var rev string + if gitClient.IsAnnotatedTag(revision) { + rev = unresolvedRevision + } else { + rev = revision + } + signature, err = gitClient.VerifyCommitSignature(rev) + if err != nil { + return nil, err + } + } + appPath, err := argopath.Path(gitClient.Root(), source.Path) if err != nil { return nil, err } - } - appPath, err := apppathutil.Path(gitClient.Root(), source.Path) - if err != nil { - return nil, err - } - return &operationContext{appPath, signature}, nil - }) + return &operationContext{appPath, signature}, nil + }) + } } func getRepoSanitizerRegex(rootDir string) *regexp.Regexp { @@ -487,7 +497,7 @@ func resolveReferencedSources(hasMultipleSources bool, source *v1alpha1.Applicat return nil, fmt.Errorf("source referenced %q, which is not one of the available sources (%s)", refVar, strings.Join(refKeys, ", ")) } if refSourceMapping.Chart != "" { - return nil, errors.New("source has a 'chart' field defined, but Helm charts are not yet not supported for 'ref' sources") + return nil, fmt.Errorf("source has a 'chart' field defined, but Helm charts are not yet not supported for 'ref' sources") } normalizedRepoURL := git.NormalizeGitURL(refSourceMapping.Repo.Repo) _, ok = repoRefs[normalizedRepoURL] @@ -531,7 +541,7 @@ func (s *Service) GenerateManifest(ctx context.Context, q *apiclient.ManifestReq operation := func(repoRoot, commitSHA, cacheKey string, ctxSrc operationContextSrc) error { // do not generate manifests if Path and Chart fields are not set for a source in Multiple Sources if q.HasMultipleSources && q.ApplicationSource.Path == "" && q.ApplicationSource.Chart == "" { - log.WithFields(map[string]any{ + log.WithFields(map[string]interface{}{ "source": q.ApplicationSource, }).Debugf("not generating manifests as path and chart fields are empty") res = &apiclient.ManifestResponse{ @@ -594,22 +604,23 @@ func (s *Service) GenerateManifestWithFiles(stream apiclient.RepoServerService_G } if !s.initConstants.AllowOutOfBoundsSymlinks { - err := apppathutil.CheckOutOfBoundsSymlinks(workDir) + err := argopath.CheckOutOfBoundsSymlinks(workDir) if err != nil { - oobError := &apppathutil.OutOfBoundsSymlinkError{} + oobError := &argopath.OutOfBoundsSymlinkError{} if errors.As(err, &oobError) { log.WithFields(log.Fields{ common.SecurityField: common.SecurityHigh, "file": oobError.File, }).Warn("streamed files contains out-of-bounds symlink") return fmt.Errorf("streamed files contains out-of-bounds symlinks. file: %s", oobError.File) + } else { + return err } - return err } } promise := s.runManifestGen(stream.Context(), workDir, "streamed", metadata.Checksum, func() (*operationContext, error) { - appPath, err := apppathutil.Path(workDir, req.ApplicationSource.Path) + appPath, err := argopath.Path(workDir, req.ApplicationSource.Path) if err != nil { return nil, fmt.Errorf("failed to get app path: %w", err) } @@ -732,7 +743,7 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, return } if refSourceMapping.Chart != "" { - ch.errCh <- errors.New("source has a 'chart' field defined, but Helm charts are not yet not supported for 'ref' sources") + ch.errCh <- fmt.Errorf("source has a 'chart' field defined, but Helm charts are not yet not supported for 'ref' sources") return } normalizedRepoURL := git.NormalizeGitURL(refSourceMapping.Repo.Repo) @@ -771,9 +782,9 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, // Symlink check must happen after acquiring lock. if !s.initConstants.AllowOutOfBoundsSymlinks { - err := apppathutil.CheckOutOfBoundsSymlinks(gitClient.Root()) + err := argopath.CheckOutOfBoundsSymlinks(gitClient.Root()) if err != nil { - oobError := &apppathutil.OutOfBoundsSymlinkError{} + oobError := &argopath.OutOfBoundsSymlinkError{} if errors.As(err, &oobError) { log.WithFields(log.Fields{ common.SecurityField: common.SecurityHigh, @@ -783,9 +794,10 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, }).Warn("repository contains out-of-bounds symlink") ch.errCh <- fmt.Errorf("repository contains out-of-bounds symlinks. file: %s", oobError.File) return + } else { + ch.errCh <- err + return } - ch.errCh <- err - return } } @@ -920,7 +932,6 @@ func (s *Service) getManifestCacheEntry(cacheKey string, q *apiclient.ManifestRe // Otherwise, manifest generation is still paused log.Infof("manifest error cache hit: %s/%s", q.ApplicationSource.String(), cacheKey) - // nolint:staticcheck // Error message constant is very old, best not to lowercase the first letter. cachedErrorResponse := fmt.Errorf(cachedManifestGenerationPrefix+": %s", res.MostRecentError) if firstInvocation { @@ -963,9 +974,9 @@ func getHelmRepos(appPath string, repositories []*v1alpha1.Repository, helmRepoC return nil, fmt.Errorf("error retrieving helm dependency repos: %w", err) } reposByName := make(map[string]*v1alpha1.Repository) - reposByURL := make(map[string]*v1alpha1.Repository) + reposByUrl := make(map[string]*v1alpha1.Repository) for _, repo := range repositories { - reposByURL[repo.Repo] = repo + reposByUrl[repo.Repo] = repo if repo.Name != "" { reposByName[repo.Name] = repo } @@ -974,7 +985,7 @@ func getHelmRepos(appPath string, repositories []*v1alpha1.Repository, helmRepoC repos := make([]helm.HelmRepository, 0) for _, dep := range dependencies { // find matching repo credentials by URL or name - repo, ok := reposByURL[dep.Repo] + repo, ok := reposByUrl[dep.Repo] if !ok && dep.Name != "" { repo, ok = reposByName[dep.Name] } @@ -988,7 +999,6 @@ func getHelmRepos(appPath string, repositories []*v1alpha1.Repository, helmRepoC repo.SSHPrivateKey = repositoryCredential.SSHPrivateKey repo.TLSClientCertData = repositoryCredential.TLSClientCertData repo.TLSClientCertKey = repositoryCredential.TLSClientCertKey - repo.UseAzureWorkloadIdentity = repositoryCredential.UseAzureWorkloadIdentity } else if repo.EnableOCI { // finally if repo is OCI and no credentials found, use the first OCI credential matching by hostname // see https://github.com/argoproj/argo-cd/issues/14636 @@ -998,7 +1008,6 @@ func getHelmRepos(appPath string, repositories []*v1alpha1.Repository, helmRepoC if _, err := url.Parse("oci://" + dep.Repo); err == nil && cred.EnableOCI && strings.HasPrefix(dep.Repo, cred.Repo) { repo.Username = cred.Username repo.Password = cred.Password - repo.UseAzureWorkloadIdentity = cred.UseAzureWorkloadIdentity break } } @@ -1056,6 +1065,15 @@ func sanitizeRepoName(repoName string) string { return strings.ReplaceAll(repoName, "/", "-") } +func isConcurrencyAllowed(appPath string) bool { + if _, err := os.Stat(path.Join(appPath, allowConcurrencyFile)); err == nil { + return true + } + return false +} + +var manifestGenerateLock = sync.NewKeyLock() + // runHelmBuild executes `helm dependency build` in a given path and ensures that it is executed only once // if multiple threads are trying to run it. // Multiple goroutines might process same helm app in one repo concurrently when repo server process multiple @@ -1087,7 +1105,13 @@ func isSourcePermitted(url string, repos []string) bool { return p.IsSourcePermitted(v1alpha1.ApplicationSource{RepoURL: url}) } -func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclient.ManifestRequest, isLocal bool, gitRepoPaths utilio.TempPaths) ([]*unstructured.Unstructured, string, error) { +func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclient.ManifestRequest, isLocal bool, gitRepoPaths io.TempPaths) ([]*unstructured.Unstructured, string, error) { + concurrencyAllowed := helmConcurrencyDefault || isConcurrencyAllowed(appPath) + if !concurrencyAllowed { + manifestGenerateLock.Lock(appPath) + defer manifestGenerateLock.Unlock(appPath) + } + // We use the app name as Helm's release name property, which must not // contain any underscore characters and must not exceed 53 characters. // We are not interested in the fully qualified application name while @@ -1206,7 +1230,12 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie return nil, "", err } - err = runHelmBuild(appPath, h) + if concurrencyAllowed { + err = runHelmBuild(appPath, h) + } else { + err = h.DependencyBuild() + } + if err != nil { var reposNotPermitted []string // We do a sanity check here to give a nicer error message in case any of the Helm repositories are not permitted by @@ -1244,7 +1273,7 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie // redactPaths removes temp repo paths, since those paths are randomized (and therefore not helpful for the user) and // sensitive (so not suitable for logging). It also replaces the path of the randomly-named values file which is used // to hold the `spec.source.helm.values` or `valuesObject` contents. -func redactPaths(s string, paths utilio.TempPaths, extraValuesPath pathutil.ResolvedFilePath) string { +func redactPaths(s string, paths io.TempPaths, extraValuesPath pathutil.ResolvedFilePath) string { if paths == nil { return s } @@ -1265,7 +1294,7 @@ func getResolvedValueFiles( allowedValueFilesSchemas []string, rawValueFiles []string, refSources map[string]*v1alpha1.RefTarget, - gitRepoPaths utilio.TempPaths, + gitRepoPaths io.TempPaths, ignoreMissingValueFiles bool, ) ([]pathutil.ResolvedFilePath, error) { var resolvedValueFiles []pathutil.ResolvedFilePath @@ -1309,7 +1338,7 @@ func getResolvedRefValueFile( env *v1alpha1.Env, allowedValueFilesSchemas []string, refSourceRepo string, - gitRepoPaths utilio.TempPaths, + gitRepoPaths io.TempPaths, ) (pathutil.ResolvedFilePath, error) { pathStrings := strings.Split(rawValueFile, "/") repoPath := gitRepoPaths.GetPathIfExists(git.NormalizeGitURL(refSourceRepo)) @@ -1389,7 +1418,7 @@ func WithCMPUseManifestGeneratePaths(enabled bool) GenerateManifestOpt { } // 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 utilio.TempPaths, opts ...GenerateManifestOpt) (*apiclient.ManifestResponse, error) { +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...) var targetObjs []*unstructured.Unstructured @@ -1452,22 +1481,21 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, } var targets []*unstructured.Unstructured - switch { - case obj.IsList(): + if obj.IsList() { err = obj.EachListItem(func(object runtime.Object) error { unstructuredObj, ok := object.(*unstructured.Unstructured) if ok { targets = append(targets, unstructuredObj) return nil } - return errors.New("resource list item has unexpected type") + return fmt.Errorf("resource list item has unexpected type") }) if err != nil { return nil, err } - case isNullList(obj): + } else if isNullList(obj) { // noop - default: + } else { targets = []*unstructured.Unstructured{obj} } @@ -1499,7 +1527,6 @@ func newEnv(q *apiclient.ManifestRequest, revision string) *v1alpha1.Env { return &v1alpha1.Env{ &v1alpha1.EnvEntry{Name: "ARGOCD_APP_NAME", Value: q.AppName}, &v1alpha1.EnvEntry{Name: "ARGOCD_APP_NAMESPACE", Value: q.Namespace}, - &v1alpha1.EnvEntry{Name: "ARGOCD_APP_PROJECT_NAME", Value: q.ProjectName}, &v1alpha1.EnvEntry{Name: "ARGOCD_APP_REVISION", Value: revision}, &v1alpha1.EnvEntry{Name: "ARGOCD_APP_REVISION_SHORT", Value: shortRevision}, &v1alpha1.EnvEntry{Name: "ARGOCD_APP_REVISION_SHORT_8", Value: shortRevision8}, @@ -1543,12 +1570,11 @@ func mergeSourceParameters(source *v1alpha1.ApplicationSource, path, appName str for _, filename := range overrides { info, err := os.Stat(filename) - switch { - case os.IsNotExist(err): + if os.IsNotExist(err) { continue - case info != nil && info.IsDir(): + } else if info != nil && info.IsDir() { continue - case err != nil: + } else if err != nil { // filename should be part of error message here return err } @@ -1650,7 +1676,7 @@ func findManifests(logCtx *log.Entry, appPath string, repoRoot string, env *v1al if !discovery.IsManifestGenerationEnabled(v1alpha1.ApplicationSourceTypeDirectory, enabledManifestGeneration) { continue } - vm, err := makeJsonnetVM(appPath, repoRoot, directory.Jsonnet, env) + vm, err := makeJsonnetVm(appPath, repoRoot, directory.Jsonnet, env) if err != nil { return nil, err } @@ -1673,7 +1699,7 @@ func findManifests(logCtx *log.Entry, appPath string, repoRoot string, env *v1al objs = append(objs, &jsonObj) } } else { - err := getObjsFromYAMLOrJSON(logCtx, manifestPath, manifestFileInfo.Name(), &objs) + err := getObjsFromYAMLOrJson(logCtx, manifestPath, manifestFileInfo.Name(), &objs) if err != nil { return nil, err } @@ -1682,8 +1708,8 @@ func findManifests(logCtx *log.Entry, appPath string, repoRoot string, env *v1al return objs, nil } -// getObjsFromYAMLOrJSON unmarshals the given yaml or json file and appends it to the given list of objects. -func getObjsFromYAMLOrJSON(logCtx *log.Entry, manifestPath string, filename string, objs *[]*unstructured.Unstructured) error { +// getObjsFromYAMLOrJson unmarshals the given yaml or json file and appends it to the given list of objects. +func getObjsFromYAMLOrJson(logCtx *log.Entry, manifestPath string, filename string, objs *[]*unstructured.Unstructured) error { reader, err := utfutil.OpenFile(manifestPath, utfutil.UTF8) if err != nil { return status.Errorf(codes.FailedPrecondition, "Failed to open %q", manifestPath) @@ -1871,7 +1897,7 @@ func getPotentiallyValidManifests(logCtx *log.Entry, appPath string, repoRoot st return potentiallyValidManifests, nil } -func makeJsonnetVM(appPath string, repoRoot string, sourceJsonnet v1alpha1.ApplicationSourceJsonnet, env *v1alpha1.Env) (*jsonnet.VM, error) { +func makeJsonnetVm(appPath string, repoRoot string, sourceJsonnet v1alpha1.ApplicationSourceJsonnet, env *v1alpha1.Env) (*jsonnet.VM, error) { vm := jsonnet.MakeVM() for i, j := range sourceJsonnet.TLAs { sourceJsonnet.TLAs[i].Value = env.Envsubst(j.Value) @@ -1928,7 +1954,7 @@ func getPluginParamEnvs(envVars []string, plugin *v1alpha1.ApplicationSourcePlug for i, v := range env { parsedVar, err := v1alpha1.NewEnvEntry(v) if err != nil { - return nil, errors.New("failed to parse env vars") + return nil, fmt.Errorf("failed to parse env vars") } parsedEnv[i] = parsedVar } @@ -1961,7 +1987,7 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, p if err != nil { return nil, err } - defer utilio.Close(conn) + defer io.Close(conn) rootPath := repoPath if useManifestGeneratePaths { @@ -2087,7 +2113,7 @@ func (s *Service) createGetAppDetailsCacheHandler(res *apiclient.RepoAppDetailsR } } -func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath string, repoRoot string, q *apiclient.RepoServerAppDetailsQuery, gitRepoPaths utilio.TempPaths) error { +func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath string, repoRoot string, q *apiclient.RepoServerAppDetailsQuery, gitRepoPaths io.TempPaths) error { var selectedValueFiles []string var availableValueFiles []string @@ -2214,10 +2240,10 @@ func populatePluginAppDetails(ctx context.Context, res *apiclient.RepoAppDetails res.Plugin = &apiclient.PluginAppSpec{} envVars := []string{ - "ARGOCD_APP_NAME=" + q.AppName, - "ARGOCD_APP_SOURCE_REPO_URL=" + q.Repo.Repo, - "ARGOCD_APP_SOURCE_PATH=" + q.Source.Path, - "ARGOCD_APP_SOURCE_TARGET_REVISION=" + q.Source.TargetRevision, + fmt.Sprintf("ARGOCD_APP_NAME=%s", q.AppName), + fmt.Sprintf("ARGOCD_APP_SOURCE_REPO_URL=%s", q.Repo.Repo), + fmt.Sprintf("ARGOCD_APP_SOURCE_PATH=%s", q.Source.Path), + fmt.Sprintf("ARGOCD_APP_SOURCE_TARGET_REVISION=%s", q.Source.TargetRevision), } env, err := getPluginParamEnvs(envVars, q.Source.Plugin) @@ -2234,7 +2260,7 @@ func populatePluginAppDetails(ctx context.Context, res *apiclient.RepoAppDetails if err != nil { return fmt.Errorf("failed to detect CMP for app: %w", err) } - defer utilio.Close(conn) + defer io.Close(conn) parametersAnnouncementStream, err := cmpClient.GetParametersAnnouncement(ctx, grpc_retry.Disable()) if err != nil { @@ -2257,8 +2283,8 @@ func populatePluginAppDetails(ctx context.Context, res *apiclient.RepoAppDetails return nil } -func (s *Service) GetRevisionMetadata(_ context.Context, q *apiclient.RepoServerRevisionMetadataRequest) (*v1alpha1.RevisionMetadata, error) { - if !git.IsCommitSHA(q.Revision) && !git.IsTruncatedCommitSHA(q.Revision) { +func (s *Service) GetRevisionMetadata(ctx context.Context, q *apiclient.RepoServerRevisionMetadataRequest) (*v1alpha1.RevisionMetadata, error) { + if !(git.IsCommitSHA(q.Revision) || git.IsTruncatedCommitSHA(q.Revision)) { return nil, fmt.Errorf("revision %s must be resolved", q.Revision) } metadata, err := s.cache.GetRevisionMetadata(q.Repo.Repo, q.Revision) @@ -2268,14 +2294,15 @@ func (s *Service) GetRevisionMetadata(_ context.Context, q *apiclient.RepoServer // and re-generate the meta data. Otherwise, if there is signature info // in the metadata, but none was requested, we remove it from the data // that we return. - if !q.CheckSignature || metadata.SignatureInfo != "" { + if q.CheckSignature && metadata.SignatureInfo == "" { + log.Infof("revision metadata cache hit, but need to regenerate due to missing signature info: %s/%s", q.Repo.Repo, q.Revision) + } else { log.Infof("revision metadata cache hit: %s/%s", q.Repo.Repo, q.Revision) if !q.CheckSignature { metadata.SignatureInfo = "" } return metadata, nil } - log.Infof("revision metadata cache hit, but need to regenerate due to missing signature info: %s/%s", q.Repo.Repo, q.Revision) } else { if !errors.Is(err, cache.ErrCacheMiss) { log.Warnf("revision metadata cache error %s/%s: %v", q.Repo.Repo, q.Revision, err) @@ -2299,7 +2326,7 @@ func (s *Service) GetRevisionMetadata(_ context.Context, q *apiclient.RepoServer return nil, fmt.Errorf("error acquiring repo lock: %w", err) } - defer utilio.Close(closer) + defer io.Close(closer) m, err := gitClient.RevisionMetadata(q.Revision) if err != nil { @@ -2318,7 +2345,7 @@ func (s *Service) GetRevisionMetadata(_ context.Context, q *apiclient.RepoServer if cs != "" { vr := gpg.ParseGitCommitVerification(cs) if vr.Result == gpg.VerifyResultUnknown { - signatureInfo = "UNKNOWN signature: " + vr.Message + signatureInfo = fmt.Sprintf("UNKNOWN signature: %s", vr.Message) } else { signatureInfo = fmt.Sprintf("%s signature from %s key %s", vr.Result, vr.Cipher, gpg.KeyID(vr.KeyID)) } @@ -2333,16 +2360,17 @@ func (s *Service) GetRevisionMetadata(_ context.Context, q *apiclient.RepoServer } // GetRevisionChartDetails returns the helm chart details of a given version -func (s *Service) GetRevisionChartDetails(_ context.Context, q *apiclient.RepoServerRevisionChartDetailsRequest) (*v1alpha1.ChartDetails, error) { +func (s *Service) GetRevisionChartDetails(ctx context.Context, q *apiclient.RepoServerRevisionChartDetailsRequest) (*v1alpha1.ChartDetails, error) { details, err := s.cache.GetRevisionChartDetails(q.Repo.Repo, q.Name, q.Revision) if err == nil { log.Infof("revision chart details cache hit: %s/%s/%s", q.Repo.Repo, q.Name, q.Revision) return details, nil - } - if errors.Is(err, cache.ErrCacheMiss) { - log.Infof("revision metadata cache miss: %s/%s/%s", q.Repo.Repo, q.Name, q.Revision) } else { - log.Warnf("revision metadata cache error %s/%s/%s: %v", q.Repo.Repo, q.Name, q.Revision, err) + if errors.Is(err, cache.ErrCacheMiss) { + log.Infof("revision metadata cache miss: %s/%s/%s", q.Repo.Repo, q.Name, q.Revision) + } else { + log.Warnf("revision metadata cache error %s/%s/%s: %v", q.Repo.Repo, q.Name, q.Revision, err) + } } helmClient, revision, err := s.newHelmClientResolveRevision(q.Repo, q.Revision, q.Name, true) if err != nil { @@ -2352,7 +2380,7 @@ func (s *Service) GetRevisionChartDetails(_ context.Context, q *apiclient.RepoSe if err != nil { return nil, fmt.Errorf("error extracting chart: %w", err) } - defer utilio.Close(closer) + defer io.Close(closer) helmCmd, err := helm.NewCmdWithVersion(chartPath, q.Repo.EnableOCI, q.Repo.Proxy, q.Repo.NoProxy) if err != nil { return nil, fmt.Errorf("error creating helm cmd: %w", err) @@ -2404,37 +2432,40 @@ func (s *Service) newClientResolveRevision(repo *v1alpha1.Repository, revision s func (s *Service) newHelmClientResolveRevision(repo *v1alpha1.Repository, revision string, chart string, noRevisionCache bool) (helm.Client, string, error) { enableOCI := repo.EnableOCI || helm.IsHelmOciRepo(repo.Repo) helmClient := s.newHelmClient(repo.Repo, repo.GetHelmCreds(), enableOCI, repo.Proxy, repo.NoProxy, helm.WithIndexCache(s.cache), helm.WithChartPaths(s.chartPaths)) - - // Note: This check runs the risk of returning a version which is not found in the helm registry. - if versions.IsVersion(revision) { + if helm.IsVersion(revision) { return helmClient, revision, nil } + constraints, err := semver.NewConstraint(revision) + if err != nil { + return nil, "", fmt.Errorf("invalid revision '%s': %w", revision, err) + } - var tags []string if enableOCI { - var err error - tags, err = helmClient.GetTags(chart, noRevisionCache) + tags, err := helmClient.GetTags(chart, noRevisionCache) if err != nil { return nil, "", fmt.Errorf("unable to get tags: %w", err) } - } else { - index, err := helmClient.GetIndex(noRevisionCache, s.initConstants.HelmRegistryMaxIndexSize) + + version, err := tags.MaxVersion(constraints) if err != nil { - return nil, "", err + return nil, "", fmt.Errorf("no version for constraints: %w", err) } - entries, err := index.GetEntries(chart) - if err != nil { - return nil, "", err - } - tags = entries.Tags() + return helmClient, version.String(), nil } - maxV, err := versions.MaxVersion(revision, tags) + index, err := helmClient.GetIndex(noRevisionCache, s.initConstants.HelmRegistryMaxIndexSize) if err != nil { - return nil, "", fmt.Errorf("invalid revision: %w", err) + return nil, "", err } - - return helmClient, maxV, nil + entries, err := index.GetEntries(chart) + if err != nil { + return nil, "", err + } + version, err := entries.MaxVersion(constraints) + if err != nil { + return nil, "", err + } + return helmClient, version.String(), nil } // directoryPermissionInitializer ensures the directory has read/write/execute permissions and returns @@ -2448,7 +2479,7 @@ func directoryPermissionInitializer(rootPath string) goio.Closer { } } - return utilio.NewCloser(func() error { + return io.NewCloser(func() error { if err := os.Chmod(rootPath, 0o000); err != nil { log.Warnf("Failed to remove permissions on %s: %v", rootPath, err) } else { @@ -2460,6 +2491,7 @@ func directoryPermissionInitializer(rootPath string) goio.Closer { // checkoutRevision is a convenience function to initialize a repo, fetch, and checkout a revision // Returns the 40 character commit SHA after the checkout has been performed +// nolint:unparam func (s *Service) checkoutRevision(gitClient git.Client, revision string, submoduleEnabled bool) (goio.Closer, error) { closer := s.gitRepoInitializer(gitClient.Root()) err := checkoutRevision(gitClient, revision, submoduleEnabled) @@ -2521,7 +2553,7 @@ func checkoutRevision(gitClient git.Client, revision string, submoduleEnabled bo revisionPresent := gitClient.IsRevisionPresent(revision) - log.WithFields(map[string]any{ + log.WithFields(map[string]interface{}{ "skipFetch": revisionPresent, }).Debugf("Checking out revision %v", revision) @@ -2555,22 +2587,25 @@ func checkoutRevision(gitClient git.Client, revision string, submoduleEnabled bo return err } -func (s *Service) GetHelmCharts(_ context.Context, q *apiclient.HelmChartsRequest) (*apiclient.HelmChartsResponse, error) { +func (s *Service) GetHelmCharts(ctx context.Context, q *apiclient.HelmChartsRequest) (*apiclient.HelmChartsResponse, error) { index, err := s.newHelmClient(q.Repo.Repo, q.Repo.GetHelmCreds(), q.Repo.EnableOCI, q.Repo.Proxy, q.Repo.NoProxy, helm.WithIndexCache(s.cache), helm.WithChartPaths(s.chartPaths)).GetIndex(true, s.initConstants.HelmRegistryMaxIndexSize) if err != nil { return nil, err } res := apiclient.HelmChartsResponse{} for chartName, entries := range index.Entries { - res.Items = append(res.Items, &apiclient.HelmChart{ - Name: chartName, - Versions: entries.Tags(), - }) + chart := apiclient.HelmChart{ + Name: chartName, + } + for _, entry := range entries { + chart.Versions = append(chart.Versions, entry.Version) + } + res.Items = append(res.Items, &chart) } return &res, nil } -func (s *Service) TestRepository(_ context.Context, q *apiclient.TestRepositoryRequest) (*apiclient.TestRepositoryResponse, error) { +func (s *Service) TestRepository(ctx context.Context, q *apiclient.TestRepositoryRequest) (*apiclient.TestRepositoryResponse, error) { repo := q.Repo // per Type doc, "git" should be assumed if empty or absent if repo.Type == "" { @@ -2587,9 +2622,10 @@ func (s *Service) TestRepository(_ context.Context, q *apiclient.TestRepositoryR } _, err := helm.NewClient(repo.Repo, repo.GetHelmCreds(), repo.EnableOCI, repo.Proxy, repo.NoProxy).TestHelmOCI() return err + } else { + _, err := helm.NewClient(repo.Repo, repo.GetHelmCreds(), repo.EnableOCI, repo.Proxy, repo.NoProxy).GetIndex(false, s.initConstants.HelmRegistryMaxIndexSize) + return err } - _, err := helm.NewClient(repo.Repo, repo.GetHelmCreds(), repo.EnableOCI, repo.Proxy, repo.NoProxy).GetIndex(false, s.initConstants.HelmRegistryMaxIndexSize) - return err }, } check := checks[repo.Type] @@ -2602,7 +2638,7 @@ func (s *Service) TestRepository(_ context.Context, q *apiclient.TestRepositoryR } // ResolveRevision resolves the revision/ambiguousRevision specified in the ResolveRevisionRequest request into a concrete revision. -func (s *Service) ResolveRevision(_ context.Context, q *apiclient.ResolveRevisionRequest) (*apiclient.ResolveRevisionResponse, error) { +func (s *Service) ResolveRevision(ctx context.Context, q *apiclient.ResolveRevisionRequest) (*apiclient.ResolveRevisionResponse, error) { repo := q.Repo app := q.App ambiguousRevision := q.AmbiguousRevision @@ -2617,20 +2653,21 @@ func (s *Service) ResolveRevision(_ context.Context, q *apiclient.ResolveRevisio Revision: revision, AmbiguousRevision: fmt.Sprintf("%v (%v)", ambiguousRevision, revision), }, nil + } else { + gitClient, err := git.NewClient(repo.Repo, repo.GetGitCreds(s.gitCredsStore), repo.IsInsecure(), repo.IsLFSEnabled(), repo.Proxy, repo.NoProxy) + if err != nil { + return &apiclient.ResolveRevisionResponse{Revision: "", AmbiguousRevision: ""}, err + } + revision, err = gitClient.LsRemote(ambiguousRevision) + if err != nil { + s.metricsServer.IncGitLsRemoteFail(gitClient.Root(), revision) + return &apiclient.ResolveRevisionResponse{Revision: "", AmbiguousRevision: ""}, err + } + return &apiclient.ResolveRevisionResponse{ + Revision: revision, + AmbiguousRevision: fmt.Sprintf("%s (%s)", ambiguousRevision, revision), + }, nil } - gitClient, err := git.NewClient(repo.Repo, repo.GetGitCreds(s.gitCredsStore), repo.IsInsecure(), repo.IsLFSEnabled(), repo.Proxy, repo.NoProxy) - if err != nil { - return &apiclient.ResolveRevisionResponse{Revision: "", AmbiguousRevision: ""}, err - } - revision, err = gitClient.LsRemote(ambiguousRevision) - if err != nil { - s.metricsServer.IncGitLsRemoteFail(gitClient.Root(), revision) - return &apiclient.ResolveRevisionResponse{Revision: "", AmbiguousRevision: ""}, err - } - return &apiclient.ResolveRevisionResponse{ - Revision: revision, - AmbiguousRevision: fmt.Sprintf("%s (%s)", ambiguousRevision, revision), - }, nil } func (s *Service) GetGitFiles(_ context.Context, request *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error) { @@ -2674,7 +2711,7 @@ func (s *Service) GetGitFiles(_ context.Context, request *apiclient.GitFilesRequ if err != nil { return nil, status.Errorf(codes.Internal, "unable to checkout git repo %s with revision %s pattern %s: %v", repo.Repo, revision, gitPath, err) } - defer utilio.Close(closer) + defer io.Close(closer) gitFiles, err := gitClient.LsFiles(gitPath, enableNewGitFileGlobbing) if err != nil { @@ -2711,12 +2748,14 @@ func verifyCommitSignature(verifyCommit bool, gitClient git.Client, revision str if cs == "" { return fmt.Errorf("revision %s is not signed", revision) + } else { + vr := gpg.ParseGitCommitVerification(cs) + if vr.Result == gpg.VerifyResultUnknown { + return fmt.Errorf("UNKNOWN signature: %s", vr.Message) + } else { + log.Debugf("%s signature from %s key %s", vr.Result, vr.Cipher, gpg.KeyID(vr.KeyID)) + } } - vr := gpg.ParseGitCommitVerification(cs) - if vr.Result == gpg.VerifyResultUnknown { - return fmt.Errorf("UNKNOWN signature: %s", vr.Message) - } - log.Debugf("%s signature from %s key %s", vr.Result, vr.Cipher, gpg.KeyID(vr.KeyID)) } return nil } @@ -2756,7 +2795,7 @@ func (s *Service) GetGitDirectories(_ context.Context, request *apiclient.GitDir if err != nil { return nil, status.Errorf(codes.Internal, "unable to checkout git repo %s with revision %s: %v", repo.Repo, revision, err) } - defer utilio.Close(closer) + defer io.Close(closer) repoRoot := gitClient.Root() var paths []string @@ -2848,7 +2887,7 @@ func (s *Service) UpdateRevisionForPaths(_ context.Context, request *apiclient.U if err != nil { return nil, status.Errorf(codes.Internal, "unable to checkout git repo %s with revision %s: %v", repo.Repo, revision, err) } - defer utilio.Close(closer) + defer io.Close(closer) if err := s.fetch(gitClient, []string{syncedRevision}); err != nil { return nil, status.Errorf(codes.Internal, "unable to fetch git repo %s with syncedRevisions %s: %v", repo.Repo, syncedRevision, err) diff --git a/reposerver/repository/repository.proto b/reposerver/repository/repository.proto index 007088e088..784ef0cafa 100644 --- a/reposerver/repository/repository.proto +++ b/reposerver/repository/repository.proto @@ -1,14 +1,14 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/reposerver/apiclient"; +option go_package = "github.com/argoproj/argo-cd/v2/reposerver/apiclient"; package repository; -import "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto"; +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; import "google/protobuf/empty.proto"; // ManifestRequest is a query for manifest generation. message ManifestRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; // revision, potentially un-resolved string revision = 2; bool noCache = 3; @@ -16,24 +16,24 @@ message ManifestRequest { // Name of the application for which the request is triggered string appName = 5; string namespace = 8; - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSource applicationSource = 10; - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repos = 11; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSource applicationSource = 10; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repos = 11; // Deprecated: use sidecar plugins instead. - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ConfigManagementPlugin plugins = 12; - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.KustomizeOptions kustomizeOptions = 13; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ConfigManagementPlugin plugins = 12; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.KustomizeOptions kustomizeOptions = 13; // KubeVersion is the Kubernetes API version from the destination cluster. string kubeVersion = 14; // ApiVersions is the list of API versions from the destination cluster, used for rendering Helm charts. repeated string apiVersions = 15; // Request to verify the signature when generating the manifests (only for Git repositories) bool verifySignature = 16; - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepoCreds helmRepoCreds = 17; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds helmRepoCreds = 17; bool noRevisionCache = 18; string trackingMethod = 19; map enabledSourceTypes = 20; - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.HelmOptions helmOptions = 21; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmOptions helmOptions = 21; bool hasMultipleSources = 22; - map refSources = 23; + map refSources = 23; // This is used to surface "source not permitted" errors for Helm repositories repeated string projectSourceRepos = 24; // This is used to surface "source not permitted" errors for Helm repositories @@ -65,7 +65,7 @@ message ManifestFileChunk { // TestRepositoryRequest is a query to test repository is valid or not and has valid access. message TestRepositoryRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; } // TestRepositoryResponse represents the TestRepository response @@ -76,8 +76,8 @@ message TestRepositoryResponse { // ResolveRevisionRequest message ResolveRevisionRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Application app = 2; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application app = 2; string ambiguousRevision = 3; int64 sourceIndex = 4; } @@ -103,7 +103,7 @@ message ManifestResponse { } message ListRefsRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; } // A subset of the repository's named refs @@ -114,7 +114,7 @@ message Refs { // ListAppsRequest requests a repository directory structure message ListAppsRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; string revision = 2; map enabledSourceTypes = 3; } @@ -135,17 +135,17 @@ message PluginList { // RepoServerAppDetailsQuery contains query information for app details request message RepoServerAppDetailsQuery { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSource source = 2; - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repos = 3; - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.KustomizeOptions kustomizeOptions = 4; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSource source = 2; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repos = 3; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.KustomizeOptions kustomizeOptions = 4; string appName = 5; bool noCache = 6; bool noRevisionCache = 7; string trackingMethod = 8; map enabledSourceTypes = 9; - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.HelmOptions helmOptions = 10; - map refSources = 11; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmOptions helmOptions = 10; + map refSources = 11; } // RepoAppDetailsResponse application details @@ -159,7 +159,7 @@ message RepoAppDetailsResponse { message RepoServerRevisionMetadataRequest { // the repo - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; // the revision within the repo string revision = 2; // whether to check signature on revision @@ -168,7 +168,7 @@ message RepoServerRevisionMetadataRequest { message RepoServerRevisionChartDetailsRequest { // the repo - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; // the chart string name = 2; // the revision within the chart @@ -180,11 +180,11 @@ message HelmAppSpec { string name = 1; repeated string valueFiles = 3; // the output of `helm inspect values` - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.HelmParameter parameters = 4; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmParameter parameters = 4; // the contents of values.yaml string values = 5; // helm file parameters - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.HelmFileParameter fileParameters = 6; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmFileParameter fileParameters = 6; } // KustomizeAppSpec contains kustomize images @@ -227,7 +227,7 @@ message PluginAppSpec { } message HelmChartsRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; } message HelmChart { @@ -240,7 +240,7 @@ message HelmChartsResponse { } message GitFilesRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; bool submoduleEnabled = 2; string revision = 3; string path = 4; @@ -255,7 +255,7 @@ message GitFilesResponse { } message GitDirectoriesRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; bool submoduleEnabled = 2; string revision = 3; bool noRevisionCache = 4; @@ -268,14 +268,14 @@ message GitDirectoriesResponse { } message UpdateRevisionForPathsRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; string appLabelKey = 2; string appName = 3; string namespace = 4; - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSource applicationSource = 5; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSource applicationSource = 5; string trackingMethod = 6; - map refSources = 7; + map refSources = 7; string kubeVersion = 8; repeated string apiVersions = 9; bool hasMultipleSources = 10; @@ -332,11 +332,11 @@ service RepoServerService { } // Get the meta-data (author, date, tags, message) for a specific revision of the repo - rpc GetRevisionMetadata(RepoServerRevisionMetadataRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RevisionMetadata) { + rpc GetRevisionMetadata(RepoServerRevisionMetadataRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RevisionMetadata) { } // Get the chart details (author, date, tags, message) for a specific revision of the repo - rpc GetRevisionChartDetails(RepoServerRevisionChartDetailsRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ChartDetails) { + rpc GetRevisionChartDetails(RepoServerRevisionChartDetailsRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ChartDetails) { } // GetHelmCharts returns list of helm charts in the specified repository diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go index 82414b18e7..9d4909e907 100644 --- a/reposerver/repository/repository_test.go +++ b/reposerver/repository/repository_test.go @@ -24,30 +24,31 @@ import ( "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/util/intstr" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/reposerver/cache" - repositorymocks "github.com/argoproj/argo-cd/v3/reposerver/cache/mocks" - "github.com/argoproj/argo-cd/v3/reposerver/metrics" - fileutil "github.com/argoproj/argo-cd/v3/test/fixture/path" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/git" - gitmocks "github.com/argoproj/argo-cd/v3/util/git/mocks" - "github.com/argoproj/argo-cd/v3/util/helm" - helmmocks "github.com/argoproj/argo-cd/v3/util/helm/mocks" - utilio "github.com/argoproj/argo-cd/v3/util/io" - iomocks "github.com/argoproj/argo-cd/v3/util/io/mocks" + "github.com/argoproj/argo-cd/v2/common" + "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" + "github.com/argoproj/argo-cd/v2/reposerver/cache" + repositorymocks "github.com/argoproj/argo-cd/v2/reposerver/cache/mocks" + "github.com/argoproj/argo-cd/v2/reposerver/metrics" + fileutil "github.com/argoproj/argo-cd/v2/test/fixture/path" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/git" + gitmocks "github.com/argoproj/argo-cd/v2/util/git/mocks" + "github.com/argoproj/argo-cd/v2/util/helm" + helmmocks "github.com/argoproj/argo-cd/v2/util/helm/mocks" + "github.com/argoproj/argo-cd/v2/util/io" + iomocks "github.com/argoproj/argo-cd/v2/util/io/mocks" ) const testSignature = `gpg: Signature made Wed Feb 26 23:22:34 2020 CET @@ -126,9 +127,8 @@ func newServiceWithMocks(t *testing.T, root string, signed bool) (*Service, *git chart: {{Version: "1.0.0"}, {Version: version}}, oobChart: {{Version: "1.0.0"}, {Version: version}}, }}, nil) - helmClient.On("GetTags", mock.Anything, mock.Anything).Return(nil, nil) - helmClient.On("ExtractChart", chart, version, false, int64(0), false).Return("./testdata/my-chart", utilio.NopCloser, nil) - helmClient.On("ExtractChart", oobChart, version, false, int64(0), false).Return("./testdata2/out-of-bounds-chart", utilio.NopCloser, nil) + helmClient.On("ExtractChart", chart, version, false, int64(0), false).Return("./testdata/my-chart", io.NopCloser, nil) + helmClient.On("ExtractChart", oobChart, version, false, int64(0), false).Return("./testdata2/out-of-bounds-chart", io.NopCloser, nil) helmClient.On("CleanChartCache", chart, version).Return(nil) helmClient.On("CleanChartCache", oobChart, version).Return(nil) helmClient.On("DependencyBuild").Return(nil) @@ -150,14 +150,14 @@ func newServiceWithOpt(t *testing.T, cf clientFunc, root string) (*Service, *git t.Cleanup(cacheMocks.mockCache.StopRedisCallback) service := NewService(metrics.NewMetricsServer(), cacheMocks.cache, RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, root) - service.newGitClient = func(_ string, _ string, _ git.Creds, _ bool, _ bool, _ string, _ string, _ ...git.ClientOpts) (client git.Client, e error) { + service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, noProxy string, opts ...git.ClientOpts) (client git.Client, e error) { return gitClient, nil } - service.newHelmClient = func(_ string, _ helm.Creds, _ bool, _ string, _ string, _ ...helm.ClientOpts) helm.Client { + service.newHelmClient = func(repoURL string, creds helm.Creds, enableOci bool, proxy string, noProxy string, opts ...helm.ClientOpts) helm.Client { return helmClient } - service.gitRepoInitializer = func(_ string) goio.Closer { - return utilio.NopCloser + service.gitRepoInitializer = func(rootPath string) goio.Closer { + return io.NopCloser } service.gitRepoPaths = paths return service, gitClient, cacheMocks @@ -184,7 +184,7 @@ func newServiceWithCommitSHA(t *testing.T, root, revision string) *Service { revisionErr = errors.New("not a commit SHA") } - service, gitClient, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + service, gitClient, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", mock.Anything).Return(false) gitClient.On("Fetch", mock.Anything).Return(nil) @@ -196,7 +196,7 @@ func newServiceWithCommitSHA(t *testing.T, root, revision string) *Service { paths.On("GetPathIfExists", mock.Anything).Return(root, nil) }, root) - service.newGitClient = func(_ string, _ string, _ git.Creds, _ bool, _ bool, _ string, _ string, _ ...git.ClientOpts) (client git.Client, e error) { + service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, noProxy string, opts ...git.ClientOpts) (client git.Client, e error) { return gitClient, nil } @@ -206,9 +206,9 @@ func newServiceWithCommitSHA(t *testing.T, root, revision string) *Service { func TestGenerateYamlManifestInDir(t *testing.T) { service := newService(t, "../../manifests/base") - src := v1alpha1.ApplicationSource{Path: "."} + src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + Repo: &argoappv1.Repository{}, ApplicationSource: &src, ProjectName: "something", ProjectSourceRepos: []string{"*"}, @@ -217,13 +217,13 @@ func TestGenerateYamlManifestInDir(t *testing.T) { // update this value if we add/remove manifests const countOfManifests = 50 - res1, err := service.GenerateManifest(t.Context(), &q) + res1, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Len(t, res1.Manifests, countOfManifests) // this will test concatenated manifests to verify we split YAMLs correctly - res2, err := GenerateManifests(t.Context(), "./testdata/concatenated", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) + res2, err := GenerateManifests(context.Background(), "./testdata/concatenated", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) require.NoError(t, err) assert.Len(t, res2.Manifests, 3) } @@ -279,10 +279,10 @@ func Test_GenerateManifests_NoOutOfBoundsAccess(t *testing.T) { } q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: &v1alpha1.ApplicationSource{}, ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res, err := GenerateManifests(t.Context(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) + res, err := GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) require.Error(t, err) assert.NotContains(t, err.Error(), mustNotContain) require.ErrorContains(t, err, "illegal filepath") @@ -297,20 +297,20 @@ func TestGenerateManifests_MissingSymlinkDestination(t *testing.T) { require.NoError(t, err) q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: &v1alpha1.ApplicationSource{}, ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - _, err = GenerateManifests(t.Context(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) + _, err = GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) require.NoError(t, err) } func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { service := newService(t, "../../manifests/base") - src := v1alpha1.ApplicationSource{Path: "."} + src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ KubeVersion: "v1.16.0", - Repo: &v1alpha1.Repository{}, + Repo: &argoappv1.Repository{}, ApplicationSource: &src, ProjectName: "something", ProjectSourceRepos: []string{"*"}, @@ -321,12 +321,12 @@ func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: cachedFakeResponse}, nil, "") require.NoError(t, err) - res, err := service.GenerateManifest(t.Context(), &q) + res, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Equal(t, cachedFakeResponse, res) q.KubeVersion = "v1.17.0" - res, err = service.GenerateManifest(t.Context(), &q) + res, err = service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.NotEqual(t, cachedFakeResponse, res) assert.Greater(t, len(res.Manifests), 1) @@ -335,9 +335,9 @@ func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { func TestGenerateManifests_EmptyCache(t *testing.T) { service, gitMocks, mockCache := newServiceWithMocks(t, "../../manifests/base", false) - src := v1alpha1.ApplicationSource{Path: "."} + src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + Repo: &argoappv1.Repository{}, ApplicationSource: &src, ProjectName: "something", ProjectSourceRepos: []string{"*"}, @@ -346,7 +346,7 @@ func TestGenerateManifests_EmptyCache(t *testing.T) { err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: nil}, nil, "") require.NoError(t, err) - res, err := service.GenerateManifest(t.Context(), &q) + res, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.NotEmpty(t, res.Manifests) mockCache.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ @@ -363,20 +363,20 @@ func TestGenerateManifests_EmptyCache(t *testing.T) { func TestGenerateManifest_RefOnlyShortCircuit(t *testing.T) { lsremoteCalled := false dir := t.TempDir() - repopath := dir + "/tmprepo" - repoRemote := "file://" + repopath + repopath := fmt.Sprintf("%s/tmprepo", dir) + repoRemote := fmt.Sprintf("file://%s", repopath) cacheMocks := newCacheMocks() t.Cleanup(cacheMocks.mockCache.StopRedisCallback) service := NewService(metrics.NewMetricsServer(), cacheMocks.cache, RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, repopath) service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, noProxy string, opts ...git.ClientOpts) (client git.Client, e error) { opts = append(opts, git.WithEventHandlers(git.EventHandlers{ // Primary check, we want to make sure ls-remote is not called when the item is in cache - OnLsRemote: func(_ string) func() { + OnLsRemote: func(repo string) func() { return func() { lsremoteCalled = true } }, - OnFetch: func(_ string) func() { + OnFetch: func(repo string) func() { return func() { assert.Fail(t, "Fetch should not be called from GenerateManifest when the source is ref only") } @@ -391,8 +391,8 @@ func TestGenerateManifest_RefOnlyShortCircuit(t *testing.T) { remote: repoRemote, addEmptyCommit: true, }) - src := v1alpha1.ApplicationSource{RepoURL: repoRemote, TargetRevision: "HEAD", Ref: "test-ref"} - repo := &v1alpha1.Repository{ + src := argoappv1.ApplicationSource{RepoURL: repoRemote, TargetRevision: "HEAD", Ref: "test-ref"} + repo := &argoappv1.Repository{ Repo: repoRemote, } q := apiclient.ManifestRequest{ @@ -403,7 +403,7 @@ func TestGenerateManifest_RefOnlyShortCircuit(t *testing.T) { ProjectName: "default", ProjectSourceRepos: []string{"*"}, } - _, err := service.GenerateManifest(t.Context(), &q) + _, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ ExternalSets: 2, @@ -411,25 +411,27 @@ func TestGenerateManifest_RefOnlyShortCircuit(t *testing.T) { }) assert.True(t, lsremoteCalled, "ls-remote should be called when the source is ref only") var revisions [][2]string - require.NoError(t, cacheMocks.cacheutilCache.GetItem("git-refs|"+repoRemote, &revisions)) + require.NoError(t, cacheMocks.cacheutilCache.GetItem(fmt.Sprintf("git-refs|%s", repoRemote), &revisions)) assert.ElementsMatch(t, [][2]string{{"refs/heads/main", revision}, {"HEAD", "ref: refs/heads/main"}}, revisions) } // Test that calling manifest generation on source helm reference helm files that when the revision is cached it does not call ls-remote func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { dir := t.TempDir() - repopath := dir + "/tmprepo" + repopath := fmt.Sprintf("%s/tmprepo", dir) cacheMocks := newCacheMocks() t.Cleanup(func() { cacheMocks.mockCache.StopRedisCallback() err := filepath.WalkDir(dir, - func(path string, _ fs.DirEntry, err error) error { + func(path string, di fs.DirEntry, err error) error { if err == nil { return os.Chmod(path, 0o777) } return err }) - require.NoError(t, err) + if err != nil { + t.Fatal(err) + } }) service := NewService(metrics.NewMetricsServer(), cacheMocks.cache, RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, repopath) var gitClient git.Client @@ -437,7 +439,7 @@ func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, noProxy string, opts ...git.ClientOpts) (client git.Client, e error) { opts = append(opts, git.WithEventHandlers(git.EventHandlers{ // Primary check, we want to make sure ls-remote is not called when the item is in cache - OnLsRemote: func(_ string) func() { + OnLsRemote: func(repo string) func() { return func() { assert.Fail(t, "LsRemote should not be called when the item is in cache") } @@ -446,7 +448,7 @@ func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { gitClient, err = git.NewClientExt(rawRepoURL, root, creds, insecure, enableLfs, proxy, noProxy, opts...) return gitClient, err } - repoRemote := "file://" + repopath + repoRemote := fmt.Sprintf("file://%s", repopath) revision := initGitRepo(t, newGitRepoOptions{ path: repopath, createPath: true, @@ -457,10 +459,10 @@ func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { valuesFiles: map[string]map[string]string{"test.yaml": {"testval": "test"}}, }, }) - src := v1alpha1.ApplicationSource{RepoURL: repoRemote, Path: ".", TargetRevision: "HEAD", Helm: &v1alpha1.ApplicationSourceHelm{ + src := argoappv1.ApplicationSource{RepoURL: repoRemote, Path: ".", TargetRevision: "HEAD", Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"$ref/test.yaml"}, }} - repo := &v1alpha1.Repository{ + repo := &argoappv1.Repository{ Repo: repoRemote, } q := apiclient.ManifestRequest{ @@ -470,11 +472,11 @@ func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { ApplicationSource: &src, ProjectName: "default", ProjectSourceRepos: []string{"*"}, - RefSources: map[string]*v1alpha1.RefTarget{"$ref": {TargetRevision: "HEAD", Repo: *repo}}, + RefSources: map[string]*argoappv1.RefTarget{"$ref": {TargetRevision: "HEAD", Repo: *repo}}, } - err = cacheMocks.cacheutilCache.SetItem("git-refs|"+repoRemote, [][2]string{{"HEAD", revision}}, nil) + err = cacheMocks.cacheutilCache.SetItem(fmt.Sprintf("git-refs|%s", repoRemote), [][2]string{{"HEAD", revision}}, nil) require.NoError(t, err) - _, err = service.GenerateManifest(t.Context(), &q) + _, err = service.GenerateManifest(context.Background(), &q) require.NoError(t, err) cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ ExternalSets: 2, @@ -486,12 +488,12 @@ func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { func TestHelmManifestFromChartRepo(t *testing.T) { root := t.TempDir() service, gitMocks, mockCache := newServiceWithMocks(t, root, false) - source := &v1alpha1.ApplicationSource{Chart: "my-chart", TargetRevision: ">= 1.0.0"} + source := &argoappv1.ApplicationSource{Chart: "my-chart", TargetRevision: ">= 1.0.0"} request := &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: source, NoCache: true, ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - response, err := service.GenerateManifest(t.Context(), request) + response, err := service.GenerateManifest(context.Background(), request) require.NoError(t, err) assert.NotNil(t, response) assert.Equal(t, &apiclient.ManifestResponse{ @@ -511,25 +513,25 @@ func TestHelmManifestFromChartRepo(t *testing.T) { func TestHelmChartReferencingExternalValues(t *testing.T) { service := newService(t, ".") - spec := v1alpha1.ApplicationSpec{ - Sources: []v1alpha1.ApplicationSource{ - {RepoURL: "https://helm.example.com", Chart: "my-chart", TargetRevision: ">= 1.0.0", Helm: &v1alpha1.ApplicationSourceHelm{ + spec := argoappv1.ApplicationSpec{ + Sources: []argoappv1.ApplicationSource{ + {RepoURL: "https://helm.example.com", Chart: "my-chart", TargetRevision: ">= 1.0.0", Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"$ref/testdata/my-chart/my-chart-values.yaml"}, }}, {Ref: "ref", RepoURL: "https://git.example.com/test/repo"}, }, } - refSources, err := argo.GetRefSources(t.Context(), spec.Sources, spec.Project, func(_ context.Context, _ string, _ string) (*v1alpha1.Repository, error) { - return &v1alpha1.Repository{ + refSources, err := argo.GetRefSources(context.Background(), spec.Sources, spec.Project, func(ctx context.Context, url string, project string) (*argoappv1.Repository, error) { + return &argoappv1.Repository{ Repo: "https://git.example.com/test/repo", }, nil }, []string{}, false) require.NoError(t, err) request := &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true, ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - response, err := service.GenerateManifest(t.Context(), request) + response, err := service.GenerateManifest(context.Background(), request) require.NoError(t, err) assert.NotNil(t, response) assert.Equal(t, &apiclient.ManifestResponse{ @@ -543,9 +545,9 @@ func TestHelmChartReferencingExternalValues(t *testing.T) { } func TestHelmChartReferencingExternalValues_InvalidRefs(t *testing.T) { - spec := v1alpha1.ApplicationSpec{ - Sources: []v1alpha1.ApplicationSource{ - {RepoURL: "https://helm.example.com", Chart: "my-chart", TargetRevision: ">= 1.0.0", Helm: &v1alpha1.ApplicationSourceHelm{ + spec := argoappv1.ApplicationSpec{ + Sources: []argoappv1.ApplicationSource{ + {RepoURL: "https://helm.example.com", Chart: "my-chart", TargetRevision: ">= 1.0.0", Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"$ref/testdata/my-chart/my-chart-values.yaml"}, }}, {RepoURL: "https://git.example.com/test/repo"}, @@ -555,20 +557,20 @@ func TestHelmChartReferencingExternalValues_InvalidRefs(t *testing.T) { // Empty refsource service := newService(t, ".") - getRepository := func(_ context.Context, _ string, _ string) (*v1alpha1.Repository, error) { - return &v1alpha1.Repository{ + getRepository := func(ctx context.Context, url string, project string) (*argoappv1.Repository, error) { + return &argoappv1.Repository{ Repo: "https://git.example.com/test/repo", }, nil } - refSources, err := argo.GetRefSources(t.Context(), spec.Sources, spec.Project, getRepository, []string{}, false) + refSources, err := argo.GetRefSources(context.Background(), spec.Sources, spec.Project, getRepository, []string{}, false) require.NoError(t, err) request := &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true, ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - response, err := service.GenerateManifest(t.Context(), request) + response, err := service.GenerateManifest(context.Background(), request) require.Error(t, err) assert.Nil(t, response) @@ -576,14 +578,14 @@ func TestHelmChartReferencingExternalValues_InvalidRefs(t *testing.T) { service = newService(t, ".") spec.Sources[1].Ref = "Invalid" - refSources, err = argo.GetRefSources(t.Context(), spec.Sources, spec.Project, getRepository, []string{}, false) + refSources, err = argo.GetRefSources(context.Background(), spec.Sources, spec.Project, getRepository, []string{}, false) require.NoError(t, err) request = &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true, ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - response, err = service.GenerateManifest(t.Context(), request) + response, err = service.GenerateManifest(context.Background(), request) require.Error(t, err) assert.Nil(t, response) @@ -592,14 +594,14 @@ func TestHelmChartReferencingExternalValues_InvalidRefs(t *testing.T) { spec.Sources[1].Ref = "ref" spec.Sources[1].Chart = "helm-chart" - refSources, err = argo.GetRefSources(t.Context(), spec.Sources, spec.Project, getRepository, []string{}, false) + refSources, err = argo.GetRefSources(context.Background(), spec.Sources, spec.Project, getRepository, []string{}, false) require.NoError(t, err) request = &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true, ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - response, err = service.GenerateManifest(t.Context(), request) + response, err = service.GenerateManifest(context.Background(), request) require.Error(t, err) assert.Nil(t, response) } @@ -617,10 +619,10 @@ func TestHelmChartReferencingExternalValues_OutOfBounds_Symlink(t *testing.T) { // Create a regular file to reference from another source err = os.WriteFile("./testdata/oob-symlink/values.yaml", []byte("foo: bar"), 0o644) require.NoError(t, err) - spec := v1alpha1.ApplicationSpec{ + spec := argoappv1.ApplicationSpec{ Project: "default", - Sources: []v1alpha1.ApplicationSource{ - {RepoURL: "https://helm.example.com", Chart: "my-chart", TargetRevision: ">= 1.0.0", Helm: &v1alpha1.ApplicationSourceHelm{ + Sources: []argoappv1.ApplicationSource{ + {RepoURL: "https://helm.example.com", Chart: "my-chart", TargetRevision: ">= 1.0.0", Helm: &argoappv1.ApplicationSourceHelm{ // Reference `ref` but do not use the oob symlink. The mere existence of the link should be enough to // cause an error. ValueFiles: []string{"$ref/testdata/oob-symlink/values.yaml"}, @@ -628,28 +630,28 @@ func TestHelmChartReferencingExternalValues_OutOfBounds_Symlink(t *testing.T) { {Ref: "ref", RepoURL: "https://git.example.com/test/repo"}, }, } - refSources, err := argo.GetRefSources(t.Context(), spec.Sources, spec.Project, func(_ context.Context, _ string, _ string) (*v1alpha1.Repository, error) { - return &v1alpha1.Repository{ + refSources, err := argo.GetRefSources(context.Background(), spec.Sources, spec.Project, func(ctx context.Context, url string, project string) (*argoappv1.Repository, error) { + return &argoappv1.Repository{ Repo: "https://git.example.com/test/repo", }, nil }, []string{}, false) require.NoError(t, err) - request := &apiclient.ManifestRequest{Repo: &v1alpha1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true} - _, err = service.GenerateManifest(t.Context(), request) + request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true} + _, err = service.GenerateManifest(context.Background(), request) require.Error(t, err) } func TestGenerateManifestsUseExactRevision(t *testing.T) { service, gitClient, _ := newServiceWithMocks(t, ".", false) - src := v1alpha1.ApplicationSource{Path: "./testdata/recurse", Directory: &v1alpha1.ApplicationSourceDirectory{Recurse: true}} + src := argoappv1.ApplicationSource{Path: "./testdata/recurse", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: &src, Revision: "abc", ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: &src, Revision: "abc", ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res1, err := service.GenerateManifest(t.Context(), &q) + res1, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Len(t, res1.Manifests, 2) assert.Equal(t, "abc", gitClient.Calls[0].Arguments[0]) @@ -658,14 +660,14 @@ func TestGenerateManifestsUseExactRevision(t *testing.T) { func TestRecurseManifestsInDir(t *testing.T) { service := newService(t, ".") - src := v1alpha1.ApplicationSource{Path: "./testdata/recurse", Directory: &v1alpha1.ApplicationSourceDirectory{Recurse: true}} + src := argoappv1.ApplicationSource{Path: "./testdata/recurse", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: &src, ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: &src, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res1, err := service.GenerateManifest(t.Context(), &q) + res1, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Len(t, res1.Manifests, 2) } @@ -673,20 +675,20 @@ func TestRecurseManifestsInDir(t *testing.T) { func TestInvalidManifestsInDir(t *testing.T) { service := newService(t, ".") - src := v1alpha1.ApplicationSource{Path: "./testdata/invalid-manifests", Directory: &v1alpha1.ApplicationSourceDirectory{Recurse: true}} + src := argoappv1.ApplicationSource{Path: "./testdata/invalid-manifests", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} - q := apiclient.ManifestRequest{Repo: &v1alpha1.Repository{}, ApplicationSource: &src} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src} - _, err := service.GenerateManifest(t.Context(), &q) + _, err := service.GenerateManifest(context.Background(), &q) require.Error(t, err) } func TestInvalidMetadata(t *testing.T) { service := newService(t, ".") - src := v1alpha1.ApplicationSource{Path: "./testdata/invalid-metadata", Directory: &v1alpha1.ApplicationSourceDirectory{Recurse: true}} - q := apiclient.ManifestRequest{Repo: &v1alpha1.Repository{}, ApplicationSource: &src, AppLabelKey: "test", AppName: "invalid-metadata", TrackingMethod: "annotation+label"} - _, err := service.GenerateManifest(t.Context(), &q) + 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) assert.ErrorContains(t, err, "contains non-string value in the map under key \"invalid\"") } @@ -694,9 +696,9 @@ func TestNilMetadataAccessors(t *testing.T) { service := newService(t, ".") expected := "{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{\"argocd.argoproj.io/tracking-id\":\"nil-metadata-accessors:/ConfigMap:/my-map\"},\"labels\":{\"test\":\"nil-metadata-accessors\"},\"name\":\"my-map\"},\"stringData\":{\"foo\":\"bar\"}}" - src := v1alpha1.ApplicationSource{Path: "./testdata/nil-metadata-accessors", Directory: &v1alpha1.ApplicationSourceDirectory{Recurse: true}} - q := apiclient.ManifestRequest{Repo: &v1alpha1.Repository{}, ApplicationSource: &src, AppLabelKey: "test", AppName: "nil-metadata-accessors", TrackingMethod: "annotation+label"} - res, err := service.GenerateManifest(t.Context(), &q) + src := argoappv1.ApplicationSource{Path: "./testdata/nil-metadata-accessors", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, AppLabelKey: "test", AppName: "nil-metadata-accessors", TrackingMethod: "annotation+label"} + res, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Len(t, res.Manifests, 1) assert.Equal(t, expected, res.Manifests[0]) @@ -706,13 +708,13 @@ func TestGenerateJsonnetManifestInDir(t *testing.T) { service := newService(t, ".") q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./testdata/jsonnet", - Directory: &v1alpha1.ApplicationSourceDirectory{ - Jsonnet: v1alpha1.ApplicationSourceJsonnet{ - ExtVars: []v1alpha1.JsonnetVar{{Name: "extVarString", Value: "extVarString"}, {Name: "extVarCode", Value: "\"extVarCode\"", Code: true}}, - TLAs: []v1alpha1.JsonnetVar{{Name: "tlaString", Value: "tlaString"}, {Name: "tlaCode", Value: "\"tlaCode\"", Code: true}}, + Directory: &argoappv1.ApplicationSourceDirectory{ + Jsonnet: argoappv1.ApplicationSourceJsonnet{ + ExtVars: []argoappv1.JsonnetVar{{Name: "extVarString", Value: "extVarString"}, {Name: "extVarCode", Value: "\"extVarCode\"", Code: true}}, + TLAs: []argoappv1.JsonnetVar{{Name: "tlaString", Value: "tlaString"}, {Name: "tlaCode", Value: "\"tlaCode\"", Code: true}}, Libs: []string{"testdata/jsonnet/vendor"}, }, }, @@ -720,7 +722,7 @@ func TestGenerateJsonnetManifestInDir(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res1, err := service.GenerateManifest(t.Context(), &q) + res1, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Len(t, res1.Manifests, 2) } @@ -729,13 +731,13 @@ func TestGenerateJsonnetManifestInRootDir(t *testing.T) { service := newService(t, "testdata/jsonnet-1") q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", - Directory: &v1alpha1.ApplicationSourceDirectory{ - Jsonnet: v1alpha1.ApplicationSourceJsonnet{ - ExtVars: []v1alpha1.JsonnetVar{{Name: "extVarString", Value: "extVarString"}, {Name: "extVarCode", Value: "\"extVarCode\"", Code: true}}, - TLAs: []v1alpha1.JsonnetVar{{Name: "tlaString", Value: "tlaString"}, {Name: "tlaCode", Value: "\"tlaCode\"", Code: true}}, + Directory: &argoappv1.ApplicationSourceDirectory{ + Jsonnet: argoappv1.ApplicationSourceJsonnet{ + ExtVars: []argoappv1.JsonnetVar{{Name: "extVarString", Value: "extVarString"}, {Name: "extVarCode", Value: "\"extVarCode\"", Code: true}}, + TLAs: []argoappv1.JsonnetVar{{Name: "tlaString", Value: "tlaString"}, {Name: "tlaCode", Value: "\"tlaCode\"", Code: true}}, Libs: []string{"."}, }, }, @@ -743,7 +745,7 @@ func TestGenerateJsonnetManifestInRootDir(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res1, err := service.GenerateManifest(t.Context(), &q) + res1, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Len(t, res1.Manifests, 2) } @@ -752,11 +754,11 @@ func TestGenerateJsonnetLibOutside(t *testing.T) { service := newService(t, ".") q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./testdata/jsonnet", - Directory: &v1alpha1.ApplicationSourceDirectory{ - Jsonnet: v1alpha1.ApplicationSourceJsonnet{ + Directory: &argoappv1.ApplicationSourceDirectory{ + Jsonnet: argoappv1.ApplicationSourceJsonnet{ Libs: []string{"../../../testdata/jsonnet/vendor"}, }, }, @@ -764,7 +766,7 @@ func TestGenerateJsonnetLibOutside(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - _, err := service.GenerateManifest(t.Context(), &q) + _, err := service.GenerateManifest(context.Background(), &q) require.ErrorContains(t, err, "file '../../../testdata/jsonnet/vendor' resolved to outside repository root") } @@ -835,14 +837,14 @@ func TestManifestGenErrorCacheByNumRequests(t *testing.T) { fmt.Printf("%d )-------------------------------------------\n", invocationCount) manifestRequest := &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./testdata/invalid-helm", }, } - res, err := service.GenerateManifest(t.Context(), manifestRequest) + res, err := service.GenerateManifest(context.Background(), manifestRequest) // Verify invariant: res != nil xor err != nil if err != nil { @@ -860,22 +862,30 @@ func TestManifestGenErrorCacheByNumRequests(t *testing.T) { require.False(t, isCachedError) require.NotNil(t, cachedManifestResponse) + // nolint:staticcheck assert.Nil(t, cachedManifestResponse.ManifestResponse) + // nolint:staticcheck assert.NotEqual(t, 0, cachedManifestResponse.FirstFailureTimestamp) // Internal cache consec failures value should increase with invocations, cached response should stay the same, + // nolint:staticcheck assert.Equal(t, cachedManifestResponse.NumberOfConsecutiveFailures, adjustedInvocation+1) + // nolint:staticcheck assert.Equal(t, 0, cachedManifestResponse.NumberOfCachedResponsesReturned) } else { // GenerateManifest SHOULD return cached errors for the next X responses, where X is the // PauseGenerationOnFailureForRequests constant assert.True(t, isCachedError) require.NotNil(t, cachedManifestResponse) + // nolint:staticcheck assert.Nil(t, cachedManifestResponse.ManifestResponse) + // nolint:staticcheck assert.NotEqual(t, 0, cachedManifestResponse.FirstFailureTimestamp) // Internal cache values should update correctly based on number of return cache entries, consecutive failures should stay the same + // nolint:staticcheck assert.Equal(t, cachedManifestResponse.NumberOfConsecutiveFailures, service.initConstants.PauseGenerationAfterFailedGenerationAttempts) + // nolint:staticcheck assert.Equal(t, cachedManifestResponse.NumberOfCachedResponsesReturned, (adjustedInvocation - service.initConstants.PauseGenerationAfterFailedGenerationAttempts + 1)) } } @@ -917,10 +927,10 @@ func TestManifestGenErrorCacheFileContentsChange(t *testing.T) { require.NoError(t, err) } - res, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", }, ProjectName: "something", @@ -975,10 +985,10 @@ func TestManifestGenErrorCacheByMinutesElapsed(t *testing.T) { // 1) Put the cache into the failure state for x := 0; x < 2; x++ { - res, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./testdata/invalid-helm", }, }) @@ -993,10 +1003,10 @@ func TestManifestGenErrorCacheByMinutesElapsed(t *testing.T) { // 2) Jump forward X-1 minutes in time, where X is the expiration boundary currentTime = currentTime.Add(time.Duration(tt.PauseGenerationOnFailureForMinutes-1) * time.Minute) - res, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./testdata/invalid-helm", }, }) @@ -1008,10 +1018,10 @@ func TestManifestGenErrorCacheByMinutesElapsed(t *testing.T) { // 4) Jump forward 2 minutes in time, such that the pause generation time has elapsed and we should return to normal state currentTime = currentTime.Add(2 * time.Minute) - res, err = service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + res, err = service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./testdata/invalid-helm", }, }) @@ -1035,10 +1045,10 @@ func TestManifestGenErrorCacheRespectsNoCache(t *testing.T) { // 1) Put the cache into the failure state for x := 0; x < 2; x++ { - res, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./testdata/invalid-helm", }, }) @@ -1052,10 +1062,10 @@ func TestManifestGenErrorCacheRespectsNoCache(t *testing.T) { } // 2) Call generateManifest with NoCache enabled - res, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./testdata/invalid-helm", }, NoCache: true, @@ -1066,10 +1076,10 @@ func TestManifestGenErrorCacheRespectsNoCache(t *testing.T) { assert.False(t, strings.HasPrefix(err.Error(), cachedManifestGenerationPrefix)) // 4) Call generateManifest - res, err = service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + res, err = service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./testdata/invalid-helm", }, }) @@ -1082,12 +1092,12 @@ func TestManifestGenErrorCacheRespectsNoCache(t *testing.T) { func TestGenerateHelmWithValues(t *testing.T) { service := newService(t, "../../util/helm/testdata/redis") - res, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"values-production.yaml"}, ValuesObject: &runtime.RawExtension{Raw: []byte(`cluster: {slaveCount: 2}`)}, }, @@ -1105,7 +1115,7 @@ func TestGenerateHelmWithValues(t *testing.T) { require.NoError(t, err) if obj.GetKind() == "Deployment" && obj.GetName() == "test-redis-slave" { - var dep appsv1.Deployment + var dep v1.Deployment err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &dep) require.NoError(t, err) assert.Equal(t, int32(2), *dep.Spec.Replicas) @@ -1120,11 +1130,11 @@ func TestHelmWithMissingValueFiles(t *testing.T) { missingValuesFile := "values-prod-overrides.yaml" req := &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"values-production.yaml", missingValuesFile}, }, }, @@ -1133,24 +1143,24 @@ func TestHelmWithMissingValueFiles(t *testing.T) { } // Should fail since we're passing a non-existent values file, and error should indicate that - _, err := service.GenerateManifest(t.Context(), req) - require.ErrorContains(t, err, missingValuesFile+": no such file or directory") + _, err := service.GenerateManifest(context.Background(), req) + 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 - _, err = service.GenerateManifest(t.Context(), req) + _, err = service.GenerateManifest(context.Background(), req) require.NoError(t, err) } func TestGenerateHelmWithEnvVars(t *testing.T) { service := newService(t, "../../util/helm/testdata/redis") - res, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "production", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"values-$ARGOCD_APP_NAME.yaml"}, }, }, @@ -1167,7 +1177,7 @@ func TestGenerateHelmWithEnvVars(t *testing.T) { require.NoError(t, err) if obj.GetKind() == "Deployment" && obj.GetName() == "production-redis-slave" { - var dep appsv1.Deployment + var dep v1.Deployment err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &dep) require.NoError(t, err) assert.Equal(t, int32(3), *dep.Spec.Replicas) @@ -1181,12 +1191,12 @@ func TestGenerateHelmWithEnvVars(t *testing.T) { // since the requested value is still under the repo directory (`~/go/src/github.com/argoproj/argo-cd`), it is allowed func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { service := newService(t, "../../util/helm/testdata") - _, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./redis", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"../minio/values.yaml"}, ValuesObject: &runtime.RawExtension{Raw: []byte(`cluster: {slaveCount: 2}`)}, }, @@ -1198,10 +1208,10 @@ func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { // Test the case where the path is "." service = newService(t, "./testdata") - _, err = service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + _, err = service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./my-chart", }, ProjectName: "something", @@ -1212,9 +1222,9 @@ func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { func TestChartRepoWithOutOfBoundsSymlink(t *testing.T) { service := newService(t, ".") - source := &v1alpha1.ApplicationSource{Chart: "out-of-bounds-chart", TargetRevision: ">= 1.0.0"} - request := &apiclient.ManifestRequest{Repo: &v1alpha1.Repository{}, ApplicationSource: source, NoCache: true} - _, err := service.GenerateManifest(t.Context(), request) + source := &argoappv1.ApplicationSource{Chart: "out-of-bounds-chart", TargetRevision: ">= 1.0.0"} + request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true} + _, err := service.GenerateManifest(context.Background(), request) assert.ErrorContains(t, err, "chart contains out-of-bounds symlinks") } @@ -1222,21 +1232,21 @@ func TestChartRepoWithOutOfBoundsSymlink(t *testing.T) { // (`~/go/src/github.com/argoproj/argo-cd/reposerver/repository`), so it is allowed func TestHelmManifestFromChartRepoWithValueFile(t *testing.T) { service := newService(t, ".") - source := &v1alpha1.ApplicationSource{ + source := &argoappv1.ApplicationSource{ Chart: "my-chart", TargetRevision: ">= 1.0.0", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"./my-chart-values.yaml"}, }, } request := &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - response, err := service.GenerateManifest(t.Context(), request) + response, err := service.GenerateManifest(context.Background(), request) require.NoError(t, err) assert.NotNil(t, response) assert.Equal(t, &apiclient.ManifestResponse{ @@ -1253,33 +1263,33 @@ func TestHelmManifestFromChartRepoWithValueFile(t *testing.T) { // (`~/go/src/github.com/argoproj/argo-cd/reposerver/repository`), so it is not allowed func TestHelmManifestFromChartRepoWithValueFileOutsideRepo(t *testing.T) { service := newService(t, ".") - source := &v1alpha1.ApplicationSource{ + source := &argoappv1.ApplicationSource{ Chart: "my-chart", TargetRevision: ">= 1.0.0", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"../my-chart-2/my-chart-2-values.yaml"}, }, } - request := &apiclient.ManifestRequest{Repo: &v1alpha1.Repository{}, ApplicationSource: source, NoCache: true} - _, err := service.GenerateManifest(t.Context(), request) + request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true} + _, err := service.GenerateManifest(context.Background(), request) require.Error(t, err) } func TestHelmManifestFromChartRepoWithValueFileLinks(t *testing.T) { t.Run("Valid symlink", func(t *testing.T) { service := newService(t, ".") - source := &v1alpha1.ApplicationSource{ + source := &argoappv1.ApplicationSource{ Chart: "my-chart", TargetRevision: ">= 1.0.0", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"my-chart-link.yaml"}, }, } request := &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: source, NoCache: true, ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - _, err := service.GenerateManifest(t.Context(), request) + _, err := service.GenerateManifest(context.Background(), request) require.NoError(t, err) }) } @@ -1287,19 +1297,19 @@ func TestHelmManifestFromChartRepoWithValueFileLinks(t *testing.T) { func TestGenerateHelmWithURL(t *testing.T) { service := newService(t, "../../util/helm/testdata/redis") - _, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"https://raw.githubusercontent.com/argoproj/argocd-example-apps/master/helm-guestbook/values.yaml"}, ValuesObject: &runtime.RawExtension{Raw: []byte(`cluster: {slaveCount: 2}`)}, }, }, ProjectName: "something", ProjectSourceRepos: []string{"*"}, - HelmOptions: &v1alpha1.HelmOptions{ValuesFileSchemes: []string{"https"}}, + HelmOptions: &argoappv1.HelmOptions{ValuesFileSchemes: []string{"https"}}, }) require.NoError(t, err) } @@ -1309,12 +1319,12 @@ func TestGenerateHelmWithURL(t *testing.T) { func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { t.Run("Values file with relative path pointing outside repo root", func(t *testing.T) { service := newService(t, "../../util/helm/testdata/redis") - _, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"../minio/values.yaml"}, ValuesObject: &runtime.RawExtension{Raw: []byte(`cluster: {slaveCount: 2}`)}, }, @@ -1327,12 +1337,12 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { t.Run("Values file with relative path pointing inside repo root", func(t *testing.T) { service := newService(t, "./testdata") - _, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./my-chart", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"../my-chart/my-chart-values.yaml"}, ValuesObject: &runtime.RawExtension{Raw: []byte(`cluster: {slaveCount: 2}`)}, }, @@ -1345,12 +1355,12 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { t.Run("Values file with absolute path stays within repo root", func(t *testing.T) { service := newService(t, "./testdata") - _, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./my-chart", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"/my-chart/my-chart-values.yaml"}, ValuesObject: &runtime.RawExtension{Raw: []byte(`cluster: {slaveCount: 2}`)}, }, @@ -1363,12 +1373,12 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { t.Run("Values file with absolute path using back-references outside repo root", func(t *testing.T) { service := newService(t, "./testdata") - _, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./my-chart", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"/../../../my-chart-values.yaml"}, ValuesObject: &runtime.RawExtension{Raw: []byte(`cluster: {slaveCount: 2}`)}, }, @@ -1381,12 +1391,12 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { t.Run("Remote values file from forbidden protocol", func(t *testing.T) { service := newService(t, "./testdata") - _, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./my-chart", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"file://../../../../my-chart-values.yaml"}, ValuesObject: &runtime.RawExtension{Raw: []byte(`cluster: {slaveCount: 2}`)}, }, @@ -1399,16 +1409,16 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { t.Run("Remote values file from custom allowed protocol", func(t *testing.T) { service := newService(t, "./testdata") - _, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./my-chart", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"s3://my-bucket/my-chart-values.yaml"}, }, }, - HelmOptions: &v1alpha1.HelmOptions{ValuesFileSchemes: []string{"s3"}}, + HelmOptions: &argoappv1.HelmOptions{ValuesFileSchemes: []string{"s3"}}, ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) @@ -1420,7 +1430,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { func TestGenerateHelmWithAbsoluteFileParameter(t *testing.T) { service := newService(t, "../..") - file, err := os.CreateTemp(t.TempDir(), "external-secret.txt") + file, err := os.CreateTemp("", "external-secret.txt") require.NoError(t, err) externalSecretPath := file.Name() defer func() { _ = os.RemoveAll(externalSecretPath) }() @@ -1434,15 +1444,15 @@ func TestGenerateHelmWithAbsoluteFileParameter(t *testing.T) { } }() - _, err = service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + _, err = service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./util/helm/testdata/redis", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"values-production.yaml"}, ValuesObject: &runtime.RawExtension{Raw: []byte(`cluster: {slaveCount: 2}`)}, - FileParameters: []v1alpha1.HelmFileParameter{{ + FileParameters: []argoappv1.HelmFileParameter{{ Name: "passwordContent", Path: externalSecretPath, }}, @@ -1461,16 +1471,16 @@ func TestGenerateHelmWithAbsoluteFileParameter(t *testing.T) { func TestGenerateHelmWithFileParameter(t *testing.T) { service := newService(t, "../../util/helm/testdata") - res, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, AppName: "test", - ApplicationSource: &v1alpha1.ApplicationSource{ + ApplicationSource: &argoappv1.ApplicationSource{ Path: "./redis", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"values-production.yaml"}, Values: `cluster: {slaveCount: 10}`, ValuesObject: &runtime.RawExtension{Raw: []byte(`cluster: {slaveCount: 2}`)}, - FileParameters: []v1alpha1.HelmFileParameter{{ + FileParameters: []argoappv1.HelmFileParameter{{ Name: "passwordContent", Path: "../external/external-secret.txt", }}, @@ -1487,9 +1497,9 @@ func TestGenerateNullList(t *testing.T) { service := newService(t, ".") t.Run("null list", func(t *testing.T) { - res1, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{Path: "./testdata/null-list"}, + res1, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/null-list"}, NoCache: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, @@ -1500,9 +1510,9 @@ func TestGenerateNullList(t *testing.T) { }) t.Run("empty list", func(t *testing.T) { - res1, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{Path: "./testdata/empty-list"}, + res1, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/empty-list"}, NoCache: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, @@ -1513,9 +1523,9 @@ func TestGenerateNullList(t *testing.T) { }) t.Run("weird list", func(t *testing.T) { - res1, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{Path: "./testdata/weird-list"}, + res1, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/weird-list"}, NoCache: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, @@ -1526,27 +1536,27 @@ func TestGenerateNullList(t *testing.T) { } func TestIdentifyAppSourceTypeByAppDirWithKustomizations(t *testing.T) { - sourceType, err := GetAppSourceType(t.Context(), &v1alpha1.ApplicationSource{}, "./testdata/kustomization_yaml", "./testdata", "testapp", map[string]bool{}, []string{}, []string{}) + sourceType, err := GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yaml", "./testdata", "testapp", map[string]bool{}, []string{}, []string{}) require.NoError(t, err) - assert.Equal(t, v1alpha1.ApplicationSourceTypeKustomize, sourceType) + assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType) - sourceType, err = GetAppSourceType(t.Context(), &v1alpha1.ApplicationSource{}, "./testdata/kustomization_yml", "./testdata", "testapp", map[string]bool{}, []string{}, []string{}) + sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yml", "./testdata", "testapp", map[string]bool{}, []string{}, []string{}) require.NoError(t, err) - assert.Equal(t, v1alpha1.ApplicationSourceTypeKustomize, sourceType) + assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType) - sourceType, err = GetAppSourceType(t.Context(), &v1alpha1.ApplicationSource{}, "./testdata/Kustomization", "./testdata", "testapp", map[string]bool{}, []string{}, []string{}) + sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/Kustomization", "./testdata", "testapp", map[string]bool{}, []string{}, []string{}) require.NoError(t, err) - assert.Equal(t, v1alpha1.ApplicationSourceTypeKustomize, sourceType) + assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType) } func TestGenerateFromUTF16(t *testing.T) { q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{}, + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{}, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res1, err := GenerateManifests(t.Context(), "./testdata/utf-16", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) + res1, err := GenerateManifests(context.Background(), "./testdata/utf-16", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) require.NoError(t, err) assert.Len(t, res1.Manifests, 2) } @@ -1554,7 +1564,7 @@ func TestGenerateFromUTF16(t *testing.T) { func TestListApps(t *testing.T) { service := newService(t, "./testdata") - res, err := service.ListApps(t.Context(), &apiclient.ListAppsRequest{Repo: &v1alpha1.Repository{}}) + res, err := service.ListApps(context.Background(), &apiclient.ListAppsRequest{Repo: &argoappv1.Repository{}}) require.NoError(t, err) expectedApps := map[string]string{ @@ -1585,9 +1595,9 @@ func TestListApps(t *testing.T) { func TestGetAppDetailsHelm(t *testing.T) { service := newService(t, "../../util/helm/testdata/dependency") - res, err := service.GetAppDetails(t.Context(), &apiclient.RepoServerAppDetailsQuery{ - Repo: &v1alpha1.Repository{}, - Source: &v1alpha1.ApplicationSource{ + res, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ Path: ".", }, }) @@ -1596,15 +1606,15 @@ func TestGetAppDetailsHelm(t *testing.T) { assert.NotNil(t, res.Helm) assert.Equal(t, "Helm", res.Type) - assert.Equal(t, []string{"values-production.yaml", "values.yaml"}, res.Helm.ValueFiles) + assert.EqualValues(t, []string{"values-production.yaml", "values.yaml"}, res.Helm.ValueFiles) } func TestGetAppDetailsHelmUsesCache(t *testing.T) { service := newService(t, "../../util/helm/testdata/dependency") - res, err := service.GetAppDetails(t.Context(), &apiclient.RepoServerAppDetailsQuery{ - Repo: &v1alpha1.Repository{}, - Source: &v1alpha1.ApplicationSource{ + res, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ Path: ".", }, }) @@ -1613,15 +1623,15 @@ func TestGetAppDetailsHelmUsesCache(t *testing.T) { assert.NotNil(t, res.Helm) assert.Equal(t, "Helm", res.Type) - assert.Equal(t, []string{"values-production.yaml", "values.yaml"}, res.Helm.ValueFiles) + assert.EqualValues(t, []string{"values-production.yaml", "values.yaml"}, res.Helm.ValueFiles) } func TestGetAppDetailsHelm_WithNoValuesFile(t *testing.T) { service := newService(t, "../../util/helm/testdata/api-versions") - res, err := service.GetAppDetails(t.Context(), &apiclient.RepoServerAppDetailsQuery{ - Repo: &v1alpha1.Repository{}, - Source: &v1alpha1.ApplicationSource{ + res, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ Path: ".", }, }) @@ -1631,15 +1641,15 @@ func TestGetAppDetailsHelm_WithNoValuesFile(t *testing.T) { assert.Equal(t, "Helm", res.Type) assert.Empty(t, res.Helm.ValueFiles) - assert.Empty(t, res.Helm.Values) + assert.Equal(t, "", res.Helm.Values) } func TestGetAppDetailsKustomize(t *testing.T) { service := newService(t, "../../util/kustomize/testdata/kustomization_yaml") - res, err := service.GetAppDetails(t.Context(), &apiclient.RepoServerAppDetailsQuery{ - Repo: &v1alpha1.Repository{}, - Source: &v1alpha1.ApplicationSource{ + res, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ Path: ".", }, }) @@ -1648,12 +1658,12 @@ func TestGetAppDetailsKustomize(t *testing.T) { assert.Equal(t, "Kustomize", res.Type) assert.NotNil(t, res.Kustomize) - assert.Equal(t, []string{"nginx:1.15.4", "registry.k8s.io/nginx-slim:0.8"}, res.Kustomize.Images) + assert.EqualValues(t, []string{"nginx:1.15.4", "registry.k8s.io/nginx-slim:0.8"}, res.Kustomize.Images) } func TestGetHelmCharts(t *testing.T) { service := newService(t, "../..") - res, err := service.GetHelmCharts(t.Context(), &apiclient.HelmChartsRequest{Repo: &v1alpha1.Repository{}}) + res, err := service.GetHelmCharts(context.Background(), &apiclient.HelmChartsRequest{Repo: &argoappv1.Repository{}}) // fix flakiness sort.Slice(res.Items, func(i, j int) bool { @@ -1665,11 +1675,11 @@ func TestGetHelmCharts(t *testing.T) { item := res.Items[0] assert.Equal(t, "my-chart", item.Name) - assert.Equal(t, []string{"1.0.0", "1.1.0"}, item.Versions) + assert.EqualValues(t, []string{"1.0.0", "1.1.0"}, item.Versions) item2 := res.Items[1] assert.Equal(t, "out-of-bounds-chart", item2.Name) - assert.Equal(t, []string{"1.0.0", "1.1.0"}, item2.Versions) + assert.EqualValues(t, []string{"1.0.0", "1.1.0"}, item2.Versions) } func TestGetRevisionMetadata(t *testing.T) { @@ -1683,8 +1693,8 @@ func TestGetRevisionMetadata(t *testing.T) { Tags: []string{"tag1", "tag2"}, }, nil) - res, err := service.GetRevisionMetadata(t.Context(), &apiclient.RepoServerRevisionMetadataRequest{ - Repo: &v1alpha1.Repository{}, + res, err := service.GetRevisionMetadata(context.Background(), &apiclient.RepoServerRevisionMetadataRequest{ + Repo: &argoappv1.Repository{}, Revision: "c0b400fc458875d925171398f9ba9eabd5529923", CheckSignature: true, }) @@ -1693,12 +1703,12 @@ func TestGetRevisionMetadata(t *testing.T) { assert.Equal(t, "test", res.Message) assert.Equal(t, now, res.Date.Time) assert.Equal(t, "author", res.Author) - assert.Equal(t, []string{"tag1", "tag2"}, res.Tags) + assert.EqualValues(t, []string{"tag1", "tag2"}, res.Tags) assert.NotEmpty(t, res.SignatureInfo) // Check for truncated revision value - res, err = service.GetRevisionMetadata(t.Context(), &apiclient.RepoServerRevisionMetadataRequest{ - Repo: &v1alpha1.Repository{}, + res, err = service.GetRevisionMetadata(context.Background(), &apiclient.RepoServerRevisionMetadataRequest{ + Repo: &argoappv1.Repository{}, Revision: "c0b400f", CheckSignature: true, }) @@ -1707,12 +1717,12 @@ func TestGetRevisionMetadata(t *testing.T) { assert.Equal(t, "test", res.Message) assert.Equal(t, now, res.Date.Time) assert.Equal(t, "author", res.Author) - assert.Equal(t, []string{"tag1", "tag2"}, res.Tags) + assert.EqualValues(t, []string{"tag1", "tag2"}, res.Tags) assert.NotEmpty(t, res.SignatureInfo) // Cache hit - signature info should not be in result - res, err = service.GetRevisionMetadata(t.Context(), &apiclient.RepoServerRevisionMetadataRequest{ - Repo: &v1alpha1.Repository{}, + res, err = service.GetRevisionMetadata(context.Background(), &apiclient.RepoServerRevisionMetadataRequest{ + Repo: &argoappv1.Repository{}, Revision: "c0b400fc458875d925171398f9ba9eabd5529923", CheckSignature: false, }) @@ -1720,8 +1730,8 @@ func TestGetRevisionMetadata(t *testing.T) { assert.Empty(t, res.SignatureInfo) // Enforce cache miss - signature info should not be in result - res, err = service.GetRevisionMetadata(t.Context(), &apiclient.RepoServerRevisionMetadataRequest{ - Repo: &v1alpha1.Repository{}, + res, err = service.GetRevisionMetadata(context.Background(), &apiclient.RepoServerRevisionMetadataRequest{ + Repo: &argoappv1.Repository{}, Revision: "da52afd3b2df1ec49470603d8bbb46954dab1091", CheckSignature: false, }) @@ -1729,8 +1739,8 @@ func TestGetRevisionMetadata(t *testing.T) { assert.Empty(t, res.SignatureInfo) // Cache hit on previous entry that did not have signature info - res, err = service.GetRevisionMetadata(t.Context(), &apiclient.RepoServerRevisionMetadataRequest{ - Repo: &v1alpha1.Repository{}, + res, err = service.GetRevisionMetadata(context.Background(), &apiclient.RepoServerRevisionMetadataRequest{ + Repo: &argoappv1.Repository{}, Revision: "da52afd3b2df1ec49470603d8bbb46954dab1091", CheckSignature: true, }) @@ -1743,16 +1753,16 @@ func TestGetSignatureVerificationResult(t *testing.T) { { service := newServiceWithSignature(t, "../../manifests/base") - src := v1alpha1.ApplicationSource{Path: "."} + src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + Repo: &argoappv1.Repository{}, ApplicationSource: &src, VerifySignature: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res, err := service.GenerateManifest(t.Context(), &q) + res, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Equal(t, testSignature, res.VerifyResult) } @@ -1760,13 +1770,13 @@ func TestGetSignatureVerificationResult(t *testing.T) { { service := newServiceWithSignature(t, "../../manifests/base") - src := v1alpha1.ApplicationSource{Path: "."} + src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: &src, ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: &src, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res, err := service.GenerateManifest(t.Context(), &q) + res, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Empty(t, res.VerifyResult) } @@ -1774,13 +1784,13 @@ func TestGetSignatureVerificationResult(t *testing.T) { { service := newService(t, "../../manifests/base") - src := v1alpha1.ApplicationSource{Path: "."} + src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: &src, VerifySignature: true, ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: &src, VerifySignature: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res, err := service.GenerateManifest(t.Context(), &q) + res, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Empty(t, res.VerifyResult) } @@ -1788,35 +1798,33 @@ func TestGetSignatureVerificationResult(t *testing.T) { { service := newService(t, "../../manifests/base") - src := v1alpha1.ApplicationSource{Path: "."} + src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, ApplicationSource: &src, VerifySignature: true, ProjectName: "something", + Repo: &argoappv1.Repository{}, ApplicationSource: &src, VerifySignature: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res, err := service.GenerateManifest(t.Context(), &q) + res, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Empty(t, res.VerifyResult) } } func Test_newEnv(t *testing.T) { - assert.Equal(t, &v1alpha1.Env{ - &v1alpha1.EnvEntry{Name: "ARGOCD_APP_NAME", Value: "my-app-name"}, - &v1alpha1.EnvEntry{Name: "ARGOCD_APP_NAMESPACE", Value: "my-namespace"}, - &v1alpha1.EnvEntry{Name: "ARGOCD_APP_PROJECT_NAME", Value: "my-project-name"}, - &v1alpha1.EnvEntry{Name: "ARGOCD_APP_REVISION", Value: "my-revision"}, - &v1alpha1.EnvEntry{Name: "ARGOCD_APP_REVISION_SHORT", Value: "my-revi"}, - &v1alpha1.EnvEntry{Name: "ARGOCD_APP_REVISION_SHORT_8", Value: "my-revis"}, - &v1alpha1.EnvEntry{Name: "ARGOCD_APP_SOURCE_REPO_URL", Value: "https://github.com/my-org/my-repo"}, - &v1alpha1.EnvEntry{Name: "ARGOCD_APP_SOURCE_PATH", Value: "my-path"}, - &v1alpha1.EnvEntry{Name: "ARGOCD_APP_SOURCE_TARGET_REVISION", Value: "my-target-revision"}, + assert.Equal(t, &argoappv1.Env{ + &argoappv1.EnvEntry{Name: "ARGOCD_APP_NAME", Value: "my-app-name"}, + &argoappv1.EnvEntry{Name: "ARGOCD_APP_NAMESPACE", Value: "my-namespace"}, + &argoappv1.EnvEntry{Name: "ARGOCD_APP_REVISION", Value: "my-revision"}, + &argoappv1.EnvEntry{Name: "ARGOCD_APP_REVISION_SHORT", Value: "my-revi"}, + &argoappv1.EnvEntry{Name: "ARGOCD_APP_REVISION_SHORT_8", Value: "my-revis"}, + &argoappv1.EnvEntry{Name: "ARGOCD_APP_SOURCE_REPO_URL", Value: "https://github.com/my-org/my-repo"}, + &argoappv1.EnvEntry{Name: "ARGOCD_APP_SOURCE_PATH", Value: "my-path"}, + &argoappv1.EnvEntry{Name: "ARGOCD_APP_SOURCE_TARGET_REVISION", Value: "my-target-revision"}, }, newEnv(&apiclient.ManifestRequest{ - AppName: "my-app-name", - Namespace: "my-namespace", - ProjectName: "my-project-name", - Repo: &v1alpha1.Repository{Repo: "https://github.com/my-org/my-repo"}, - ApplicationSource: &v1alpha1.ApplicationSource{ + AppName: "my-app-name", + Namespace: "my-namespace", + Repo: &argoappv1.Repository{Repo: "https://github.com/my-org/my-repo"}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: "my-path", TargetRevision: "my-target-revision", }, @@ -1827,12 +1835,12 @@ func TestService_newHelmClientResolveRevision(t *testing.T) { service := newService(t, ".") t.Run("EmptyRevision", func(t *testing.T) { - _, _, err := service.newHelmClientResolveRevision(&v1alpha1.Repository{}, "", "my-chart", true) - assert.EqualError(t, err, "invalid revision: failed to determine semver constraint: improper constraint: ") + _, _, err := service.newHelmClientResolveRevision(&argoappv1.Repository{}, "", "", true) + assert.EqualError(t, err, "invalid revision '': improper constraint: ") }) t.Run("InvalidRevision", func(t *testing.T) { - _, _, err := service.newHelmClientResolveRevision(&v1alpha1.Repository{}, "???", "my-chart", true) - assert.EqualError(t, err, "invalid revision: failed to determine semver constraint: improper constraint: ???") + _, _, err := service.newHelmClientResolveRevision(&argoappv1.Repository{}, "???", "", true) + assert.EqualError(t, err, "invalid revision '???': improper constraint: ???", true) }) } @@ -1841,83 +1849,83 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { t.Helper() - details, err := service.GetAppDetails(t.Context(), &apiclient.RepoServerAppDetailsQuery{ - Repo: &v1alpha1.Repository{}, - Source: &v1alpha1.ApplicationSource{ + details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ Path: path, }, }) require.NoError(t, err) - assert.Equal(t, []string{"quay.io/argoprojlabs/argocd-e2e-container:0.2"}, details.Kustomize.Images) + assert.EqualValues(t, []string{"gcr.io/heptio-images/ks-guestbook-demo:0.2"}, details.Kustomize.Images) }) }) 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(t.Context(), &apiclient.RepoServerAppDetailsQuery{ - Repo: &v1alpha1.Repository{}, - Source: &v1alpha1.ApplicationSource{ + details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ Path: path, }, AppName: "testapp", }) require.NoError(t, err) - assert.Equal(t, []string{"quay.io/argoprojlabs/argocd-e2e-container:0.2"}, details.Kustomize.Images) + assert.EqualValues(t, []string{"gcr.io/heptio-images/ks-guestbook-demo:0.2"}, details.Kustomize.Images) }) }) 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(t.Context(), &apiclient.RepoServerAppDetailsQuery{ - Repo: &v1alpha1.Repository{}, - Source: &v1alpha1.ApplicationSource{ + details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ Path: path, }, AppName: "testapp", }) require.NoError(t, err) - assert.Equal(t, []string{"quay.io/argoprojlabs/argocd-e2e-container:0.3"}, details.Kustomize.Images) + assert.EqualValues(t, []string{"gcr.io/heptio-images/ks-guestbook-demo:0.3"}, details.Kustomize.Images) }) }) 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(t.Context(), &apiclient.RepoServerAppDetailsQuery{ - Repo: &v1alpha1.Repository{}, - Source: &v1alpha1.ApplicationSource{ + details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ Path: path, }, AppName: "testapp", }) require.NoError(t, err) - assert.Equal(t, []string{"quay.io/argoprojlabs/argocd-e2e-container:0.3"}, details.Kustomize.Images) + assert.EqualValues(t, []string{"gcr.io/heptio-images/ks-guestbook-demo:0.3"}, details.Kustomize.Images) }) }) 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(t.Context(), &apiclient.RepoServerAppDetailsQuery{ - Repo: &v1alpha1.Repository{}, - Source: &v1alpha1.ApplicationSource{ + details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ Path: path, }, AppName: "unmergeable", }) require.NoError(t, err) - assert.Equal(t, []string{"quay.io/argoprojlabs/argocd-e2e-container:0.3"}, details.Kustomize.Images) + assert.EqualValues(t, []string{"gcr.io/heptio-images/ks-guestbook-demo:0.3"}, details.Kustomize.Images) }) }) 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(t.Context(), &apiclient.RepoServerAppDetailsQuery{ - Repo: &v1alpha1.Repository{}, - Source: &v1alpha1.ApplicationSource{ + _, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ Path: path, }, AppName: "broken", @@ -1958,9 +1966,9 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { runWithTempTestdata(t, "single-global", func(t *testing.T, path string) { t.Helper() service := newService(t, ".") - manifests, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: path, }, ProjectName: "something", @@ -1978,9 +1986,9 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { require.True(t, ok) containers, ok, _ := unstructured.NestedSlice(deployment.Object, "spec", "template", "spec", "containers") require.True(t, ok) - image, ok, _ := unstructured.NestedString(containers[0].(map[string]any), "image") + image, ok, _ := unstructured.NestedString(containers[0].(map[string]interface{}), "image") require.True(t, ok) - assert.Equal(t, "quay.io/argoprojlabs/argocd-e2e-container:0.2", image) + assert.Equal(t, "gcr.io/heptio-images/ks-guestbook-demo:0.2", image) }) }) @@ -1988,9 +1996,9 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { runWithTempTestdata(t, "single-global-helm", func(t *testing.T, path string) { t.Helper() service := newService(t, ".") - manifests, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: path, }, ProjectName: "something", @@ -2008,9 +2016,9 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { require.True(t, ok) containers, ok, _ := unstructured.NestedSlice(deployment.Object, "spec", "template", "spec", "containers") require.True(t, ok) - image, ok, _ := unstructured.NestedString(containers[0].(map[string]any), "image") + image, ok, _ := unstructured.NestedString(containers[0].(map[string]interface{}), "image") require.True(t, ok) - assert.Equal(t, "quay.io/argoprojlabs/argocd-e2e-container:0.2", image) + assert.Equal(t, "gcr.io/heptio-images/ks-guestbook-demo:0.2", image) }) }) @@ -2018,9 +2026,9 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { t.Helper() - manifests, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: path, }, AppName: "testapp", @@ -2039,19 +2047,19 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { require.True(t, ok) containers, ok, _ := unstructured.NestedSlice(deployment.Object, "spec", "template", "spec", "containers") require.True(t, ok) - image, ok, _ := unstructured.NestedString(containers[0].(map[string]any), "image") + image, ok, _ := unstructured.NestedString(containers[0].(map[string]interface{}), "image") require.True(t, ok) - assert.Equal(t, "quay.io/argoprojlabs/argocd-e2e-container:0.3", image) + assert.Equal(t, "gcr.io/heptio-images/ks-guestbook-demo:0.3", image) }) }) 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, _ string) { + runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { t.Helper() - manifests, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: "", Chart: "", Ref: "test", @@ -2071,9 +2079,9 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { t.Helper() - manifests, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: path, }, AppName: "testapp2", @@ -2092,9 +2100,9 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { require.True(t, ok) containers, ok, _ := unstructured.NestedSlice(deployment.Object, "spec", "template", "spec", "containers") require.True(t, ok) - image, ok, _ := unstructured.NestedString(containers[0].(map[string]any), "image") + image, ok, _ := unstructured.NestedString(containers[0].(map[string]interface{}), "image") require.True(t, ok) - assert.Equal(t, "quay.io/argoprojlabs/argocd-e2e-container:0.1", image) + assert.Equal(t, "gcr.io/heptio-images/ks-guestbook-demo:0.1", image) }) }) @@ -2102,12 +2110,12 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "single-global", func(t *testing.T, path string) { t.Helper() - source := &v1alpha1.ApplicationSource{ + source := &argoappv1.ApplicationSource{ Path: path, } sourceCopy := source.DeepCopy() // make a copy in case GenerateManifest mutates it. - _, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, + _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, ApplicationSource: sourceCopy, AppName: "test", ProjectName: "something", @@ -2118,7 +2126,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { // Try to pull from the cache with a `source` that does not include any overrides. Overrides should not be // part of the cache key, because you can't get the overrides without a repo operation. And avoiding repo // operations is the point of the cache. - err = service.cache.GetManifests(mock.Anything, source, v1alpha1.RefTargetRevisionMapping{}, &v1alpha1.ClusterInfo{}, "", "", "", "test", res, nil, "") + err = service.cache.GetManifests(mock.Anything, source, argoappv1.RefTargetRevisionMapping{}, &argoappv1.ClusterInfo{}, "", "", "", "test", res, nil, "") require.NoError(t, err) }) }) @@ -2139,10 +2147,10 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { }{ { name: "Case: Git tag hash matches latest commit SHA (regular tag)", - ctx: t.Context(), + ctx: context.Background(), manifestRequest: &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ TargetRevision: regularGitTagHash, }, NoCache: true, @@ -2155,10 +2163,10 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { { name: "Case: Git tag hash does not match latest commit SHA (annotated tag)", - ctx: t.Context(), + ctx: context.Background(), manifestRequest: &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ TargetRevision: annotatedGitTaghash, }, NoCache: true, @@ -2171,10 +2179,10 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { { name: "Case: Git tag hash is invalid", - ctx: t.Context(), + ctx: context.Background(), manifestRequest: &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ TargetRevision: invalidGitTaghash, }, NoCache: true, @@ -2189,10 +2197,15 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { t.Run(tt.name, func(t *testing.T) { manifestResponse, err := tt.service.GenerateManifest(tt.ctx, tt.manifestRequest) if !tt.wantError { - require.NoError(t, err) - assert.Equal(t, manifestResponse.Revision, actualCommitSHA) + if err == nil { + assert.Equal(t, manifestResponse.Revision, actualCommitSHA) + } else { + t.Errorf("unexpected error") + } } else { - assert.Errorf(t, err, "expected an error but did not throw one") + if err == nil { + t.Errorf("expected an error but did not throw one") + } } }) } @@ -2203,21 +2216,21 @@ func TestGenerateManifestWithAnnotatedTagsAndMultiSourceApp(t *testing.T) { service := newServiceWithCommitSHA(t, ".", annotatedGitTaghash) - refSources := map[string]*v1alpha1.RefTarget{} + refSources := map[string]*argoappv1.RefTarget{} - refSources["$global"] = &v1alpha1.RefTarget{ + refSources["$global"] = &argoappv1.RefTarget{ TargetRevision: annotatedGitTaghash, } - refSources["$default"] = &v1alpha1.RefTarget{ + refSources["$default"] = &argoappv1.RefTarget{ TargetRevision: annotatedGitTaghash, } manifestRequest := &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ TargetRevision: annotatedGitTaghash, - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"$global/values.yaml", "$default/secrets.yaml"}, }, }, @@ -2226,9 +2239,14 @@ func TestGenerateManifestWithAnnotatedTagsAndMultiSourceApp(t *testing.T) { RefSources: refSources, } - response, err := service.GenerateManifest(t.Context(), manifestRequest) - require.NoError(t, err) - assert.Equalf(t, response.Revision, annotatedGitTaghash, "returned SHA %s is different from expected annotated tag %s", response.Revision, annotatedGitTaghash) + response, err := service.GenerateManifest(context.Background(), manifestRequest) + if err != nil { + t.Errorf("unexpected %s", err) + } + + if response.Revision != annotatedGitTaghash { + t.Errorf("returned SHA %s is different from expected annotated tag %s", response.Revision, annotatedGitTaghash) + } } func TestGenerateMultiSourceHelmWithFileParameter(t *testing.T) { @@ -2239,12 +2257,12 @@ func TestGenerateMultiSourceHelmWithFileParameter(t *testing.T) { testCases := []struct { name string - refSources map[string]*v1alpha1.RefTarget + refSources map[string]*argoappv1.RefTarget expectedContent string expectedErr bool }{{ name: "Successfully resolve multi-source ref for helm set-file", - refSources: map[string]*v1alpha1.RefTarget{ + refSources: map[string]*argoappv1.RefTarget{ "$global": { TargetRevision: "HEAD", }, @@ -2253,7 +2271,7 @@ func TestGenerateMultiSourceHelmWithFileParameter(t *testing.T) { expectedErr: false, }, { name: "Failed to resolve multi-source ref for helm set-file", - refSources: map[string]*v1alpha1.RefTarget{}, + refSources: map[string]*argoappv1.RefTarget{}, expectedContent: "DOES-NOT-EXIST", expectedErr: true, }} @@ -2262,14 +2280,14 @@ func TestGenerateMultiSourceHelmWithFileParameter(t *testing.T) { tc := testCases[i] t.Run(tc.name, func(t *testing.T) { manifestRequest := &apiclient.ManifestRequest{ - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Ref: "$global", Path: "./redis", TargetRevision: "HEAD", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ ValueFiles: []string{"$global/redis/values-production.yaml"}, - FileParameters: []v1alpha1.HelmFileParameter{{ + FileParameters: []argoappv1.HelmFileParameter{{ Name: "passwordContent", Path: "$global/external/external-secret.txt", }}, @@ -2280,7 +2298,7 @@ func TestGenerateMultiSourceHelmWithFileParameter(t *testing.T) { RefSources: tc.refSources, } - res, err := service.GenerateManifest(t.Context(), manifestRequest) + res, err := service.GenerateManifest(context.Background(), manifestRequest) if !tc.expectedErr { require.NoError(t, err) @@ -2331,7 +2349,7 @@ func TestFindResources(t *testing.T) { for i := range testCases { tc := testCases[i] t.Run(tc.name, func(t *testing.T) { - objs, err := findManifests(&log.Entry{}, "testdata/app-include-exclude", ".", nil, v1alpha1.ApplicationSourceDirectory{ + objs, err := findManifests(&log.Entry{}, "testdata/app-include-exclude", ".", nil, argoappv1.ApplicationSourceDirectory{ Recurse: true, Include: tc.include, Exclude: tc.exclude, @@ -2347,7 +2365,7 @@ func TestFindResources(t *testing.T) { } func TestFindManifests_Exclude(t *testing.T) { - objs, err := findManifests(&log.Entry{}, "testdata/app-include-exclude", ".", nil, v1alpha1.ApplicationSourceDirectory{ + objs, err := findManifests(&log.Entry{}, "testdata/app-include-exclude", ".", nil, argoappv1.ApplicationSourceDirectory{ Recurse: true, Exclude: "subdir/deploymentSub.yaml", }, map[string]bool{}, resource.MustParse("0")) @@ -2359,7 +2377,7 @@ func TestFindManifests_Exclude(t *testing.T) { } func TestFindManifests_Exclude_NothingMatches(t *testing.T) { - objs, err := findManifests(&log.Entry{}, "testdata/app-include-exclude", ".", nil, v1alpha1.ApplicationSourceDirectory{ + objs, err := findManifests(&log.Entry{}, "testdata/app-include-exclude", ".", nil, argoappv1.ApplicationSourceDirectory{ Recurse: true, Exclude: "nothing.yaml", }, map[string]bool{}, resource.MustParse("0")) @@ -2632,13 +2650,10 @@ func Test_getPotentiallyValidManifests(t *testing.T) { t.Run("circular link should throw an error", func(t *testing.T) { const testDir = "./testdata/circular-link" require.DirExists(t, testDir) - t.Cleanup(func() { - os.Remove(path.Join(testDir, "a.json")) - os.Remove(path.Join(testDir, "b.json")) - }) - t.Chdir(testDir) - require.NoError(t, fileutil.CreateSymlink(t, "a.json", "b.json")) - require.NoError(t, fileutil.CreateSymlink(t, "b.json", "a.json")) + require.NoError(t, fileutil.CreateSymlink(t, testDir, "a.json", "b.json")) + defer os.Remove(path.Join(testDir, "a.json")) + require.NoError(t, fileutil.CreateSymlink(t, testDir, "b.json", "a.json")) + defer os.Remove(path.Join(testDir, "b.json")) manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/circular-link", "./testdata/circular-link", false, "", "", resource.MustParse("0")) assert.Empty(t, manifests) require.Error(t, err) @@ -2692,7 +2707,7 @@ func Test_getPotentiallyValidManifests(t *testing.T) { func Test_findManifests(t *testing.T) { logCtx := log.WithField("test", "test") - noRecurse := v1alpha1.ApplicationSourceDirectory{Recurse: false} + noRecurse := argoappv1.ApplicationSourceDirectory{Recurse: false} t.Run("unreadable file throws error", func(t *testing.T) { appDir := t.TempDir() @@ -2720,7 +2735,7 @@ func Test_findManifests(t *testing.T) { }) t.Run("recursion when recursion is enabled", func(t *testing.T) { - recurse := v1alpha1.ApplicationSourceDirectory{Recurse: true} + recurse := argoappv1.ApplicationSourceDirectory{Recurse: true} manifests, err := findManifests(logCtx, "./testdata/recurse", "./testdata/recurse", nil, recurse, nil, resource.MustParse("0")) assert.Len(t, manifests, 4) require.NoError(t, err) @@ -2735,13 +2750,10 @@ func Test_findManifests(t *testing.T) { t.Run("circular link should throw an error", func(t *testing.T) { const testDir = "./testdata/circular-link" require.DirExists(t, testDir) - t.Cleanup(func() { - os.Remove(path.Join(testDir, "a.json")) - os.Remove(path.Join(testDir, "b.json")) - }) - t.Chdir(testDir) - require.NoError(t, fileutil.CreateSymlink(t, "a.json", "b.json")) - require.NoError(t, fileutil.CreateSymlink(t, "b.json", "a.json")) + require.NoError(t, fileutil.CreateSymlink(t, testDir, "a.json", "b.json")) + defer os.Remove(path.Join(testDir, "a.json")) + require.NoError(t, fileutil.CreateSymlink(t, testDir, "b.json", "a.json")) + defer os.Remove(path.Join(testDir, "b.json")) manifests, err := findManifests(logCtx, "./testdata/circular-link", "./testdata/circular-link", nil, noRecurse, nil, resource.MustParse("0")) assert.Empty(t, manifests) require.Error(t, err) @@ -2852,8 +2864,8 @@ func Test_findManifests(t *testing.T) { func TestTestRepoOCI(t *testing.T) { service := newService(t, ".") - _, err := service.TestRepository(t.Context(), &apiclient.TestRepositoryRequest{ - Repo: &v1alpha1.Repository{ + _, err := service.TestRepository(context.Background(), &apiclient.TestRepositoryRequest{ + Repo: &argoappv1.Repository{ Repo: "https://demo.goharbor.io", Type: "helm", EnableOCI: true, @@ -2875,9 +2887,9 @@ func Test_getHelmDependencyRepos(t *testing.T) { func TestResolveRevision(t *testing.T) { service := newService(t, ".") - repo := &v1alpha1.Repository{Repo: "https://github.com/argoproj/argo-cd"} - app := &v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}}} - resolveRevisionResponse, err := service.ResolveRevision(t.Context(), &apiclient.ResolveRevisionRequest{ + repo := &argoappv1.Repository{Repo: "https://github.com/argoproj/argo-cd"} + app := &argoappv1.Application{Spec: argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{}}} + resolveRevisionResponse, err := service.ResolveRevision(context.Background(), &apiclient.ResolveRevisionRequest{ Repo: repo, App: app, AmbiguousRevision: "v2.2.2", @@ -2895,9 +2907,9 @@ func TestResolveRevision(t *testing.T) { func TestResolveRevisionNegativeScenarios(t *testing.T) { service := newService(t, ".") - repo := &v1alpha1.Repository{Repo: "https://github.com/argoproj/argo-cd"} - app := &v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}}} - resolveRevisionResponse, err := service.ResolveRevision(t.Context(), &apiclient.ResolveRevisionRequest{ + repo := &argoappv1.Repository{Repo: "https://github.com/argoproj/argo-cd"} + app := &argoappv1.Application{Spec: argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{}}} + resolveRevisionResponse, err := service.ResolveRevision(context.Background(), &apiclient.ResolveRevisionRequest{ Repo: repo, App: app, AmbiguousRevision: "v2.a.2", @@ -2918,7 +2930,7 @@ func TestDirectoryPermissionInitializer(t *testing.T) { file, err := os.CreateTemp(dir, "") require.NoError(t, err) - utilio.Close(file) + io.Close(file) // remove read permissions require.NoError(t, os.Chmod(dir, 0o000)) @@ -2935,7 +2947,7 @@ func TestDirectoryPermissionInitializer(t *testing.T) { require.NoError(t, err) // make sure permission are removed by closer - utilio.Close(closer) + io.Close(closer) _, err = os.ReadFile(file.Name()) require.Error(t, err) } @@ -3163,19 +3175,19 @@ func Test_walkHelmValueFilesInPath(t *testing.T) { t.Run("unrelated root", func(t *testing.T) { var files []string root := "./testdata/values-files" - unrelatedRoot := "/different/root/path" - err := filepath.Walk(root, walkHelmValueFilesInPath(unrelatedRoot, &files)) + unrelated_root := "/different/root/path" + err := filepath.Walk(root, walkHelmValueFilesInPath(unrelated_root, &files)) require.Error(t, err) }) } func Test_populateHelmAppDetails(t *testing.T) { - emptyTempPaths := utilio.NewRandomizedTempPaths(t.TempDir()) + emptyTempPaths := io.NewRandomizedTempPaths(t.TempDir()) res := apiclient.RepoAppDetailsResponse{} q := apiclient.RepoServerAppDetailsQuery{ - Repo: &v1alpha1.Repository{}, - Source: &v1alpha1.ApplicationSource{ - Helm: &v1alpha1.ApplicationSourceHelm{ValueFiles: []string{"exclude.yaml", "has-the-word-values.yaml"}}, + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ + Helm: &argoappv1.ApplicationSourceHelm{ValueFiles: []string{"exclude.yaml", "has-the-word-values.yaml"}}, }, } appPath, err := filepath.Abs("./testdata/values-files/") @@ -3187,10 +3199,10 @@ func Test_populateHelmAppDetails(t *testing.T) { } func Test_populateHelmAppDetails_values_symlinks(t *testing.T) { - emptyTempPaths := utilio.NewRandomizedTempPaths(t.TempDir()) + emptyTempPaths := io.NewRandomizedTempPaths(t.TempDir()) t.Run("inbound", func(t *testing.T) { res := apiclient.RepoAppDetailsResponse{} - q := apiclient.RepoServerAppDetailsQuery{Repo: &v1alpha1.Repository{}, Source: &v1alpha1.ApplicationSource{}} + q := apiclient.RepoServerAppDetailsQuery{Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{}} err := populateHelmAppDetails(&res, "./testdata/in-bounds-values-file-link/", "./testdata/in-bounds-values-file-link/", &q, emptyTempPaths) require.NoError(t, err) assert.NotEmpty(t, res.Helm.Values) @@ -3199,7 +3211,7 @@ func Test_populateHelmAppDetails_values_symlinks(t *testing.T) { t.Run("out of bounds", func(t *testing.T) { res := apiclient.RepoAppDetailsResponse{} - q := apiclient.RepoServerAppDetailsQuery{Repo: &v1alpha1.Repository{}, Source: &v1alpha1.ApplicationSource{}} + q := apiclient.RepoServerAppDetailsQuery{Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{}} err := populateHelmAppDetails(&res, "./testdata/out-of-bounds-values-file-link/", "./testdata/out-of-bounds-values-file-link/", &q, emptyTempPaths) require.NoError(t, err) assert.Empty(t, res.Helm.Values) @@ -3208,8 +3220,8 @@ func Test_populateHelmAppDetails_values_symlinks(t *testing.T) { } func TestGetHelmRepos_OCIDependenciesWithHelmRepo(t *testing.T) { - src := v1alpha1.ApplicationSource{Path: "."} - q := apiclient.ManifestRequest{Repos: []*v1alpha1.Repository{}, ApplicationSource: &src, HelmRepoCreds: []*v1alpha1.RepoCreds{ + src := argoappv1.ApplicationSource{Path: "."} + q := apiclient.ManifestRequest{Repos: []*argoappv1.Repository{}, ApplicationSource: &src, HelmRepoCreds: []*argoappv1.RepoCreds{ {URL: "example.com", Username: "test", Password: "test", EnableOCI: true}, }} @@ -3217,27 +3229,27 @@ func TestGetHelmRepos_OCIDependenciesWithHelmRepo(t *testing.T) { require.NoError(t, err) assert.Len(t, helmRepos, 1) - assert.Equal(t, "test", helmRepos[0].GetUsername()) + assert.Equal(t, "test", helmRepos[0].Username) assert.True(t, helmRepos[0].EnableOci) assert.Equal(t, "example.com/myrepo", helmRepos[0].Repo) } func TestGetHelmRepos_OCIDependenciesWithRepo(t *testing.T) { - src := v1alpha1.ApplicationSource{Path: "."} - q := apiclient.ManifestRequest{Repos: []*v1alpha1.Repository{{Repo: "example.com", Username: "test", Password: "test", EnableOCI: true}}, ApplicationSource: &src, HelmRepoCreds: []*v1alpha1.RepoCreds{}} + src := argoappv1.ApplicationSource{Path: "."} + q := apiclient.ManifestRequest{Repos: []*argoappv1.Repository{{Repo: "example.com", Username: "test", Password: "test", EnableOCI: true}}, ApplicationSource: &src, HelmRepoCreds: []*argoappv1.RepoCreds{}} helmRepos, err := getHelmRepos("./testdata/oci-dependencies", q.Repos, q.HelmRepoCreds) require.NoError(t, err) assert.Len(t, helmRepos, 1) - assert.Equal(t, "test", helmRepos[0].GetUsername()) + assert.Equal(t, "test", helmRepos[0].Username) assert.True(t, helmRepos[0].EnableOci) assert.Equal(t, "example.com/myrepo", helmRepos[0].Repo) } func TestGetHelmRepo_NamedRepos(t *testing.T) { - src := v1alpha1.ApplicationSource{Path: "."} - q := apiclient.ManifestRequest{Repo: &v1alpha1.Repository{}, ApplicationSource: &src, Repos: []*v1alpha1.Repository{{ + src := argoappv1.ApplicationSource{Path: "."} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, Repos: []*argoappv1.Repository{{ Name: "custom-repo", Repo: "https://example.com", Username: "test", @@ -3247,13 +3259,13 @@ func TestGetHelmRepo_NamedRepos(t *testing.T) { require.NoError(t, err) assert.Len(t, helmRepos, 1) - assert.Equal(t, "test", helmRepos[0].GetUsername()) + assert.Equal(t, "test", helmRepos[0].Username) assert.Equal(t, "https://example.com", helmRepos[0].Repo) } func TestGetHelmRepo_NamedReposAlias(t *testing.T) { - src := v1alpha1.ApplicationSource{Path: "."} - q := apiclient.ManifestRequest{Repo: &v1alpha1.Repository{}, ApplicationSource: &src, Repos: []*v1alpha1.Repository{{ + src := argoappv1.ApplicationSource{Path: "."} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, Repos: []*argoappv1.Repository{{ Name: "custom-repo-alias", Repo: "https://example.com", Username: "test-alias", @@ -3263,38 +3275,38 @@ func TestGetHelmRepo_NamedReposAlias(t *testing.T) { require.NoError(t, err) assert.Len(t, helmRepos, 1) - assert.Equal(t, "test-alias", helmRepos[0].GetUsername()) + assert.Equal(t, "test-alias", helmRepos[0].Username) assert.Equal(t, "https://example.com", helmRepos[0].Repo) } func Test_getResolvedValueFiles(t *testing.T) { tempDir := t.TempDir() - paths := utilio.NewRandomizedTempPaths(tempDir) + paths := io.NewRandomizedTempPaths(tempDir) paths.Add(git.NormalizeGitURL("https://github.com/org/repo1"), path.Join(tempDir, "repo1")) testCases := []struct { name string rawPath string - env *v1alpha1.Env - refSources map[string]*v1alpha1.RefTarget + env *argoappv1.Env + refSources map[string]*argoappv1.RefTarget expectedPath string expectedErr bool }{ { name: "simple path", rawPath: "values.yaml", - env: &v1alpha1.Env{}, - refSources: map[string]*v1alpha1.RefTarget{}, + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{}, expectedPath: path.Join(tempDir, "main-repo", "values.yaml"), }, { name: "simple ref", rawPath: "$ref/values.yaml", - env: &v1alpha1.Env{}, - refSources: map[string]*v1alpha1.RefTarget{ + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{ "$ref": { - Repo: v1alpha1.Repository{ + Repo: argoappv1.Repository{ Repo: "https://github.com/org/repo1", }, }, @@ -3304,10 +3316,10 @@ func Test_getResolvedValueFiles(t *testing.T) { { name: "only ref", rawPath: "$ref", - env: &v1alpha1.Env{}, - refSources: map[string]*v1alpha1.RefTarget{ + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{ "$ref": { - Repo: v1alpha1.Repository{ + Repo: argoappv1.Repository{ Repo: "https://github.com/org/repo1", }, }, @@ -3317,10 +3329,10 @@ func Test_getResolvedValueFiles(t *testing.T) { { name: "attempted traversal", rawPath: "$ref/../values.yaml", - env: &v1alpha1.Env{}, - refSources: map[string]*v1alpha1.RefTarget{ + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{ "$ref": { - Repo: v1alpha1.Repository{ + Repo: argoappv1.Repository{ Repo: "https://github.com/org/repo1", }, }, @@ -3333,17 +3345,17 @@ func Test_getResolvedValueFiles(t *testing.T) { // ref targets were introduced. name: "ref doesn't exist", rawPath: "$ref/values.yaml", - env: &v1alpha1.Env{}, - refSources: map[string]*v1alpha1.RefTarget{}, + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{}, expectedPath: path.Join(tempDir, "main-repo", "values.yaml"), }, { name: "repo doesn't exist", rawPath: "$ref/values.yaml", - env: &v1alpha1.Env{}, - refSources: map[string]*v1alpha1.RefTarget{ + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{ "$ref": { - Repo: v1alpha1.Repository{ + Repo: argoappv1.Repository{ Repo: "https://github.com/org/repo2", }, }, @@ -3353,15 +3365,15 @@ func Test_getResolvedValueFiles(t *testing.T) { { name: "env var is resolved", rawPath: "$ref/$APP_PATH/values.yaml", - env: &v1alpha1.Env{ - &v1alpha1.EnvEntry{ + env: &argoappv1.Env{ + &argoappv1.EnvEntry{ Name: "APP_PATH", Value: "app-path", }, }, - refSources: map[string]*v1alpha1.RefTarget{ + refSources: map[string]*argoappv1.RefTarget{ "$ref": { - Repo: v1alpha1.Repository{ + Repo: argoappv1.Repository{ Repo: "https://github.com/org/repo1", }, }, @@ -3371,15 +3383,15 @@ func Test_getResolvedValueFiles(t *testing.T) { { name: "traversal in env var is blocked", rawPath: "$ref/$APP_PATH/values.yaml", - env: &v1alpha1.Env{ - &v1alpha1.EnvEntry{ + env: &argoappv1.Env{ + &argoappv1.EnvEntry{ Name: "APP_PATH", Value: "..", }, }, - refSources: map[string]*v1alpha1.RefTarget{ + refSources: map[string]*argoappv1.RefTarget{ "$ref": { - Repo: v1alpha1.Repository{ + Repo: argoappv1.Repository{ Repo: "https://github.com/org/repo1", }, }, @@ -3389,20 +3401,20 @@ func Test_getResolvedValueFiles(t *testing.T) { { name: "env var prefix", rawPath: "$APP_PATH/values.yaml", - env: &v1alpha1.Env{ - &v1alpha1.EnvEntry{ + env: &argoappv1.Env{ + &argoappv1.EnvEntry{ Name: "APP_PATH", Value: "app-path", }, }, - refSources: map[string]*v1alpha1.RefTarget{}, + refSources: map[string]*argoappv1.RefTarget{}, expectedPath: path.Join(tempDir, "main-repo", "app-path", "values.yaml"), }, { name: "unresolved env var", rawPath: "$APP_PATH/values.yaml", - env: &v1alpha1.Env{}, - refSources: map[string]*v1alpha1.RefTarget{}, + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{}, expectedPath: path.Join(tempDir, "main-repo", "values.yaml"), }, } @@ -3443,7 +3455,7 @@ func TestErrorGetGitDirectories(t *testing.T) { wantErr assert.ErrorAssertionFunc }{ {name: "InvalidRepo", fields: fields{service: newService(t, ".")}, args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.GitDirectoriesRequest{ Repo: nil, SubmoduleEnabled: false, @@ -3451,26 +3463,26 @@ func TestErrorGetGitDirectories(t *testing.T) { }, }, want: nil, wantErr: assert.Error}, {name: "InvalidResolveRevision", fields: fields{service: func() *Service { - s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) - gitClient.On("LsRemote", mock.Anything).Return("", errors.New("ah error")) + gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) gitClient.On("Root").Return(root) paths.On("GetPath", mock.Anything).Return(".", nil) paths.On("GetPathIfExists", mock.Anything).Return(".", nil) }, ".") return s }()}, args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.GitDirectoriesRequest{ - Repo: &v1alpha1.Repository{Repo: "not-a-valid-url"}, + Repo: &argoappv1.Repository{Repo: "not-a-valid-url"}, SubmoduleEnabled: false, Revision: "sadfsadf", }, }, want: nil, wantErr: assert.Error}, {name: "ErrorVerifyCommit", fields: fields{service: func() *Service { - s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) - gitClient.On("LsRemote", mock.Anything).Return("", errors.New("ah error")) + gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) gitClient.On("VerifyCommitSignature", mock.Anything).Return("", fmt.Errorf("revision %s is not signed", "sadfsadf")) gitClient.On("Root").Return(root) paths.On("GetPath", mock.Anything).Return(".", nil) @@ -3478,9 +3490,9 @@ func TestErrorGetGitDirectories(t *testing.T) { }, ".") return s }()}, args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.GitDirectoriesRequest{ - Repo: &v1alpha1.Repository{Repo: "not-a-valid-url"}, + Repo: &argoappv1.Repository{Repo: "not-a-valid-url"}, SubmoduleEnabled: false, Revision: "sadfsadf", VerifyCommit: true, @@ -3502,7 +3514,7 @@ func TestErrorGetGitDirectories(t *testing.T) { func TestGetGitDirectories(t *testing.T) { // test not using the cache root := "./testdata/git-files-dirs" - s, _, cacheMocks := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, cacheMocks := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", mock.Anything).Return(false) gitClient.On("Fetch", mock.Anything).Return(nil) @@ -3513,17 +3525,17 @@ func TestGetGitDirectories(t *testing.T) { paths.On("GetPathIfExists", mock.Anything).Return(root, nil) }, root) dirRequest := &apiclient.GitDirectoriesRequest{ - Repo: &v1alpha1.Repository{Repo: "a-url.com"}, + Repo: &argoappv1.Repository{Repo: "a-url.com"}, SubmoduleEnabled: false, Revision: "HEAD", } - directories, err := s.GetGitDirectories(t.Context(), dirRequest) + directories, err := s.GetGitDirectories(context.TODO(), dirRequest) require.NoError(t, err) assert.ElementsMatch(t, directories.GetPaths(), []string{"app", "app/bar", "app/foo/bar", "somedir", "app/foo"}) // do the same request again to use the cache // we only allow CheckOut to be called once in the mock - directories, err = s.GetGitDirectories(t.Context(), dirRequest) + directories, err = s.GetGitDirectories(context.TODO(), dirRequest) require.NoError(t, err) assert.ElementsMatch(t, []string{"app", "app/bar", "app/foo/bar", "somedir", "app/foo"}, directories.GetPaths()) cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ @@ -3535,7 +3547,7 @@ func TestGetGitDirectories(t *testing.T) { func TestGetGitDirectoriesWithHiddenDirSupported(t *testing.T) { // test not using the cache root := "./testdata/git-files-dirs" - s, _, cacheMocks := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, cacheMocks := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", mock.Anything).Return(false) gitClient.On("Fetch", mock.Anything).Return(nil) @@ -3547,17 +3559,17 @@ func TestGetGitDirectoriesWithHiddenDirSupported(t *testing.T) { }, root) s.initConstants.IncludeHiddenDirectories = true dirRequest := &apiclient.GitDirectoriesRequest{ - Repo: &v1alpha1.Repository{Repo: "a-url.com"}, + Repo: &argoappv1.Repository{Repo: "a-url.com"}, SubmoduleEnabled: false, Revision: "HEAD", } - directories, err := s.GetGitDirectories(t.Context(), dirRequest) + directories, err := s.GetGitDirectories(context.TODO(), dirRequest) require.NoError(t, err) assert.ElementsMatch(t, directories.GetPaths(), []string{"app", "app/bar", "app/foo/bar", "somedir", "app/foo", "app/bar/.hidden"}) // do the same request again to use the cache // we only allow CheckOut to be called once in the mock - directories, err = s.GetGitDirectories(t.Context(), dirRequest) + directories, err = s.GetGitDirectories(context.TODO(), dirRequest) require.NoError(t, err) assert.ElementsMatch(t, []string{"app", "app/bar", "app/foo/bar", "somedir", "app/foo", "app/bar/.hidden"}, directories.GetPaths()) cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ @@ -3585,7 +3597,7 @@ func TestErrorGetGitFiles(t *testing.T) { wantErr assert.ErrorAssertionFunc }{ {name: "InvalidRepo", fields: fields{service: newService(t, ".")}, args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.GitFilesRequest{ Repo: nil, SubmoduleEnabled: false, @@ -3593,18 +3605,18 @@ func TestErrorGetGitFiles(t *testing.T) { }, }, want: nil, wantErr: assert.Error}, {name: "InvalidResolveRevision", fields: fields{service: func() *Service { - s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) - gitClient.On("LsRemote", mock.Anything).Return("", errors.New("ah error")) + gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) gitClient.On("Root").Return(root) paths.On("GetPath", mock.Anything).Return(".", nil) paths.On("GetPathIfExists", mock.Anything).Return(".", nil) }, ".") return s }()}, args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.GitFilesRequest{ - Repo: &v1alpha1.Repository{Repo: "not-a-valid-url"}, + Repo: &argoappv1.Repository{Repo: "not-a-valid-url"}, SubmoduleEnabled: false, Revision: "sadfsadf", }, @@ -3629,7 +3641,7 @@ func TestGetGitFiles(t *testing.T) { "./testdata/git-files-dirs/config.yaml", "./testdata/git-files-dirs/config.yaml", "./testdata/git-files-dirs/app/foo/bar/config.yaml", } root := "" - s, _, cacheMocks := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, cacheMocks := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", mock.Anything).Return(false) gitClient.On("Fetch", mock.Anything).Return(nil) @@ -3641,7 +3653,7 @@ func TestGetGitFiles(t *testing.T) { paths.On("GetPathIfExists", mock.Anything).Return(root, nil) }, root) filesRequest := &apiclient.GitFilesRequest{ - Repo: &v1alpha1.Repository{Repo: "a-url.com"}, + Repo: &argoappv1.Repository{Repo: "a-url.com"}, SubmoduleEnabled: false, Revision: "HEAD", } @@ -3654,13 +3666,13 @@ func TestGetGitFiles(t *testing.T) { expected[filePath] = fileContents } - fileResponse, err := s.GetGitFiles(t.Context(), filesRequest) + fileResponse, err := s.GetGitFiles(context.TODO(), filesRequest) require.NoError(t, err) assert.Equal(t, expected, fileResponse.GetMap()) // do the same request again to use the cache // we only allow LsFiles to be called once in the mock - fileResponse, err = s.GetGitFiles(t.Context(), filesRequest) + fileResponse, err = s.GetGitFiles(context.TODO(), filesRequest) require.NoError(t, err) assert.Equal(t, expected, fileResponse.GetMap()) cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ @@ -3688,7 +3700,7 @@ func TestErrorUpdateRevisionForPaths(t *testing.T) { wantErr assert.ErrorAssertionFunc }{ {name: "InvalidRepo", fields: fields{service: newService(t, ".")}, args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.UpdateRevisionForPathsRequest{ Repo: nil, Revision: "HEAD", @@ -3696,37 +3708,37 @@ func TestErrorUpdateRevisionForPaths(t *testing.T) { }, }, want: nil, wantErr: assert.Error}, {name: "InvalidResolveRevision", fields: fields{service: func() *Service { - s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) - gitClient.On("LsRemote", mock.Anything).Return("", errors.New("ah error")) + gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) gitClient.On("Root").Return(root) paths.On("GetPath", mock.Anything).Return(".", nil) paths.On("GetPathIfExists", mock.Anything).Return(".", nil) }, ".") return s }()}, args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.UpdateRevisionForPathsRequest{ - Repo: &v1alpha1.Repository{Repo: "not-a-valid-url"}, + Repo: &argoappv1.Repository{Repo: "not-a-valid-url"}, Revision: "sadfsadf", SyncedRevision: "HEAD", Paths: []string{"."}, }, }, want: nil, wantErr: assert.Error}, {name: "InvalidResolveSyncedRevision", fields: fields{service: func() *Service { - s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) gitClient.On("LsRemote", "HEAD").Once().Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) - gitClient.On("LsRemote", mock.Anything).Return("", errors.New("ah error")) + gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) gitClient.On("Root").Return(root) paths.On("GetPath", mock.Anything).Return(".", nil) paths.On("GetPathIfExists", mock.Anything).Return(".", nil) }, ".") return s }()}, args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.UpdateRevisionForPathsRequest{ - Repo: &v1alpha1.Repository{Repo: "not-a-valid-url"}, + Repo: &argoappv1.Repository{Repo: "not-a-valid-url"}, Revision: "HEAD", SyncedRevision: "sadfsadf", Paths: []string{"."}, @@ -3767,7 +3779,7 @@ func TestUpdateRevisionForPaths(t *testing.T) { cacheHit *cacheHit }{ {name: "NoPathAbort", fields: func() fields { - s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, _ *iomocks.TempPaths) { + s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) }, ".") return fields{ @@ -3775,14 +3787,14 @@ func TestUpdateRevisionForPaths(t *testing.T) { cache: c, } }(), args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.UpdateRevisionForPathsRequest{ - Repo: &v1alpha1.Repository{Repo: "a-url.com"}, + Repo: &argoappv1.Repository{Repo: "a-url.com"}, Paths: []string{}, }, }, want: &apiclient.UpdateRevisionForPathsResponse{}, wantErr: assert.NoError}, {name: "SameResolvedRevisionAbort", fields: func() fields { - s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) gitClient.On("LsRemote", "HEAD").Once().Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) gitClient.On("LsRemote", "SYNCEDHEAD").Once().Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) @@ -3794,9 +3806,9 @@ func TestUpdateRevisionForPaths(t *testing.T) { cache: c, } }(), args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.UpdateRevisionForPathsRequest{ - Repo: &v1alpha1.Repository{Repo: "a-url.com"}, + Repo: &argoappv1.Repository{Repo: "a-url.com"}, Revision: "HEAD", SyncedRevision: "SYNCEDHEAD", Paths: []string{"."}, @@ -3805,7 +3817,7 @@ func TestUpdateRevisionForPaths(t *testing.T) { Revision: "632039659e542ed7de0c170a4fcc1c571b288fc0", }, wantErr: assert.NoError}, {name: "ChangedFilesDoNothing", fields: func() fields { - s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("Fetch", mock.Anything).Once().Return(nil) gitClient.On("IsRevisionPresent", "632039659e542ed7de0c170a4fcc1c571b288fc0").Once().Return(false) @@ -3826,9 +3838,9 @@ func TestUpdateRevisionForPaths(t *testing.T) { cache: c, } }(), args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.UpdateRevisionForPathsRequest{ - Repo: &v1alpha1.Repository{Repo: "a-url.com"}, + Repo: &argoappv1.Repository{Repo: "a-url.com"}, Revision: "HEAD", SyncedRevision: "SYNCEDHEAD", Paths: []string{"."}, @@ -3838,7 +3850,7 @@ func TestUpdateRevisionForPaths(t *testing.T) { Changes: true, }, wantErr: assert.NoError}, {name: "NoChangesUpdateCache", fields: func() fields { - s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("Fetch", mock.Anything).Once().Return(nil) gitClient.On("IsRevisionPresent", "632039659e542ed7de0c170a4fcc1c571b288fc0").Once().Return(false) @@ -3859,9 +3871,9 @@ func TestUpdateRevisionForPaths(t *testing.T) { cache: c, } }(), args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.UpdateRevisionForPathsRequest{ - Repo: &v1alpha1.Repository{Repo: "a-url.com"}, + Repo: &argoappv1.Repository{Repo: "a-url.com"}, Revision: "HEAD", SyncedRevision: "SYNCEDHEAD", Paths: []string{"."}, @@ -3870,7 +3882,7 @@ func TestUpdateRevisionForPaths(t *testing.T) { AppName: "no-change-update-cache", Namespace: "default", TrackingMethod: "annotation+label", - ApplicationSource: &v1alpha1.ApplicationSource{Path: "."}, + ApplicationSource: &argoappv1.ApplicationSource{Path: "."}, KubeVersion: "v1.16.0", }, }, want: &apiclient.UpdateRevisionForPathsResponse{ @@ -3880,7 +3892,7 @@ func TestUpdateRevisionForPaths(t *testing.T) { revision: "632039659e542ed7de0c170a4fcc1c571b288fc0", }}, {name: "NoChangesHelmMultiSourceUpdateCache", fields: func() fields { - s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, _ *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", "632039659e542ed7de0c170a4fcc1c571b288fc0").Once().Return(false) gitClient.On("Fetch", mock.Anything).Once().Return(nil) @@ -3900,9 +3912,9 @@ func TestUpdateRevisionForPaths(t *testing.T) { cache: c, } }(), args: args{ - ctx: t.Context(), + ctx: context.TODO(), request: &apiclient.UpdateRevisionForPathsRequest{ - Repo: &v1alpha1.Repository{Repo: "a-url.com"}, + Repo: &argoappv1.Repository{Repo: "a-url.com"}, Revision: "HEAD", SyncedRevision: "SYNCEDHEAD", Paths: []string{"."}, @@ -3911,7 +3923,7 @@ func TestUpdateRevisionForPaths(t *testing.T) { AppName: "no-change-update-cache", Namespace: "default", TrackingMethod: "annotation+label", - ApplicationSource: &v1alpha1.ApplicationSource{Path: ".", Helm: &v1alpha1.ApplicationSourceHelm{ReleaseName: "test"}}, + ApplicationSource: &argoappv1.ApplicationSource{Path: ".", Helm: &argoappv1.ApplicationSourceHelm{ReleaseName: "test"}}, KubeVersion: "v1.16.0", HasMultipleSources: true, @@ -3978,7 +3990,7 @@ func TestGetRefs_CacheWithLockDisabled(t *testing.T) { wg.Add(1) go func() { defer wg.Done() - client, err := git.NewClient("file://"+dir, git.NopCreds{}, true, false, "", "", git.WithCache(cacheMocks.cache, true)) + client, err := git.NewClient(fmt.Sprintf("file://%s", dir), git.NopCreds{}, true, false, "", "", git.WithCache(cacheMocks.cache, true)) require.NoError(t, err) refs, err := client.LsRefs() require.NoError(t, err) @@ -4005,7 +4017,7 @@ func TestGetRefs_CacheDisabled(t *testing.T) { }) cacheMocks := newCacheMocks() t.Cleanup(cacheMocks.mockCache.StopRedisCallback) - client, err := git.NewClient("file://"+dir, git.NopCreds{}, true, false, "", "", git.WithCache(cacheMocks.cache, false)) + client, err := git.NewClient(fmt.Sprintf("file://%s", dir), git.NopCreds{}, true, false, "", "", git.WithCache(cacheMocks.cache, false)) require.NoError(t, err) refs, err := client.LsRefs() require.NoError(t, err) @@ -4034,7 +4046,7 @@ func TestGetRefs_CacheWithLock(t *testing.T) { wg.Add(1) go func() { defer wg.Done() - client, err := git.NewClient("file://"+dir, git.NopCreds{}, true, false, "", "", git.WithCache(cacheMocks.cache, true)) + client, err := git.NewClient(fmt.Sprintf("file://%s", dir), git.NopCreds{}, true, false, "", "", git.WithCache(cacheMocks.cache, true)) require.NoError(t, err) refs, err := client.LsRefs() require.NoError(t, err) @@ -4062,8 +4074,8 @@ func TestGetRefs_CacheUnlockedOnUpdateFailed(t *testing.T) { }) cacheMocks := newCacheMocks() t.Cleanup(cacheMocks.mockCache.StopRedisCallback) - repoURL := "file://" + dir - client, err := git.NewClient(repoURL, git.NopCreds{}, true, false, "", "", git.WithCache(cacheMocks.cache, true)) + repoUrl := fmt.Sprintf("file://%s", dir) + client, err := git.NewClient(repoUrl, git.NopCreds{}, true, false, "", "", git.WithCache(cacheMocks.cache, true)) require.NoError(t, err) refs, err := client.LsRefs() require.NoError(t, err) @@ -4071,7 +4083,7 @@ func TestGetRefs_CacheUnlockedOnUpdateFailed(t *testing.T) { assert.NotEmpty(t, refs.Branches, "Expected branches to be populated") assert.NotEmpty(t, refs.Branches[0]) var output [][2]string - err = cacheMocks.cacheutilCache.GetItem(fmt.Sprintf("git-refs|%s|%s", repoURL, common.CacheVersion), &output) + err = cacheMocks.cacheutilCache.GetItem(fmt.Sprintf("git-refs|%s|%s", repoUrl, common.CacheVersion), &output) require.Error(t, err, "Should be a cache miss") assert.Empty(t, output, "Expected cache to be empty for key") cacheMocks.mockCache.AssertNumberOfCalls(t, "UnlockGitReferences", 0) @@ -4091,10 +4103,10 @@ func TestGetRefs_CacheLockTryLockGitRefCacheError(t *testing.T) { }) cacheMocks := newCacheMocks() t.Cleanup(cacheMocks.mockCache.StopRedisCallback) - repoURL := "file://" + dir + repoUrl := fmt.Sprintf("file://%s", dir) // buf := bytes.Buffer{} // log.SetOutput(&buf) - client, err := git.NewClient(repoURL, git.NopCreds{}, true, false, "", "", git.WithCache(cacheMocks.cache, true)) + client, err := git.NewClient(repoUrl, git.NopCreds{}, true, false, "", "", git.WithCache(cacheMocks.cache, true)) require.NoError(t, err) refs, err := client.LsRefs() require.NoError(t, err) @@ -4102,12 +4114,12 @@ func TestGetRefs_CacheLockTryLockGitRefCacheError(t *testing.T) { } func TestGetRevisionChartDetails(t *testing.T) { - t.Run("Test revision semver", func(t *testing.T) { + t.Run("Test revision semvar", func(t *testing.T) { root := t.TempDir() service := newService(t, root) - _, err := service.GetRevisionChartDetails(t.Context(), &apiclient.RepoServerRevisionChartDetailsRequest{ + _, err := service.GetRevisionChartDetails(context.Background(), &apiclient.RepoServerRevisionChartDetailsRequest{ Repo: &v1alpha1.Repository{ - Repo: "file://" + root, + Repo: fmt.Sprintf("file://%s", root), Name: "test-repo-name", Type: "helm", }, @@ -4120,16 +4132,16 @@ func TestGetRevisionChartDetails(t *testing.T) { t.Run("Test GetRevisionChartDetails", func(t *testing.T) { root := t.TempDir() service := newService(t, root) - repoURL := "file://" + root - err := service.cache.SetRevisionChartDetails(repoURL, "my-chart", "1.1.0", &v1alpha1.ChartDetails{ + repoUrl := fmt.Sprintf("file://%s", root) + err := service.cache.SetRevisionChartDetails(repoUrl, "my-chart", "1.1.0", &argoappv1.ChartDetails{ Description: "test-description", Home: "test-home", Maintainers: []string{"test-maintainer"}, }) require.NoError(t, err) - chartDetails, err := service.GetRevisionChartDetails(t.Context(), &apiclient.RepoServerRevisionChartDetailsRequest{ + chartDetails, err := service.GetRevisionChartDetails(context.Background(), &apiclient.RepoServerRevisionChartDetailsRequest{ Repo: &v1alpha1.Repository{ - Repo: "file://" + root, + Repo: fmt.Sprintf("file://%s", root), Name: "test-repo-name", Type: "helm", }, @@ -4153,6 +4165,7 @@ func TestVerifyCommitSignature(t *testing.T) { mockGitClient := &gitmocks.Client{} mockGitClient.On("VerifyCommitSignature", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(testSignature, nil) + err := verifyCommitSignature(true, mockGitClient, "abcd1234", repo) require.NoError(t, err) }) @@ -4162,26 +4175,32 @@ func TestVerifyCommitSignature(t *testing.T) { mockGitClient := &gitmocks.Client{} mockGitClient.On("VerifyCommitSignature", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return("", nil) + err := verifyCommitSignature(true, mockGitClient, "abcd1234", repo) - assert.EqualError(t, err, "revision abcd1234 is not signed") + require.Error(t, err) + assert.Equal(t, "revision abcd1234 is not signed", err.Error()) }) t.Run("VerifyCommitSignature with unknown signature", func(t *testing.T) { t.Setenv("ARGOCD_GPG_ENABLED", "true") mockGitClient := &gitmocks.Client{} mockGitClient.On("VerifyCommitSignature", mock.Anything, mock.Anything, mock.Anything, mock.Anything). - Return("", errors.New("UNKNOWN signature: gpg: Unknown signature from ABCDEFGH")) + Return("", fmt.Errorf("UNKNOWN signature: gpg: Unknown signature from ABCDEFGH")) + err := verifyCommitSignature(true, mockGitClient, "abcd1234", repo) - assert.EqualError(t, err, "UNKNOWN signature: gpg: Unknown signature from ABCDEFGH") + require.Error(t, err) + assert.Equal(t, "UNKNOWN signature: gpg: Unknown signature from ABCDEFGH", err.Error()) }) t.Run("VerifyCommitSignature with error verifying signature", func(t *testing.T) { t.Setenv("ARGOCD_GPG_ENABLED", "true") mockGitClient := &gitmocks.Client{} mockGitClient.On("VerifyCommitSignature", mock.Anything, mock.Anything, mock.Anything, mock.Anything). - Return("", errors.New("error verifying signature of commit 'abcd1234' in repo 'https://github.com/example/repo.git': failed to verify signature")) + Return("", fmt.Errorf("error verifying signature of commit 'abcd1234' in repo 'https://github.com/example/repo.git': failed to verify signature")) + err := verifyCommitSignature(true, mockGitClient, "abcd1234", repo) - assert.EqualError(t, err, "error verifying signature of commit 'abcd1234' in repo 'https://github.com/example/repo.git': failed to verify signature") + require.Error(t, err) + assert.Equal(t, "error verifying signature of commit 'abcd1234' in repo 'https://github.com/example/repo.git': failed to verify signature", err.Error()) }) t.Run("VerifyCommitSignature with signature verification disabled", func(t *testing.T) { @@ -4202,17 +4221,17 @@ func Test_GenerateManifests_Commands(t *testing.T) { Namespace: "test-namespace", KubeVersion: "1.2.3", ApiVersions: []string{"v1/Test", "v2/Test"}, - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", - Helm: &v1alpha1.ApplicationSourceHelm{ - FileParameters: []v1alpha1.HelmFileParameter{ + Helm: &argoappv1.ApplicationSourceHelm{ + FileParameters: []argoappv1.HelmFileParameter{ { Name: "test-file-param-name", Path: "test-file-param.yaml", }, }, - Parameters: []v1alpha1.HelmParameter{ + Parameters: []argoappv1.HelmParameter{ { Name: "test-param-name", // Use build env var to test substitution. @@ -4238,7 +4257,7 @@ func Test_GenerateManifests_Commands(t *testing.T) { ProjectSourceRepos: []string{"*"}, } - res, err := service.GenerateManifest(t.Context(), &q) + res, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Equal(t, []string{"helm template . --name-template test-app --namespace test-namespace --kube-version 1.2.3 --set test-param-bool-name=false --set-string test-param-name=test-value-test-app --set-file test-file-param-name=./test-file-param.yaml --values ./my-chart-values.yaml --values --api-versions v1/Test --api-versions v2/Test"}, res.Commands) @@ -4250,7 +4269,7 @@ func Test_GenerateManifests_Commands(t *testing.T) { q.ApplicationSource.Helm.Namespace = "different-namespace" q.ApplicationSource.Helm.ReleaseName = "different-release-name" - res, err = service.GenerateManifest(t.Context(), &q) + res, err = service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Equal(t, []string{"helm template . --name-template different-release-name --namespace different-namespace --kube-version 5.6.7 --set test-param-bool-name=false --set-string test-param-name=test-value-test-app --set-file test-file-param-name=./test-file-param.yaml --values ./my-chart-values.yaml --values --api-versions v3 --api-versions v4"}, res.Commands) @@ -4273,15 +4292,15 @@ func Test_GenerateManifests_Commands(t *testing.T) { q := apiclient.ManifestRequest{ AppName: "test-app", Namespace: "test-namespace", - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", }, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res, err := service.GenerateManifest(t.Context(), &q) + res, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Equal(t, []string{"helm template . --name-template test-app --namespace test-namespace --include-crds"}, res.Commands) @@ -4315,16 +4334,16 @@ images: service := newService(t, tempDir) - // Fill the manifest request with as many parameters affecting Kustomize commands as possible. + // Fill the manifest request with as many parameters affecting Helm commands as possible. q := apiclient.ManifestRequest{ AppName: "test-app", Namespace: "test-namespace", KubeVersion: "1.2.3", ApiVersions: []string{"v1/Test", "v2/Test"}, - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", - Kustomize: &v1alpha1.ApplicationSourceKustomize{ + Kustomize: &argoappv1.ApplicationSourceKustomize{ APIVersions: []string{"v1", "v2"}, CommonAnnotations: map[string]string{ // Use build env var to test substitution. @@ -4337,16 +4356,15 @@ images: Components: []string{"component"}, ForceCommonAnnotations: true, ForceCommonLabels: true, - Images: v1alpha1.KustomizeImages{ + Images: argoappv1.KustomizeImages{ "image=override", }, - KubeVersion: "5.6.7", - LabelWithoutSelector: true, - LabelIncludeTemplates: true, - NamePrefix: "test-prefix", - NameSuffix: "test-suffix", - Namespace: "override-namespace", - Replicas: v1alpha1.KustomizeReplicas{ + KubeVersion: "5.6.7", + LabelWithoutSelector: true, + NamePrefix: "test-prefix", + NameSuffix: "test-suffix", + Namespace: "override-namespace", + Replicas: argoappv1.KustomizeReplicas{ { Name: "guestbook-ui", Count: intstr.Parse("1337"), @@ -4358,7 +4376,7 @@ images: ProjectSourceRepos: []string{"*"}, } - res, err := service.GenerateManifest(t.Context(), &q) + res, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Equal(t, []string{ @@ -4366,7 +4384,7 @@ images: "kustomize edit set namesuffix -- test-suffix", "kustomize edit set image image=override", "kustomize edit set replicas guestbook-ui=1337", - "kustomize edit add label --force --without-selector --include-templates test:label", + "kustomize edit add label --force --without-selector test:label", "kustomize edit add annotation --force test:annotation-test-app", "kustomize edit set namespace -- override-namespace", "kustomize edit add component component", @@ -4381,16 +4399,16 @@ func Test_SkipSchemaValidation(t *testing.T) { q := apiclient.ManifestRequest{ AppName: "test-app", - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ SkipSchemaValidation: true, }, }, } - res, err := service.GenerateManifest(t.Context(), &q) + res, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Equal(t, []string{"helm template . --name-template test-app --include-crds --skip-schema-validation"}, res.Commands) @@ -4400,16 +4418,16 @@ func Test_SkipSchemaValidation(t *testing.T) { q := apiclient.ManifestRequest{ AppName: "test-app", - Repo: &v1alpha1.Repository{}, - ApplicationSource: &v1alpha1.ApplicationSource{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argoappv1.ApplicationSourceHelm{ SkipSchemaValidation: false, }, }, } - _, err := service.GenerateManifest(t.Context(), &q) + _, err := service.GenerateManifest(context.Background(), &q) require.ErrorContains(t, err, "values don't meet the specifications of the schema(s)") }) diff --git a/reposerver/repository/testdata/app-parameters/multi/.argocd-source-broken.yaml b/reposerver/repository/testdata/app-parameters/multi/.argocd-source-broken.yaml index 88aed61dbb..a2a93cfc12 100644 --- a/reposerver/repository/testdata/app-parameters/multi/.argocd-source-broken.yaml +++ b/reposerver/repository/testdata/app-parameters/multi/.argocd-source-broken.yaml @@ -1,4 +1,4 @@ aloi kustomize: images: - - quay.io/argoprojlabs/argocd-e2e-container:0.2 + - gcr.io/heptio-images/ks-guestbook-demo:0.2 diff --git a/reposerver/repository/testdata/app-parameters/multi/.argocd-source-testapp.yaml b/reposerver/repository/testdata/app-parameters/multi/.argocd-source-testapp.yaml index d9a3e89708..4ae4c973e3 100644 --- a/reposerver/repository/testdata/app-parameters/multi/.argocd-source-testapp.yaml +++ b/reposerver/repository/testdata/app-parameters/multi/.argocd-source-testapp.yaml @@ -1,3 +1,3 @@ kustomize: images: - - quay.io/argoprojlabs/argocd-e2e-container:0.3 + - gcr.io/heptio-images/ks-guestbook-demo:0.3 diff --git a/reposerver/repository/testdata/app-parameters/multi/.argocd-source-unmergeable.yaml b/reposerver/repository/testdata/app-parameters/multi/.argocd-source-unmergeable.yaml index aa5422fafd..baae7e7467 100644 --- a/reposerver/repository/testdata/app-parameters/multi/.argocd-source-unmergeable.yaml +++ b/reposerver/repository/testdata/app-parameters/multi/.argocd-source-unmergeable.yaml @@ -1,6 +1,6 @@ repo: https://somewhere kustomize: images: - - quay.io/argoprojlabs/argocd-e2e-container:0.3 + - gcr.io/heptio-images/ks-guestbook-demo:0.3 invalid: - I don't know diff --git a/reposerver/repository/testdata/app-parameters/multi/.argocd-source.yaml b/reposerver/repository/testdata/app-parameters/multi/.argocd-source.yaml index 631fd809f5..592624a909 100644 --- a/reposerver/repository/testdata/app-parameters/multi/.argocd-source.yaml +++ b/reposerver/repository/testdata/app-parameters/multi/.argocd-source.yaml @@ -1,3 +1,3 @@ kustomize: images: - - quay.io/argoprojlabs/argocd-e2e-container:0.2 \ No newline at end of file + - gcr.io/heptio-images/ks-guestbook-demo:0.2 \ No newline at end of file diff --git a/reposerver/repository/testdata/app-parameters/multi/guestbook.yaml b/reposerver/repository/testdata/app-parameters/multi/guestbook.yaml index b4ce7a199b..7afcc593a6 100644 --- a/reposerver/repository/testdata/app-parameters/multi/guestbook.yaml +++ b/reposerver/repository/testdata/app-parameters/multi/guestbook.yaml @@ -12,7 +12,7 @@ spec: app: guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.1 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.1 name: guestbook-ui ports: - containerPort: 81 diff --git a/reposerver/repository/testdata/app-parameters/multi/kustomization.yaml b/reposerver/repository/testdata/app-parameters/multi/kustomization.yaml index 78655aff5f..4b35aa5881 100644 --- a/reposerver/repository/testdata/app-parameters/multi/kustomization.yaml +++ b/reposerver/repository/testdata/app-parameters/multi/kustomization.yaml @@ -4,5 +4,5 @@ kind: Kustomization resources: - guestbook.yaml images: -- name: quay.io/argoprojlabs/argocd-e2e-container +- name: gcr.io/heptio-images/ks-guestbook-demo newTag: "0.1" diff --git a/reposerver/repository/testdata/app-parameters/single-app-only/.argocd-source-testapp.yaml b/reposerver/repository/testdata/app-parameters/single-app-only/.argocd-source-testapp.yaml index d9a3e89708..4ae4c973e3 100644 --- a/reposerver/repository/testdata/app-parameters/single-app-only/.argocd-source-testapp.yaml +++ b/reposerver/repository/testdata/app-parameters/single-app-only/.argocd-source-testapp.yaml @@ -1,3 +1,3 @@ kustomize: images: - - quay.io/argoprojlabs/argocd-e2e-container:0.3 + - gcr.io/heptio-images/ks-guestbook-demo:0.3 diff --git a/reposerver/repository/testdata/app-parameters/single-app-only/guestbook.yaml b/reposerver/repository/testdata/app-parameters/single-app-only/guestbook.yaml index b4ce7a199b..7afcc593a6 100644 --- a/reposerver/repository/testdata/app-parameters/single-app-only/guestbook.yaml +++ b/reposerver/repository/testdata/app-parameters/single-app-only/guestbook.yaml @@ -12,7 +12,7 @@ spec: app: guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.1 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.1 name: guestbook-ui ports: - containerPort: 81 diff --git a/reposerver/repository/testdata/app-parameters/single-app-only/kustomization.yaml b/reposerver/repository/testdata/app-parameters/single-app-only/kustomization.yaml index 78655aff5f..4b35aa5881 100644 --- a/reposerver/repository/testdata/app-parameters/single-app-only/kustomization.yaml +++ b/reposerver/repository/testdata/app-parameters/single-app-only/kustomization.yaml @@ -4,5 +4,5 @@ kind: Kustomization resources: - guestbook.yaml images: -- name: quay.io/argoprojlabs/argocd-e2e-container +- name: gcr.io/heptio-images/ks-guestbook-demo newTag: "0.1" diff --git a/reposerver/repository/testdata/app-parameters/single-global-helm/templates/deployment.yaml b/reposerver/repository/testdata/app-parameters/single-global-helm/templates/deployment.yaml index 327d45ab58..2702a963be 100644 --- a/reposerver/repository/testdata/app-parameters/single-global-helm/templates/deployment.yaml +++ b/reposerver/repository/testdata/app-parameters/single-global-helm/templates/deployment.yaml @@ -12,7 +12,7 @@ spec: app: guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:{{.Values.image.tag}} + - image: gcr.io/heptio-images/ks-guestbook-demo:{{.Values.image.tag}} name: guestbook-ui ports: - containerPort: 81 diff --git a/reposerver/repository/testdata/app-parameters/single-global/.argocd-source.yaml b/reposerver/repository/testdata/app-parameters/single-global/.argocd-source.yaml index 631fd809f5..592624a909 100644 --- a/reposerver/repository/testdata/app-parameters/single-global/.argocd-source.yaml +++ b/reposerver/repository/testdata/app-parameters/single-global/.argocd-source.yaml @@ -1,3 +1,3 @@ kustomize: images: - - quay.io/argoprojlabs/argocd-e2e-container:0.2 \ No newline at end of file + - gcr.io/heptio-images/ks-guestbook-demo:0.2 \ No newline at end of file diff --git a/reposerver/repository/testdata/app-parameters/single-global/guestbook.yaml b/reposerver/repository/testdata/app-parameters/single-global/guestbook.yaml index b4ce7a199b..7afcc593a6 100644 --- a/reposerver/repository/testdata/app-parameters/single-global/guestbook.yaml +++ b/reposerver/repository/testdata/app-parameters/single-global/guestbook.yaml @@ -12,7 +12,7 @@ spec: app: guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.1 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.1 name: guestbook-ui ports: - containerPort: 81 diff --git a/reposerver/repository/testdata/app-parameters/single-global/kustomization.yaml b/reposerver/repository/testdata/app-parameters/single-global/kustomization.yaml index 78655aff5f..4b35aa5881 100644 --- a/reposerver/repository/testdata/app-parameters/single-global/kustomization.yaml +++ b/reposerver/repository/testdata/app-parameters/single-global/kustomization.yaml @@ -4,5 +4,5 @@ kind: Kustomization resources: - guestbook.yaml images: -- name: quay.io/argoprojlabs/argocd-e2e-container +- name: gcr.io/heptio-images/ks-guestbook-demo newTag: "0.1" diff --git a/reposerver/repository/testdata/jsonnet-1/params.libsonnet b/reposerver/repository/testdata/jsonnet-1/params.libsonnet index d8350ab614..ef968d6a45 100644 --- a/reposerver/repository/testdata/jsonnet-1/params.libsonnet +++ b/reposerver/repository/testdata/jsonnet-1/params.libsonnet @@ -1,6 +1,6 @@ { containerPort: 80, - image: "quay.io/argoprojlabs/argocd-e2e-container:0.2", + image: "gcr.io/heptio-images/ks-guestbook-demo:0.2", name: "guestbook-ui", replicas: 1, servicePort: 80, diff --git a/reposerver/repository/testdata/jsonnet/params.libsonnet b/reposerver/repository/testdata/jsonnet/params.libsonnet index d8350ab614..ef968d6a45 100644 --- a/reposerver/repository/testdata/jsonnet/params.libsonnet +++ b/reposerver/repository/testdata/jsonnet/params.libsonnet @@ -1,6 +1,6 @@ { containerPort: 80, - image: "quay.io/argoprojlabs/argocd-e2e-container:0.2", + image: "gcr.io/heptio-images/ks-guestbook-demo:0.2", name: "guestbook-ui", replicas: 1, servicePort: 80, diff --git a/reposerver/repository/types.go b/reposerver/repository/types.go index 257ac6b52e..3e45a5bf3a 100644 --- a/reposerver/repository/types.go +++ b/reposerver/repository/types.go @@ -10,5 +10,5 @@ type Chart struct { type Maintainer struct { Name string `yaml:"name,omitempty"` Email string `yaml:"email,omitempty"` - Url string `yaml:"url,omitempty"` //nolint:revive //FIXME(var-naming) + Url string `yaml:"url,omitempty"` } diff --git a/reposerver/repository/utils.go b/reposerver/repository/utils.go index 9dc45f2b85..d77bef728d 100644 --- a/reposerver/repository/utils.go +++ b/reposerver/repository/utils.go @@ -7,8 +7,8 @@ import ( securejoin "github.com/cyphar/filepath-securejoin" log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/io/files" + "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 diff --git a/reposerver/repository/utils_test.go b/reposerver/repository/utils_test.go index 1664adf02d..3eb2428f09 100644 --- a/reposerver/repository/utils_test.go +++ b/reposerver/repository/utils_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" ) func TestGetCommonRootPath(t *testing.T) { diff --git a/reposerver/server.go b/reposerver/server.go index f6ef29ff85..5d280329de 100644 --- a/reposerver/server.go +++ b/reposerver/server.go @@ -6,12 +6,12 @@ import ( "os" "path/filepath" - grpc_prometheus "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery" - "github.com/prometheus/client_golang/prometheus" - log "github.com/sirupsen/logrus" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" + + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + log "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/health" @@ -19,18 +19,18 @@ import ( "google.golang.org/grpc/keepalive" "google.golang.org/grpc/reflection" - "github.com/argoproj/argo-cd/v3/common" - versionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/version" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - reposervercache "github.com/argoproj/argo-cd/v3/reposerver/cache" - "github.com/argoproj/argo-cd/v3/reposerver/metrics" - "github.com/argoproj/argo-cd/v3/reposerver/repository" - "github.com/argoproj/argo-cd/v3/server/version" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/git" - grpc_util "github.com/argoproj/argo-cd/v3/util/grpc" - tlsutil "github.com/argoproj/argo-cd/v3/util/tls" + "github.com/argoproj/argo-cd/v2/common" + versionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/version" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + reposervercache "github.com/argoproj/argo-cd/v2/reposerver/cache" + "github.com/argoproj/argo-cd/v2/reposerver/metrics" + "github.com/argoproj/argo-cd/v2/reposerver/repository" + "github.com/argoproj/argo-cd/v2/server/version" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/git" + grpc_util "github.com/argoproj/argo-cd/v2/util/grpc" + tlsutil "github.com/argoproj/argo-cd/v2/util/tls" ) // ArgoCDRepoServer is the repo server implementation @@ -45,7 +45,7 @@ type ArgoCDRepoServer struct { } // The hostnames to generate self-signed issues with -var tlsHostList = []string{"localhost", "reposerver"} +var tlsHostList []string = []string{"localhost", "reposerver"} // NewServer returns a new instance of the Argo CD Repo server func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cache, tlsConfCustomizer tlsutil.ConfigCustomizer, initConstants repository.RepoServerInitConstants, gitCredsStore git.CredsStore) (*ArgoCDRepoServer, error) { @@ -55,8 +55,8 @@ func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cach // repository server. if tlsConfCustomizer != nil { var err error - certPath := env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath) + "/reposerver/tls/tls.crt" - keyPath := env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath) + "/reposerver/tls/tls.key" + certPath := fmt.Sprintf("%s/reposerver/tls/tls.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)) + keyPath := fmt.Sprintf("%s/reposerver/tls/tls.key", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)) tlsConfig, err = tlsutil.CreateServerTLSConfig(certPath, keyPath, tlsHostList) if err != nil { return nil, fmt.Errorf("error creating server TLS config: %w", err) @@ -64,32 +64,28 @@ func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cach tlsConfCustomizer(tlsConfig) } - var serverMetricsOptions []grpc_prometheus.ServerMetricsOption if os.Getenv(common.EnvEnableGRPCTimeHistogramEnv) == "true" { - serverMetricsOptions = append(serverMetricsOptions, grpc_prometheus.WithServerHandlingTimeHistogram()) + grpc_prometheus.EnableHandlingTimeHistogram() } - serverMetrics := grpc_prometheus.NewServerMetrics(serverMetricsOptions...) - reg := prometheus.NewRegistry() - reg.MustRegister(serverMetrics) serverLog := log.NewEntry(log.StandardLogger()) streamInterceptors := []grpc.StreamServerInterceptor{ otelgrpc.StreamServerInterceptor(), //nolint:staticcheck // TODO: ignore SA1019 for depreciation: see https://github.com/argoproj/argo-cd/issues/18258 - logging.StreamServerInterceptor(grpc_util.InterceptorLogger(serverLog)), - serverMetrics.StreamServerInterceptor(), - recovery.StreamServerInterceptor(recovery.WithRecoveryHandler(grpc_util.LoggerRecoveryHandler(serverLog))), + grpc_logrus.StreamServerInterceptor(serverLog), + grpc_prometheus.StreamServerInterceptor, + grpc_util.PanicLoggerStreamServerInterceptor(serverLog), } unaryInterceptors := []grpc.UnaryServerInterceptor{ otelgrpc.UnaryServerInterceptor(), //nolint:staticcheck // TODO: ignore SA1019 for depreciation: see https://github.com/argoproj/argo-cd/issues/18258 - logging.UnaryServerInterceptor(grpc_util.InterceptorLogger(serverLog)), - serverMetrics.UnaryServerInterceptor(), - recovery.UnaryServerInterceptor(recovery.WithRecoveryHandler(grpc_util.LoggerRecoveryHandler(serverLog))), + grpc_logrus.UnaryServerInterceptor(serverLog), + grpc_prometheus.UnaryServerInterceptor, + grpc_util.PanicLoggerUnaryServerInterceptor(serverLog), grpc_util.ErrorSanitizerUnaryServerInterceptor(), } serverOpts := []grpc.ServerOption{ - grpc.ChainUnaryInterceptor(unaryInterceptors...), - grpc.ChainStreamInterceptor(streamInterceptors...), + grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(unaryInterceptors...)), + grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(streamInterceptors...)), grpc.MaxRecvMsgSize(apiclient.MaxGRPCMessageSize), grpc.MaxSendMsgSize(apiclient.MaxGRPCMessageSize), grpc.KeepaliveEnforcementPolicy( diff --git a/resource_customizations/_.crossplane.io/_/health.lua b/resource_customizations/_.crossplane.io/_/health.lua deleted file mode 100644 index c4cd585cfd..0000000000 --- a/resource_customizations/_.crossplane.io/_/health.lua +++ /dev/null @@ -1,66 +0,0 @@ --- Health check copied from here: https://github.com/crossplane/docs/blob/bd701357e9d5eecf529a0b42f23a78850a6d1d87/content/master/guides/crossplane-with-argo-cd.md - -health_status = { - status = "Progressing", - message = "Provisioning ..." -} - -local function contains (table, val) - for i, v in ipairs(table) do - if v == val then - return true - end - end - return false -end - -local has_no_status = { - "Composition", - "CompositionRevision", - "DeploymentRuntimeConfig", - "ControllerConfig", - "ProviderConfig", - "ProviderConfigUsage" -} -if obj.status == nil or next(obj.status) == nil and contains(has_no_status, obj.kind) then - health_status.status = "Healthy" - health_status.message = "Resource is up-to-date." - return health_status -end - -if obj.status == nil or next(obj.status) == nil or obj.status.conditions == nil then - if obj.kind == "ProviderConfig" and obj.status.users ~= nil then - health_status.status = "Healthy" - health_status.message = "Resource is in use." - return health_status - end - return health_status -end - -for i, condition in ipairs(obj.status.conditions) do - if condition.type == "LastAsyncOperation" then - if condition.status == "False" then - health_status.status = "Degraded" - health_status.message = condition.message - return health_status - end - end - - if condition.type == "Synced" then - if condition.status == "False" then - health_status.status = "Degraded" - health_status.message = condition.message - return health_status - end - end - - if contains({"Ready", "Healthy", "Offered", "Established"}, condition.type) then - if condition.status == "True" then - health_status.status = "Healthy" - health_status.message = "Resource is up-to-date." - return health_status - end - end -end - -return health_status diff --git a/resource_customizations/_.crossplane.io/_/health_test.yaml b/resource_customizations/_.crossplane.io/_/health_test.yaml deleted file mode 100644 index 7ef0da9913..0000000000 --- a/resource_customizations/_.crossplane.io/_/health_test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -tests: - - healthStatus: - status: Healthy - message: "Resource is up-to-date." - inputPath: testdata/composition_healthy.yaml diff --git a/resource_customizations/_.crossplane.io/_/testdata/composition_healthy.yaml b/resource_customizations/_.crossplane.io/_/testdata/composition_healthy.yaml deleted file mode 100644 index 56ae5ac89e..0000000000 --- a/resource_customizations/_.crossplane.io/_/testdata/composition_healthy.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Taken from here May 9, 2025: https://docs.crossplane.io/latest/concepts/compositions/ -apiVersion: apiextensions.crossplane.io/v1 -kind: Composition -metadata: - name: example -spec: - compositeTypeRef: - apiVersion: custom-api.example.org/v1alpha1 - kind: AcmeBucket - mode: Pipeline - pipeline: - - step: patch-and-transform - functionRef: - name: function-patch-and-transform - input: - apiVersion: pt.fn.crossplane.io/v1beta1 - kind: Resources - resources: - - name: storage-bucket - base: - apiVersion: s3.aws.upbound.io/v1beta1 - kind: Bucket - spec: - forProvider: - region: "us-east-2" diff --git a/resource_customizations/_.upbound.io/_/health.lua b/resource_customizations/_.upbound.io/_/health.lua deleted file mode 100644 index 57869c81f8..0000000000 --- a/resource_customizations/_.upbound.io/_/health.lua +++ /dev/null @@ -1,63 +0,0 @@ --- Health check copied from here: https://github.com/crossplane/docs/blob/bd701357e9d5eecf529a0b42f23a78850a6d1d87/content/master/guides/crossplane-with-argo-cd.md - -health_status = { - status = "Progressing", - message = "Provisioning ..." -} - -local function contains (table, val) - for i, v in ipairs(table) do - if v == val then - return true - end - end - return false -end - -local has_no_status = { - "ProviderConfig", - "ProviderConfigUsage" -} - -if obj.status == nil or next(obj.status) == nil and contains(has_no_status, obj.kind) then - health_status.status = "Healthy" - health_status.message = "Resource is up-to-date." - return health_status -end - -if obj.status == nil or next(obj.status) == nil or obj.status.conditions == nil then - if obj.kind == "ProviderConfig" and obj.status.users ~= nil then - health_status.status = "Healthy" - health_status.message = "Resource is in use." - return health_status - end - return health_status -end - -for i, condition in ipairs(obj.status.conditions) do - if condition.type == "LastAsyncOperation" then - if condition.status == "False" then - health_status.status = "Degraded" - health_status.message = condition.message - return health_status - end - end - - if condition.type == "Synced" then - if condition.status == "False" then - health_status.status = "Degraded" - health_status.message = condition.message - return health_status - end - end - - if condition.type == "Ready" then - if condition.status == "True" then - health_status.status = "Healthy" - health_status.message = "Resource is up-to-date." - return health_status - end - end -end - -return health_status diff --git a/resource_customizations/_.upbound.io/_/health_test.yaml b/resource_customizations/_.upbound.io/_/health_test.yaml deleted file mode 100644 index a11541d263..0000000000 --- a/resource_customizations/_.upbound.io/_/health_test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -tests: - - healthStatus: - status: Healthy - message: "Resource is up-to-date." - inputPath: testdata/providerconfig_healthy.yaml diff --git a/resource_customizations/_.upbound.io/_/testdata/providerconfig_healthy.yaml b/resource_customizations/_.upbound.io/_/testdata/providerconfig_healthy.yaml deleted file mode 100644 index 5429ac065c..0000000000 --- a/resource_customizations/_.upbound.io/_/testdata/providerconfig_healthy.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: aws.upbound.io/v1beta1 -kind: ProviderConfig -metadata: - name: irsa-with-role-chaining -spec: - credentials: - source: IRSA - assumeRoleChain: - - roleARN: - - roleARN: diff --git a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/health.lua b/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/health.lua deleted file mode 100644 index 23d944fc46..0000000000 --- a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/health.lua +++ /dev/null @@ -1,82 +0,0 @@ -local hs = {} - --- Check if CRD is terminating -if obj.metadata.deletionTimestamp ~= nil then - hs.status = "Progressing" - hs.message = "CRD is terminating" - return hs -end - -if obj.status.conditions == nil then - hs.status = "Progressing" - hs.message = "Status conditions not found" - return hs -end - -if #obj.status.conditions == 0 then - hs.status = "Progressing" - hs.message = "Status conditions not found" - return hs -end - -local isEstablished -local isTerminating -local namesNotAccepted -local hasViolations -local conditionMsg = "" - -for _, condition in pairs(obj.status.conditions) do - - -- Check if CRD is terminating - if condition.type == "Terminating" and condition.status == "True" then - isTerminating = true - conditionMsg = condition.message - end - - -- Check if K8s has accepted names for this CRD - if condition.type == "NamesAccepted" and condition.status == "False" then - namesNotAccepted = true - conditionMsg = condition.message - end - - -- Checking if CRD is established - if condition.type == "Established" and condition.status == "True" then - isEstablished = true - conditionMsg = condition.message - end - - -- Checking if CRD has violations - if condition.type == "NonStructuralSchema" and condition.status == "True" then - hasViolations = true - conditionMsg = condition.message - end - -end - -if isTerminating then - hs.status = "Progressing" - hs.message = "CRD is terminating: " .. conditionMsg - return hs -end - -if namesNotAccepted then - hs.status = "Degraded" - hs.message = "CRD names have not been accepted: " .. conditionMsg - return hs -end - -if not isEstablished then - hs.status = "Degraded" - hs.message = "CRD is not established" - return hs -end - -if hasViolations then - hs.status = "Degraded" - hs.message = "Schema violations found: " .. conditionMsg - return hs -end - -hs.status = "Healthy" -hs.message = "CRD is healthy" -return hs \ No newline at end of file diff --git a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/health_test.yaml b/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/health_test.yaml deleted file mode 100644 index fd984be026..0000000000 --- a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/health_test.yaml +++ /dev/null @@ -1,29 +0,0 @@ -tests: -- healthStatus: - status: Healthy - message: "CRD is healthy" - inputPath: testdata/crd-v1-healthy.yaml -- healthStatus: - status: Degraded - message: "CRD names have not been accepted: the initial names have not been accepted" - inputPath: testdata/crd-v1-names-not-accepted-degraded.yaml -- healthStatus: - status: Degraded - message: "Schema violations found: spec.preserveUnknownFields: Invalid value: true: must be false" - inputPath: testdata/crd-v1-non-structual-degraded.yaml -- healthStatus: - status: Degraded - message: "CRD is not established" - inputPath: testdata/crd-v1-not-established-degraded.yaml -- healthStatus: - status: Progressing - message: "CRD is terminating: user has deleted the CRD" - inputPath: testdata/crd-v1-terminating-condition-progressing.yaml -- healthStatus: - status: Progressing - message: "CRD is terminating" - inputPath: testdata/crd-v1-terminating-timestamp-progressing.yaml -- healthStatus: - status: Progressing - message: "Status conditions not found" - inputPath: testdata/crd-v1-no-conditions-progressing.yaml \ No newline at end of file diff --git a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-healthy.yaml b/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-healthy.yaml deleted file mode 100644 index 09e00f70bc..0000000000 --- a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-healthy.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: examples.example.io -spec: - conversion: - strategy: None - group: example.io - names: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - preserveUnknownFields: true - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: >- - CreationTimestamp is a timestamp representing the server time when - this object was created. It is not guaranteed to be set in - happens-before order across separate operations. Clients may not set - this value. It is represented in RFC3339 form and is in UTC. - - - Populated by the system. Read-only. Null for lists. More info: - https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - served: true - storage: true - subresources: {} -status: - acceptedNames: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - conditions: - - lastTransitionTime: '2024-05-19T23:35:28Z' - message: no conflicts found - reason: NoConflicts - status: 'True' - type: NamesAccepted - - lastTransitionTime: '2024-05-19T23:35:28Z' - message: the initial names have been accepted - reason: InitialNamesAccepted - status: 'True' - type: Established - storedVersions: - - v1alpha1 \ No newline at end of file diff --git a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-names-not-accepted-degraded.yaml b/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-names-not-accepted-degraded.yaml deleted file mode 100644 index 196344b585..0000000000 --- a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-names-not-accepted-degraded.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: examples.example.io -spec: - conversion: - strategy: None - group: example.io - names: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - preserveUnknownFields: true - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: >- - CreationTimestamp is a timestamp representing the server time when - this object was created. It is not guaranteed to be set in - happens-before order across separate operations. Clients may not set - this value. It is represented in RFC3339 form and is in UTC. - - - Populated by the system. Read-only. Null for lists. More info: - https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - served: true - storage: true - subresources: {} -status: - acceptedNames: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - conditions: - - lastTransitionTime: '2024-05-19T23:35:28Z' - message: the initial names have not been accepted - reason: NoConflicts - status: 'False' - type: NamesAccepted - - lastTransitionTime: '2024-05-19T23:35:28Z' - message: the initial names have been accepted - reason: InitialNamesAccepted - status: 'False' - type: Established - storedVersions: - - v1alpha1 \ No newline at end of file diff --git a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-no-conditions-progressing.yaml b/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-no-conditions-progressing.yaml deleted file mode 100644 index f12ce016bd..0000000000 --- a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-no-conditions-progressing.yaml +++ /dev/null @@ -1,46 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: examples.example.io -spec: - conversion: - strategy: None - group: example.io - names: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - preserveUnknownFields: true - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: >- - CreationTimestamp is a timestamp representing the server time when - this object was created. It is not guaranteed to be set in - happens-before order across separate operations. Clients may not set - this value. It is represented in RFC3339 form and is in UTC. - - - Populated by the system. Read-only. Null for lists. More info: - https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - served: true - storage: true - subresources: {} -status: - acceptedNames: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - conditions: [] - storedVersions: - - v1alpha1 \ No newline at end of file diff --git a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-non-structual-degraded.yaml b/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-non-structual-degraded.yaml deleted file mode 100644 index 3c7a07f3e3..0000000000 --- a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-non-structual-degraded.yaml +++ /dev/null @@ -1,61 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: examples.example.io -spec: - conversion: - strategy: None - group: example.io - names: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - preserveUnknownFields: true - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: >- - CreationTimestamp is a timestamp representing the server time when - this object was created. It is not guaranteed to be set in - happens-before order across separate operations. Clients may not set - this value. It is represented in RFC3339 form and is in UTC. - - - Populated by the system. Read-only. Null for lists. More info: - https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - served: true - storage: true - subresources: {} -status: - acceptedNames: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - conditions: - - lastTransitionTime: '2024-05-19T23:35:28Z' - message: no conflicts found - reason: NoConflicts - status: 'True' - type: NamesAccepted - - lastTransitionTime: '2024-05-19T23:35:28Z' - message: the initial names have been accepted - reason: InitialNamesAccepted - status: 'True' - type: Established - - lastTransitionTime: '2024-10-26T19:44:57Z' - message: 'spec.preserveUnknownFields: Invalid value: true: must be false' - reason: Violations - status: 'True' - type: NonStructuralSchema - storedVersions: - - v1alpha1 \ No newline at end of file diff --git a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-not-established-degraded.yaml b/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-not-established-degraded.yaml deleted file mode 100644 index 54495d16ab..0000000000 --- a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-not-established-degraded.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: examples.example.io -spec: - conversion: - strategy: None - group: example.io - names: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - preserveUnknownFields: true - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: >- - CreationTimestamp is a timestamp representing the server time when - this object was created. It is not guaranteed to be set in - happens-before order across separate operations. Clients may not set - this value. It is represented in RFC3339 form and is in UTC. - - - Populated by the system. Read-only. Null for lists. More info: - https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - served: true - storage: true - subresources: {} -status: - acceptedNames: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - conditions: - - lastTransitionTime: '2024-05-19T23:35:28Z' - message: no conflicts found - reason: NoConflicts - status: 'True' - type: NamesAccepted - - lastTransitionTime: '2024-05-19T23:35:28Z' - message: the initial names have not been accepted - reason: InitialNamesAccepted - status: 'False' - type: Established - storedVersions: - - v1alpha1 \ No newline at end of file diff --git a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-terminating-condition-progressing.yaml b/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-terminating-condition-progressing.yaml deleted file mode 100644 index d55e8e0c03..0000000000 --- a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-terminating-condition-progressing.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: examples.example.io -spec: - conversion: - strategy: None - group: example.io - names: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - preserveUnknownFields: true - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: >- - CreationTimestamp is a timestamp representing the server time when - this object was created. It is not guaranteed to be set in - happens-before order across separate operations. Clients may not set - this value. It is represented in RFC3339 form and is in UTC. - - - Populated by the system. Read-only. Null for lists. More info: - https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - served: true - storage: true - subresources: {} -status: - acceptedNames: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - conditions: - - lastTransitionTime: '2024-05-19T23:35:28Z' - message: no conflicts found - reason: NoConflicts - status: 'True' - type: NamesAccepted - - lastTransitionTime: '2024-05-19T23:35:28Z' - message: user has deleted the CRD - reason: terminating - status: 'True' - type: Terminating - storedVersions: - - v1alpha1 \ No newline at end of file diff --git a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-terminating-timestamp-progressing.yaml b/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-terminating-timestamp-progressing.yaml deleted file mode 100644 index 73d19e4832..0000000000 --- a/resource_customizations/apiextensions.k8s.io/CustomResourceDefinition/testdata/crd-v1-terminating-timestamp-progressing.yaml +++ /dev/null @@ -1,57 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: examples.example.io - deletionTimestamp: '2024-12-28T13:51:19Z' -spec: - conversion: - strategy: None - group: example.io - names: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - preserveUnknownFields: true - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: >- - CreationTimestamp is a timestamp representing the server time when - this object was created. It is not guaranteed to be set in - happens-before order across separate operations. Clients may not set - this value. It is represented in RFC3339 form and is in UTC. - - - Populated by the system. Read-only. Null for lists. More info: - https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - served: true - storage: true - subresources: {} -status: - acceptedNames: - kind: Example - listKind: ExampleList - plural: examples - shortNames: - - ex - singular: example - conditions: - - lastTransitionTime: '2024-05-19T23:35:28Z' - message: no conflicts found - reason: NoConflicts - status: 'True' - type: NamesAccepted - - lastTransitionTime: '2024-05-19T23:35:28Z' - message: the initial names have been accepted - reason: InitialNamesAccepted - status: 'True' - type: Established - storedVersions: - - v1alpha1 \ No newline at end of file diff --git a/resource_customizations/apps/Deployment/actions/action_test.yaml b/resource_customizations/apps/Deployment/actions/action_test.yaml index 67ac923fae..14538c8d0b 100644 --- a/resource_customizations/apps/Deployment/actions/action_test.yaml +++ b/resource_customizations/apps/Deployment/actions/action_test.yaml @@ -1,20 +1,10 @@ actionTests: - - action: restart - inputPath: testdata/deployment.yaml - expectedOutputPath: testdata/deployment-restarted.yaml - - action: pause - inputPath: testdata/deployment.yaml - expectedOutputPath: testdata/deployment-pause.yaml - - action: resume - inputPath: testdata/deployment-pause.yaml - expectedOutputPath: testdata/deployment-resume.yaml - - action: scale - inputPath: testdata/deployment.yaml - expectedOutputPath: testdata/deployment-scaled.yaml - parameters: - replicas: '6' - - action: scale - inputPath: testdata/deployment.yaml - expectedErrorMessage: 'invalid number: not_a_number' - parameters: - replicas: 'not_a_number' +- action: restart + inputPath: testdata/deployment.yaml + expectedOutputPath: testdata/deployment-restarted.yaml +- action: pause + inputPath: testdata/deployment.yaml + expectedOutputPath: testdata/deployment-pause.yaml +- action: resume + inputPath: testdata/deployment-pause.yaml + expectedOutputPath: testdata/deployment-resume.yaml \ No newline at end of file diff --git a/resource_customizations/apps/Deployment/actions/discovery.lua b/resource_customizations/apps/Deployment/actions/discovery.lua index f939d920f8..d090d58776 100644 --- a/resource_customizations/apps/Deployment/actions/discovery.lua +++ b/resource_customizations/apps/Deployment/actions/discovery.lua @@ -7,13 +7,4 @@ if obj.spec.paused ~= nil then actions["pause"] = {paused} end actions["resume"] = {["disabled"] = not(paused)} - -actions["scale"] = { - ["params"] = { - { - ["name"] = "replicas", - ["default"] = tostring(obj.spec.replicas) - } - }, -} return actions diff --git a/resource_customizations/apps/Deployment/actions/scale/action.lua b/resource_customizations/apps/Deployment/actions/scale/action.lua deleted file mode 100644 index bc27eaf345..0000000000 --- a/resource_customizations/apps/Deployment/actions/scale/action.lua +++ /dev/null @@ -1,9 +0,0 @@ -local os = require("os") - -local replicas = tonumber(actionParams["replicas"]) -if not replicas then - error("invalid number: " .. actionParams["replicas"], 0) -end - -obj.spec.replicas = replicas -return obj diff --git a/resource_customizations/apps/Deployment/actions/testdata/deployment-scaled.yaml b/resource_customizations/apps/Deployment/actions/testdata/deployment-scaled.yaml deleted file mode 100644 index ed71333a04..0000000000 --- a/resource_customizations/apps/Deployment/actions/testdata/deployment-scaled.yaml +++ /dev/null @@ -1,61 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - annotations: - deployment.kubernetes.io/revision: "1" - creationTimestamp: "2019-09-12T01:33:53Z" - generation: 1 - name: nginx-deploy - namespace: default - resourceVersion: "6897444" - selfLink: /apis/apps/v1/namespaces/default/deployments/nginx-deploy - uid: 61689d6d-d4fd-11e9-9e69-42010aa8005f -spec: - progressDeadlineSeconds: 600 - replicas: 6 - revisionHistoryLimit: 10 - selector: - matchLabels: - app: nginx - strategy: - rollingUpdate: - maxSurge: 25% - maxUnavailable: 25% - type: RollingUpdate - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: nginx:latest - imagePullPolicy: Always - name: nginx - resources: {} - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - dnsPolicy: ClusterFirst - restartPolicy: Always - schedulerName: default-scheduler - securityContext: {} - terminationGracePeriodSeconds: 30 -status: - availableReplicas: 2 - conditions: - - lastTransitionTime: "2019-09-12T01:33:53Z" - lastUpdateTime: "2019-09-12T01:33:53Z" - message: Deployment does not have minimum availability. - reason: MinimumReplicasUnavailable - status: "False" - type: Available - - lastTransitionTime: "2019-09-12T01:33:53Z" - lastUpdateTime: "2019-09-12T01:34:05Z" - message: ReplicaSet "nginx-deploy-9cb4784bd" is progressing. - reason: ReplicaSetUpdated - status: "True" - type: Progressing - observedGeneration: 1 - readyReplicas: 2 - replicas: 3 - unavailableReplicas: 1 - updatedReplicas: 3 diff --git a/resource_customizations/apps/StatefulSet/actions/action_test.yaml b/resource_customizations/apps/StatefulSet/actions/action_test.yaml index e8388a7a0e..bab15aacbd 100644 --- a/resource_customizations/apps/StatefulSet/actions/action_test.yaml +++ b/resource_customizations/apps/StatefulSet/actions/action_test.yaml @@ -1,14 +1,4 @@ actionTests: - - action: restart - inputPath: testdata/statefulset.yaml - expectedOutputPath: testdata/statefulset-restarted.yaml - - action: scale - inputPath: testdata/statefulset.yaml - expectedOutputPath: testdata/statefulset-scaled.yaml - parameters: - replicas: '6' - - action: scale - inputPath: testdata/statefulset.yaml - expectedErrorMessage: 'invalid number: not_a_number' - parameters: - replicas: 'not_a_number' +- action: restart + inputPath: testdata/statefulset.yaml + expectedOutputPath: testdata/statefulset-restarted.yaml diff --git a/resource_customizations/apps/StatefulSet/actions/discovery.lua b/resource_customizations/apps/StatefulSet/actions/discovery.lua index 83a37a874e..dc7f10431b 100644 --- a/resource_customizations/apps/StatefulSet/actions/discovery.lua +++ b/resource_customizations/apps/StatefulSet/actions/discovery.lua @@ -1,12 +1,3 @@ local actions = {} actions["restart"] = {} - -actions["scale"] = { - ["params"] = { - { - ["name"] = "replicas", - ["default"] = tostring(obj.spec.replicas) - } - }, -} return actions diff --git a/resource_customizations/apps/StatefulSet/actions/scale/action.lua b/resource_customizations/apps/StatefulSet/actions/scale/action.lua deleted file mode 100644 index bc27eaf345..0000000000 --- a/resource_customizations/apps/StatefulSet/actions/scale/action.lua +++ /dev/null @@ -1,9 +0,0 @@ -local os = require("os") - -local replicas = tonumber(actionParams["replicas"]) -if not replicas then - error("invalid number: " .. actionParams["replicas"], 0) -end - -obj.spec.replicas = replicas -return obj diff --git a/resource_customizations/apps/StatefulSet/actions/testdata/statefulset-scaled.yaml b/resource_customizations/apps/StatefulSet/actions/testdata/statefulset-scaled.yaml deleted file mode 100644 index 57b7c0e86e..0000000000 --- a/resource_customizations/apps/StatefulSet/actions/testdata/statefulset-scaled.yaml +++ /dev/null @@ -1,50 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - creationTimestamp: "2019-09-13T08:52:54Z" - generation: 2 - labels: - app.kubernetes.io/instance: extensions - name: statefulset - namespace: statefulset - resourceVersion: "7471813" - selfLink: /apis/apps/v1/namespaces/statefulset/statefulsets/statefulset - uid: dfe8fadf-d603-11e9-9e69-42010aa8005f -spec: - podManagementPolicy: OrderedReady - replicas: 6 - revisionHistoryLimit: 10 - selector: - matchLabels: - app: statefulset - serviceName: statefulset - template: - metadata: - labels: - app: statefulset - spec: - containers: - - image: registry.k8s.io/nginx-slim:0.8 - imagePullPolicy: IfNotPresent - name: nginx - resources: {} - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - dnsPolicy: ClusterFirst - restartPolicy: Always - schedulerName: default-scheduler - securityContext: {} - terminationGracePeriodSeconds: 30 - updateStrategy: - rollingUpdate: - partition: 0 - type: RollingUpdate -status: - collisionCount: 0 - currentReplicas: 3 - currentRevision: statefulset-85b7f767c6 - observedGeneration: 2 - readyReplicas: 3 - replicas: 3 - updateRevision: statefulset-85b7f767c6 - updatedReplicas: 3 diff --git a/resource_customizations/argoproj.io/ApplicationSet/health.lua b/resource_customizations/argoproj.io/ApplicationSet/health.lua index 7505d8024d..3a0cd19bc6 100644 --- a/resource_customizations/argoproj.io/ApplicationSet/health.lua +++ b/resource_customizations/argoproj.io/ApplicationSet/health.lua @@ -17,6 +17,8 @@ if obj.status ~= nil then end end -hs.status = "Progressing" -hs.message = "Waiting for the status to be reported" +-- Conditions were introduced in ApplicationSet v0.3. To give v0.2 users a good experience, we default to "Healthy". +-- Once v0.3 is more generally adopted, we'll default to "Progressing" instead. +hs.status = "Healthy" +hs.message = "" return hs diff --git a/resource_customizations/argoproj.io/ApplicationSet/health_test.yaml b/resource_customizations/argoproj.io/ApplicationSet/health_test.yaml index 86c7b14b07..8c8aadc147 100644 --- a/resource_customizations/argoproj.io/ApplicationSet/health_test.yaml +++ b/resource_customizations/argoproj.io/ApplicationSet/health_test.yaml @@ -8,6 +8,6 @@ tests: message: "found less than two generators, Merge requires two or more" inputPath: testdata/errorApplicationSetWithStatusMessage.yaml - healthStatus: - status: Progressing - message: "Waiting for the status to be reported" + status: Healthy + message: "" inputPath: testdata/noStatusApplicationSet.yaml diff --git a/resource_customizations/argoproj.io/Rollout/actions/action_test.yaml b/resource_customizations/argoproj.io/Rollout/actions/action_test.yaml index 035cbe3141..194794efec 100644 --- a/resource_customizations/argoproj.io/Rollout/actions/action_test.yaml +++ b/resource_customizations/argoproj.io/Rollout/actions/action_test.yaml @@ -12,10 +12,6 @@ discoveryTests: disabled: true - name: promote-full disabled: true - - name: skip-current-step - disabled: true - - name: pause - disabled: true - inputPath: testdata/pre_v0.6_not_paused_rollout.yaml result: - name: restart @@ -29,10 +25,6 @@ discoveryTests: disabled: true - name: promote-full disabled: true - - name: skip-current-step - disabled: true - - name: pause - disabled: false - inputPath: testdata/pre_v0.6_nil_paused_rollout.yaml result: - name: restart @@ -46,10 +38,6 @@ discoveryTests: disabled: true - name: promote-full disabled: true - - name: skip-current-step - disabled: true - - name: pause - disabled: false - inputPath: testdata/has_pause_condition_rollout.yaml result: - name: restart @@ -63,10 +51,6 @@ discoveryTests: disabled: true - name: promote-full disabled: false - - name: skip-current-step - disabled: false - - name: pause - disabled: false - inputPath: testdata/no_pause_condition_rollout.yaml result: - name: restart @@ -80,10 +64,6 @@ discoveryTests: disabled: true - name: promote-full disabled: false - - name: skip-current-step - disabled: false - - name: pause - disabled: false - inputPath: testdata/healthy_rollout.yaml result: - name: restart @@ -97,10 +77,6 @@ discoveryTests: disabled: true - name: promote-full disabled: true - - name: skip-current-step - disabled: true - - name: pause - disabled: true - inputPath: testdata/v0.9_aborted_rollout.yaml result: - name: restart @@ -114,10 +90,6 @@ discoveryTests: disabled: false - name: promote-full disabled: false - - name: skip-current-step - disabled: false - - name: pause - disabled: true - inputPath: testdata/v0.9_aborted_bg_rollout.yaml result: - name: restart @@ -131,10 +103,6 @@ discoveryTests: disabled: false - name: promote-full disabled: true - - name: skip-current-step - disabled: true - - name: pause - disabled: true - inputPath: testdata/aborted_bg_rollout.yaml result: - name: restart @@ -148,10 +116,6 @@ discoveryTests: disabled: false - name: promote-full disabled: false - - name: skip-current-step - disabled: true - - name: pause - disabled: true actionTests: - action: resume inputPath: testdata/pre_v0.6_paused_rollout.yaml @@ -174,6 +138,3 @@ actionTests: - action: promote-full inputPath: testdata/aborted_rollout.yaml expectedOutputPath: testdata/promote-full_rollout.yaml -- action: skip-current-step - inputPath: testdata/rollout-step1.yaml - expectedOutputPath: testdata/rollout-step1-after-skip-current-step.yaml diff --git a/resource_customizations/argoproj.io/Rollout/actions/discovery.lua b/resource_customizations/argoproj.io/Rollout/actions/discovery.lua index 509e29f770..966034d369 100644 --- a/resource_customizations/argoproj.io/Rollout/actions/discovery.lua +++ b/resource_customizations/argoproj.io/Rollout/actions/discovery.lua @@ -15,7 +15,6 @@ actions["resume"] = {["disabled"] = not(paused)} local fullyPromoted = obj.status.currentPodHash == obj.status.stableRS actions["abort"] = {["disabled"] = fullyPromoted or obj.status.abort} actions["retry"] = {["disabled"] = fullyPromoted or not(obj.status.abort)} -actions["pause"] = {["disabled"] = fullyPromoted or obj.status.abort or obj.spec.paused } actions["promote-full"] = {["disabled"] = true} if obj.status ~= nil and not(fullyPromoted) then @@ -29,6 +28,4 @@ if obj.status ~= nil and not(fullyPromoted) then end end -actions["skip-current-step"] = {["disabled"] = obj.spec.strategy.canary == nil or obj.spec.strategy.canary.steps == nil or obj.status.currentStepIndex == table.getn(obj.spec.strategy.canary.steps)} - return actions diff --git a/resource_customizations/argoproj.io/Rollout/actions/pause/action.lua b/resource_customizations/argoproj.io/Rollout/actions/pause/action.lua deleted file mode 100644 index 79c2b60013..0000000000 --- a/resource_customizations/argoproj.io/Rollout/actions/pause/action.lua +++ /dev/null @@ -1,2 +0,0 @@ -obj.spec.paused = true -return obj diff --git a/resource_customizations/argoproj.io/Rollout/actions/skip-current-step/action.lua b/resource_customizations/argoproj.io/Rollout/actions/skip-current-step/action.lua deleted file mode 100644 index 7c796e1549..0000000000 --- a/resource_customizations/argoproj.io/Rollout/actions/skip-current-step/action.lua +++ /dev/null @@ -1,9 +0,0 @@ -if obj.status ~= nil then - if obj.spec.strategy.canary ~= nil and obj.spec.strategy.canary.steps ~= nil and obj.status.currentStepIndex < table.getn(obj.spec.strategy.canary.steps) then - if obj.status.pauseConditions ~= nil and table.getn(obj.status.pauseConditions) > 0 then - obj.status.pauseConditions = nil - end - obj.status.currentStepIndex = obj.status.currentStepIndex + 1 - end -end -return obj \ No newline at end of file diff --git a/resource_customizations/argoproj.io/Rollout/actions/testdata/one_replica_rollout.yaml b/resource_customizations/argoproj.io/Rollout/actions/testdata/one_replica_rollout.yaml index c7457f677c..949e4eab89 100644 --- a/resource_customizations/argoproj.io/Rollout/actions/testdata/one_replica_rollout.yaml +++ b/resource_customizations/argoproj.io/Rollout/actions/testdata/one_replica_rollout.yaml @@ -28,7 +28,7 @@ spec: app: guestbook-bluegreen spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook-bluegreen ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/actions/testdata/pre_v0.6_nil_paused_rollout.yaml b/resource_customizations/argoproj.io/Rollout/actions/testdata/pre_v0.6_nil_paused_rollout.yaml index c7457f677c..949e4eab89 100644 --- a/resource_customizations/argoproj.io/Rollout/actions/testdata/pre_v0.6_nil_paused_rollout.yaml +++ b/resource_customizations/argoproj.io/Rollout/actions/testdata/pre_v0.6_nil_paused_rollout.yaml @@ -28,7 +28,7 @@ spec: app: guestbook-bluegreen spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook-bluegreen ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/actions/testdata/pre_v0.6_not_paused_rollout.yaml b/resource_customizations/argoproj.io/Rollout/actions/testdata/pre_v0.6_not_paused_rollout.yaml index e883249a7f..8e81cffb04 100644 --- a/resource_customizations/argoproj.io/Rollout/actions/testdata/pre_v0.6_not_paused_rollout.yaml +++ b/resource_customizations/argoproj.io/Rollout/actions/testdata/pre_v0.6_not_paused_rollout.yaml @@ -28,7 +28,7 @@ spec: app: guestbook-bluegreen spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook-bluegreen ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/actions/testdata/pre_v0.6_paused_rollout.yaml b/resource_customizations/argoproj.io/Rollout/actions/testdata/pre_v0.6_paused_rollout.yaml index 896d1899d1..0c7062d3b8 100644 --- a/resource_customizations/argoproj.io/Rollout/actions/testdata/pre_v0.6_paused_rollout.yaml +++ b/resource_customizations/argoproj.io/Rollout/actions/testdata/pre_v0.6_paused_rollout.yaml @@ -29,7 +29,7 @@ spec: app: guestbook-bluegreen spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook-bluegreen ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/actions/testdata/rollout-step1-after-skip-current-step.yaml b/resource_customizations/argoproj.io/Rollout/actions/testdata/rollout-step1-after-skip-current-step.yaml deleted file mode 100644 index b0ebfc235f..0000000000 --- a/resource_customizations/argoproj.io/Rollout/actions/testdata/rollout-step1-after-skip-current-step.yaml +++ /dev/null @@ -1,81 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Rollout -metadata: - name: rollouts-demo - namespace: rollout-test-custom-actions -spec: - replicas: 5 - restartAt: "2025-05-15T14:13:44Z" - revisionHistoryLimit: 2 - selector: - matchLabels: - app: rollouts-demo - strategy: - canary: - steps: - - pause: {} - - pause: {} - template: - metadata: - labels: - app: rollouts-demo - spec: - containers: - - image: argoproj/rollouts-demo:blue - name: rollouts-demo - ports: - - containerPort: 8080 - name: http - protocol: TCP - resources: - requests: - cpu: 5m - memory: 32Mi -status: - HPAReplicas: 5 - availableReplicas: 5 - blueGreen: {} - canary: {} - conditions: - - lastTransitionTime: "2025-05-15T14:15:48Z" - lastUpdateTime: "2025-05-15T14:15:48Z" - message: Rollout has minimum availability - reason: AvailableReason - status: "True" - type: Available - - lastTransitionTime: "2025-05-15T14:16:58Z" - lastUpdateTime: "2025-05-15T14:16:58Z" - message: Rollout is not healthy - reason: RolloutHealthy - status: "False" - type: Healthy - - lastTransitionTime: "2025-05-15T14:16:58Z" - lastUpdateTime: "2025-05-15T14:16:58Z" - message: RolloutCompleted - reason: RolloutCompleted - status: "False" - type: Completed - - lastTransitionTime: "2025-05-15T14:16:58Z" - lastUpdateTime: "2025-05-15T14:16:58Z" - message: Rollout is paused - reason: RolloutPaused - status: Unknown - type: Progressing - - lastTransitionTime: "2025-05-15T14:16:58Z" - lastUpdateTime: "2025-05-15T14:16:58Z" - message: Rollout is paused - reason: RolloutPaused - status: "True" - type: Paused - controllerPause: true - currentPodHash: 687d76d795 - currentStepHash: 79c9b9f6bf - currentStepIndex: 1 - message: CanaryPauseStep - observedGeneration: "20" - phase: Paused - readyReplicas: 5 - replicas: 5 - restartedAt: "2025-05-15T14:13:44Z" - selector: app=rollouts-demo - stableRS: 6cf78c66c5 \ No newline at end of file diff --git a/resource_customizations/argoproj.io/Rollout/actions/testdata/rollout-step1.yaml b/resource_customizations/argoproj.io/Rollout/actions/testdata/rollout-step1.yaml deleted file mode 100644 index 989cee8468..0000000000 --- a/resource_customizations/argoproj.io/Rollout/actions/testdata/rollout-step1.yaml +++ /dev/null @@ -1,84 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Rollout -metadata: - name: rollouts-demo - namespace: rollout-test-custom-actions -spec: - replicas: 5 - restartAt: "2025-05-15T14:13:44Z" - revisionHistoryLimit: 2 - selector: - matchLabels: - app: rollouts-demo - strategy: - canary: - steps: - - pause: {} - - pause: {} - template: - metadata: - labels: - app: rollouts-demo - spec: - containers: - - image: argoproj/rollouts-demo:blue - name: rollouts-demo - ports: - - containerPort: 8080 - name: http - protocol: TCP - resources: - requests: - cpu: 5m - memory: 32Mi -status: - HPAReplicas: 5 - availableReplicas: 5 - blueGreen: {} - canary: {} - conditions: - - lastTransitionTime: "2025-05-15T14:15:48Z" - lastUpdateTime: "2025-05-15T14:15:48Z" - message: Rollout has minimum availability - reason: AvailableReason - status: "True" - type: Available - - lastTransitionTime: "2025-05-15T14:16:58Z" - lastUpdateTime: "2025-05-15T14:16:58Z" - message: Rollout is not healthy - reason: RolloutHealthy - status: "False" - type: Healthy - - lastTransitionTime: "2025-05-15T14:16:58Z" - lastUpdateTime: "2025-05-15T14:16:58Z" - message: RolloutCompleted - reason: RolloutCompleted - status: "False" - type: Completed - - lastTransitionTime: "2025-05-15T14:16:58Z" - lastUpdateTime: "2025-05-15T14:16:58Z" - message: Rollout is paused - reason: RolloutPaused - status: Unknown - type: Progressing - - lastTransitionTime: "2025-05-15T14:16:58Z" - lastUpdateTime: "2025-05-15T14:16:58Z" - message: Rollout is paused - reason: RolloutPaused - status: "True" - type: Paused - controllerPause: true - currentPodHash: 687d76d795 - currentStepHash: 79c9b9f6bf - currentStepIndex: 0 - message: CanaryPauseStep - observedGeneration: "20" - pauseConditions: - - reason: CanaryPauseStep - startTime: "2025-05-15T14:16:58Z" - phase: Paused - readyReplicas: 5 - replicas: 5 - restartedAt: "2025-05-15T14:13:44Z" - selector: app=rollouts-demo - stableRS: 6cf78c66c5 diff --git a/resource_customizations/argoproj.io/Rollout/actions/testdata/three_replica_rollout.yaml b/resource_customizations/argoproj.io/Rollout/actions/testdata/three_replica_rollout.yaml index dcedfe4bb3..2a531f6e21 100644 --- a/resource_customizations/argoproj.io/Rollout/actions/testdata/three_replica_rollout.yaml +++ b/resource_customizations/argoproj.io/Rollout/actions/testdata/three_replica_rollout.yaml @@ -28,7 +28,7 @@ spec: app: guestbook-bluegreen spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook-bluegreen ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/testdata/bluegreen/healthy_servingActiveService.yaml b/resource_customizations/argoproj.io/Rollout/testdata/bluegreen/healthy_servingActiveService.yaml index 66f9ed6d30..45000bc126 100644 --- a/resource_customizations/argoproj.io/Rollout/testdata/bluegreen/healthy_servingActiveService.yaml +++ b/resource_customizations/argoproj.io/Rollout/testdata/bluegreen/healthy_servingActiveService.yaml @@ -32,7 +32,7 @@ spec: app: ks-guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: ks-guestbook-ui ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/testdata/bluegreen/progressing_addingMoreReplicas.yaml b/resource_customizations/argoproj.io/Rollout/testdata/bluegreen/progressing_addingMoreReplicas.yaml index 796ad7df00..ae3a8e19fe 100644 --- a/resource_customizations/argoproj.io/Rollout/testdata/bluegreen/progressing_addingMoreReplicas.yaml +++ b/resource_customizations/argoproj.io/Rollout/testdata/bluegreen/progressing_addingMoreReplicas.yaml @@ -31,7 +31,7 @@ spec: app: ks-guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.1 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.1 name: ks-guestbook-ui ports: - containerPort: 83 diff --git a/resource_customizations/argoproj.io/Rollout/testdata/bluegreen/progressing_waitingUntilAvailable.yaml b/resource_customizations/argoproj.io/Rollout/testdata/bluegreen/progressing_waitingUntilAvailable.yaml index ca2a94fa3b..901ddd5709 100644 --- a/resource_customizations/argoproj.io/Rollout/testdata/bluegreen/progressing_waitingUntilAvailable.yaml +++ b/resource_customizations/argoproj.io/Rollout/testdata/bluegreen/progressing_waitingUntilAvailable.yaml @@ -32,7 +32,7 @@ spec: app: ks-guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.1 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.1 name: ks-guestbook-ui ports: - containerPort: 83 diff --git a/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_emptyStepsList.yaml b/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_emptyStepsList.yaml index cc8df9991b..7b8efea9f8 100644 --- a/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_emptyStepsList.yaml +++ b/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_emptyStepsList.yaml @@ -32,7 +32,7 @@ spec: app: guestbook-canary spec: containers: - - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.2' + - image: 'gcr.io/heptio-images/ks-guestbook-demo:0.2' name: guestbook-canary ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_executedAllSteps.yaml b/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_executedAllSteps.yaml index dce0df276f..a4d5485e5d 100644 --- a/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_executedAllSteps.yaml +++ b/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_executedAllSteps.yaml @@ -3,7 +3,7 @@ kind: Rollout metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: > - {"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}} + {"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}} rollout.argoproj.io/revision: '1' clusterName: '' creationTimestamp: '2019-05-01T21:55:30Z' @@ -39,7 +39,7 @@ spec: app: guestbook-canary spec: containers: - - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1' + - image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1' name: guestbook-canary ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_executedAllStepsPreV0.8.yaml b/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_executedAllStepsPreV0.8.yaml index 36326cb9f2..52073ff65e 100644 --- a/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_executedAllStepsPreV0.8.yaml +++ b/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_executedAllStepsPreV0.8.yaml @@ -3,7 +3,7 @@ kind: Rollout metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: > - {"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}} + {"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}} rollout.argoproj.io/revision: '1' clusterName: '' creationTimestamp: '2019-05-01T21:55:30Z' @@ -39,7 +39,7 @@ spec: app: guestbook-canary spec: containers: - - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1' + - image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1' name: guestbook-canary ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_noSteps.yaml b/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_noSteps.yaml index 35657f3a4d..092d45ca6d 100644 --- a/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_noSteps.yaml +++ b/resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_noSteps.yaml @@ -3,7 +3,7 @@ kind: Rollout metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: > - {"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}} + {"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}} rollout.argoproj.io/revision: '2' clusterName: '' creationTimestamp: '2019-05-01T21:55:30Z' @@ -33,7 +33,7 @@ spec: app: guestbook-canary spec: containers: - - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.2' + - image: 'gcr.io/heptio-images/ks-guestbook-demo:0.2' name: guestbook-canary ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_killingOldReplicas.yaml b/resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_killingOldReplicas.yaml index aff8e7043f..aab3d8fada 100644 --- a/resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_killingOldReplicas.yaml +++ b/resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_killingOldReplicas.yaml @@ -3,7 +3,7 @@ kind: Rollout metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"name":"example-rollout-canary","namespace":"default"},"spec":{"minReadySeconds":30,"replicas":5,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook"}},"strategy":{"canary":{"steps":[{"setWeight":20},{"pause":{"duration":20}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook"}},"spec":{"containers":[{"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook","ports":[{"containerPort":80}]}]}}}} + {"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"name":"example-rollout-canary","namespace":"default"},"spec":{"minReadySeconds":30,"replicas":5,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook"}},"strategy":{"canary":{"steps":[{"setWeight":20},{"pause":{"duration":20}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook","ports":[{"containerPort":80}]}]}}}} rollout.argoproj.io/revision: "3" creationTimestamp: "2019-10-20T15:42:26Z" generation: 101 @@ -28,7 +28,7 @@ spec: app: guestbook spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.1 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.1 name: guestbook ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_noSteps.yaml b/resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_noSteps.yaml index 59afd64bf2..41e7a07313 100644 --- a/resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_noSteps.yaml +++ b/resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_noSteps.yaml @@ -31,7 +31,7 @@ spec: app: guestbook-canary spec: containers: - - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.2' + - image: 'gcr.io/heptio-images/ks-guestbook-demo:0.2' name: guestbook-canary ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_setWeightStep.yaml b/resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_setWeightStep.yaml index a3fad7ef29..a521be9e6a 100644 --- a/resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_setWeightStep.yaml +++ b/resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_setWeightStep.yaml @@ -3,7 +3,7 @@ kind: Rollout metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"name":"example-rollout-canary","namespace":"default"},"spec":{"minReadySeconds":30,"replicas":5,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook"}},"strategy":{"canary":{"steps":[{"setWeight":20},{"pause":{"duration":20}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook"}},"spec":{"containers":[{"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook","ports":[{"containerPort":80}]}]}}}} + {"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"name":"example-rollout-canary","namespace":"default"},"spec":{"minReadySeconds":30,"replicas":5,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook"}},"strategy":{"canary":{"steps":[{"setWeight":20},{"pause":{"duration":20}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook","ports":[{"containerPort":80}]}]}}}} rollout.argoproj.io/revision: "2" clusterName: "" creationTimestamp: 2019-04-26T20:17:43Z @@ -35,7 +35,7 @@ spec: app: guestbook spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook ports: - containerPort: 80 diff --git a/resource_customizations/argoproj.io/Rollout/testdata/degraded_rolloutTimeout.yaml b/resource_customizations/argoproj.io/Rollout/testdata/degraded_rolloutTimeout.yaml index 463a39b5ec..bfded3c8de 100644 --- a/resource_customizations/argoproj.io/Rollout/testdata/degraded_rolloutTimeout.yaml +++ b/resource_customizations/argoproj.io/Rollout/testdata/degraded_rolloutTimeout.yaml @@ -38,7 +38,7 @@ spec: release: guestbook-bluegreen spec: containers: - - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.3' + - image: 'gcr.io/heptio-images/ks-guestbook-demo:0.3' imagePullPolicy: IfNotPresent livenessProbe: httpGet: diff --git a/resource_customizations/argoproj.io/Rollout/testdata/suspended_userPause.yaml b/resource_customizations/argoproj.io/Rollout/testdata/suspended_userPause.yaml index ec99567acf..66c958fa29 100644 --- a/resource_customizations/argoproj.io/Rollout/testdata/suspended_userPause.yaml +++ b/resource_customizations/argoproj.io/Rollout/testdata/suspended_userPause.yaml @@ -20,7 +20,7 @@ spec: app: guestbook spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.2 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.2 name: guestbook status: HPAReplicas: 5 diff --git a/resource_customizations/cluster.x-k8s.io/MachinePool/health.lua b/resource_customizations/cluster.x-k8s.io/MachinePool/health.lua index 8da35f08f9..521aa9a611 100644 --- a/resource_customizations/cluster.x-k8s.io/MachinePool/health.lua +++ b/resource_customizations/cluster.x-k8s.io/MachinePool/health.lua @@ -6,7 +6,7 @@ function getStatusBasedOnPhase(obj, hs) -- https://github.com/kubernetes-sigs/cluster-api/blob/release-1.8/exp/api/v1beta1/machinepool_types.go#L139-L182 if obj.status ~= nil and obj.status.phase ~= nil then hs.message = "MachinePool is " .. obj.status.phase - if obj.status.phase == "Running" or obj.status.phase == "Scaling" then + if obj.status.phase == "Running" then hs.status = "Healthy" end if obj.status.phase == "Failed" or obj.status.phase == "Unknown" then diff --git a/resource_customizations/cluster.x-k8s.io/MachinePool/health_test.yaml b/resource_customizations/cluster.x-k8s.io/MachinePool/health_test.yaml index d8e2228f7a..3ea490456e 100644 --- a/resource_customizations/cluster.x-k8s.io/MachinePool/health_test.yaml +++ b/resource_customizations/cluster.x-k8s.io/MachinePool/health_test.yaml @@ -3,10 +3,6 @@ tests: status: Healthy message: 'MachinePool is Running' inputPath: testdata/healthy_provisioned.yaml -- healthStatus: - status: Healthy - message: 'MachinePool is Scaling' - inputPath: testdata/scaling_provisioned.yaml - healthStatus: status: Progressing message: 'MachinePool is Provisioning: Not Ready (WaitingForInfrastructure), Not InfrastructureReady (WaitingForInfrastructure)' diff --git a/resource_customizations/cluster.x-k8s.io/MachinePool/testdata/scaling_provisioned.yaml b/resource_customizations/cluster.x-k8s.io/MachinePool/testdata/scaling_provisioned.yaml deleted file mode 100644 index ce13ae2028..0000000000 --- a/resource_customizations/cluster.x-k8s.io/MachinePool/testdata/scaling_provisioned.yaml +++ /dev/null @@ -1,58 +0,0 @@ -apiVersion: cluster.x-k8s.io/v1beta1 -kind: MachinePool -metadata: - labels: - argocd.argoproj.io/instance: foo - cluster.x-k8s.io/cluster-name: foo - name: foo-pool - namespace: default -spec: - clusterName: foo - replicas: 3 - template: - metadata: {} - spec: - bootstrap: - dataSecretName: "" - clusterName: foo - infrastructureRef: - apiVersion: infrastructure.cluster.x-k8s.io/v1beta2 - kind: AWSManagedMachinePool - name: foo-pool - namespace: default - version: v1.30.0 -status: - availableReplicas: 2 - bootstrapReady: true - conditions: - - lastTransitionTime: '2024-08-19T20:33:02Z' - status: 'True' - type: Ready - - lastTransitionTime: '2024-08-19T20:18:31Z' - status: 'True' - type: BootstrapReady - - lastTransitionTime: '2024-08-19T20:33:02Z' - status: 'True' - type: InfrastructureReady - - lastTransitionTime: '2024-08-19T20:18:31Z' - status: 'True' - type: ReplicasReady - infrastructureReady: true - nodeRefs: - - apiVersion: v1 - kind: Node - name: ip-18-232-50-123-ec2.internal - uid: e4b3a44f-1c2d-4fd3-bb9e-3b0e08787a5a - - apiVersion: v1 - kind: Node - name: ip-52-23-45-67-ec2.internal - uid: 2b9dabe5-3a1d-429a-985b-5e7ffb9649c6 - - apiVersion: v1 - kind: Node - name: ip-34-207-89-12-ec2.internal - uid: 6f94031a-d3e4-48f7-bc94-22bb9b687f5e - observedGeneration: 2 - phase: Scaling - readyReplicas: 2 - unavailableReplicas: 1 - replicas: 3 diff --git a/resource_customizations/embed.go b/resource_customizations/embed.go index 8b2157b826..8a4d5316cd 100644 --- a/resource_customizations/embed.go +++ b/resource_customizations/embed.go @@ -6,5 +6,5 @@ import ( // Embedded contains embedded resource customization // -//go:embed all:* +//go:embed * var Embedded embed.FS diff --git a/resource_customizations/external-secrets.io/ExternalSecret/actions/discovery.lua b/resource_customizations/external-secrets.io/ExternalSecret/actions/discovery.lua index 7afe48d9c1..89d806c8de 100644 --- a/resource_customizations/external-secrets.io/ExternalSecret/actions/discovery.lua +++ b/resource_customizations/external-secrets.io/ExternalSecret/actions/discovery.lua @@ -1,15 +1,3 @@ local actions = {} - -local disable_refresh = false -local time_units = {"ns", "us", "µs", "ms", "s", "m", "h"} -local digits = obj.spec.refreshInterval -for _, time_unit in ipairs(time_units) do - digits, _ = digits:gsub(time_unit, "") - if tonumber(digits) == 0 then - disable_refresh = true - break - end -end - -actions["refresh"] = {["disabled"] = disable_refresh} +actions["refresh"] = {["disabled"] = false} return actions diff --git a/resource_customizations/external-secrets.io/PushSecret/actions/discovery.lua b/resource_customizations/external-secrets.io/PushSecret/actions/discovery.lua index ab0b8883af..6b095fbd98 100644 --- a/resource_customizations/external-secrets.io/PushSecret/actions/discovery.lua +++ b/resource_customizations/external-secrets.io/PushSecret/actions/discovery.lua @@ -1,15 +1,3 @@ -local actions = {} - -local disable_push = false -local time_units = {"ns", "us", "µs", "ms", "s", "m", "h"} -local digits = obj.spec.refreshInterval -for _, time_unit in ipairs(time_units) do - digits, _ = digits:gsub(time_unit, "") - if tonumber(digits) == 0 then - disable_push = true - break - end -end - -actions["push"] = {["disabled"] = disable_push} +actions = {} +actions["push"] = {["disabled"] = false} return actions diff --git a/resource_customizations/grafana.integreatly.org/GrafanaDashboard/health.lua b/resource_customizations/grafana.integreatly.org/GrafanaDashboard/health.lua deleted file mode 100644 index 76b1b00cec..0000000000 --- a/resource_customizations/grafana.integreatly.org/GrafanaDashboard/health.lua +++ /dev/null @@ -1,43 +0,0 @@ --- Reference CRD can be found here: --- https://grafana.github.io/grafana-operator/docs/api/#grafanadashboard - -function getStatusFromConditions(obj, hs) - if obj.status ~= nil and obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.status ~= nil then - if hs.message ~= "" then - hs.message = hs.message .. ", " - end - - if condition.reason ~= nil then - hs.message = hs.message .. condition.reason - if condition.type ~= nil then - hs.message = hs.message .. " for " .. condition.type - if condition.message ~= nil then - hs.message = hs.message .. " because " .. condition.message - end - end - end - - if condition.status == "False" then - hs.status = "Degraded" - return hs - end - - if condition.status == "True" then - hs.status = "Healthy" - end - end - end - end - - return hs -end - -local hs = {} -hs.status = "Progressing" -hs.message = "" - -hs = getStatusFromConditions(obj, hs) - -return hs diff --git a/resource_customizations/grafana.integreatly.org/GrafanaDashboard/health_test.yaml b/resource_customizations/grafana.integreatly.org/GrafanaDashboard/health_test.yaml deleted file mode 100644 index d4028fcef5..0000000000 --- a/resource_customizations/grafana.integreatly.org/GrafanaDashboard/health_test.yaml +++ /dev/null @@ -1,16 +0,0 @@ -tests: -- healthStatus: - status: Progressing - message: "" - inputPath: testdata/progressing.yaml -- healthStatus: - status: Healthy - message: "ApplySuccessful for DashboardSynchronized because Dashboard was successfully applied to 1 instances" - inputPath: testdata/healthy.yaml -- healthStatus: - status: Degraded - message: >- - ApplyFailed for DashboardSynchronized because Dashboard failed to be applied for 1 out of 1 instances. Errors: - - - grafana-operator/grafana: Get "https://dashboards.grafana.com/api/search?limit=1000&page=1&type=dash-db": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) - inputPath: testdata/degraded.yaml diff --git a/resource_customizations/grafana.integreatly.org/GrafanaDashboard/testdata/degraded.yaml b/resource_customizations/grafana.integreatly.org/GrafanaDashboard/testdata/degraded.yaml deleted file mode 100644 index 51aa35c12f..0000000000 --- a/resource_customizations/grafana.integreatly.org/GrafanaDashboard/testdata/degraded.yaml +++ /dev/null @@ -1,42 +0,0 @@ -apiVersion: grafana.integreatly.org/v1beta1 -kind: GrafanaDashboard -metadata: - annotations: - argocd.argoproj.io/installation-id: argocd.com - argocd.argoproj.io/tracking-id: >- - foo:grafana.integreatly.org/GrafanaDashboard:grafana-operator/degraded - creationTimestamp: '2025-03-21T20:19:50Z' - finalizers: - - operator.grafana.com/finalizer - generation: 1 - labels: - argocd.argoproj.io/instance: foo - name: degraded - namespace: grafana-operator - resourceVersion: '185954752' - uid: a7d497f7-5a8d-450b-8b44-50d5f50ce72e -spec: - allowCrossNamespaceImport: false - folderRef: barfolder - instanceSelector: - matchLabels: - dashboards: grafana - json: | - { - } - resyncPeriod: 10m0s -status: - conditions: - - lastTransitionTime: '2025-03-21T20:20:21Z' - message: >- - Dashboard failed to be applied for 1 out of 1 instances. Errors: - - - grafana-operator/grafana: Get - "https://dashboards.grafana.com/api/search?limit=1000&page=1&type=dash-db": - net/http: request canceled while waiting for connection (Client.Timeout - exceeded while awaiting headers) - observedGeneration: 1 - reason: ApplyFailed - status: 'False' - type: DashboardSynchronized - lastResync: '2025-03-26T15:02:40Z' diff --git a/resource_customizations/grafana.integreatly.org/GrafanaDashboard/testdata/healthy.yaml b/resource_customizations/grafana.integreatly.org/GrafanaDashboard/testdata/healthy.yaml deleted file mode 100644 index 44a1c6478b..0000000000 --- a/resource_customizations/grafana.integreatly.org/GrafanaDashboard/testdata/healthy.yaml +++ /dev/null @@ -1,38 +0,0 @@ -apiVersion: grafana.integreatly.org/v1beta1 -kind: GrafanaDashboard -metadata: - annotations: - argocd.argoproj.io/installation-id: argocd.com - argocd.argoproj.io/tracking-id: >- - foo:grafana.integreatly.org/GrafanaDashboard:grafana-operator/healthy - creationTimestamp: '2025-03-21T20:19:50Z' - finalizers: - - operator.grafana.com/finalizer - generation: 1 - labels: - argocd.argoproj.io/instance: foo - name: healthy - namespace: grafana-operator - resourceVersion: '185954752' - uid: a7d497f7-5a8d-450b-8b44-50d5f50ce72e -spec: - allowCrossNamespaceImport: false - folderRef: barfolder - instanceSelector: - matchLabels: - dashboards: grafana - json: | - { - } - resyncPeriod: 10m0s -status: - conditions: - - lastTransitionTime: '2025-03-21T20:27:27Z' - message: Dashboard was successfully applied to 1 instances - observedGeneration: 1 - reason: ApplySuccessful - status: 'True' - type: DashboardSynchronized - hash: 783fb827a235e91feb4a5a38c90b36bc072015970789b334724dfc42b6f1a3f6 - lastResync: '2025-03-26T15:05:34Z' - uid: 72e0e05bef5099e5f049b05fdc429ed4 diff --git a/resource_customizations/grafana.integreatly.org/GrafanaDashboard/testdata/progressing.yaml b/resource_customizations/grafana.integreatly.org/GrafanaDashboard/testdata/progressing.yaml deleted file mode 100644 index 386feca7aa..0000000000 --- a/resource_customizations/grafana.integreatly.org/GrafanaDashboard/testdata/progressing.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: grafana.integreatly.org/v1beta1 -kind: GrafanaDashboard -metadata: - annotations: - argocd.argoproj.io/installation-id: argocd.com - argocd.argoproj.io/tracking-id: >- - foo:grafana.integreatly.org/GrafanaDashboard:grafana-operator/progressing - creationTimestamp: '2025-03-21T20:19:50Z' - finalizers: - - operator.grafana.com/finalizer - generation: 1 - labels: - argocd.argoproj.io/instance: foo - name: progressing - namespace: grafana-operator - resourceVersion: '185954752' - uid: a7d497f7-5a8d-450b-8b44-50d5f50ce72e -spec: - allowCrossNamespaceImport: false - folderRef: barfolder - instanceSelector: - matchLabels: - dashboards: grafana - json: | - { - } - resyncPeriod: 10m0s diff --git a/resource_customizations/grafana.integreatly.org/GrafanaFolder/health.lua b/resource_customizations/grafana.integreatly.org/GrafanaFolder/health.lua deleted file mode 100644 index c08e2a999d..0000000000 --- a/resource_customizations/grafana.integreatly.org/GrafanaFolder/health.lua +++ /dev/null @@ -1,43 +0,0 @@ --- Reference CRD can be found here: --- https://grafana.github.io/grafana-operator/docs/api/#grafanafolder - -function getStatusFromConditions(obj, hs) - if obj.status ~= nil and obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.status ~= nil then - if hs.message ~= "" then - hs.message = hs.message .. ", " - end - - if condition.reason ~= nil then - hs.message = hs.message .. condition.reason - if condition.type ~= nil then - hs.message = hs.message .. " for " .. condition.type - if condition.message ~= nil then - hs.message = hs.message .. " because " .. condition.message - end - end - end - - if condition.status == "False" then - hs.status = "Degraded" - return hs - end - - if condition.status == "True" then - hs.status = "Healthy" - end - end - end - end - - return hs -end - -local hs = {} -hs.status = "Progressing" -hs.message = "" - -hs = getStatusFromConditions(obj, hs) - -return hs diff --git a/resource_customizations/grafana.integreatly.org/GrafanaFolder/health_test.yaml b/resource_customizations/grafana.integreatly.org/GrafanaFolder/health_test.yaml deleted file mode 100644 index 0edd1a71e1..0000000000 --- a/resource_customizations/grafana.integreatly.org/GrafanaFolder/health_test.yaml +++ /dev/null @@ -1,16 +0,0 @@ -tests: -- healthStatus: - status: Progressing - message: "" - inputPath: testdata/progressing.yaml -- healthStatus: - status: Healthy - message: "ApplySuccessful for FolderSynchronized because Folder was successfully applied to 1 instances" - inputPath: testdata/healthy.yaml -- healthStatus: - status: Degraded - message: >- - ApplyFailed for FolderSynchronized because Folder failed to be applied for 1 out of 1 instances. Errors: - - - grafana-operator/grafana: Get "https://dashboards.grafana.com/api/folders?limit=10000&page=1": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) - inputPath: testdata/degraded.yaml diff --git a/resource_customizations/grafana.integreatly.org/GrafanaFolder/testdata/degraded.yaml b/resource_customizations/grafana.integreatly.org/GrafanaFolder/testdata/degraded.yaml deleted file mode 100644 index 6f8a4adbe5..0000000000 --- a/resource_customizations/grafana.integreatly.org/GrafanaFolder/testdata/degraded.yaml +++ /dev/null @@ -1,40 +0,0 @@ -apiVersion: grafana.integreatly.org/v1beta1 -kind: GrafanaFolder -metadata: - annotations: - argocd.argoproj.io/installation-id: argocd.com - argocd.argoproj.io/tracking-id: >- - foo:grafana.integreatly.org/GrafanaFolder:grafana-operator/bar - creationTimestamp: '2025-03-21T19:55:18Z' - finalizers: - - operator.grafana.com/finalizer - generation: 1 - labels: - argocd.argoproj.io/instance: foo - name: bar - namespace: grafana-operator - resourceVersion: '185973434' - uid: ada2bab9-613e-4a1c-98c0-75094b72978e -spec: - allowCrossNamespaceImport: false - instanceSelector: - matchLabels: - dashboards: grafana - resyncPeriod: 10m0s - title: Baz-Folder -status: - conditions: - - lastTransitionTime: '2025-03-21T19:55:38Z' - message: >- - Folder failed to be applied for 1 out of 1 instances. Errors: - - - grafana-operator/grafana: Get - "https://dashboards.grafana.com/api/folders?limit=10000&page=1": - net/http: request canceled while waiting for connection (Client.Timeout - exceeded while awaiting headers) - observedGeneration: 1 - reason: ApplyFailed - status: 'False' - type: FolderSynchronized - hash: d6cea1a429ba926fb709e2ac7f468f5a99e534049a96eecc28e1d881f49d93f2 - lastResync: '2025-03-26T15:29:24Z' diff --git a/resource_customizations/grafana.integreatly.org/GrafanaFolder/testdata/healthy.yaml b/resource_customizations/grafana.integreatly.org/GrafanaFolder/testdata/healthy.yaml deleted file mode 100644 index c4f4428de4..0000000000 --- a/resource_customizations/grafana.integreatly.org/GrafanaFolder/testdata/healthy.yaml +++ /dev/null @@ -1,35 +0,0 @@ -apiVersion: grafana.integreatly.org/v1beta1 -kind: GrafanaFolder -metadata: - annotations: - argocd.argoproj.io/installation-id: argocd.com - argocd.argoproj.io/tracking-id: >- - foo:grafana.integreatly.org/GrafanaFolder:grafana-operator/bar - creationTimestamp: '2025-03-26T14:50:23Z' - finalizers: - - operator.grafana.com/finalizer - generation: 1 - labels: - argocd.argoproj.io/instance: foo - name: bar - namespace: grafana-operator - resourceVersion: '185974148' - uid: 226a9af3-4a5d-4ebb-9705-ddfec0f6db47 -spec: - allowCrossNamespaceImport: false - instanceSelector: - matchLabels: - dashboards: grafana - parentFolderRef: baz - resyncPeriod: 10m0s - title: Bar-Folder -status: - conditions: - - lastTransitionTime: '2025-03-26T14:50:23Z' - message: Folder was successfully applied to 1 instances - observedGeneration: 1 - reason: ApplySuccessful - status: 'True' - type: FolderSynchronized - hash: f929c3bb9a96dbba11dd9ecf049ab28f98d7f8fbf5403aee0877c2c7b6f2547f - lastResync: '2025-03-26T15:30:24Z' diff --git a/resource_customizations/grafana.integreatly.org/GrafanaFolder/testdata/progressing.yaml b/resource_customizations/grafana.integreatly.org/GrafanaFolder/testdata/progressing.yaml deleted file mode 100644 index 80fb2e7914..0000000000 --- a/resource_customizations/grafana.integreatly.org/GrafanaFolder/testdata/progressing.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: grafana.integreatly.org/v1beta1 -kind: GrafanaFolder -metadata: - annotations: - argocd.argoproj.io/installation-id: argocd.com - argocd.argoproj.io/tracking-id: >- - foo:grafana.integreatly.org/GrafanaFolder:grafana-operator/bar - creationTimestamp: '2025-03-26T14:50:23Z' - finalizers: - - operator.grafana.com/finalizer - generation: 1 - labels: - argocd.argoproj.io/instance: foo - name: bar - namespace: grafana-operator - resourceVersion: '185974148' - uid: 226a9af3-4a5d-4ebb-9705-ddfec0f6db47 -spec: - allowCrossNamespaceImport: false - instanceSelector: - matchLabels: - dashboards: grafana - parentFolderRef: baz - resyncPeriod: 10m0s - title: Bar-Folder diff --git a/resource_customizations/keda.sh/ScaledObject/health.lua b/resource_customizations/keda.sh/ScaledObject/health.lua index 2f67e99e29..84cc5ad17a 100644 --- a/resource_customizations/keda.sh/ScaledObject/health.lua +++ b/resource_customizations/keda.sh/ScaledObject/health.lua @@ -17,10 +17,6 @@ if obj.status ~= nil then hs.message = condition.message suspended = true end - if condition.status == "True" and condition.type == "Fallback" then - hs.message = condition.message - degraded = true - end end end end @@ -36,4 +32,4 @@ elseif healthy == true and suspended == true then end hs.status = "Progressing" hs.message = "Creating HorizontalPodAutoscaler Object" -return hs +return hs \ No newline at end of file diff --git a/resource_customizations/keda.sh/ScaledObject/health_test.yaml b/resource_customizations/keda.sh/ScaledObject/health_test.yaml index ef3ba2de90..969334650b 100644 --- a/resource_customizations/keda.sh/ScaledObject/health_test.yaml +++ b/resource_customizations/keda.sh/ScaledObject/health_test.yaml @@ -19,7 +19,3 @@ tests: status: Suspended message: "ScaledObject is paused" inputPath: testdata/keda-suspended.yaml -- healthStatus: - status: Degraded - message: "At least one trigger is falling back on this scaled object" - inputPath: testdata/keda-fallback.yaml diff --git a/resource_customizations/keda.sh/ScaledObject/testdata/keda-fallback.yaml b/resource_customizations/keda.sh/ScaledObject/testdata/keda-fallback.yaml deleted file mode 100644 index 6aaf7c1e07..0000000000 --- a/resource_customizations/keda.sh/ScaledObject/testdata/keda-fallback.yaml +++ /dev/null @@ -1,58 +0,0 @@ -apiVersion: keda.sh/v1alpha1 -kind: ScaledObject -metadata: - annotations: - finalizers: - - finalizer.keda.sh - labels: - argocd.argoproj.io/instance: keda-default - name: keda-with-fallback - namespace: keda - resourceVersion: '160591443' - uid: 83ee438a-f383-43f3-9346-b901d9773f5c -spec: - maxReplicaCount: 10 - minReplicaCount: 1 - fallback: - failureThreshold: 3 - replicas: 5 - scaleTargetRef: - name: keda-service - triggers: - - type: prometheus - metadata: - serverAddress: http://prometheus-server.monitoring.svc.cluster.local - metricName: http_requests_total - threshold: '100' - query: sum(rate(http_requests_total{app="keda-service"}[2m])) -status: - conditions: - - message: ScaledObject is defined correctly and is ready for scaling - reason: ScaledObjectReady - status: 'True' - type: Ready - - message: Scaling is performed because triggers are active - reason: ScalerActive - status: 'True' - type: Active - - message: At least one trigger is falling back on this scaled object - reason: FallbackExists - status: 'True' - type: Fallback - - status: 'False' - type: Paused - externalMetricNames: - - s0-prometheus - health: - "prometheus": - numberOfFailures: 4 - status: Failing - hpaName: keda-with-fallback-hpa - lastActiveTime: '2023-12-19T10:35:22Z' - originalReplicaCount: 1 - scaleTargetGVKR: - group: apps - kind: Deployment - resource: deployments - version: v1 - scaleTargetKind: apps/v1.Deployment diff --git a/resource_customizations/kyverno.io/Policy/health.lua b/resource_customizations/kyverno.io/Policy/health.lua deleted file mode 100644 index 67d1881a79..0000000000 --- a/resource_customizations/kyverno.io/Policy/health.lua +++ /dev/null @@ -1,15 +0,0 @@ -local hs = {} - -if obj.status ~= nil and obj.status.conditions ~= nil then - for _, condition in ipairs(obj.status.conditions) do - if condition.type == "Ready" and condition.status == "True" and condition.reason == "Succeeded" and condition.message == "Ready" then - hs.status = "Healthy" - hs.message = "Policy is ready" - return hs - end - end -end - -hs.status = "Progressing" -hs.message = "Waiting for Policy to be ready" -return hs diff --git a/resource_customizations/kyverno.io/Policy/health_test.yaml b/resource_customizations/kyverno.io/Policy/health_test.yaml deleted file mode 100644 index d23f27e854..0000000000 --- a/resource_customizations/kyverno.io/Policy/health_test.yaml +++ /dev/null @@ -1,9 +0,0 @@ -tests: -- healthStatus: - status: Progressing - message: "Waiting for Policy to be ready" - inputPath: testdata/progressing.yaml -- healthStatus: - status: Healthy - message: "Policy is ready" - inputPath: testdata/healthy.yaml diff --git a/resource_customizations/kyverno.io/Policy/testdata/healthy.yaml b/resource_customizations/kyverno.io/Policy/testdata/healthy.yaml deleted file mode 100644 index 5946ece704..0000000000 --- a/resource_customizations/kyverno.io/Policy/testdata/healthy.yaml +++ /dev/null @@ -1,260 +0,0 @@ -apiVersion: kyverno.io/v1 -kind: Policy -metadata: - annotations: - name: sample-policy - namespace: test-namespace -spec: {} -status: - autogen: - rules: - - exclude: - resources: {} - generate: - clone: {} - cloneList: {} - match: - resources: - kinds: - - DaemonSet - - Deployment - - Job - - StatefulSet - - ReplicaSet - - ReplicationController - mutate: {} - name: autogen-require-label-app - skipBackgroundRequests: true - validate: - message: An `app` label is required. - pattern: - spec: - template: - metadata: - labels: - app: ?* - - exclude: - resources: {} - generate: - clone: {} - cloneList: {} - match: - resources: - kinds: - - CronJob - mutate: {} - name: autogen-cronjob-require-label-app - skipBackgroundRequests: true - validate: - message: An `app` label is required. - pattern: - spec: - jobTemplate: - spec: - template: - metadata: - labels: - app: ?* - - exclude: - resources: {} - generate: - clone: {} - cloneList: {} - match: - resources: - kinds: - - DaemonSet - - Deployment - - Job - - StatefulSet - - ReplicaSet - - ReplicationController - mutate: {} - name: autogen-require-label-environment - skipBackgroundRequests: true - validate: - message: An `environment` label is required. - pattern: - spec: - template: - metadata: - labels: - environment: ?* - - exclude: - resources: {} - generate: - clone: {} - cloneList: {} - match: - resources: - kinds: - - CronJob - mutate: {} - name: autogen-cronjob-require-label-environment - skipBackgroundRequests: true - validate: - message: An `environment` label is required. - pattern: - spec: - jobTemplate: - spec: - template: - metadata: - labels: - environment: ?* - - exclude: - resources: {} - generate: - clone: {} - cloneList: {} - match: - resources: - kinds: - - DaemonSet - - Deployment - - Job - - StatefulSet - - ReplicaSet - - ReplicationController - mutate: {} - name: autogen-require-annotation-version - skipBackgroundRequests: true - validate: - message: A `version` annotation is required. - pattern: - spec: - template: - metadata: - annotations: - version: ?* - - exclude: - resources: {} - generate: - clone: {} - cloneList: {} - match: - resources: - kinds: - - CronJob - mutate: {} - name: autogen-cronjob-require-annotation-version - skipBackgroundRequests: true - validate: - message: A `version` annotation is required. - pattern: - spec: - jobTemplate: - spec: - template: - metadata: - annotations: - version: ?* - - exclude: - resources: {} - generate: - clone: {} - cloneList: {} - match: - resources: - kinds: - - DaemonSet - - Deployment - - Job - - StatefulSet - - ReplicaSet - - ReplicationController - mutate: {} - name: autogen-require-annotation-maintainer - skipBackgroundRequests: true - validate: - message: A `maintainer` annotation is required. - pattern: - spec: - template: - metadata: - annotations: - maintainer: ?* - - exclude: - resources: {} - generate: - clone: {} - cloneList: {} - match: - resources: - kinds: - - CronJob - mutate: {} - name: autogen-cronjob-require-annotation-maintainer - skipBackgroundRequests: true - validate: - message: A `maintainer` annotation is required. - pattern: - spec: - jobTemplate: - spec: - template: - metadata: - annotations: - maintainer: ?* - - exclude: - resources: {} - generate: - clone: {} - cloneList: {} - match: - resources: - kinds: - - DaemonSet - - Deployment - - Job - - StatefulSet - - ReplicaSet - - ReplicationController - mutate: {} - name: autogen-require-spec-containers - skipBackgroundRequests: true - validate: - message: The Pod must have at least one container. - pattern: - spec: - template: - spec: - containers: - - name: ?* - - exclude: - resources: {} - generate: - clone: {} - cloneList: {} - match: - resources: - kinds: - - CronJob - mutate: {} - name: autogen-cronjob-require-spec-containers - skipBackgroundRequests: true - validate: - message: The Pod must have at least one container. - pattern: - spec: - jobTemplate: - spec: - template: - spec: - containers: - - name: ?* - conditions: - - lastTransitionTime: "2025-01-17T19:09:11Z" - message: Ready - reason: Succeeded - status: "True" - type: Ready - rulecount: - generate: 0 - mutate: 0 - validate: 5 - verifyimages: 0 - validatingadmissionpolicy: - generated: false - message: "" - diff --git a/resource_customizations/kyverno.io/Policy/testdata/progressing.yaml b/resource_customizations/kyverno.io/Policy/testdata/progressing.yaml deleted file mode 100644 index ad65efb8ad..0000000000 --- a/resource_customizations/kyverno.io/Policy/testdata/progressing.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: kyverno.io/v1 -kind: Policy -metadata: - name: sample-policy - namespace: test-namespace -spec: {} - diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/action_test.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/action_test.yaml deleted file mode 100644 index a612c6187e..0000000000 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/action_test.yaml +++ /dev/null @@ -1,7 +0,0 @@ -actionTests: -- action: enable-force-promote - inputPath: testdata/ISBServiceRollout/rollout-enable-force-promote.yaml - expectedOutputPath: testdata/ISBServiceRollout/rollout-disable-force-promote.yaml -- action: disable-force-promote - inputPath: testdata/ISBServiceRollout/rollout-disable-force-promote.yaml - expectedOutputPath: testdata/ISBServiceRollout/rollout-enable-force-promote.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/disable-force-promote/action.lua b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/disable-force-promote/action.lua deleted file mode 100644 index 0cce04d86a..0000000000 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/disable-force-promote/action.lua +++ /dev/null @@ -1,9 +0,0 @@ -if (obj.spec.strategy == nil) then - obj.spec.strategy = {} - obj.spec.strategy.progressive = {} -elseif (obj.spec.strategy.progressive == nil) then - obj.spec.strategy.progressive = {} -end - -obj.spec.strategy.progressive.forcePromote = false -return obj \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/discovery.lua b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/discovery.lua deleted file mode 100644 index 0df8ac33bc..0000000000 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/discovery.lua +++ /dev/null @@ -1,19 +0,0 @@ -local actions = {} -actions["enable-force-promote"] = { - ["disabled"] = true, - ["displayName"] = "Enable Force Promote" -} -actions["disable-force-promote"] = { - ["disabled"] = true, - ["displayName"] = "Disable Force Promote" -} - --- force-promote -if (obj.status ~= nil and obj.status.upgradeInProgress == "Progressive" and obj.status.phase == "Pending") then - actions["enable-force-promote"]["disabled"] = false -end -if (obj.spec ~= nil and obj.spec.strategy ~= nil and obj.spec.strategy.progressive ~= nil and obj.spec.strategy.progressive.forcePromote == true) then - actions["disable-force-promote"]["disabled"] = false -end - -return actions \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/enable-force-promote/action.lua b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/enable-force-promote/action.lua deleted file mode 100644 index 32d6c97b35..0000000000 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/enable-force-promote/action.lua +++ /dev/null @@ -1,9 +0,0 @@ -if (obj.spec.strategy == nil) then - obj.spec.strategy = {} - obj.spec.strategy.progressive = {} -elseif (obj.spec.strategy.progressive == nil) then - obj.spec.strategy.progressive = {} -end - -obj.spec.strategy.progressive.forcePromote = true -return obj \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/testdata/ISBServiceRollout/rollout-disable-force-promote.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/testdata/ISBServiceRollout/rollout-disable-force-promote.yaml deleted file mode 100644 index 129922d874..0000000000 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/testdata/ISBServiceRollout/rollout-disable-force-promote.yaml +++ /dev/null @@ -1,71 +0,0 @@ -apiVersion: numaplane.numaproj.io/v1alpha1 -kind: ISBServiceRollout -metadata: - creationTimestamp: "2025-02-21T19:43:06Z" - finalizers: - - numaplane.numaproj.io/numaplane-controller - generation: 4 - name: test-isbservice-rollout - namespace: numaplane-system - resourceVersion: "6984" - uid: 0c926b94-f7a7-4580-a865-f9dd8d54525f -spec: - strategy: - progressive: - assessmentSchedule: 60,60,10 - forcePromote: true - interStepBufferService: - metadata: {} - spec: - jetstream: - containerTemplate: - resources: - limits: - memory: 2Gi - persistence: - volumeSize: 20Mi - version: 2.10.11 -status: - conditions: - - lastTransitionTime: "2025-02-21T19:43:06Z" - message: Successful - observedGeneration: 3 - reason: Successful - status: "True" - type: ChildResourceDeployed - - lastTransitionTime: "2025-02-21T19:55:13Z" - message: Successful - observedGeneration: 4 - reason: Successful - status: "True" - type: ChildResourcesHealthy - - lastTransitionTime: "2025-02-21T19:43:06Z" - message: no need for pause - observedGeneration: 4 - reason: NoPause - status: "False" - type: PausingPipelines - - lastTransitionTime: "2025-02-21T19:57:27Z" - message: New Child Object numaplane-system/test-isbservice-rollout-2 Failed - observedGeneration: 4 - reason: Failed - status: "False" - type: ProgressiveUpgradeSucceeded - lastFailureTime: "2025-02-21T19:53:30Z" - message: Progressing - nameCount: 3 - observedGeneration: 4 - pauseRequestStatus: - lastPauseBeginTime: null - lastPauseEndTime: null - lastPausePhaseChangeTime: null - phase: Pending - progressiveStatus: - promotedISBServiceStatus: - name: test-isbservice-rollout-1 - upgradingISBServiceStatus: - assessmentEndTime: "2025-02-21T19:58:27Z" - assessmentResult: Failure - assessmentStartTime: "2025-02-21T19:57:05Z" - name: test-isbservice-rollout-2 - upgradeInProgress: Progressive \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/testdata/ISBServiceRollout/rollout-enable-force-promote.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/testdata/ISBServiceRollout/rollout-enable-force-promote.yaml deleted file mode 100644 index 2b0fd61324..0000000000 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/actions/testdata/ISBServiceRollout/rollout-enable-force-promote.yaml +++ /dev/null @@ -1,71 +0,0 @@ -apiVersion: numaplane.numaproj.io/v1alpha1 -kind: ISBServiceRollout -metadata: - creationTimestamp: "2025-02-21T19:43:06Z" - finalizers: - - numaplane.numaproj.io/numaplane-controller - generation: 4 - name: test-isbservice-rollout - namespace: numaplane-system - resourceVersion: "6984" - uid: 0c926b94-f7a7-4580-a865-f9dd8d54525f -spec: - strategy: - progressive: - assessmentSchedule: 60,60,10 - forcePromote: false - interStepBufferService: - metadata: {} - spec: - jetstream: - containerTemplate: - resources: - limits: - memory: 2Gi - persistence: - volumeSize: 20Mi - version: 2.10.11 -status: - conditions: - - lastTransitionTime: "2025-02-21T19:43:06Z" - message: Successful - observedGeneration: 3 - reason: Successful - status: "True" - type: ChildResourceDeployed - - lastTransitionTime: "2025-02-21T19:55:13Z" - message: Successful - observedGeneration: 4 - reason: Successful - status: "True" - type: ChildResourcesHealthy - - lastTransitionTime: "2025-02-21T19:43:06Z" - message: no need for pause - observedGeneration: 4 - reason: NoPause - status: "False" - type: PausingPipelines - - lastTransitionTime: "2025-02-21T19:57:27Z" - message: New Child Object numaplane-system/test-isbservice-rollout-2 Failed - observedGeneration: 4 - reason: Failed - status: "False" - type: ProgressiveUpgradeSucceeded - lastFailureTime: "2025-02-21T19:53:30Z" - message: Progressing - nameCount: 3 - observedGeneration: 4 - pauseRequestStatus: - lastPauseBeginTime: null - lastPauseEndTime: null - lastPausePhaseChangeTime: null - phase: Pending - progressiveStatus: - promotedISBServiceStatus: - name: test-isbservice-rollout-1 - upgradingISBServiceStatus: - assessmentEndTime: "2025-02-21T19:58:27Z" - assessmentResult: Failure - assessmentStartTime: "2025-02-21T19:57:05Z" - name: test-isbservice-rollout-2 - upgradeInProgress: Progressive \ 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 fed0b5ccb5..934c59d585 100644 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua @@ -1,104 +1,60 @@ --- return true if degraded, along with the reason -function isDegraded(obj) - if obj.status == nil then - return false, "" - end - -- check phase=Failed, healthy condition failed, progressive upgrade failed - if obj.status.phase == "Failed" then - return true, obj.status.message - end - - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" and condition.status == "False" and condition.reason == "ISBSvcFailed" then - return true, condition.message - elseif condition.type == "ProgressiveUpgradeSucceeded" and condition.status == "False" then - return true, "Progressive upgrade failed" - end - end - end - - return false, "" -end - -function isProgressing(obj) - -- if there's no Status at all, we haven't been reconciled - if obj.status == nil then - return true, "Not yet reconciled" - end - - if obj.metadata.generation ~= obj.status.observedGeneration then - return true, "Not yet reconciled" - end - - -- if we are in the middle of an upgrade - if obj.status.upgradeInProgress ~= nil and obj.status.upgradeInProgress ~= "" or obj.status.phase == "Pending" then - -- first check if Progressive Upgrade Failed; in that case, we won't return true (because "Degraded" will take precedence) - progressiveUpgradeFailed = false - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ProgressiveUpgradeSucceeded" and condition.status == "False" then - progressiveUpgradeFailed = true - end - end - end - - if progressiveUpgradeFailed == false then - return true, "Update in progress" - end - end - - -- if the child is Progressing - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" and condition.status == "False" and condition.reason == "Progressing" then - return true, "Child Progressing" - end - end - end - - return false, "" -end - --- return true if healthy, along with the reason -function isHealthy(obj) - if obj.status == nil then - return false, "" - end - - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" and condition.status == "True" then - return true, "Healthy" - end - end - end -end - local hs = {} +local healthyCondition = {} +-- check for certain cases of "Progressing" -progressing, reason = isProgressing(obj) -if progressing then +if obj.status == nil then -- if there's no Status at all, we haven't been reconciled hs.status = "Progressing" - hs.message = reason + hs.message = "Not yet reconciled" return hs end -degraded, reason = isDegraded(obj) -if degraded then +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 (healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "ISBSvcFailed") or obj.status.phase == "Failed" then hs.status = "Degraded" - hs.message = reason + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message + end return hs -end - -healthy, reason = isHealthy(obj) -if healthy then +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 = reason + hs.message = healthyCondition.message return hs end hs.status = "Unknown" -hs.message = "Unknown status" -return hs +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 41b98ed847..c728c3d300 100644 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health_test.yaml @@ -5,7 +5,7 @@ tests: inputPath: testdata/ISBServiceRollout/progressing-observedgen.yaml - healthStatus: status: Healthy - message: "Healthy" + message: "Successful" inputPath: testdata/ISBServiceRollout/healthy.yaml - healthStatus: status: Degraded @@ -17,13 +17,9 @@ tests: inputPath: testdata/ISBServiceRollout/progressing-nostatus.yaml - healthStatus: status: Progressing - message: "Child Progressing" + message: "Progressing" inputPath: testdata/ISBServiceRollout/progressing-reason.yaml - healthStatus: status: Progressing - message: "Update in progress" - inputPath: testdata/ISBServiceRollout/pending-upgrade-in-progress.yaml -- healthStatus: - status: Degraded - message: "Progressive upgrade failed" - inputPath: testdata/ISBServiceRollout/progressive-failed.yaml \ No newline at end of file + 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/ISBServiceRollout/progressive-failed.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressive-failed.yaml deleted file mode 100644 index 7e05163c17..0000000000 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressive-failed.yaml +++ /dev/null @@ -1,60 +0,0 @@ -apiVersion: numaplane.numaproj.io/v1alpha1 -kind: ISBServiceRollout -metadata: - annotations: - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"ISBServiceRollout","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-isbsvc","namespace":"example-namespace"},"spec":{"interStepBufferService":{"spec":{"jetstream":{"persistence":{"volumeSize":"1Gi"},"version":"2.10.3"}}}}} - creationTimestamp: "2025-01-26T05:38:04Z" - finalizers: - - numaplane.numaproj.io/numaplane-controller - generation: 4 - labels: - argocd.argoproj.io/instance: demo-app - name: my-isbsvc - namespace: example-namespace - resourceVersion: "664511" - uid: c45f8283-f799-45a3-8058-ac462756e654 -spec: - interStepBufferService: - metadata: {} - spec: - jetstream: - persistence: - volumeSize: 1Gi - version: 2.10.3 -status: - conditions: - - lastTransitionTime: "2025-01-26T05:38:04Z" - message: Successful - observedGeneration: 4 - reason: Successful - status: "True" - type: ChildResourceDeployed - - lastTransitionTime: "2025-01-26T05:39:04Z" - message: Successful - observedGeneration: 4 - reason: Successful - status: "True" - type: ChildResourcesHealthy - - lastTransitionTime: "2025-01-26T05:38:04Z" - message: no need for pause - observedGeneration: 4 - reason: NoPause - status: "False" - type: PausingPipelines - - lastTransitionTime: "2025-01-26T05:48:44Z" - message: New Child Object example-namespace/my-isbsvc-2 Failed - observedGeneration: 4 - reason: Failed - status: "False" - type: ProgressiveUpgradeSucceeded - message: Deployed - nameCount: 3 - observedGeneration: 4 - pauseRequestStatus: {} - phase: Deployed - progressiveStatus: - upgradingChildStatus: - assessmentResult: Success - name: my-isbsvc-2 - nextAssessmentTime: "2025-01-26T05:48:05Z" \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/action_test.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/action_test.yaml index 6c0f648bfd..516e32f793 100644 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/action_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/action_test.yaml @@ -4,10 +4,4 @@ actionTests: expectedOutputPath: testdata/MonoVertexRollout/rollout-paused.yaml - action: unpause inputPath: testdata/MonoVertexRollout/rollout-paused.yaml - expectedOutputPath: testdata/MonoVertexRollout/rollout-running.yaml -- action: enable-force-promote - inputPath: testdata/MonoVertexRollout/rollout-enable-force-promote.yaml - expectedOutputPath: testdata/MonoVertexRollout/rollout-disable-force-promote.yaml -- action: disable-force-promote - inputPath: testdata/MonoVertexRollout/rollout-disable-force-promote.yaml - expectedOutputPath: testdata/MonoVertexRollout/rollout-enable-force-promote.yaml \ No newline at end of file + expectedOutputPath: testdata/MonoVertexRollout/rollout-running.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/disable-force-promote/action.lua b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/disable-force-promote/action.lua deleted file mode 100644 index 0cce04d86a..0000000000 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/disable-force-promote/action.lua +++ /dev/null @@ -1,9 +0,0 @@ -if (obj.spec.strategy == nil) then - obj.spec.strategy = {} - obj.spec.strategy.progressive = {} -elseif (obj.spec.strategy.progressive == nil) then - obj.spec.strategy.progressive = {} -end - -obj.spec.strategy.progressive.forcePromote = false -return obj \ 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 index fa7328cc40..2961869dbd 100644 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/discovery.lua +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/discovery.lua @@ -1,16 +1,7 @@ local actions = {} actions["pause"] = {["disabled"] = true} actions["unpause"] = {["disabled"] = true} -actions["enable-force-promote"] = { - ["disabled"] = true, - ["displayName"] = "Enable Force Promote" -} -actions["disable-force-promote"] = { - ["disabled"] = true, - ["displayName"] = "Disable Force Promote" -} --- pause/unpause 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 @@ -20,13 +11,4 @@ if paused then else actions["pause"]["disabled"] = false end - --- force-promote -if (obj.status ~= nil and obj.status.upgradeInProgress == "Progressive" and obj.status.phase == "Pending") then - actions["enable-force-promote"]["disabled"] = false -end -if (obj.spec ~= nil and obj.spec.strategy ~= nil and obj.spec.strategy.progressive ~= nil and obj.spec.strategy.progressive.forcePromote == true) then - actions["disable-force-promote"]["disabled"] = false -end - return actions \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/enable-force-promote/action.lua b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/enable-force-promote/action.lua deleted file mode 100644 index 32d6c97b35..0000000000 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/enable-force-promote/action.lua +++ /dev/null @@ -1,9 +0,0 @@ -if (obj.spec.strategy == nil) then - obj.spec.strategy = {} - obj.spec.strategy.progressive = {} -elseif (obj.spec.strategy.progressive == nil) then - obj.spec.strategy.progressive = {} -end - -obj.spec.strategy.progressive.forcePromote = true -return obj \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-disable-force-promote.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-disable-force-promote.yaml deleted file mode 100644 index a1bf0d601f..0000000000 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-disable-force-promote.yaml +++ /dev/null @@ -1,70 +0,0 @@ -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":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-go/sink-log:stable"}}},"source":{"udsource":{"container":{"image":"quay.io/numaio/numaflow-go/source-simple-source:bad-image"}}}}},"strategy":{"progressive":{"assessmentSchedule":"60,60,10"}}}} - creationTimestamp: "2025-03-03T18:51:52Z" - finalizers: - - numaplane.numaproj.io/numaplane-controller - generation: 3 - name: my-monovertex - namespace: example-namespace - resourceVersion: "314047" - uid: d948cd56-e383-4a18-8100-34b513976614 -spec: - monoVertex: - metadata: {} - spec: - sink: - udsink: - container: - image: quay.io/numaio/numaflow-go/sink-log:stable - source: - udsource: - container: - image: quay.io/numaio/numaflow-go/source-simple-source:bad-image - strategy: - progressive: - assessmentSchedule: 60,60,10 - forcePromote: true -status: - conditions: - - lastTransitionTime: "2025-03-03T18:51:52Z" - message: Successful - observedGeneration: 2 - reason: Successful - status: "True" - type: ChildResourceDeployed - - lastTransitionTime: "2025-03-03T18:54:08Z" - message: Successful - observedGeneration: 3 - reason: Successful - status: "True" - type: ChildResourcesHealthy - - lastTransitionTime: "2025-03-03T18:51:52Z" - message: MonoVertex unpaused - observedGeneration: 3 - reason: Unpaused - status: "False" - type: MonoVertexPausingOrPaused - - lastTransitionTime: "2025-03-03T18:54:02Z" - message: New Child Object example-namespace/my-monovertex-1 Failed - observedGeneration: 3 - reason: Failed - status: "False" - type: ProgressiveUpgradeSucceeded - message: Progressing - nameCount: 2 - observedGeneration: 3 - phase: Pending - progressiveStatus: - promotedMonoVertexStatus: - name: my-monovertex-0 - scaleValuesRestoredToOriginal: true - upgradingMonoVertexStatus: - assessmentEndTime: "2025-03-03T18:54:56Z" - assessmentResult: Failure - assessmentStartTime: "2025-03-03T18:53:53Z" - name: my-monovertex-1 - upgradeInProgress: Progressive \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-enable-force-promote.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-enable-force-promote.yaml deleted file mode 100644 index 78243c959d..0000000000 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-enable-force-promote.yaml +++ /dev/null @@ -1,70 +0,0 @@ -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":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-go/sink-log:stable"}}},"source":{"udsource":{"container":{"image":"quay.io/numaio/numaflow-go/source-simple-source:bad-image"}}}}},"strategy":{"progressive":{"assessmentSchedule":"60,60,10"}}}} - creationTimestamp: "2025-03-03T18:51:52Z" - finalizers: - - numaplane.numaproj.io/numaplane-controller - generation: 3 - name: my-monovertex - namespace: example-namespace - resourceVersion: "314047" - uid: d948cd56-e383-4a18-8100-34b513976614 -spec: - monoVertex: - metadata: {} - spec: - sink: - udsink: - container: - image: quay.io/numaio/numaflow-go/sink-log:stable - source: - udsource: - container: - image: quay.io/numaio/numaflow-go/source-simple-source:bad-image - strategy: - progressive: - assessmentSchedule: 60,60,10 - forcePromote: false -status: - conditions: - - lastTransitionTime: "2025-03-03T18:51:52Z" - message: Successful - observedGeneration: 2 - reason: Successful - status: "True" - type: ChildResourceDeployed - - lastTransitionTime: "2025-03-03T18:54:08Z" - message: Successful - observedGeneration: 3 - reason: Successful - status: "True" - type: ChildResourcesHealthy - - lastTransitionTime: "2025-03-03T18:51:52Z" - message: MonoVertex unpaused - observedGeneration: 3 - reason: Unpaused - status: "False" - type: MonoVertexPausingOrPaused - - lastTransitionTime: "2025-03-03T18:54:02Z" - message: New Child Object example-namespace/my-monovertex-1 Failed - observedGeneration: 3 - reason: Failed - status: "False" - type: ProgressiveUpgradeSucceeded - message: Progressing - nameCount: 2 - observedGeneration: 3 - phase: Pending - progressiveStatus: - promotedMonoVertexStatus: - name: my-monovertex-0 - scaleValuesRestoredToOriginal: true - upgradingMonoVertexStatus: - assessmentEndTime: "2025-03-03T18:54:56Z" - assessmentResult: Failure - assessmentStartTime: "2025-03-03T18:53:53Z" - name: my-monovertex-1 - upgradeInProgress: Progressive \ 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 dfd3e93ea0..e91efc6ac6 100644 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health.lua +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health.lua @@ -1,127 +1,73 @@ --- return true if paused, along with the reason -function isPaused(obj) - if obj.status == nil then - return false, "" - end - - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "MonoVertexPausingOrPaused" and condition.status == "True" then - return true, condition.message - end - end - end -end - - - --- return true if degraded, along with the reason -function isDegraded(obj) - if obj.status == nil then - return false, "" - end - -- check phase=Failed, healthy condition failed, progressive upgrade failed - if obj.status.phase == "Failed" then - return true, obj.status.message - end - - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" and condition.status == "False" and condition.reason == "MonoVertexFailed" then - return true, condition.message - elseif condition.type == "ProgressiveUpgradeSucceeded" and condition.status == "False" then - return true, "Progressive upgrade failed" - end - end - end - - return false, "" -end - -function isProgressing(obj) - -- if there's no Status at all, we haven't been reconciled - if obj.status == nil then - return true, "Not yet reconciled" - end - - if obj.metadata.generation ~= obj.status.observedGeneration then - return true, "Not yet reconciled" - end - - -- if we are in the middle of an upgrade - if obj.status.upgradeInProgress ~= nil and obj.status.upgradeInProgress ~= "" or obj.status.phase == "Pending" then - -- first check if Progressive Upgrade Failed; in that case, we won't return true (because "Degraded" will take precedence) - progressiveUpgradeFailed = false - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ProgressiveUpgradeSucceeded" and condition.status == "False" then - progressiveUpgradeFailed = true - end - end - end - - if progressiveUpgradeFailed == false then - return true, "Update in progress" - end - end - - -- if the child is Progressing - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" and condition.status == "False" and condition.reason == "Progressing" then - return true, "Child Progressing" - end - end - end - - return false, "" -end - --- return true if healthy, along with the reason -function isHealthy(obj) - if obj.status == nil then - return false, "" - end - - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" and condition.status == "True" then - return true, "Healthy" - end - end - end -end - local hs = {} +local healthyCondition = {} +local monoVertexPaused = {} +-- check for certain cases of "Progressing" -progressing, reason = isProgressing(obj) -if progressing then +if obj.status == nil then -- if there's no Status at all, we haven't been reconciled hs.status = "Progressing" - hs.message = reason + hs.message = "Not yet reconciled" return hs end -degraded, reason = isDegraded(obj) -if degraded then +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 == "MonoVertexPausingOrPaused" then + monoVertexPaused = condition + end + end +end + + +if (healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "MonoVertexFailed") or obj.status.phase == "Failed" then hs.status = "Degraded" - hs.message = reason + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message + end return hs -end - -paused, reason = isPaused(obj) -if paused then +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 = reason + 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 -healthy, reason = isHealthy(obj) -if healthy then - hs.status = "Healthy" - hs.message = reason - return hs -end + + + hs.status = "Unknown" hs.message = "Unknown MonoVertex status" diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml index 21ab3e20a0..b86d285232 100644 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml @@ -5,7 +5,7 @@ tests: inputPath: testdata/MonoVertexRollout/progressing-observedgen.yaml - healthStatus: status: Healthy - message: "Healthy" + message: "Successful" inputPath: testdata/MonoVertexRollout/healthy.yaml - healthStatus: status: Suspended @@ -17,13 +17,9 @@ tests: inputPath: testdata/MonoVertexRollout/degraded.yaml - healthStatus: status: Progressing - message: "Child Progressing" + message: "Progressing" inputPath: testdata/MonoVertexRollout/progressing-reason.yaml - healthStatus: status: Progressing - message: "Update in progress" - inputPath: testdata/MonoVertexRollout/pending-upgrade-in-progress.yaml -- healthStatus: - status: Degraded - message: "Progressive upgrade failed" - inputPath: testdata/MonoVertexRollout/progressive-failed.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/MonoVertexRollout/progressive-failed.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/progressive-failed.yaml deleted file mode 100644 index b1b919d5ef..0000000000 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/progressive-failed.yaml +++ /dev/null @@ -1,63 +0,0 @@ -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-go/sink-log:stable"}}},"source":{"udsource":{"container":{"image":"quay.io/numaio/numaflow-go/bad-image:stable"}}}}}}} - creationTimestamp: "2025-01-26T05:38:04Z" - finalizers: - - numaplane.numaproj.io/numaplane-controller - generation: 3 - labels: - argocd.argoproj.io/instance: demo-app - name: my-monovertex - namespace: example-namespace - resourceVersion: "669046" - uid: ffc093d1-0019-4b14-bcb2-bdbaa30b2834 -spec: - monoVertex: - metadata: {} - spec: - sink: - udsink: - container: - image: quay.io/numaio/numaflow-go/sink-log:stable - source: - udsource: - container: - image: quay.io/numaio/numaflow-go/bad-image:stable -status: - conditions: - - lastTransitionTime: "2025-01-26T05:38:04Z" - message: Successful - observedGeneration: 3 - reason: Successful - status: "True" - type: ChildResourceDeployed - - lastTransitionTime: "2025-01-26T06:36:41Z" - message: Successful - observedGeneration: 3 - reason: Successful - status: "True" - type: ChildResourcesHealthy - - lastTransitionTime: "2025-01-26T05:38:04Z" - message: MonoVertex unpaused - observedGeneration: 3 - reason: Unpaused - status: "False" - type: MonoVertexPausingOrPaused - - lastTransitionTime: "2025-01-26T06:34:50Z" - message: New Child Object example-namespace/my-monovertex-1 Failed - observedGeneration: 3 - reason: Failed - status: "False" - type: ProgressiveUpgradeSucceeded - message: Deployed - nameCount: 2 - observedGeneration: 3 - phase: Deployed - progressiveStatus: - upgradingChildStatus: - assessmentResult: Failure - name: my-monovertex-1 - nextAssessmentTime: "2025-01-26T06:34:21Z" \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua index da63058e5a..4975882d7d 100644 --- a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua @@ -1,90 +1,61 @@ --- return true if degraded, along with the reason -function isDegraded(obj) - if obj.status == nil then - return false, "" - end - -- check phase=Failed, healthy condition failed - if obj.status.phase == "Failed" then - return true, obj.status.message - end - - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" and condition.status == "False" and condition.reason ~= "Progressing" then - return true, condition.message - end - end - end - - return false, "" -end - -function isProgressing(obj) - -- if there's no Status at all, we haven't been reconciled - if obj.status == nil then - return true, "Not yet reconciled" - end - - if obj.metadata.generation ~= obj.status.observedGeneration then - return true, "Not yet reconciled" - end - - -- if we are in the middle of an upgrade - if obj.status.upgradeInProgress ~= nil and obj.status.upgradeInProgress ~= "" or obj.status.phase == "Pending" then - return true, "Update in progress" - end - - -- if the child is Progressing - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" and condition.status == "False" and condition.reason == "Progressing" then - return true, "Child Progressing" - end - end - end - - return false, "" -end - --- return true if healthy, along with the reason -function isHealthy(obj) - if obj.status == nil then - return false, "" - end - - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" and condition.status == "True" then - return true, "Healthy" - end - end - end -end - local hs = {} +local healthyCondition = {} +-- check for certain cases of "Progressing" -progressing, reason = isProgressing(obj) -if progressing then +if obj.status == nil then -- if there's no Status at all, we haven't been reconciled hs.status = "Progressing" - hs.message = reason + hs.message = "Not yet reconciled" return hs end -degraded, reason = isDegraded(obj) -if degraded then +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 (healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "Degraded") or obj.status.phase == "Failed" then hs.status = "Degraded" - hs.message = reason + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message + end return hs -end - -healthy, reason = isHealthy(obj) -if healthy then +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 = reason + hs.message = healthyCondition.message return hs end hs.status = "Unknown" -hs.message = "Unknown status" +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 6a75a58fe7..ef2778da7d 100644 --- a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health_test.yaml @@ -5,7 +5,7 @@ tests: inputPath: testdata/NumaflowControllerRollout/progressing-observedgen.yaml - healthStatus: status: Healthy - message: "Healthy" + message: "Successful" inputPath: testdata/NumaflowControllerRollout/healthy.yaml - healthStatus: status: Degraded @@ -13,9 +13,9 @@ tests: inputPath: testdata/NumaflowControllerRollout/degraded.yaml - healthStatus: status: Progressing - message: "Child Progressing" + message: "Progressing" inputPath: testdata/NumaflowControllerRollout/progressing-reason.yaml - healthStatus: status: Progressing - message: "Update in progress" + message: "Phase=Pending" inputPath: testdata/NumaflowControllerRollout/pending.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/action_test.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/action_test.yaml index f17851f226..b9652682b8 100644 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/action_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/action_test.yaml @@ -10,10 +10,4 @@ actionTests: 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 -- action: enable-force-promote - inputPath: testdata/PipelineRollout/rollout-enable-force-promote.yaml - expectedOutputPath: testdata/PipelineRollout/rollout-disable-force-promote.yaml -- action: disable-force-promote - inputPath: testdata/PipelineRollout/rollout-disable-force-promote.yaml - expectedOutputPath: testdata/PipelineRollout/rollout-enable-force-promote.yaml \ No newline at end of file + expectedOutputPath: testdata/PipelineRollout/rollout-disallowing-data-loss.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/disable-force-promote/action.lua b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/disable-force-promote/action.lua deleted file mode 100644 index 0cce04d86a..0000000000 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/disable-force-promote/action.lua +++ /dev/null @@ -1,9 +0,0 @@ -if (obj.spec.strategy == nil) then - obj.spec.strategy = {} - obj.spec.strategy.progressive = {} -elseif (obj.spec.strategy.progressive == nil) then - obj.spec.strategy.progressive = {} -end - -obj.spec.strategy.progressive.forcePromote = 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 index 170e02bda2..db3cb8b044 100644 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/discovery.lua +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/discovery.lua @@ -3,14 +3,6 @@ actions["pause"] = {["disabled"] = true} actions["unpause"] = {["disabled"] = true} actions["allow-data-loss"] = {["disabled"] = true} actions["disallow-data-loss"] = {["disabled"] = true} -actions["enable-force-promote"] = { - ["disabled"] = true, - ["displayName"] = "Enable Force Promote" -} -actions["disable-force-promote"] = { - ["disabled"] = true, - ["displayName"] = "Disable Force Promote" -} -- pause/unpause local paused = false @@ -31,12 +23,4 @@ if obj.metadata.annotations ~= nil and obj.metadata.annotations["numaplane.numap actions["disallow-data-loss"]["disabled"] = false end --- force-promote -if (obj.status ~= nil and obj.status.upgradeInProgress == "Progressive" and obj.status.phase == "Pending") then - actions["enable-force-promote"]["disabled"] = false -end -if (obj.spec ~= nil and obj.spec.strategy ~= nil and obj.spec.strategy.progressive ~= nil and obj.spec.strategy.progressive.forcePromote == true) then - actions["disable-force-promote"]["disabled"] = false -end - return actions \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/enable-force-promote/action.lua b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/enable-force-promote/action.lua deleted file mode 100644 index 32d6c97b35..0000000000 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/enable-force-promote/action.lua +++ /dev/null @@ -1,9 +0,0 @@ -if (obj.spec.strategy == nil) then - obj.spec.strategy = {} - obj.spec.strategy.progressive = {} -elseif (obj.spec.strategy.progressive == nil) then - obj.spec.strategy.progressive = {} -end - -obj.spec.strategy.progressive.forcePromote = true -return obj \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-disable-force-promote.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-disable-force-promote.yaml deleted file mode 100644 index 951cae6fa1..0000000000 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-disable-force-promote.yaml +++ /dev/null @@ -1,93 +0,0 @@ -apiVersion: numaplane.numaproj.io/v1alpha1 -kind: PipelineRollout -metadata: - creationTimestamp: "2025-02-21T19:43:43Z" - finalizers: - - numaplane.numaproj.io/numaplane-controller - generation: 3 - name: another-pipeline-rollout - namespace: numaplane-system - resourceVersion: "6904" - uid: 8365e0f1-18fe-47ed-a26e-cfa2963cced6 -spec: - strategy: - progressive: - assessmentSchedule: 60,60,10 - forcePromote: true - pipeline: - metadata: {} - spec: - edges: - - conditions: null - from: in - to: out - interStepBufferServiceName: test-isbservice-rollout - lifecycle: - desiredPhase: Running - vertices: - - name: in - scale: - max: 3 - min: 3 - zeroReplicaSleepSeconds: 15 - source: - generator: - duration: 1s - rpu: 5 - updateStrategy: {} - - name: out - scale: - max: 3 - min: 3 - zeroReplicaSleepSeconds: 15 - sink: - log: {} - retryStrategy: {} - updateStrategy: {} - watermark: {} -status: - conditions: - - lastTransitionTime: "2025-02-21T19:43:43Z" - message: Successful - observedGeneration: 3 - reason: Successful - status: "True" - type: ChildResourceDeployed - - lastTransitionTime: "2025-02-21T19:55:22Z" - message: Successful - observedGeneration: 3 - reason: Successful - status: "True" - type: ChildResourcesHealthy - - lastTransitionTime: "2025-02-21T19:48:13Z" - message: Pipeline unpaused - observedGeneration: 3 - reason: Unpaused - status: "False" - type: PipelinePausingOrPaused - - lastTransitionTime: "2025-02-21T19:57:20Z" - message: New Child Object numaplane-system/another-pipeline-rollout-2 Failed - observedGeneration: 3 - reason: Failed - status: "False" - type: ProgressiveUpgradeSucceeded - lastFailureTime: null - message: Progressing - nameCount: 3 - observedGeneration: 3 - pauseStatus: - lastPauseBeginTime: "2025-02-21T19:47:53Z" - lastPauseEndTime: "2025-02-21T19:48:13Z" - lastPausePhaseChangeTime: "2025-02-21T19:47:54Z" - phase: Pending - progressiveStatus: - promotedPipelineStatus: - name: another-pipeline-rollout-1 - scaleValuesRestoredToOriginal: true - upgradingPipelineStatus: - assessmentEndTime: "2025-02-21T19:58:20Z" - assessmentResult: Failure - assessmentStartTime: "2025-02-21T19:57:19Z" - interStepBufferServiceName: test-isbservice-rollout-2 - name: another-pipeline-rollout-2 - upgradeInProgress: Progressive \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-enable-force-promote.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-enable-force-promote.yaml deleted file mode 100644 index 5acc4e75ad..0000000000 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-enable-force-promote.yaml +++ /dev/null @@ -1,93 +0,0 @@ -apiVersion: numaplane.numaproj.io/v1alpha1 -kind: PipelineRollout -metadata: - creationTimestamp: "2025-02-21T19:43:43Z" - finalizers: - - numaplane.numaproj.io/numaplane-controller - generation: 3 - name: another-pipeline-rollout - namespace: numaplane-system - resourceVersion: "6904" - uid: 8365e0f1-18fe-47ed-a26e-cfa2963cced6 -spec: - strategy: - progressive: - assessmentSchedule: 60,60,10 - forcePromote: false - pipeline: - metadata: {} - spec: - edges: - - conditions: null - from: in - to: out - interStepBufferServiceName: test-isbservice-rollout - lifecycle: - desiredPhase: Running - vertices: - - name: in - scale: - max: 3 - min: 3 - zeroReplicaSleepSeconds: 15 - source: - generator: - duration: 1s - rpu: 5 - updateStrategy: {} - - name: out - scale: - max: 3 - min: 3 - zeroReplicaSleepSeconds: 15 - sink: - log: {} - retryStrategy: {} - updateStrategy: {} - watermark: {} -status: - conditions: - - lastTransitionTime: "2025-02-21T19:43:43Z" - message: Successful - observedGeneration: 3 - reason: Successful - status: "True" - type: ChildResourceDeployed - - lastTransitionTime: "2025-02-21T19:55:22Z" - message: Successful - observedGeneration: 3 - reason: Successful - status: "True" - type: ChildResourcesHealthy - - lastTransitionTime: "2025-02-21T19:48:13Z" - message: Pipeline unpaused - observedGeneration: 3 - reason: Unpaused - status: "False" - type: PipelinePausingOrPaused - - lastTransitionTime: "2025-02-21T19:57:20Z" - message: New Child Object numaplane-system/another-pipeline-rollout-2 Failed - observedGeneration: 3 - reason: Failed - status: "False" - type: ProgressiveUpgradeSucceeded - lastFailureTime: null - message: Progressing - nameCount: 3 - observedGeneration: 3 - pauseStatus: - lastPauseBeginTime: "2025-02-21T19:47:53Z" - lastPauseEndTime: "2025-02-21T19:48:13Z" - lastPausePhaseChangeTime: "2025-02-21T19:47:54Z" - phase: Pending - progressiveStatus: - promotedPipelineStatus: - name: another-pipeline-rollout-1 - scaleValuesRestoredToOriginal: true - upgradingPipelineStatus: - assessmentEndTime: "2025-02-21T19:58:20Z" - assessmentResult: Failure - assessmentStartTime: "2025-02-21T19:57:19Z" - interStepBufferServiceName: test-isbservice-rollout-2 - name: another-pipeline-rollout-2 - upgradeInProgress: Progressive \ 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 281f0c2e70..2fa58a94b0 100644 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/health.lua +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health.lua @@ -1,124 +1,66 @@ --- return true if paused, along with the reason -function isPaused(obj) - if obj.status == nil then - return false, "" - end - - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "PipelinePausingOrPaused" and condition.status == "True" then - return true, condition.message - end - end - end -end - - --- return true if degraded, along with the reason -function isDegraded(obj) - if obj.status == nil then - return false, "" - end - -- check phase=Failed, healthy condition failed, progressive upgrade failed - if obj.status.phase == "Failed" then - return true, obj.status.message - end - - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" and condition.status == "False" and condition.reason == "PipelineFailed" then - return true, condition.message - elseif condition.type == "ProgressiveUpgradeSucceeded" and condition.status == "False" then - return true, "Progressive upgrade failed" - end - end - end - - return false, "" -end - -function isProgressing(obj) - -- if there's no Status at all, we haven't been reconciled - if obj.status == nil then - return true, "Not yet reconciled" - end - - if obj.metadata.generation ~= obj.status.observedGeneration then - return true, "Not yet reconciled" - end - - -- if we are in the middle of an upgrade - if obj.status.upgradeInProgress ~= nil and obj.status.upgradeInProgress ~= "" or obj.status.phase == "Pending" then - -- first check if Progressive Upgrade Failed; in that case, we won't return true (because "Degraded" will take precedence) - progressiveUpgradeFailed = false - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ProgressiveUpgradeSucceeded" and condition.status == "False" then - progressiveUpgradeFailed = true - end - end - end - - if progressiveUpgradeFailed == false then - return true, "Update in progress" - end - end - - -- if the child is Progressing - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" and condition.status == "False" and condition.reason == "Progressing" then - return true, "Child Progressing" - end - end - end - - return false, "" -end - --- return true if healthy, along with the reason -function isHealthy(obj) - if obj.status == nil then - return false, "" - end - - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" and condition.status == "True" then - return true, "Healthy" - end - end - end -end - local hs = {} +local healthyCondition = {} +local pipelinePaused = {} +-- check for certain cases of "Progressing" -progressing, reason = isProgressing(obj) -if progressing then +if obj.status == nil then -- if there's no Status at all, we haven't been reconciled hs.status = "Progressing" - hs.message = reason + 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 -degraded, reason = isDegraded(obj) -if degraded then +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 (healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "PipelineFailed") or obj.status.phase == "Failed" then hs.status = "Degraded" - hs.message = reason + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message + end return hs -end - -paused, reason = isPaused(obj) -if paused then +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 = reason + hs.message = pipelinePaused.message return hs -end - -healthy, reason = isHealthy(obj) -if healthy then +elseif (healthyCondition ~= {} and healthyCondition.status == "True") and obj.status.phase == "Deployed" then hs.status = "Healthy" - hs.message = reason + hs.message = healthyCondition.message return hs end diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml index 98b43f26a5..3ff01e4435 100644 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml @@ -5,7 +5,7 @@ tests: inputPath: testdata/PipelineRollout/progressing-observedGen.yaml - healthStatus: status: Healthy - message: "Healthy" + message: "Successful" inputPath: testdata/PipelineRollout/healthy.yaml - healthStatus: status: Suspended @@ -17,13 +17,9 @@ tests: inputPath: testdata/PipelineRollout/degraded.yaml - healthStatus: status: Progressing - message: "Child Progressing" + message: "Progressing" inputPath: testdata/PipelineRollout/progressing-reason.yaml - healthStatus: status: Progressing - message: "Update in progress" - inputPath: testdata/PipelineRollout/pending-upgrade-in-progress.yaml -- healthStatus: - status: Degraded - message: "Progressive upgrade failed" - inputPath: testdata/PipelineRollout/progressive-failed.yaml \ No newline at end of file + 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/PipelineRollout/pending-upgrade-in-progress.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/pending-upgrade-in-progress.yaml index 48bfd8694f..2731f79aeb 100644 --- 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 @@ -56,6 +56,5 @@ status: 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/PipelineRollout/progressive-failed.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/progressive-failed.yaml deleted file mode 100644 index 30058c8bc6..0000000000 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/progressive-failed.yaml +++ /dev/null @@ -1,114 +0,0 @@ -apiVersion: numaplane.numaproj.io/v1alpha1 -kind: PipelineRollout -metadata: - annotations: - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"PipelineRollout","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-pipeline-slow","namespace":"example-namespace"},"spec":{"pipeline":{"spec":{"edges":[{"from":"in","to":"cat"},{"from":"cat","to":"cat-2"},{"from":"cat-2","to":"out"}],"interStepBufferServiceName":"my-isbsvc","lifecycle":{"pauseGracePeriodSeconds":120},"limits":{"readBatchSize":1},"vertices":[{"containerTemplate":{"env":[{"name":"NUMAFLOW_DEBUG","value":"true"}]},"name":"in","scale":{"max":1,"min":1},"source":{"generator":{"duration":"1s","rpu":1}}},{"containerTemplate":{"env":[{"name":"NUMAFLOW_DEBUG","value":"true"}]},"limits":{"readBatchSize":1},"name":"cat","scale":{"max":1,"min":1},"udf":{"container":{"env":[{"name":"SLEEP_SECONDS","value":"1"}],"image":"quay.io/numaio/numaflow-go/map-slow-cat:stable"}}},{"containerTemplate":{"env":[{"name":"NUMAFLOW_DEBUG","value":"true"}],"max":1},"name":"cat-2","scale":{"min":1},"udf":{"builtin":{"name":"cat"}}},{"name":"out","scale":{"max":1,"min":1},"sink":{"log":{}}}]}}}} - creationTimestamp: "2025-01-26T05:38:04Z" - finalizers: - - numaplane.numaproj.io/numaplane-controller - generation: 2 - labels: - argocd.argoproj.io/instance: demo-app - name: my-pipeline-slow - namespace: example-namespace - resourceVersion: "665712" - uid: 9c38589e-1ab5-43e3-a4a1-81a6d48dfddf -spec: - pipeline: - metadata: {} - spec: - edges: - - from: in - to: cat - - from: cat - to: cat-2 - - from: cat-2 - to: out - interStepBufferServiceName: my-isbsvc - lifecycle: - pauseGracePeriodSeconds: 120 - limits: - readBatchSize: 1 - vertices: - - containerTemplate: - env: - - name: NUMAFLOW_DEBUG - value: "true" - name: in - scale: - max: 1 - min: 1 - source: - generator: - duration: 1s - rpu: 1 - - containerTemplate: - env: - - name: NUMAFLOW_DEBUG - value: "true" - limits: - readBatchSize: 1 - name: cat - scale: - max: 1 - min: 1 - udf: - container: - env: - - name: SLEEP_SECONDS - value: "1" - image: quay.io/numaio/numaflow-go/map-slow-cat:stable - - containerTemplate: - env: - - name: NUMAFLOW_DEBUG - value: "true" - max: 1 - name: cat-2 - scale: - min: 1 - udf: - builtin: - name: cat - - name: out - scale: - max: 1 - min: 1 - sink: - log: {} -status: - conditions: - - lastTransitionTime: "2025-01-26T05:38:04Z" - message: Successful - observedGeneration: 2 - reason: Successful - status: "True" - type: ChildResourceDeployed - - lastTransitionTime: "2025-01-26T05:54:42Z" - message: Successful - observedGeneration: 2 - reason: Successful - status: "True" - type: ChildResourcesHealthy - - lastTransitionTime: "2025-01-26T05:38:04Z" - message: Pipeline unpaused - observedGeneration: 2 - reason: Unpaused - status: "False" - type: PipelinePausingOrPaused - - lastTransitionTime: "2025-01-26T05:48:41Z" - message: New Child Object example-namespace/my-pipeline-slow-2 Running - observedGeneration: 2 - reason: "Progressive failed" - status: "False" - type: ProgressiveUpgradeSucceeded - message: Deployed - nameCount: 3 - observedGeneration: 2 - pauseStatus: {} - phase: Deployed - progressiveStatus: - upgradingChildStatus: - assessmentResult: Failure - name: my-pipeline-slow-2 - nextAssessmentTime: "2025-01-26T05:48:05Z" \ No newline at end of file diff --git a/resource_customizations/operators.coreos.com/Subscription/health.lua b/resource_customizations/operators.coreos.com/Subscription/health.lua index 95cbedd378..ca5f917f07 100644 --- a/resource_customizations/operators.coreos.com/Subscription/health.lua +++ b/resource_customizations/operators.coreos.com/Subscription/health.lua @@ -14,30 +14,13 @@ if obj.status ~= nil then numDegraded = numDegraded + 1 end end - - -- Available states: undef/nil, UpgradeAvailable, UpgradePending, UpgradeFailed, AtLatestKnown - -- Source: https://github.com/openshift/operator-framework-olm/blob/5e2c73b7663d0122c9dc3e59ea39e515a31e2719/staging/api/pkg/operators/v1alpha1/subscription_types.go#L17-L23 - if obj.status.state == nil then - numPending = numPending + 1 - msg = msg .. ".status.state not yet known\n" - elseif obj.status.state == "" or obj.status.state == "UpgradeAvailable" or obj.status.state == "UpgradePending" then - numPending = numPending + 1 - msg = msg .. ".status.state is '" .. obj.status.state .. "'\n" - elseif obj.status.state == "UpgradeFailed" then - numDegraded = numDegraded + 1 - msg = msg .. ".status.state is '" .. obj.status.state .. "'\n" - else - -- Last possiblity of .status.state: AtLatestKnown - msg = msg .. ".status.state is '" .. obj.status.state .. "'\n" - end - if numDegraded == 0 and numPending == 0 then health_status.status = "Healthy" health_status.message = msg return health_status elseif numPending > 0 and numDegraded == 0 then health_status.status = "Progressing" - health_status.message = msg + health_status.message = "An install plan for a subscription is pending installation" return health_status else health_status.status = "Degraded" @@ -48,4 +31,4 @@ if obj.status ~= nil then end health_status.status = "Progressing" health_status.message = "An install plan for a subscription is pending installation" -return health_status +return health_status \ No newline at end of file diff --git a/resource_customizations/operators.coreos.com/Subscription/health_test.yaml b/resource_customizations/operators.coreos.com/Subscription/health_test.yaml index 2133b032f0..11f8390c2c 100644 --- a/resource_customizations/operators.coreos.com/Subscription/health_test.yaml +++ b/resource_customizations/operators.coreos.com/Subscription/health_test.yaml @@ -1,29 +1,25 @@ tests: - healthStatus: status: Progressing - message: "1: CatalogSourcesUnhealthy | False\n.status.state not yet known\n" - inputPath: testdata/first_update_with_status.yaml -- healthStatus: - status: Progressing - message: "1: CatalogSourcesUnhealthy | False\n2: InstallPlanPending | True\n.status.state is 'UpgradePending'\n" + message: "An install plan for a subscription is pending installation" inputPath: testdata/install_plan_pending.yaml - healthStatus: status: Degraded - message: "1: CatalogSourcesUnhealthy | True\n.status.state not yet known\n" + message: "1: CatalogSourcesUnhealthy | True\n" inputPath: testdata/catalog_sources_unhealthy.yaml - healthStatus: status: Healthy - message: "1: CatalogSourcesUnhealthy | False\n2: InstallPlanMissing | True\n.status.state is 'AtLatestKnown'\n" + message: "1: CatalogSourcesUnhealthy | False\n2: InstallPlanMissing | True\n" inputPath: testdata/install_plan_missing.yaml - healthStatus: status: Degraded - message: "1: CatalogSourcesUnhealthy | False\n2: InstallPlanFailed | True\n.status.state is 'AtLatestKnown'\n" + message: "1: CatalogSourcesUnhealthy | False\n2: InstallPlanFailed | True\n" inputPath: testdata/install_plan_failed.yaml - healthStatus: status: Degraded - message: "1: CatalogSourcesUnhealthy | True\n2: ResolutionFailed | True\n.status.state not yet known\n" + message: "1: CatalogSourcesUnhealthy | True\n2: ResolutionFailed | True\n" inputPath: testdata/resolution_failed.yaml - healthStatus: status: Healthy - message: "1: CatalogSourcesUnhealthy | False\n.status.state is 'AtLatestKnown'\n" - inputPath: testdata/healthy.yaml + message: "1: CatalogSourcesUnhealthy | False\n" + inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/operators.coreos.com/Subscription/testdata/first_update_with_status.yaml b/resource_customizations/operators.coreos.com/Subscription/testdata/first_update_with_status.yaml deleted file mode 100644 index 2ce1fe679a..0000000000 --- a/resource_customizations/operators.coreos.com/Subscription/testdata/first_update_with_status.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: operators.coreos.com/v1alpha1 -kind: Subscription -metadata: - creationTimestamp: "2024-10-14T08:37:15Z" - generation: 1 - labels: - operators.coreos.com/cincinnati-operator.openshift-update-service: "" - name: update-service-subscription - namespace: openshift-update-service - resourceVersion: "1728269681" - uid: ce5194f6-b60e-4206-bcb9-019ed845797e -spec: - channel: v1 - installPlanApproval: Manual - name: cincinnati-operator - source: redhat-operators - sourceNamespace: openshift-marketplace -status: - catalogHealth: - - catalogSourceRef: - apiVersion: operators.coreos.com/v1alpha1 - kind: CatalogSource - name: certified-operators - namespace: openshift-marketplace - resourceVersion: "1728260000" - uid: 5ccf7092-9df5-4898-b5c5-0368937614f1 - healthy: true - lastUpdated: "2024-10-14T08:37:15Z" - - catalogSourceRef: - apiVersion: operators.coreos.com/v1alpha1 - kind: CatalogSource - name: redhat-marketplace - namespace: openshift-marketplace - resourceVersion: "1728258210" - uid: 83648c37-b64e-440c-86c1-8c8146fc59f0 - healthy: true - lastUpdated: "2024-10-14T08:37:15Z" - - catalogSourceRef: - apiVersion: operators.coreos.com/v1alpha1 - kind: CatalogSource - name: redhat-operators - namespace: openshift-marketplace - resourceVersion: "1728263805" - uid: 99cc0db9-35c4-4f2a-87ab-7e37f0b05cc0 - healthy: true - lastUpdated: "2024-10-14T08:37:15Z" - conditions: - - lastTransitionTime: "2024-10-14T08:37:15Z" - message: all available catalogsources are healthy - reason: CatalogSourcesAdded - status: "False" - type: CatalogSourcesUnhealthy - lastUpdated: "2024-10-14T08:37:15Z" diff --git a/resource_customizations/projectcontour.io/HTTPProxy/health.lua b/resource_customizations/projectcontour.io/HTTPProxy/health.lua deleted file mode 100644 index edc74d6da0..0000000000 --- a/resource_customizations/projectcontour.io/HTTPProxy/health.lua +++ /dev/null @@ -1,19 +0,0 @@ --- Status reporting information detailed here --- https://projectcontour.io/docs/main/config/fundamentals/#status-reporting -hs = { - status = "Progressing", - message = "Waiting for status", -} - -if obj.status ~= nil then - if obj.status.currentStatus ~= nil then - if obj.status.currentStatus == "valid" then - hs.status = "Healthy" - elseif obj.status.currentStatus == "invalid" then - hs.status = "Degraded" - end - hs.message = obj.status.description - end -end - -return hs \ No newline at end of file diff --git a/resource_customizations/projectcontour.io/HTTPProxy/health_test.yaml b/resource_customizations/projectcontour.io/HTTPProxy/health_test.yaml deleted file mode 100644 index 2732b145e8..0000000000 --- a/resource_customizations/projectcontour.io/HTTPProxy/health_test.yaml +++ /dev/null @@ -1,17 +0,0 @@ -tests: -- healthStatus: - status: Healthy - message: "Valid HTTPProxy" - inputPath: testdata/healthy.yaml -- healthStatus: - status: Progressing - message: 'Waiting for status' - inputPath: testdata/progressing.yaml -- healthStatus: - status: Progressing - message: 'Waiting for controller' - inputPath: testdata/not_reconciled.yaml -- healthStatus: - status: Degraded - message: 'At least one error present, see Errors for details' - inputPath: testdata/degraded.yaml diff --git a/resource_customizations/projectcontour.io/HTTPProxy/testdata/degraded.yaml b/resource_customizations/projectcontour.io/HTTPProxy/testdata/degraded.yaml deleted file mode 100644 index 85d1c3eb52..0000000000 --- a/resource_customizations/projectcontour.io/HTTPProxy/testdata/degraded.yaml +++ /dev/null @@ -1,31 +0,0 @@ -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: basic -spec: - virtualhost: - fqdn: foo-basic.bar.com - routes: - - conditions: - - prefix: / - services: - - name: s1 - port: 80 -status: - conditions: - - errors: - - message: 'Spec.Routes unresolved service reference: service "default/s1" not found' - reason: ServiceUnresolvedReference - status: "True" - type: ServiceError - lastTransitionTime: "2025-04-07T10:00:00Z" - message: 'At least one error present, see Errors for details' - observedGeneration: 1 - reason: ErrorPresent - status: "False" - type: Valid - currentStatus: invalid - description: 'At least one error present, see Errors for details' - loadBalancer: - ingress: - - hostname: abc-123.elb.us-east-1.amazonaws.com diff --git a/resource_customizations/projectcontour.io/HTTPProxy/testdata/healthy.yaml b/resource_customizations/projectcontour.io/HTTPProxy/testdata/healthy.yaml deleted file mode 100644 index 944cb1f519..0000000000 --- a/resource_customizations/projectcontour.io/HTTPProxy/testdata/healthy.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: basic -spec: - virtualhost: - fqdn: foo-basic.bar.com - routes: - - conditions: - - prefix: / - services: - - name: s1 - port: 80 -status: - conditions: - - type: Valid - status: "True" - observedGeneration: 1 - lastTransitionTime: "2025-04-07T10:00:00Z" - reason: Valid - message: Valid HTTPProxy - currentStatus: valid - description: Valid HTTPProxy - loadBalancer: - ingress: - - hostname: www.example.com diff --git a/resource_customizations/projectcontour.io/HTTPProxy/testdata/not_reconciled.yaml b/resource_customizations/projectcontour.io/HTTPProxy/testdata/not_reconciled.yaml deleted file mode 100644 index 7cc0187852..0000000000 --- a/resource_customizations/projectcontour.io/HTTPProxy/testdata/not_reconciled.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: basic -spec: - virtualhost: - fqdn: foo-basic.bar.com - routes: - - conditions: - - prefix: / - services: - - name: s1 - port: 80 -status: - currentStatus: NotReconciled - description: Waiting for controller diff --git a/resource_customizations/projectcontour.io/HTTPProxy/testdata/progressing.yaml b/resource_customizations/projectcontour.io/HTTPProxy/testdata/progressing.yaml deleted file mode 100644 index 86bece89d2..0000000000 --- a/resource_customizations/projectcontour.io/HTTPProxy/testdata/progressing.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: basic -spec: - virtualhost: - fqdn: foo-basic.bar.com - routes: - - conditions: - - prefix: / - services: - - name: s1 - port: 80 diff --git a/resource_customizations/rabbitmq.com/Binding/health.lua b/resource_customizations/rabbitmq.com/Binding/health.lua deleted file mode 100644 index b2b96e8c8b..0000000000 --- a/resource_customizations/rabbitmq.com/Binding/health.lua +++ /dev/null @@ -1,22 +0,0 @@ -local hs = {} -if obj.status ~= nil and obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "Ready" then - if condition.status == "True" and condition.reason == "SuccessfulCreateOrUpdate" then - hs.status = "Healthy" - hs.message = "RabbitMQ binding ready" - return hs - end - - if condition.status == "False" and condition.reason == "FailedCreateOrUpdate" then - hs.status = "Degraded" - hs.message = "RabbitMQ binding failed to be created or updated" - return hs - end - end - end -end - -hs.status = "Unknown" -hs.message = "RabbitMQ binding status is unknown" -return hs \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Binding/health_test.yaml b/resource_customizations/rabbitmq.com/Binding/health_test.yaml deleted file mode 100644 index b1481c95f2..0000000000 --- a/resource_customizations/rabbitmq.com/Binding/health_test.yaml +++ /dev/null @@ -1,13 +0,0 @@ -tests: -- healthStatus: - status: Degraded - message: RabbitMQ binding failed to be created or updated - inputPath: testdata/degraded.yaml -- healthStatus: - status: Unknown - message: RabbitMQ binding status is unknown - inputPath: testdata/unknown.yaml -- healthStatus: - status: Healthy - message: RabbitMQ binding ready - inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Binding/testdata/degraded.yaml b/resource_customizations/rabbitmq.com/Binding/testdata/degraded.yaml deleted file mode 100644 index d462a7a670..0000000000 --- a/resource_customizations/rabbitmq.com/Binding/testdata/degraded.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Binding -metadata: - labels: - app: example-rabbitmq - name: example-rabbitmq - namespace: example -spec: - destination: destination - destinationType: queue - rabbitmqClusterReference: - name: example-rabbitmq - routingKey: v1.example.request - source: operation-requests - vhost: / -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: FailedCreateOrUpdate - status: "False" - type: Ready - observedGeneration: 1 diff --git a/resource_customizations/rabbitmq.com/Binding/testdata/healthy.yaml b/resource_customizations/rabbitmq.com/Binding/testdata/healthy.yaml deleted file mode 100644 index f3ec856dc4..0000000000 --- a/resource_customizations/rabbitmq.com/Binding/testdata/healthy.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Binding -metadata: - labels: - app: example-rabbitmq - name: example-rabbitmq - namespace: example -spec: - destination: destination - destinationType: queue - rabbitmqClusterReference: - name: example-rabbitmq - routingKey: v1.example.request - source: operation-requests - vhost: / -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: SuccessfulCreateOrUpdate - status: "True" - type: Ready - observedGeneration: 1 diff --git a/resource_customizations/rabbitmq.com/Binding/testdata/unknown.yaml b/resource_customizations/rabbitmq.com/Binding/testdata/unknown.yaml deleted file mode 100644 index 463d6a20c8..0000000000 --- a/resource_customizations/rabbitmq.com/Binding/testdata/unknown.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Binding -metadata: - labels: - app: example-rabbitmq - name: example-rabbitmq - namespace: example -spec: - destination: destination - destinationType: queue - rabbitmqClusterReference: - name: example-rabbitmq - routingKey: v1.example.request - source: operation-requests - vhost: / -status: {} diff --git a/resource_customizations/rabbitmq.com/Exchange/health.lua b/resource_customizations/rabbitmq.com/Exchange/health.lua deleted file mode 100644 index 54b9b1dae5..0000000000 --- a/resource_customizations/rabbitmq.com/Exchange/health.lua +++ /dev/null @@ -1,22 +0,0 @@ -local hs = {} -if obj.status ~= nil and obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "Ready" then - if condition.status == "True" and condition.reason == "SuccessfulCreateOrUpdate" then - hs.status = "Healthy" - hs.message = "RabbitMQ exchange ready" - return hs - end - - if condition.status == "False" and condition.reason == "FailedCreateOrUpdate" then - hs.status = "Degraded" - hs.message = "RabbitMQ exchange failed to be created or updated" - return hs - end - end - end -end - -hs.status = "Unknown" -hs.message = "RabbitMQ exchange status is unknown" -return hs \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Exchange/health_test.yaml b/resource_customizations/rabbitmq.com/Exchange/health_test.yaml deleted file mode 100644 index 45f0ffd6cb..0000000000 --- a/resource_customizations/rabbitmq.com/Exchange/health_test.yaml +++ /dev/null @@ -1,13 +0,0 @@ -tests: -- healthStatus: - status: Degraded - message: RabbitMQ exchange failed to be created or updated - inputPath: testdata/degraded.yaml -- healthStatus: - status: Unknown - message: RabbitMQ exchange status is unknown - inputPath: testdata/unknown.yaml -- healthStatus: - status: Healthy - message: RabbitMQ exchange ready - inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Exchange/testdata/degraded.yaml b/resource_customizations/rabbitmq.com/Exchange/testdata/degraded.yaml deleted file mode 100644 index c686453d11..0000000000 --- a/resource_customizations/rabbitmq.com/Exchange/testdata/degraded.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Exchange -metadata: - generation: 3 - name: example-rabbit - namespace: example-rabbit -spec: - autoDelete: false - durable: true - name: example-rabbit - rabbitmqClusterReference: - name: example-rabbit - type: topic - vhost: / -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: FailedCreateOrUpdate - status: "False" - type: Ready - observedGeneration: 1 diff --git a/resource_customizations/rabbitmq.com/Exchange/testdata/healthy.yaml b/resource_customizations/rabbitmq.com/Exchange/testdata/healthy.yaml deleted file mode 100644 index bdcb7dcbb0..0000000000 --- a/resource_customizations/rabbitmq.com/Exchange/testdata/healthy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Exchange -metadata: - generation: 3 - name: example-rabbit - namespace: example-rabbit -spec: - autoDelete: false - durable: true - name: example-rabbit - rabbitmqClusterReference: - name: example-rabbit - type: topic - vhost: / -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: SuccessfulCreateOrUpdate - status: "True" - type: Ready - observedGeneration: 1 diff --git a/resource_customizations/rabbitmq.com/Exchange/testdata/unknown.yaml b/resource_customizations/rabbitmq.com/Exchange/testdata/unknown.yaml deleted file mode 100644 index d9a255f214..0000000000 --- a/resource_customizations/rabbitmq.com/Exchange/testdata/unknown.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Exchange -metadata: - generation: 3 - name: example-rabbit - namespace: example-rabbit -spec: - autoDelete: false - durable: true - name: example-rabbit - rabbitmqClusterReference: - name: example-rabbit - type: topic - vhost: / -status: {} \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Permission/health.lua b/resource_customizations/rabbitmq.com/Permission/health.lua deleted file mode 100644 index f4e8beda58..0000000000 --- a/resource_customizations/rabbitmq.com/Permission/health.lua +++ /dev/null @@ -1,22 +0,0 @@ -local hs = {} -if obj.status ~= nil and obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "Ready" then - if condition.status == "True" and condition.reason == "SuccessfulCreateOrUpdate" then - hs.status = "Healthy" - hs.message = "RabbitMQ permission ready" - return hs - end - - if condition.status == "False" and condition.reason == "FailedCreateOrUpdate" then - hs.status = "Degraded" - hs.message = "RabbitMQ permission failed to be created or updated" - return hs - end - end - end -end - -hs.status = "Unknown" -hs.message = "RabbitMQ permission status is unknown" -return hs \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Permission/health_test.yaml b/resource_customizations/rabbitmq.com/Permission/health_test.yaml deleted file mode 100644 index e0d9d24c50..0000000000 --- a/resource_customizations/rabbitmq.com/Permission/health_test.yaml +++ /dev/null @@ -1,13 +0,0 @@ -tests: -- healthStatus: - status: Degraded - message: RabbitMQ permission failed to be created or updated - inputPath: testdata/degraded.yaml -- healthStatus: - status: Unknown - message: RabbitMQ permission status is unknown - inputPath: testdata/unknown.yaml -- healthStatus: - status: Healthy - message: RabbitMQ permission ready - inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Permission/testdata/degraded.yaml b/resource_customizations/rabbitmq.com/Permission/testdata/degraded.yaml deleted file mode 100644 index b64446c3d9..0000000000 --- a/resource_customizations/rabbitmq.com/Permission/testdata/degraded.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Permission -metadata: - generation: 1 - name: example-rabbit - namespace: example-rabbit -spec: - permissions: - configure: .* - read: .* - write: .* - rabbitmqClusterReference: - name: example-rabbit - namespace: exmple-rabbit - user: example_user - vhost: / -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: FailedCreateOrUpdate - status: "False" - type: Ready - observedGeneration: 1 diff --git a/resource_customizations/rabbitmq.com/Permission/testdata/healthy.yaml b/resource_customizations/rabbitmq.com/Permission/testdata/healthy.yaml deleted file mode 100644 index 495132db5e..0000000000 --- a/resource_customizations/rabbitmq.com/Permission/testdata/healthy.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Permission -metadata: - generation: 1 - name: example-rabbit - namespace: example-rabbit -spec: - permissions: - configure: .* - read: .* - write: .* - rabbitmqClusterReference: - name: example-rabbit - namespace: exmple-rabbit - user: example_user - vhost: / -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: SuccessfulCreateOrUpdate - status: "True" - type: Ready - observedGeneration: 1 diff --git a/resource_customizations/rabbitmq.com/Permission/testdata/unknown.yaml b/resource_customizations/rabbitmq.com/Permission/testdata/unknown.yaml deleted file mode 100644 index a6294492b2..0000000000 --- a/resource_customizations/rabbitmq.com/Permission/testdata/unknown.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Permission -metadata: - generation: 1 - name: example-rabbit - namespace: example-rabbit -spec: - permissions: - configure: .* - read: .* - write: .* - rabbitmqClusterReference: - name: example-rabbit - namespace: exmple-rabbit - user: example_user - vhost: / -status: {} \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Policy/health.lua b/resource_customizations/rabbitmq.com/Policy/health.lua deleted file mode 100644 index f44b543226..0000000000 --- a/resource_customizations/rabbitmq.com/Policy/health.lua +++ /dev/null @@ -1,22 +0,0 @@ -local hs = {} -if obj.status ~= nil and obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "Ready" then - if condition.status == "True" and condition.reason == "SuccessfulCreateOrUpdate" then - hs.status = "Healthy" - hs.message = "RabbitMQ policy ready" - return hs - end - - if condition.status == "False" and condition.reason == "FailedCreateOrUpdate" then - hs.status = "Degraded" - hs.message = "RabbitMQ policy failed to be created or updated" - return hs - end - end - end -end - -hs.status = "Unknown" -hs.message = "RabbitMQ policy status is unknown" -return hs \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Policy/health_test.yaml b/resource_customizations/rabbitmq.com/Policy/health_test.yaml deleted file mode 100644 index 238f952297..0000000000 --- a/resource_customizations/rabbitmq.com/Policy/health_test.yaml +++ /dev/null @@ -1,13 +0,0 @@ -tests: -- healthStatus: - status: Degraded - message: RabbitMQ policy failed to be created or updated - inputPath: testdata/degraded.yaml -- healthStatus: - status: Unknown - message: RabbitMQ policy status is unknown - inputPath: testdata/unknown.yaml -- healthStatus: - status: Healthy - message: RabbitMQ policy ready - inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Policy/testdata/degraded.yaml b/resource_customizations/rabbitmq.com/Policy/testdata/degraded.yaml deleted file mode 100644 index f6b5466d60..0000000000 --- a/resource_customizations/rabbitmq.com/Policy/testdata/degraded.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Policy -metadata: - namespace: example-rabbit - name: example-rabbit -spec: - name: example-rabbit - vhost: example-rabbit - pattern: .* - applyTo: queues - definition: {} - rabbitmqClusterReference: - name: example-rabbit - namespace: example-rabbit -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: FailedCreateOrUpdate - status: "False" - type: Ready - observedGeneration: 1 diff --git a/resource_customizations/rabbitmq.com/Policy/testdata/healthy.yaml b/resource_customizations/rabbitmq.com/Policy/testdata/healthy.yaml deleted file mode 100644 index 7ce4962a27..0000000000 --- a/resource_customizations/rabbitmq.com/Policy/testdata/healthy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Policy -metadata: - namespace: example-rabbit - name: example-rabbit -spec: - name: example-rabbit - vhost: example-rabbit - pattern: .* - applyTo: queues - definition: {} - rabbitmqClusterReference: - name: example-rabbit - namespace: example-rabbit -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: SuccessfulCreateOrUpdate - status: "True" - type: Ready - observedGeneration: 1 diff --git a/resource_customizations/rabbitmq.com/Policy/testdata/unknown.yaml b/resource_customizations/rabbitmq.com/Policy/testdata/unknown.yaml deleted file mode 100644 index e66dec82ca..0000000000 --- a/resource_customizations/rabbitmq.com/Policy/testdata/unknown.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Policy -metadata: - namespace: example-rabbit - name: example-rabbit -spec: - name: example-rabbit - vhost: example-rabbit - pattern: .* - applyTo: queues - definition: {} - rabbitmqClusterReference: - name: example-rabbit - namespace: example-rabbit -status: {} \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Queue/health.lua b/resource_customizations/rabbitmq.com/Queue/health.lua deleted file mode 100644 index 80e4c4ab94..0000000000 --- a/resource_customizations/rabbitmq.com/Queue/health.lua +++ /dev/null @@ -1,22 +0,0 @@ -local hs = {} -if obj.status ~= nil and obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "Ready" then - if condition.status == "True" and condition.reason == "SuccessfulCreateOrUpdate" then - hs.status = "Healthy" - hs.message = "RabbitMQ queue ready" - return hs - end - - if condition.status == "False" and condition.reason == "FailedCreateOrUpdate" then - hs.status = "Degraded" - hs.message = "RabbitMQ queue failed to be created or updated" - return hs - end - end - end -end - -hs.status = "Unknown" -hs.message = "RabbitMQ queue status is unknown" -return hs \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Queue/health_test.yaml b/resource_customizations/rabbitmq.com/Queue/health_test.yaml deleted file mode 100644 index c756cb5f38..0000000000 --- a/resource_customizations/rabbitmq.com/Queue/health_test.yaml +++ /dev/null @@ -1,13 +0,0 @@ -tests: -- healthStatus: - status: Degraded - message: RabbitMQ queue failed to be created or updated - inputPath: testdata/degraded.yaml -- healthStatus: - status: Unknown - message: RabbitMQ queue status is unknown - inputPath: testdata/unknown.yaml -- healthStatus: - status: Healthy - message: RabbitMQ queue ready - inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Queue/testdata/degraded.yaml b/resource_customizations/rabbitmq.com/Queue/testdata/degraded.yaml deleted file mode 100644 index fd67dbb252..0000000000 --- a/resource_customizations/rabbitmq.com/Queue/testdata/degraded.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Queue -metadata: - generation: 3 - name: example-rabbit - namespace: example-rabbit -spec: - autoDelete: false - durable: true - name: example-rabbit - rabbitmqClusterReference: - name: example-rabbit - type: quorum - vhost: / -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: FailedCreateOrUpdate - status: "False" - type: Ready - observedGeneration: 3 diff --git a/resource_customizations/rabbitmq.com/Queue/testdata/healthy.yaml b/resource_customizations/rabbitmq.com/Queue/testdata/healthy.yaml deleted file mode 100644 index dda57ec06d..0000000000 --- a/resource_customizations/rabbitmq.com/Queue/testdata/healthy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Queue -metadata: - generation: 3 - name: example-rabbit - namespace: example-rabbit -spec: - autoDelete: false - durable: true - name: example-rabbit - rabbitmqClusterReference: - name: example-rabbit - type: quorum - vhost: / -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: SuccessfulCreateOrUpdate - status: "True" - type: Ready - observedGeneration: 3 diff --git a/resource_customizations/rabbitmq.com/Queue/testdata/unknown.yaml b/resource_customizations/rabbitmq.com/Queue/testdata/unknown.yaml deleted file mode 100644 index 50fb3e0457..0000000000 --- a/resource_customizations/rabbitmq.com/Queue/testdata/unknown.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Queue -metadata: - generation: 3 - name: example-rabbit - namespace: example-rabbit -spec: - autoDelete: false - durable: true - name: example-rabbit - rabbitmqClusterReference: - name: example-rabbit - type: quorum - vhost: / -status: {} \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Shovel/health.lua b/resource_customizations/rabbitmq.com/Shovel/health.lua deleted file mode 100644 index 6aa365909e..0000000000 --- a/resource_customizations/rabbitmq.com/Shovel/health.lua +++ /dev/null @@ -1,22 +0,0 @@ -local hs = {} -if obj.status ~= nil and obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "Ready" then - if condition.status == "True" and condition.reason == "SuccessfulCreateOrUpdate" then - hs.status = "Healthy" - hs.message = "RabbitMQ shovel ready" - return hs - end - - if condition.status == "False" and condition.reason == "FailedCreateOrUpdate" then - hs.status = "Degraded" - hs.message = "RabbitMQ shovel failed to be created or updated" - return hs - end - end - end -end - -hs.status = "Unknown" -hs.message = "RabbitMQ shovel status is unknown" -return hs \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Shovel/health_test.yaml b/resource_customizations/rabbitmq.com/Shovel/health_test.yaml deleted file mode 100644 index 74fdef335a..0000000000 --- a/resource_customizations/rabbitmq.com/Shovel/health_test.yaml +++ /dev/null @@ -1,13 +0,0 @@ -tests: -- healthStatus: - status: Degraded - message: RabbitMQ shovel failed to be created or updated - inputPath: testdata/degraded.yaml -- healthStatus: - status: Unknown - message: RabbitMQ shovel status is unknown - inputPath: testdata/unknown.yaml -- healthStatus: - status: Healthy - message: RabbitMQ shovel ready - inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Shovel/testdata/degraded.yaml b/resource_customizations/rabbitmq.com/Shovel/testdata/degraded.yaml deleted file mode 100644 index 3d32863590..0000000000 --- a/resource_customizations/rabbitmq.com/Shovel/testdata/degraded.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Shovel -metadata: - namespace: example-rabbit - name: example-rabbit -spec: - name: example-rabbit - vhost: example-rabbit -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: FailedCreateOrUpdate - status: "False" - type: Ready - observedGeneration: 1 diff --git a/resource_customizations/rabbitmq.com/Shovel/testdata/healthy.yaml b/resource_customizations/rabbitmq.com/Shovel/testdata/healthy.yaml deleted file mode 100644 index d4e78ec755..0000000000 --- a/resource_customizations/rabbitmq.com/Shovel/testdata/healthy.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Shovel -metadata: - namespace: example-rabbit - name: example-rabbit -spec: - name: example-rabbit - vhost: example-rabbit -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: SuccessfulCreateOrUpdate - status: "True" - type: Ready - observedGeneration: 1 diff --git a/resource_customizations/rabbitmq.com/Shovel/testdata/unknown.yaml b/resource_customizations/rabbitmq.com/Shovel/testdata/unknown.yaml deleted file mode 100644 index 41e7c9608e..0000000000 --- a/resource_customizations/rabbitmq.com/Shovel/testdata/unknown.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Shovel -metadata: - namespace: example-rabbit - name: example-rabbit -spec: - name: example-rabbit - vhost: example-rabbit -status: {} \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/User/health.lua b/resource_customizations/rabbitmq.com/User/health.lua deleted file mode 100644 index 77f69b1a5a..0000000000 --- a/resource_customizations/rabbitmq.com/User/health.lua +++ /dev/null @@ -1,22 +0,0 @@ -local hs = {} -if obj.status ~= nil and obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "Ready" then - if condition.status == "True" and condition.reason == "SuccessfulCreateOrUpdate" then - hs.status = "Healthy" - hs.message = "RabbitMQ user ready" - return hs - end - - if condition.status == "False" and condition.reason == "FailedCreateOrUpdate" then - hs.status = "Degraded" - hs.message = "RabbitMQ user failed to be created or updated" - return hs - end - end - end -end - -hs.status = "Unknown" -hs.message = "RabbitMQ user status is unknown" -return hs \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/User/health_test.yaml b/resource_customizations/rabbitmq.com/User/health_test.yaml deleted file mode 100644 index 9769a57e52..0000000000 --- a/resource_customizations/rabbitmq.com/User/health_test.yaml +++ /dev/null @@ -1,13 +0,0 @@ -tests: -- healthStatus: - status: Degraded - message: RabbitMQ user failed to be created or updated - inputPath: testdata/degraded.yaml -- healthStatus: - status: Unknown - message: RabbitMQ user status is unknown - inputPath: testdata/unknown.yaml -- healthStatus: - status: Healthy - message: RabbitMQ user ready - inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/User/testdata/degraded.yaml b/resource_customizations/rabbitmq.com/User/testdata/degraded.yaml deleted file mode 100644 index 869b334389..0000000000 --- a/resource_customizations/rabbitmq.com/User/testdata/degraded.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: User -metadata: - generation: 1 - name: example-rabbit - namespace: exmple-rabbit -spec: - importCredentialsSecret: - name: example-rabbit - rabbitmqClusterReference: - name: example-rabbit - namespace: exmple-rabbit - tags: - - administrator -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: FailedCreateOrUpdate - status: "False" - type: Ready - credentials: - name: example-rabbit-user-credentials - observedGeneration: 1 - username: example_user diff --git a/resource_customizations/rabbitmq.com/User/testdata/healthy.yaml b/resource_customizations/rabbitmq.com/User/testdata/healthy.yaml deleted file mode 100644 index 416f01e73f..0000000000 --- a/resource_customizations/rabbitmq.com/User/testdata/healthy.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: User -metadata: - generation: 1 - name: example-rabbit - namespace: exmple-rabbit -spec: - importCredentialsSecret: - name: example-rabbit - rabbitmqClusterReference: - name: example-rabbit - namespace: exmple-rabbit - tags: - - administrator -status: - conditions: - - lastTransitionTime: 2025-01-10T20:48:01Z - reason: SuccessfulCreateOrUpdate - status: "True" - type: Ready - credentials: - name: example-rabbit-user-credentials - observedGeneration: 1 - username: example_user \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/User/testdata/unknown.yaml b/resource_customizations/rabbitmq.com/User/testdata/unknown.yaml deleted file mode 100644 index 0614ec1790..0000000000 --- a/resource_customizations/rabbitmq.com/User/testdata/unknown.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: User -metadata: - generation: 1 - name: example-rabbit - namespace: exmple-rabbit -spec: - importCredentialsSecret: - name: example-rabbit - rabbitmqClusterReference: - name: example-rabbit - namespace: exmple-rabbit - tags: - - administrator -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: FailedCreateOrUpdate - status: "False" - type: Ready - credentials: - name: example-rabbit-user-credentials - observedGeneration: 1 - username: example_user -status: {} \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Vhost/health.lua b/resource_customizations/rabbitmq.com/Vhost/health.lua deleted file mode 100644 index 70d05ff351..0000000000 --- a/resource_customizations/rabbitmq.com/Vhost/health.lua +++ /dev/null @@ -1,22 +0,0 @@ -local hs = {} -if obj.status ~= nil and obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "Ready" then - if condition.status == "True" and condition.reason == "SuccessfulCreateOrUpdate" then - hs.status = "Healthy" - hs.message = "RabbitMQ vhost ready" - return hs - end - - if condition.status == "False" and condition.reason == "FailedCreateOrUpdate" then - hs.status = "Degraded" - hs.message = "RabbitMQ vhost failed to be created or updated" - return hs - end - end - end -end - -hs.status = "Unknown" -hs.message = "RabbitMQ vhost status is unknown" -return hs \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Vhost/health_test.yaml b/resource_customizations/rabbitmq.com/Vhost/health_test.yaml deleted file mode 100644 index ed713d59ff..0000000000 --- a/resource_customizations/rabbitmq.com/Vhost/health_test.yaml +++ /dev/null @@ -1,13 +0,0 @@ -tests: -- healthStatus: - status: Degraded - message: RabbitMQ vhost failed to be created or updated - inputPath: testdata/degraded.yaml -- healthStatus: - status: Unknown - message: RabbitMQ vhost status is unknown - inputPath: testdata/unknown.yaml -- healthStatus: - status: Healthy - message: RabbitMQ vhost ready - inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/Vhost/testdata/degraded.yaml b/resource_customizations/rabbitmq.com/Vhost/testdata/degraded.yaml deleted file mode 100644 index 68bc6e3fa1..0000000000 --- a/resource_customizations/rabbitmq.com/Vhost/testdata/degraded.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Vhost -metadata: - generation: 1 - name: example-rabbit - namespace: example-rabbit -spec: - defaultQueueType: quorum - name: example-rabbit - rabbitmqClusterReference: - name: example-rabbit - namespace: example-rabbit -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: FailedCreateOrUpdate - status: "False" - type: Ready - observedGeneration: 1 diff --git a/resource_customizations/rabbitmq.com/Vhost/testdata/healthy.yaml b/resource_customizations/rabbitmq.com/Vhost/testdata/healthy.yaml deleted file mode 100644 index d2e82c8fdc..0000000000 --- a/resource_customizations/rabbitmq.com/Vhost/testdata/healthy.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Vhost -metadata: - generation: 1 - name: example-rabbit - namespace: example-rabbit -spec: - defaultQueueType: quorum - name: example-rabbit - rabbitmqClusterReference: - name: example-rabbit - namespace: example-rabbit -status: - conditions: - - lastTransitionTime: 2025-02-24T17:51:10Z - reason: SuccessfulCreateOrUpdate - status: "True" - type: Ready - observedGeneration: 1 diff --git a/resource_customizations/rabbitmq.com/Vhost/testdata/unknown.yaml b/resource_customizations/rabbitmq.com/Vhost/testdata/unknown.yaml deleted file mode 100644 index adc5ca7f09..0000000000 --- a/resource_customizations/rabbitmq.com/Vhost/testdata/unknown.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: Vhost -metadata: - generation: 1 - name: example-rabbit - namespace: example-rabbit -spec: - defaultQueueType: quorum - name: example-rabbit - rabbitmqClusterReference: - name: example-rabbit - namespace: example-rabbit -status: {} \ No newline at end of file diff --git a/resource_customizations/spot.io/SpotDeployment/testdata/healthy_spotdeployment.yaml b/resource_customizations/spot.io/SpotDeployment/testdata/healthy_spotdeployment.yaml index 2296627fba..175b698dea 100644 --- a/resource_customizations/spot.io/SpotDeployment/testdata/healthy_spotdeployment.yaml +++ b/resource_customizations/spot.io/SpotDeployment/testdata/healthy_spotdeployment.yaml @@ -24,7 +24,7 @@ spec: app: guestbook-canary spec: containers: - - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1' + - image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1' name: guestbook-canary ports: - containerPort: 80 @@ -49,6 +49,6 @@ status: selector: app=guestbook-canary liveVersionDate: "2022-07-14T07:56:27.000Z" liveVersionImages: - rollouts-demo: quay.io/argoprojlabs/argocd-e2e-container:0.1 + rollouts-demo: gcr.io/heptio-images/ks-guestbook-demo:0.1 phase: Healthy revision: "9" \ No newline at end of file diff --git a/server/account/account.go b/server/account/account.go index 7b66acb04b..dbc6e95e51 100644 --- a/server/account/account.go +++ b/server/account/account.go @@ -14,13 +14,13 @@ import ( "google.golang.org/grpc/status" "k8s.io/kubectl/pkg/util/slice" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/account" - "github.com/argoproj/argo-cd/v3/server/rbacpolicy" - "github.com/argoproj/argo-cd/v3/util/password" - "github.com/argoproj/argo-cd/v3/util/rbac" - "github.com/argoproj/argo-cd/v3/util/session" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/account" + "github.com/argoproj/argo-cd/v2/server/rbacpolicy" + "github.com/argoproj/argo-cd/v2/util/password" + "github.com/argoproj/argo-cd/v2/util/rbac" + "github.com/argoproj/argo-cd/v2/util/session" + "github.com/argoproj/argo-cd/v2/util/settings" ) // Server provides a Session service @@ -37,16 +37,15 @@ func NewServer(sessionMgr *session.SessionManager, settingsMgr *settings.Setting // UpdatePassword updates the password of the currently authenticated account or the account specified in the request. func (s *Server) UpdatePassword(ctx context.Context, q *account.UpdatePasswordRequest) (*account.UpdatePasswordResponse, error) { - username := session.GetUserIdentifier(ctx) - + issuer := session.Iss(ctx) + username := session.Sub(ctx) updatedUsername := username + if q.Name != "" { updatedUsername = q.Name } - // check for permission is user is trying to change someone else's password // assuming user is trying to update someone else if username is different or issuer is not Argo CD - issuer := session.Iss(ctx) if updatedUsername != username || issuer != session.SessionManagerClaimsIssuer { if err := s.enf.EnforceErr(ctx.Value("claims"), rbac.ResourceAccounts, rbac.ActionUpdate, q.Name); err != nil { return nil, fmt.Errorf("permission denied: %w", err) @@ -74,7 +73,7 @@ func (s *Server) UpdatePassword(ctx context.Context, q *account.UpdatePasswordRe return nil, fmt.Errorf("failed to get issue time: %w", err) } if time.Since(iat) > common.ChangePasswordSSOTokenMaxAge { - return nil, errors.New("SSO token is too old. Please use 'argocd relogin' to get a new token") + return nil, errors.New("SSO token is too old. Please use 'argocd relogin' to get a new token.") } } @@ -90,7 +89,7 @@ func (s *Server) UpdatePassword(ctx context.Context, q *account.UpdatePasswordRe } if !validPasswordRegexp.Match([]byte(q.NewPassword)) { - err := fmt.Errorf("new password does not match the following expression: %s", passwordPattern) + err := fmt.Errorf("New password does not match the following expression: %s.", passwordPattern) return nil, err } @@ -126,6 +125,21 @@ func (s *Server) CanI(ctx context.Context, r *account.CanIRequest) (*account.Can return nil, status.Errorf(codes.InvalidArgument, "%v does not contain %s", rbac.Resources, r.Resource) } + // Logs RBAC will be enforced only if an internal var serverRBACLogEnforceEnable (representing server.rbac.log.enforce.enable env var) + // is defined and has a "true" value + // Otherwise, no RBAC enforcement for logs will take place (meaning, can-i request on a logs resource will result in "yes", + // even if there is no explicit RBAC allow, or if there is an explicit RBAC deny) + if r.Resource == "logs" { + serverRBACLogEnforceEnable, err := s.settingsMgr.GetServerRBACLogEnforceEnable() + if err != nil { + return nil, fmt.Errorf("failed to get server RBAC log enforcement setting: %w", err) + } + + if !serverRBACLogEnforceEnable { + return &account.CanIResponse{Value: "yes"}, nil + } + } + ok := s.enf.Enforce(ctx.Value("claims"), r.Resource, r.Action, r.Subresource) if ok { return &account.CanIResponse{Value: "yes"}, nil @@ -154,10 +168,8 @@ func toAPIAccount(name string, a settings.Account) *account.Account { } func (s *Server) ensureHasAccountPermission(ctx context.Context, action string, account string) error { - id := session.GetUserIdentifier(ctx) - // account has always has access to itself - if id == account && session.Iss(ctx) == session.SessionManagerClaimsIssuer { + if session.Sub(ctx) == account && session.Iss(ctx) == session.SessionManagerClaimsIssuer { return nil } if err := s.enf.EnforceErr(ctx.Value("claims"), rbac.ResourceAccounts, action, account); err != nil { diff --git a/server/account/account.proto b/server/account/account.proto index 8e2af941d6..3c4fd9b029 100644 --- a/server/account/account.proto +++ b/server/account/account.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/account"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/account"; // Account Service // diff --git a/server/account/account_test.go b/server/account/account_test.go index 5ecd8e9845..81e0abc078 100644 --- a/server/account/account_test.go +++ b/server/account/account_test.go @@ -5,24 +5,25 @@ import ( "testing" "time" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/account" - sessionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" - "github.com/argoproj/argo-cd/v3/server/session" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/password" - "github.com/argoproj/argo-cd/v3/util/rbac" - sessionutil "github.com/argoproj/argo-cd/v3/util/session" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/account" + sessionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" + "github.com/argoproj/argo-cd/v2/server/session" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/password" + "github.com/argoproj/argo-cd/v2/util/rbac" + sessionutil "github.com/argoproj/argo-cd/v2/util/session" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( @@ -30,18 +31,16 @@ const ( ) // return an AccountServer which returns fake data -func newTestAccountServer(t *testing.T, ctx context.Context, opts ...func(cm *corev1.ConfigMap, secret *corev1.Secret)) (*Server, *session.Server) { - t.Helper() - return newTestAccountServerExt(t, ctx, func(_ jwt.Claims, _ ...any) bool { +func newTestAccountServer(ctx context.Context, opts ...func(cm *v1.ConfigMap, secret *v1.Secret)) (*Server, *session.Server) { + return newTestAccountServerExt(ctx, func(claims jwt.Claims, rvals ...interface{}) bool { return true }, opts...) } -func newTestAccountServerExt(t *testing.T, ctx context.Context, enforceFn rbac.ClaimsEnforcerFunc, opts ...func(cm *corev1.ConfigMap, secret *corev1.Secret)) (*Server, *session.Server) { - t.Helper() +func newTestAccountServerExt(ctx context.Context, enforceFn rbac.ClaimsEnforcerFunc, opts ...func(cm *v1.ConfigMap, secret *v1.Secret)) (*Server, *session.Server) { bcrypt, err := password.HashPassword("oldpassword") - require.NoError(t, err) - cm := &corev1.ConfigMap{ + errors.CheckError(err) + cm := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-cm", Namespace: testNamespace, @@ -51,7 +50,7 @@ func newTestAccountServerExt(t *testing.T, ctx context.Context, enforceFn rbac.C }, Data: map[string]string{}, } - secret := &corev1.Secret{ + secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: testNamespace, @@ -83,12 +82,12 @@ func getAdminAccount(mgr *settings.SettingsManager) (*settings.Account, error) { } func adminContext(ctx context.Context) context.Context { - //nolint:staticcheck + // nolint:staticcheck return context.WithValue(ctx, "claims", &jwt.RegisteredClaims{Subject: "admin", Issuer: sessionutil.SessionManagerClaimsIssuer}) } func ssoAdminContext(ctx context.Context, iat time.Time) context.Context { - //nolint:staticcheck + // nolint:staticcheck return context.WithValue(ctx, "claims", &jwt.RegisteredClaims{ Subject: "admin", Issuer: "https://myargocdhost.com/api/dex", @@ -97,7 +96,7 @@ func ssoAdminContext(ctx context.Context, iat time.Time) context.Context { } func projTokenContext(ctx context.Context) context.Context { - //nolint:staticcheck + // nolint:staticcheck return context.WithValue(ctx, "claims", &jwt.RegisteredClaims{ Subject: "proj:demo:deployer", Issuer: sessionutil.SessionManagerClaimsIssuer, @@ -105,8 +104,8 @@ func projTokenContext(ctx context.Context) context.Context { } func TestUpdatePassword(t *testing.T) { - accountServer, sessionServer := newTestAccountServer(t, t.Context()) - ctx := adminContext(t.Context()) + accountServer, sessionServer := newTestAccountServer(context.Background()) + ctx := adminContext(context.Background()) var err error // ensure password is not allowed to be updated if given bad password @@ -141,10 +140,10 @@ func TestUpdatePassword(t *testing.T) { } func TestUpdatePassword_AdminUpdatesAnotherUser(t *testing.T) { - accountServer, sessionServer := newTestAccountServer(t, t.Context(), func(cm *corev1.ConfigMap, _ *corev1.Secret) { + accountServer, sessionServer := newTestAccountServer(context.Background(), func(cm *v1.ConfigMap, secret *v1.Secret) { cm.Data["accounts.anotherUser"] = "login" }) - ctx := adminContext(t.Context()) + ctx := adminContext(context.Background()) _, err := accountServer.UpdatePassword(ctx, &account.UpdatePasswordRequest{CurrentPassword: "oldpassword", NewPassword: "newpassword", Name: "anotherUser"}) require.NoError(t, err) @@ -154,51 +153,51 @@ func TestUpdatePassword_AdminUpdatesAnotherUser(t *testing.T) { } func TestUpdatePassword_DoesNotHavePermissions(t *testing.T) { - enforcer := func(_ jwt.Claims, _ ...any) bool { + enforcer := func(claims jwt.Claims, rvals ...interface{}) bool { return false } t.Run("LocalAccountUpdatesAnotherAccount", func(t *testing.T) { - accountServer, _ := newTestAccountServerExt(t, t.Context(), enforcer, func(cm *corev1.ConfigMap, _ *corev1.Secret) { + accountServer, _ := newTestAccountServerExt(context.Background(), enforcer, func(cm *v1.ConfigMap, secret *v1.Secret) { cm.Data["accounts.anotherUser"] = "login" }) - ctx := adminContext(t.Context()) + ctx := adminContext(context.Background()) _, err := accountServer.UpdatePassword(ctx, &account.UpdatePasswordRequest{CurrentPassword: "oldpassword", NewPassword: "newpassword", Name: "anotherUser"}) assert.ErrorContains(t, err, "permission denied") }) t.Run("SSOAccountWithTheSameName", func(t *testing.T) { - accountServer, _ := newTestAccountServerExt(t, t.Context(), enforcer) - ctx := ssoAdminContext(t.Context(), time.Now()) + accountServer, _ := newTestAccountServerExt(context.Background(), enforcer) + ctx := ssoAdminContext(context.Background(), time.Now()) _, err := accountServer.UpdatePassword(ctx, &account.UpdatePasswordRequest{CurrentPassword: "oldpassword", NewPassword: "newpassword", Name: "admin"}) assert.ErrorContains(t, err, "permission denied") }) } func TestUpdatePassword_ProjectToken(t *testing.T) { - accountServer, _ := newTestAccountServer(t, t.Context(), func(cm *corev1.ConfigMap, _ *corev1.Secret) { + accountServer, _ := newTestAccountServer(context.Background(), func(cm *v1.ConfigMap, secret *v1.Secret) { cm.Data["accounts.anotherUser"] = "login" }) - ctx := projTokenContext(t.Context()) + ctx := projTokenContext(context.Background()) _, err := accountServer.UpdatePassword(ctx, &account.UpdatePasswordRequest{CurrentPassword: "oldpassword", NewPassword: "newpassword"}) assert.ErrorContains(t, err, "password can only be changed for local users") } func TestUpdatePassword_OldSSOToken(t *testing.T) { - accountServer, _ := newTestAccountServer(t, t.Context(), func(cm *corev1.ConfigMap, _ *corev1.Secret) { + accountServer, _ := newTestAccountServer(context.Background(), func(cm *v1.ConfigMap, secret *v1.Secret) { cm.Data["accounts.anotherUser"] = "login" }) - ctx := ssoAdminContext(t.Context(), time.Now().Add(-2*common.ChangePasswordSSOTokenMaxAge)) + ctx := ssoAdminContext(context.Background(), time.Now().Add(-2*common.ChangePasswordSSOTokenMaxAge)) _, err := accountServer.UpdatePassword(ctx, &account.UpdatePasswordRequest{CurrentPassword: "oldpassword", NewPassword: "newpassword", Name: "anotherUser"}) require.Error(t, err) } func TestUpdatePassword_SSOUserUpdatesAnotherUser(t *testing.T) { - accountServer, sessionServer := newTestAccountServer(t, t.Context(), func(cm *corev1.ConfigMap, _ *corev1.Secret) { + accountServer, sessionServer := newTestAccountServer(context.Background(), func(cm *v1.ConfigMap, secret *v1.Secret) { cm.Data["accounts.anotherUser"] = "login" }) - ctx := ssoAdminContext(t.Context(), time.Now()) + ctx := ssoAdminContext(context.Background(), time.Now()) _, err := accountServer.UpdatePassword(ctx, &account.UpdatePasswordRequest{CurrentPassword: "oldpassword", NewPassword: "newpassword", Name: "anotherUser"}) require.NoError(t, err) @@ -208,17 +207,17 @@ func TestUpdatePassword_SSOUserUpdatesAnotherUser(t *testing.T) { } func TestListAccounts_NoAccountsConfigured(t *testing.T) { - ctx := adminContext(t.Context()) + ctx := adminContext(context.Background()) - accountServer, _ := newTestAccountServer(t, ctx) + accountServer, _ := newTestAccountServer(ctx) resp, err := accountServer.ListAccounts(ctx, &account.ListAccountRequest{}) require.NoError(t, err) assert.Len(t, resp.Items, 1) } func TestListAccounts_AccountsAreConfigured(t *testing.T) { - ctx := adminContext(t.Context()) - accountServer, _ := newTestAccountServer(t, ctx, func(cm *corev1.ConfigMap, _ *corev1.Secret) { + ctx := adminContext(context.Background()) + accountServer, _ := newTestAccountServer(ctx, func(cm *v1.ConfigMap, secret *v1.Secret) { cm.Data["accounts.account1"] = "apiKey" cm.Data["accounts.account2"] = "login, apiKey" cm.Data["accounts.account2.enabled"] = "false" @@ -235,8 +234,8 @@ func TestListAccounts_AccountsAreConfigured(t *testing.T) { } func TestGetAccount(t *testing.T) { - ctx := adminContext(t.Context()) - accountServer, _ := newTestAccountServer(t, ctx, func(cm *corev1.ConfigMap, _ *corev1.Secret) { + ctx := adminContext(context.Background()) + accountServer, _ := newTestAccountServer(ctx, func(cm *v1.ConfigMap, secret *v1.Secret) { cm.Data["accounts.account1"] = "apiKey" }) @@ -255,8 +254,8 @@ func TestGetAccount(t *testing.T) { } func TestCreateToken_SuccessfullyCreated(t *testing.T) { - ctx := adminContext(t.Context()) - accountServer, _ := newTestAccountServer(t, ctx, func(cm *corev1.ConfigMap, _ *corev1.Secret) { + ctx := adminContext(context.Background()) + accountServer, _ := newTestAccountServer(ctx, func(cm *v1.ConfigMap, secret *v1.Secret) { cm.Data["accounts.account1"] = "apiKey" }) @@ -270,8 +269,8 @@ func TestCreateToken_SuccessfullyCreated(t *testing.T) { } func TestCreateToken_DoesNotHaveCapability(t *testing.T) { - ctx := adminContext(t.Context()) - accountServer, _ := newTestAccountServer(t, ctx, func(cm *corev1.ConfigMap, _ *corev1.Secret) { + ctx := adminContext(context.Background()) + accountServer, _ := newTestAccountServer(ctx, func(cm *v1.ConfigMap, secret *v1.Secret) { cm.Data["accounts.account1"] = "login" }) @@ -280,8 +279,8 @@ func TestCreateToken_DoesNotHaveCapability(t *testing.T) { } func TestCreateToken_UserSpecifiedID(t *testing.T) { - ctx := adminContext(t.Context()) - accountServer, _ := newTestAccountServer(t, ctx, func(cm *corev1.ConfigMap, _ *corev1.Secret) { + ctx := adminContext(context.Background()) + accountServer, _ := newTestAccountServer(ctx, func(cm *v1.ConfigMap, secret *v1.Secret) { cm.Data["accounts.account1"] = "apiKey" }) @@ -294,8 +293,8 @@ func TestCreateToken_UserSpecifiedID(t *testing.T) { } func TestDeleteToken_SuccessfullyRemoved(t *testing.T) { - ctx := adminContext(t.Context()) - accountServer, _ := newTestAccountServer(t, ctx, func(cm *corev1.ConfigMap, secret *corev1.Secret) { + ctx := adminContext(context.Background()) + accountServer, _ := newTestAccountServer(ctx, func(cm *v1.ConfigMap, secret *v1.Secret) { cm.Data["accounts.account1"] = "apiKey" secret.Data["accounts.account1.tokens"] = []byte(`[{"id":"123","iat":1583789194,"exp":1583789194}]`) }) @@ -309,26 +308,49 @@ func TestDeleteToken_SuccessfullyRemoved(t *testing.T) { assert.Empty(t, acc.Tokens) } -func TestCanI_GetLogsAllow(t *testing.T) { - accountServer, _ := newTestAccountServer(t, t.Context(), func(_ *corev1.ConfigMap, _ *corev1.Secret) { +func TestCanI_GetLogsAllowNoSwitch(t *testing.T) { + accountServer, _ := newTestAccountServer(context.Background(), func(cm *v1.ConfigMap, secret *v1.Secret) { }) - ctx := projTokenContext(t.Context()) + ctx := projTokenContext(context.Background()) resp, err := accountServer.CanI(ctx, &account.CanIRequest{Resource: "logs", Action: "get", Subresource: ""}) require.NoError(t, err) - assert.Equal(t, "yes", resp.Value) + assert.EqualValues(t, "yes", resp.Value) } -func TestCanI_GetLogsDeny(t *testing.T) { - enforcer := func(_ jwt.Claims, _ ...any) bool { +func TestCanI_GetLogsDenySwitchOn(t *testing.T) { + enforcer := func(claims jwt.Claims, rvals ...interface{}) bool { return false } - accountServer, _ := newTestAccountServerExt(t, t.Context(), enforcer, func(_ *corev1.ConfigMap, _ *corev1.Secret) { + accountServer, _ := newTestAccountServerExt(context.Background(), enforcer, func(cm *v1.ConfigMap, secret *v1.Secret) { + cm.Data["server.rbac.log.enforce.enable"] = "true" }) - ctx := projTokenContext(t.Context()) + ctx := projTokenContext(context.Background()) resp, err := accountServer.CanI(ctx, &account.CanIRequest{Resource: "logs", Action: "get", Subresource: "*/*"}) require.NoError(t, err) - assert.Equal(t, "no", resp.Value) + assert.EqualValues(t, "no", resp.Value) +} + +func TestCanI_GetLogsAllowSwitchOn(t *testing.T) { + accountServer, _ := newTestAccountServer(context.Background(), func(cm *v1.ConfigMap, secret *v1.Secret) { + cm.Data["server.rbac.log.enforce.enable"] = "true" + }) + + ctx := projTokenContext(context.Background()) + resp, err := accountServer.CanI(ctx, &account.CanIRequest{Resource: "logs", Action: "get", Subresource: ""}) + require.NoError(t, err) + assert.EqualValues(t, "yes", resp.Value) +} + +func TestCanI_GetLogsAllowSwitchOff(t *testing.T) { + accountServer, _ := newTestAccountServer(context.Background(), func(cm *v1.ConfigMap, secret *v1.Secret) { + cm.Data["server.rbac.log.enforce.enable"] = "false" + }) + + ctx := projTokenContext(context.Background()) + resp, err := accountServer.CanI(ctx, &account.CanIRequest{Resource: "logs", Action: "get", Subresource: ""}) + require.NoError(t, err) + assert.EqualValues(t, "yes", resp.Value) } diff --git a/server/application/application.go b/server/application/application.go index b9f1d38ce0..6c1b165450 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -12,16 +12,12 @@ import ( "strings" "time" - "github.com/argoproj/gitops-engine/pkg/health" - - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - kubecache "github.com/argoproj/gitops-engine/pkg/cache" "github.com/argoproj/gitops-engine/pkg/diff" "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/argoproj/gitops-engine/pkg/utils/text" - "github.com/argoproj/pkg/v2/sync" + "github.com/argoproj/pkg/sync" jsonpatch "github.com/evanphx/json-patch" log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" @@ -40,32 +36,34 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/utils/ptr" - argocommon "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - servercache "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/server/deeplinks" - applog "github.com/argoproj/argo-cd/v3/util/app/log" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/collections" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/git" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/lua" - "github.com/argoproj/argo-cd/v3/util/manifeststream" - "github.com/argoproj/argo-cd/v3/util/rbac" - "github.com/argoproj/argo-cd/v3/util/security" - "github.com/argoproj/argo-cd/v3/util/session" - "github.com/argoproj/argo-cd/v3/util/settings" + argocommon "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/server/deeplinks" + "github.com/argoproj/argo-cd/v2/util/argo" + argoutil "github.com/argoproj/argo-cd/v2/util/argo" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/argoproj/argo-cd/v2/util/collections" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/git" + ioutil "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/lua" + "github.com/argoproj/argo-cd/v2/util/manifeststream" + "github.com/argoproj/argo-cd/v2/util/rbac" + "github.com/argoproj/argo-cd/v2/util/security" + "github.com/argoproj/argo-cd/v2/util/session" + "github.com/argoproj/argo-cd/v2/util/settings" - applicationType "github.com/argoproj/argo-cd/v3/pkg/apis/application" + applicationType "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) -type AppResourceTreeFn func(ctx context.Context, app *v1alpha1.Application) (*v1alpha1.ApplicationTree, error) +type AppResourceTreeFn func(ctx context.Context, app *appv1.Application) (*appv1.ApplicationTree, error) const ( backgroundPropagationPolicy string = "background" @@ -73,29 +71,29 @@ const ( ) var ( - ErrCacheMiss = cacheutil.ErrCacheMiss - watchAPIBufferSize = env.ParseNumFromEnv(argocommon.EnvWatchAPIBufferSize, 1000, 0, math.MaxInt32) + ErrCacheMiss = cacheutil.ErrCacheMiss + watchAPIBufferSize = env.ParseNumFromEnv(argocommon.EnvWatchAPIBufferSize, 1000, 0, math.MaxInt32) + permissionDeniedErr = status.Error(codes.PermissionDenied, "permission denied") ) // Server provides an Application service type Server struct { - ns string - kubeclientset kubernetes.Interface - appclientset appclientset.Interface - appLister applisters.ApplicationLister - appInformer cache.SharedIndexInformer - appBroadcaster Broadcaster - repoClientset apiclient.Clientset - kubectl kube.Kubectl - db db.ArgoDB - enf *rbac.Enforcer - projectLock sync.KeyLock - auditLogger *argo.AuditLogger - settingsMgr *settings.SettingsManager - cache *servercache.Cache - projInformer cache.SharedIndexInformer - enabledNamespaces []string - syncWithReplaceAllowed bool + ns string + kubeclientset kubernetes.Interface + appclientset appclientset.Interface + appLister applisters.ApplicationLister + appInformer cache.SharedIndexInformer + appBroadcaster Broadcaster + repoClientset apiclient.Clientset + kubectl kube.Kubectl + db db.ArgoDB + enf *rbac.Enforcer + projectLock sync.KeyLock + auditLogger *argo.AuditLogger + settingsMgr *settings.SettingsManager + cache *servercache.Cache + projInformer cache.SharedIndexInformer + enabledNamespaces []string } // NewServer returns a new instance of the Application service @@ -116,7 +114,6 @@ func NewServer( projInformer cache.SharedIndexInformer, enabledNamespaces []string, enableK8sEvent []string, - syncWithReplaceAllowed bool, ) (application.ApplicationServiceServer, AppResourceTreeFn) { if appBroadcaster == nil { appBroadcaster = &broadcasterHandler{} @@ -126,23 +123,22 @@ func NewServer( log.Error(err) } s := &Server{ - ns: namespace, - appclientset: &deepCopyAppClientset{appclientset}, - appLister: &deepCopyApplicationLister{appLister}, - appInformer: appInformer, - appBroadcaster: appBroadcaster, - kubeclientset: kubeclientset, - cache: cache, - db: db, - repoClientset: repoClientset, - kubectl: kubectl, - enf: enf, - projectLock: projectLock, - auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server", enableK8sEvent), - settingsMgr: settingsMgr, - projInformer: projInformer, - enabledNamespaces: enabledNamespaces, - syncWithReplaceAllowed: syncWithReplaceAllowed, + ns: namespace, + appclientset: &deepCopyAppClientset{appclientset}, + appLister: &deepCopyApplicationLister{appLister}, + appInformer: appInformer, + appBroadcaster: appBroadcaster, + kubeclientset: kubeclientset, + cache: cache, + db: db, + repoClientset: repoClientset, + kubectl: kubectl, + enf: enf, + projectLock: projectLock, + auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server", enableK8sEvent), + settingsMgr: settingsMgr, + projInformer: projInformer, + enabledNamespaces: enabledNamespaces, } return s, s.getAppResources } @@ -157,7 +153,7 @@ func NewServer( // // If the user does provide a "project," we can respond more specifically. If the user does not have access to the given // app name in the given project, we return "permission denied." If the app exists, but the project is different from -func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespace, name string, getApp func() (*v1alpha1.Application, error)) (*v1alpha1.Application, *v1alpha1.AppProject, error) { +func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespace, name string, getApp func() (*appv1.Application, error)) (*appv1.Application, *appv1.AppProject, error) { user := session.Username(ctx) if user == "" { user = "Unknown user" @@ -179,7 +175,7 @@ func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespa // but the app is in a different project" response. We don't want the user inferring the existence of the // app from response time. _, _ = getApp() - return nil, nil, argocommon.PermissionDeniedAPIError + return nil, nil, permissionDeniedErr } } a, err := getApp() @@ -192,10 +188,10 @@ func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespa // We don't know if the user was allowed to get the Application, and we don't want to leak information about // the Application's existence. Return 403. logCtx.Warn("application does not exist") - return nil, nil, argocommon.PermissionDeniedAPIError + return nil, nil, permissionDeniedErr } logCtx.Errorf("failed to get application: %s", err) - return nil, nil, argocommon.PermissionDeniedAPIError + return nil, nil, permissionDeniedErr } // Even if we performed an initial RBAC check (because the request was fully parameterized), we still need to // perform a second RBAC check to ensure that the user has access to the actual Application's project (not just the @@ -213,7 +209,7 @@ func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespa } // The user didn't specify a project. We always return permission denied for both lack of access and lack of // existence. - return nil, nil, argocommon.PermissionDeniedAPIError + return nil, nil, permissionDeniedErr } effectiveProject := "default" if a.Spec.Project != "" { @@ -239,9 +235,9 @@ func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespa // getApplicationEnforceRBACInformer uses an informer to get an Application. If the app does not exist, permission is // denied, or any other error occurs when getting the app, we return a permission denied error to obscure any sensitive // information. -func (s *Server) getApplicationEnforceRBACInformer(ctx context.Context, action, project, namespace, name string) (*v1alpha1.Application, *v1alpha1.AppProject, error) { +func (s *Server) getApplicationEnforceRBACInformer(ctx context.Context, action, project, namespace, name string) (*appv1.Application, *appv1.AppProject, error) { namespaceOrDefault := s.appNamespaceOrDefault(namespace) - return s.getAppEnforceRBAC(ctx, action, project, namespaceOrDefault, name, func() (*v1alpha1.Application, error) { + return s.getAppEnforceRBAC(ctx, action, project, namespaceOrDefault, name, func() (*appv1.Application, error) { return s.appLister.Applications(namespaceOrDefault).Get(name) }) } @@ -249,29 +245,25 @@ func (s *Server) getApplicationEnforceRBACInformer(ctx context.Context, action, // getApplicationEnforceRBACClient uses a client to get an Application. If the app does not exist, permission is denied, // or any other error occurs when getting the app, we return a permission denied error to obscure any sensitive // information. -func (s *Server) getApplicationEnforceRBACClient(ctx context.Context, action, project, namespace, name, resourceVersion string) (*v1alpha1.Application, *v1alpha1.AppProject, error) { +func (s *Server) getApplicationEnforceRBACClient(ctx context.Context, action, project, namespace, name, resourceVersion string) (*appv1.Application, *appv1.AppProject, error) { namespaceOrDefault := s.appNamespaceOrDefault(namespace) - return s.getAppEnforceRBAC(ctx, action, project, namespaceOrDefault, name, func() (*v1alpha1.Application, error) { + return s.getAppEnforceRBAC(ctx, action, project, namespaceOrDefault, name, func() (*appv1.Application, error) { if !s.isNamespaceEnabled(namespaceOrDefault) { return nil, security.NamespaceNotPermittedError(namespaceOrDefault) } - app, err := s.appclientset.ArgoprojV1alpha1().Applications(namespaceOrDefault).Get(ctx, name, metav1.GetOptions{ + return s.appclientset.ArgoprojV1alpha1().Applications(namespaceOrDefault).Get(ctx, name, metav1.GetOptions{ ResourceVersion: resourceVersion, }) - if err != nil { - return nil, err - } - return app, nil }) } // List returns list of applications -func (s *Server) List(ctx context.Context, q *application.ApplicationQuery) (*v1alpha1.ApplicationList, error) { +func (s *Server) List(ctx context.Context, q *application.ApplicationQuery) (*appv1.ApplicationList, error) { selector, err := labels.Parse(q.GetSelector()) if err != nil { return nil, fmt.Errorf("error parsing the selector: %w", err) } - var apps []*v1alpha1.Application + var apps []*appv1.Application if q.GetAppNamespace() == "" { apps, err = s.appLister.List(selector) } else { @@ -284,16 +276,16 @@ func (s *Server) List(ctx context.Context, q *application.ApplicationQuery) (*v1 filteredApps := apps // Filter applications by name if q.Name != nil { - filteredApps = argo.FilterByNameP(filteredApps, *q.Name) + filteredApps = argoutil.FilterByNameP(filteredApps, *q.Name) } // Filter applications by projects - filteredApps = argo.FilterByProjectsP(filteredApps, getProjectsFromApplicationQuery(*q)) + filteredApps = argoutil.FilterByProjectsP(filteredApps, getProjectsFromApplicationQuery(*q)) // Filter applications by source repo URL - filteredApps = argo.FilterByRepoP(filteredApps, q.GetRepo()) + filteredApps = argoutil.FilterByRepoP(filteredApps, q.GetRepo()) - newItems := make([]v1alpha1.Application, 0) + newItems := make([]appv1.Application, 0) for _, a := range filteredApps { // Skip any application that is neither in the control plane's namespace // nor in the list of enabled namespaces. @@ -310,7 +302,7 @@ func (s *Server) List(ctx context.Context, q *application.ApplicationQuery) (*v1 return newItems[i].Name < newItems[j].Name }) - appList := v1alpha1.ApplicationList{ + appList := appv1.ApplicationList{ ListMeta: metav1.ListMeta{ ResourceVersion: s.appInformer.LastSyncResourceVersion(), }, @@ -320,7 +312,7 @@ func (s *Server) List(ctx context.Context, q *application.ApplicationQuery) (*v1 } // Create creates an application -func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateRequest) (*v1alpha1.Application, error) { +func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateRequest) (*appv1.Application, error) { if q.GetApplication() == nil { return nil, errors.New("error creating application: application is nil in request") } @@ -338,7 +330,7 @@ func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateReq validate = *q.Validate } - proj, err := s.getAppProject(ctx, a, log.WithFields(applog.GetAppLogFields(a))) + proj, err := s.getAppProject(ctx, a, log.WithField("application", a.Name)) if err != nil { return nil, err } @@ -356,16 +348,16 @@ func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateReq // Don't let the app creator set the operation explicitly. Those requests should always go through the Sync API. if a.Operation != nil { - log.WithFields(applog.GetAppLogFields(a)). - WithFields(log.Fields{ - argocommon.SecurityField: argocommon.SecurityLow, - }).Warn("User attempted to set operation on application creation. This could have allowed them to bypass branch protection rules by setting manifests directly. Ignoring the set operation.") + log.WithFields(log.Fields{ + "application": a.Name, + argocommon.SecurityField: argocommon.SecurityLow, + }).Warn("User attempted to set operation on application creation. This could have allowed them to bypass branch protection rules by setting manifests directly. Ignoring the set operation.") a.Operation = nil } created, err := s.appclientset.ArgoprojV1alpha1().Applications(appNs).Create(ctx, a, metav1.CreateOptions{}) if err == nil { - s.logAppEvent(ctx, created, argo.EventReasonResourceCreated, "created application") + s.logAppEvent(created, ctx, argo.EventReasonResourceCreated, "created application") s.waitSync(created) return created, nil } @@ -379,11 +371,11 @@ func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateReq return nil, status.Errorf(codes.Internal, "unable to check existing application details (%s): %v", appNs, err) } - if _, err := argo.GetDestinationCluster(ctx, existing.Spec.Destination, s.db); err != nil { + if err := argo.ValidateDestination(ctx, &existing.Spec.Destination, s.db); err != nil { return nil, status.Errorf(codes.InvalidArgument, "application destination spec for %s is invalid: %s", existing.Name, err.Error()) } - equalSpecs := reflect.DeepEqual(existing.Spec.Destination, a.Spec.Destination) && + equalSpecs := existing.Spec.Destination.Equals(a.Spec.Destination) && reflect.DeepEqual(existing.Spec, a.Spec) && reflect.DeepEqual(existing.Labels, a.Labels) && reflect.DeepEqual(existing.Annotations, a.Annotations) && @@ -398,18 +390,18 @@ func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateReq if err := s.enf.EnforceErr(ctx.Value("claims"), rbac.ResourceApplications, rbac.ActionUpdate, a.RBACName(s.ns)); err != nil { return nil, err } - updated, err := s.updateApp(ctx, existing, a, true) + updated, err := s.updateApp(existing, a, ctx, true) if err != nil { return nil, fmt.Errorf("error updating application: %w", err) } return updated, nil } -func (s *Server) queryRepoServer(ctx context.Context, proj *v1alpha1.AppProject, action func( +func (s *Server) queryRepoServer(ctx context.Context, proj *appv1.AppProject, action func( client apiclient.RepoServerServiceClient, - helmRepos []*v1alpha1.Repository, - helmCreds []*v1alpha1.RepoCreds, - helmOptions *v1alpha1.HelmOptions, + helmRepos []*appv1.Repository, + helmCreds []*appv1.RepoCreds, + helmOptions *appv1.HelmOptions, enabledSourceTypes map[string]bool, ) error, ) error { @@ -417,7 +409,7 @@ func (s *Server) queryRepoServer(ctx context.Context, proj *v1alpha1.AppProject, if err != nil { return fmt.Errorf("error creating repo server client: %w", err) } - defer utilio.Close(closer) + defer ioutil.Close(closer) helmRepos, err := s.db.ListHelmRepositories(ctx) if err != nil { @@ -463,7 +455,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan manifestInfos := make([]*apiclient.ManifestResponse, 0) err = s.queryRepoServer(ctx, proj, func( - client apiclient.RepoServerServiceClient, helmRepos []*v1alpha1.Repository, helmCreds []*v1alpha1.RepoCreds, helmOptions *v1alpha1.HelmOptions, enableGenerateManifests map[string]bool, + client apiclient.RepoServerServiceClient, helmRepos []*appv1.Repository, helmCreds []*appv1.RepoCreds, helmOptions *appv1.HelmOptions, enableGenerateManifests map[string]bool, ) error { appInstanceLabelKey, err := s.settingsMgr.GetAppInstanceLabelKey() if err != nil { @@ -485,13 +477,13 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan return fmt.Errorf("error getting API resources: %w", err) } - sources := make([]v1alpha1.ApplicationSource, 0) + sources := make([]appv1.ApplicationSource, 0) appSpec := a.Spec if a.Spec.HasMultipleSources() { numOfSources := int64(len(a.Spec.GetSources())) for i, pos := range q.SourcePositions { if pos <= 0 || pos > numOfSources { - return errors.New("source position is out of range") + return fmt.Errorf("source position is out of range") } appSpec.Sources[pos-1].TargetRevision = q.Revisions[i] } @@ -529,10 +521,6 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan if err != nil { return fmt.Errorf("error getting installation ID: %w", err) } - trackingMethod, err := s.settingsMgr.GetTrackingMethod() - if err != nil { - return fmt.Errorf("error getting trackingMethod from settings: %w", err) - } manifestInfo, err := client.GenerateManifest(ctx, &apiclient.ManifestRequest{ Repo: repo, @@ -547,7 +535,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan ApiVersions: argo.APIResourcesToStrings(apiResources, true), HelmRepoCreds: helmCreds, HelmOptions: helmOptions, - TrackingMethod: trackingMethod, + TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), EnabledSourceTypes: enableGenerateManifests, ProjectName: proj.Name, ProjectSourceRepos: proj.Spec.SourceRepos, @@ -611,18 +599,13 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get var manifestInfo *apiclient.ManifestResponse err = s.queryRepoServer(ctx, proj, func( - client apiclient.RepoServerServiceClient, helmRepos []*v1alpha1.Repository, helmCreds []*v1alpha1.RepoCreds, helmOptions *v1alpha1.HelmOptions, enableGenerateManifests map[string]bool, + client apiclient.RepoServerServiceClient, helmRepos []*appv1.Repository, helmCreds []*appv1.RepoCreds, helmOptions *appv1.HelmOptions, enableGenerateManifests map[string]bool, ) error { appInstanceLabelKey, err := s.settingsMgr.GetAppInstanceLabelKey() if err != nil { return fmt.Errorf("error getting app instance label key from settings: %w", err) } - trackingMethod, err := s.settingsMgr.GetTrackingMethod() - if err != nil { - return fmt.Errorf("error getting trackingMethod from settings: %w", err) - } - config, err := s.getApplicationClusterConfig(ctx, a) if err != nil { return fmt.Errorf("error getting application cluster config: %w", err) @@ -640,7 +623,7 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get source := a.Spec.GetSource() - proj, err := argo.GetAppProject(ctx, a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db) + proj, err := argo.GetAppProject(a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx) if err != nil { return fmt.Errorf("error getting app project: %w", err) } @@ -672,7 +655,7 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get ApiVersions: argo.APIResourcesToStrings(apiResources, true), HelmRepoCreds: helmCreds, HelmOptions: helmOptions, - TrackingMethod: trackingMethod, + TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), EnabledSourceTypes: enableGenerateManifests, ProjectName: proj.Name, ProjectSourceRepos: proj.Spec.SourceRepos, @@ -725,7 +708,7 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get } // Get returns an application by name -func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*v1alpha1.Application, error) { +func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*appv1.Application, error) { appName := q.GetName() appNs := s.appNamespaceOrDefault(q.GetAppNamespace()) @@ -751,31 +734,31 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*v1a return a, nil } - refreshType := v1alpha1.RefreshTypeNormal - if *q.Refresh == string(v1alpha1.RefreshTypeHard) { - refreshType = v1alpha1.RefreshTypeHard + refreshType := appv1.RefreshTypeNormal + if *q.Refresh == string(appv1.RefreshTypeHard) { + refreshType = appv1.RefreshTypeHard } appIf := s.appclientset.ArgoprojV1alpha1().Applications(appNs) // subscribe early with buffered channel to ensure we don't miss events - events := make(chan *v1alpha1.ApplicationWatchEvent, watchAPIBufferSize) - unsubscribe := s.appBroadcaster.Subscribe(events, func(event *v1alpha1.ApplicationWatchEvent) bool { + events := make(chan *appv1.ApplicationWatchEvent, watchAPIBufferSize) + unsubscribe := s.appBroadcaster.Subscribe(events, func(event *appv1.ApplicationWatchEvent) bool { return event.Application.Name == appName && event.Application.Namespace == appNs }) defer unsubscribe() - app, err := argo.RefreshApp(appIf, appName, refreshType, true) + app, err := argoutil.RefreshApp(appIf, appName, refreshType, true) if err != nil { return nil, fmt.Errorf("error refreshing the app: %w", err) } - if refreshType == v1alpha1.RefreshTypeHard { + if refreshType == appv1.RefreshTypeHard { // force refresh cached application details if err := s.queryRepoServer(ctx, proj, func( client apiclient.RepoServerServiceClient, - helmRepos []*v1alpha1.Repository, - _ []*v1alpha1.RepoCreds, - helmOptions *v1alpha1.HelmOptions, + helmRepos []*appv1.Repository, + _ []*appv1.RepoCreds, + helmOptions *appv1.HelmOptions, enabledSourceTypes map[string]bool, ) error { source := app.Spec.GetSource() @@ -787,10 +770,6 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*v1a if err != nil { return fmt.Errorf("error getting kustomize settings: %w", err) } - trackingMethod, err := s.settingsMgr.GetTrackingMethod() - if err != nil { - return fmt.Errorf("error getting trackingMethod from settings: %w", err) - } kustomizeOptions, err := kustomizeSettings.GetOptions(a.Spec.GetSource()) if err != nil { return fmt.Errorf("error getting kustomize settings options: %w", err) @@ -802,7 +781,7 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*v1a KustomizeOptions: kustomizeOptions, Repos: helmRepos, NoCache: true, - TrackingMethod: trackingMethod, + TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), EnabledSourceTypes: enabledSourceTypes, HelmOptions: helmOptions, }) @@ -827,8 +806,8 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*v1a if annotations == nil { annotations = make(map[string]string) } - if _, ok := annotations[v1alpha1.AnnotationKeyRefresh]; !ok { - return event.Application.DeepCopy(), nil + if _, ok := annotations[appv1.AnnotationKeyRefresh]; !ok { + return &event.Application, nil } } } @@ -865,7 +844,7 @@ func (s *Server) ListResourceEvents(ctx context.Context, q *application.Applicat } found := false for _, n := range append(tree.Nodes, tree.OrphanedNodes...) { - if n.UID == q.GetResourceUID() && n.Name == q.GetResourceName() && n.Namespace == q.GetResourceNamespace() { + if n.ResourceRef.UID == q.GetResourceUID() && n.ResourceRef.Name == q.GetResourceName() && n.ResourceRef.Namespace == q.GetResourceNamespace() { found = true break } @@ -901,7 +880,7 @@ func (s *Server) ListResourceEvents(ctx context.Context, q *application.Applicat // validateAndUpdateApp validates and updates the application. currentProject is the name of the project the app // currently is under. If not specified, we assume that the app is under the project specified in the app spec. -func (s *Server) validateAndUpdateApp(ctx context.Context, newApp *v1alpha1.Application, merge bool, validate bool, action string, currentProject string) (*v1alpha1.Application, error) { +func (s *Server) validateAndUpdateApp(ctx context.Context, newApp *appv1.Application, merge bool, validate bool, action string, currentProject string) (*appv1.Application, error) { s.projectLock.RLock(newApp.Spec.GetProject()) defer s.projectLock.RUnlock(newApp.Spec.GetProject()) @@ -915,7 +894,7 @@ func (s *Server) validateAndUpdateApp(ctx context.Context, newApp *v1alpha1.Appl return nil, fmt.Errorf("error validating and normalizing app: %w", err) } - a, err := s.updateApp(ctx, app, newApp, merge) + a, err := s.updateApp(app, newApp, ctx, merge) if err != nil { return nil, fmt.Errorf("error updating application: %w", err) } @@ -931,8 +910,8 @@ var informerSyncTimeout = 2 * time.Second // eventually consistent, it is possible that it doesn't reflect an application change immediately // after a mutating API call (create/update). This function should be called after a creates & // update to give a probable (but not guaranteed) chance of being up-to-date after the create/update. -func (s *Server) waitSync(app *v1alpha1.Application) { - logCtx := log.WithFields(applog.GetAppLogFields(app)) +func (s *Server) waitSync(app *appv1.Application) { + logCtx := log.WithField("application", app.Name) deadline := time.Now().Add(informerSyncTimeout) minVersion, err := strconv.Atoi(app.ResourceVersion) if err != nil { @@ -955,7 +934,7 @@ func (s *Server) waitSync(app *v1alpha1.Application) { logCtx.Warnf("waitSync failed: timed out") } -func (s *Server) updateApp(ctx context.Context, app *v1alpha1.Application, newApp *v1alpha1.Application, merge bool) (*v1alpha1.Application, error) { +func (s *Server) updateApp(app *appv1.Application, newApp *appv1.Application, ctx context.Context, merge bool) (*appv1.Application, error) { for i := 0; i < 10; i++ { app.Spec = newApp.Spec if merge { @@ -970,7 +949,7 @@ func (s *Server) updateApp(ctx context.Context, app *v1alpha1.Application, newAp res, err := s.appclientset.ArgoprojV1alpha1().Applications(app.Namespace).Update(ctx, app, metav1.UpdateOptions{}) if err == nil { - s.logAppEvent(ctx, app, argo.EventReasonResourceUpdated, "updated application spec") + s.logAppEvent(app, ctx, argo.EventReasonResourceUpdated, "updated application spec") s.waitSync(res) return res, nil } @@ -988,7 +967,7 @@ func (s *Server) updateApp(ctx context.Context, app *v1alpha1.Application, newAp } // Update updates an application -func (s *Server) Update(ctx context.Context, q *application.ApplicationUpdateRequest) (*v1alpha1.Application, error) { +func (s *Server) Update(ctx context.Context, q *application.ApplicationUpdateRequest) (*appv1.Application, error) { if q.GetApplication() == nil { return nil, errors.New("error updating application: application is nil in request") } @@ -1005,7 +984,7 @@ func (s *Server) Update(ctx context.Context, q *application.ApplicationUpdateReq } // UpdateSpec updates an application spec and filters out any invalid parameter overrides -func (s *Server) UpdateSpec(ctx context.Context, q *application.ApplicationUpdateSpecRequest) (*v1alpha1.ApplicationSpec, error) { +func (s *Server) UpdateSpec(ctx context.Context, q *application.ApplicationUpdateSpecRequest) (*appv1.ApplicationSpec, error) { if q.GetSpec() == nil { return nil, errors.New("error updating application spec: spec is nil in request") } @@ -1027,7 +1006,7 @@ func (s *Server) UpdateSpec(ctx context.Context, q *application.ApplicationUpdat } // Patch patches an application -func (s *Server) Patch(ctx context.Context, q *application.ApplicationPatchRequest) (*v1alpha1.Application, error) { +func (s *Server) Patch(ctx context.Context, q *application.ApplicationPatchRequest) (*appv1.Application, error) { app, _, err := s.getApplicationEnforceRBACClient(ctx, rbac.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName(), "") if err != nil { return nil, err @@ -1063,7 +1042,7 @@ func (s *Server) Patch(ctx context.Context, q *application.ApplicationPatchReque return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("Patch type '%s' is not supported", q.GetPatchType())) } - newApp := &v1alpha1.Application{} + newApp := &appv1.Application{} err = json.Unmarshal(patchApp, newApp) if err != nil { return nil, fmt.Errorf("error unmarshaling patched app: %w", err) @@ -1071,8 +1050,8 @@ func (s *Server) Patch(ctx context.Context, q *application.ApplicationPatchReque return s.validateAndUpdateApp(ctx, newApp, false, true, rbac.ActionUpdate, q.GetProject()) } -func (s *Server) getAppProject(ctx context.Context, a *v1alpha1.Application, logCtx *log.Entry) (*v1alpha1.AppProject, error) { - proj, err := argo.GetAppProject(ctx, a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db) +func (s *Server) getAppProject(ctx context.Context, a *appv1.Application, logCtx *log.Entry) (*appv1.AppProject, error) { + proj, err := argo.GetAppProject(a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx) if err == nil { return proj, nil } @@ -1084,7 +1063,7 @@ func (s *Server) getAppProject(ctx context.Context, a *v1alpha1.Application, log return nil, vagueError } - var applicationNotAllowedToUseProjectErr *v1alpha1.ErrApplicationNotAllowedToUseProject + var applicationNotAllowedToUseProjectErr *appv1.ErrApplicationNotAllowedToUseProject if errors.As(err, &applicationNotAllowedToUseProjectErr) { logCtx.WithFields(map[string]any{ "project": a.Spec.Project, @@ -1154,11 +1133,11 @@ func (s *Server) Delete(ctx context.Context, q *application.ApplicationDeleteReq if err != nil { return nil, fmt.Errorf("error deleting application: %w", err) } - s.logAppEvent(ctx, a, argo.EventReasonResourceDeleted, "deleted application") + s.logAppEvent(a, ctx, argo.EventReasonResourceDeleted, "deleted application") return &application.ApplicationResponse{}, nil } -func (s *Server) isApplicationPermitted(selector labels.Selector, minVersion int, claims any, appName, appNs string, projects map[string]bool, a v1alpha1.Application) bool { +func (s *Server) isApplicationPermitted(selector labels.Selector, minVersion int, claims any, appName, appNs string, projects map[string]bool, a appv1.Application) bool { if len(projects) > 0 && !projects[a.Spec.GetProject()] { return false } @@ -1208,13 +1187,13 @@ func (s *Server) Watch(q *application.ApplicationQuery, ws application.Applicati // sendIfPermitted is a helper to send the application to the client's streaming channel if the // caller has RBAC privileges permissions to view it - sendIfPermitted := func(a v1alpha1.Application, eventType watch.EventType) { + sendIfPermitted := func(a appv1.Application, eventType watch.EventType) { permitted := s.isApplicationPermitted(selector, minVersion, claims, appName, appNs, projects, a) if !permitted { return } s.inferResourcesStatusHealth(&a) - err := ws.Send(&v1alpha1.ApplicationWatchEvent{ + err := ws.Send(&appv1.ApplicationWatchEvent{ Type: eventType, Application: a, }) @@ -1224,7 +1203,7 @@ func (s *Server) Watch(q *application.ApplicationQuery, ws application.Applicati } } - events := make(chan *v1alpha1.ApplicationWatchEvent, watchAPIBufferSize) + events := make(chan *appv1.ApplicationWatchEvent, watchAPIBufferSize) // Mimic watch API behavior: send ADDED events if no resource version provided // If watch API is executed for one application when emit event even if resource version is provided // This is required since single app watch API is used for during operations like app syncing and it is @@ -1253,7 +1232,7 @@ func (s *Server) Watch(q *application.ApplicationQuery, ws application.Applicati } } -func (s *Server) validateAndNormalizeApp(ctx context.Context, app *v1alpha1.Application, proj *v1alpha1.AppProject, validate bool) error { +func (s *Server) validateAndNormalizeApp(ctx context.Context, app *appv1.Application, proj *appv1.AppProject, validate bool) error { if app.GetName() == "" { return errors.New("resource name may not be empty") } @@ -1291,14 +1270,14 @@ func (s *Server) validateAndNormalizeApp(ctx context.Context, app *v1alpha1.Appl } } - if _, err := argo.GetDestinationCluster(ctx, app.Spec.Destination, s.db); err != nil { + if err := argo.ValidateDestination(ctx, &app.Spec.Destination, s.db); err != nil { return status.Errorf(codes.InvalidArgument, "application destination spec for %s is invalid: %s", app.Name, err.Error()) } - var conditions []v1alpha1.ApplicationCondition + var conditions []appv1.ApplicationCondition if validate { - conditions := make([]v1alpha1.ApplicationCondition, 0) + conditions := make([]appv1.ApplicationCondition, 0) condition, err := argo.ValidateRepo(ctx, app, s.repoClientset, s.db, s.kubectl, proj, s.settingsMgr) if err != nil { return fmt.Errorf("error validating the repo: %w", err) @@ -1321,12 +1300,15 @@ func (s *Server) validateAndNormalizeApp(ctx context.Context, app *v1alpha1.Appl return nil } -func (s *Server) getApplicationClusterConfig(ctx context.Context, a *v1alpha1.Application) (*rest.Config, error) { - cluster, err := argo.GetDestinationCluster(ctx, a.Spec.Destination, s.db) - if err != nil { +func (s *Server) getApplicationClusterConfig(ctx context.Context, a *appv1.Application) (*rest.Config, error) { + if err := argo.ValidateDestination(ctx, &a.Spec.Destination, s.db); err != nil { return nil, fmt.Errorf("error validating destination: %w", err) } - config, err := cluster.RESTConfig() + clst, err := s.db.GetCluster(ctx, a.Spec.Destination.Server) + if err != nil { + return nil, fmt.Errorf("error getting cluster: %w", err) + } + config, err := clst.RESTConfig() if err != nil { return nil, fmt.Errorf("error getting cluster REST config: %w", err) } @@ -1335,20 +1317,20 @@ func (s *Server) getApplicationClusterConfig(ctx context.Context, a *v1alpha1.Ap } // getCachedAppState loads the cached state and trigger app refresh if cache is missing -func (s *Server) getCachedAppState(ctx context.Context, a *v1alpha1.Application, getFromCache func() error) error { +func (s *Server) getCachedAppState(ctx context.Context, a *appv1.Application, getFromCache func() error) error { err := getFromCache() if err != nil && errors.Is(err, servercache.ErrCacheMiss) { - conditions := a.Status.GetConditions(map[v1alpha1.ApplicationConditionType]bool{ - v1alpha1.ApplicationConditionComparisonError: true, - v1alpha1.ApplicationConditionInvalidSpecError: true, + conditions := a.Status.GetConditions(map[appv1.ApplicationConditionType]bool{ + appv1.ApplicationConditionComparisonError: true, + appv1.ApplicationConditionInvalidSpecError: true, }) if len(conditions) > 0 { - return errors.New(argo.FormatAppConditions(conditions)) + return errors.New(argoutil.FormatAppConditions(conditions)) } _, err = s.Get(ctx, &application.ApplicationQuery{ Name: ptr.To(a.GetName()), AppNamespace: ptr.To(a.GetNamespace()), - Refresh: ptr.To(string(v1alpha1.RefreshTypeNormal)), + Refresh: ptr.To(string(appv1.RefreshTypeNormal)), }) if err != nil { return fmt.Errorf("error getting application by query: %w", err) @@ -1358,8 +1340,8 @@ func (s *Server) getCachedAppState(ctx context.Context, a *v1alpha1.Application, return err } -func (s *Server) getAppResources(ctx context.Context, a *v1alpha1.Application) (*v1alpha1.ApplicationTree, error) { - var tree v1alpha1.ApplicationTree +func (s *Server) getAppResources(ctx context.Context, a *appv1.Application) (*appv1.ApplicationTree, error) { + var tree appv1.ApplicationTree err := s.getCachedAppState(ctx, a, func() error { return s.cache.GetAppResourcesTree(a.InstanceName(s.ns), &tree) }) @@ -1396,7 +1378,7 @@ func (s *Server) getAppLiveResource(ctx context.Context, action string, q *appli } found := tree.FindNode(q.GetGroup(), q.GetKind(), q.GetNamespace(), q.GetResourceName()) - if found == nil || found.UID == "" { + if found == nil || found.ResourceRef.UID == "" { return nil, nil, nil, status.Errorf(codes.InvalidArgument, "%s %s %s not found as part of application %s", q.GetKind(), q.GetGroup(), q.GetResourceName(), q.GetName()) } config, err := s.getApplicationClusterConfig(ctx, a) @@ -1479,7 +1461,7 @@ func (s *Server) PatchResource(ctx context.Context, q *application.ApplicationRe if err != nil { return nil, fmt.Errorf("erro marshaling manifest object: %w", err) } - s.logAppEvent(ctx, a, argo.EventReasonResourceUpdated, fmt.Sprintf("patched resource %s/%s '%s'", q.GetGroup(), q.GetKind(), q.GetResourceName())) + s.logAppEvent(a, ctx, argo.EventReasonResourceUpdated, fmt.Sprintf("patched resource %s/%s '%s'", q.GetGroup(), q.GetKind(), q.GetResourceName())) m := string(data) return &application.ApplicationResourceResponse{ Manifest: &m, @@ -1519,11 +1501,11 @@ func (s *Server) DeleteResource(ctx context.Context, q *application.ApplicationR if err != nil { return nil, fmt.Errorf("error deleting resource: %w", err) } - s.logAppEvent(ctx, a, argo.EventReasonResourceDeleted, fmt.Sprintf("deleted resource %s/%s '%s'", q.GetGroup(), q.GetKind(), q.GetResourceName())) + s.logAppEvent(a, ctx, argo.EventReasonResourceDeleted, fmt.Sprintf("deleted resource %s/%s '%s'", q.GetGroup(), q.GetKind(), q.GetResourceName())) return &application.ApplicationResponse{}, nil } -func (s *Server) ResourceTree(ctx context.Context, q *application.ResourcesQuery) (*v1alpha1.ApplicationTree, error) { +func (s *Server) ResourceTree(ctx context.Context, q *application.ResourcesQuery) (*appv1.ApplicationTree, error) { a, _, err := s.getApplicationEnforceRBACInformer(ctx, rbac.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetApplicationName()) if err != nil { return nil, err @@ -1540,7 +1522,7 @@ func (s *Server) WatchResourceTree(q *application.ResourcesQuery, ws application cacheKey := argo.AppInstanceName(q.GetApplicationName(), q.GetAppNamespace(), s.ns) return s.cache.OnAppResourcesTreeChanged(ws.Context(), cacheKey, func() error { - var tree v1alpha1.ApplicationTree + var tree appv1.ApplicationTree err := s.cache.GetAppResourcesTree(cacheKey, &tree) if err != nil { return fmt.Errorf("error getting app resource tree: %w", err) @@ -1549,7 +1531,7 @@ func (s *Server) WatchResourceTree(q *application.ResourcesQuery, ws application }) } -func (s *Server) RevisionMetadata(ctx context.Context, q *application.RevisionMetadataQuery) (*v1alpha1.RevisionMetadata, error) { +func (s *Server) RevisionMetadata(ctx context.Context, q *application.RevisionMetadataQuery) (*appv1.RevisionMetadata, error) { a, proj, err := s.getApplicationEnforceRBACInformer(ctx, rbac.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName()) if err != nil { return nil, err @@ -1568,7 +1550,7 @@ func (s *Server) RevisionMetadata(ctx context.Context, q *application.RevisionMe if err != nil { return nil, fmt.Errorf("error creating repo server client: %w", err) } - defer utilio.Close(conn) + defer ioutil.Close(conn) return repoClient.GetRevisionMetadata(ctx, &apiclient.RepoServerRevisionMetadataRequest{ Repo: repo, Revision: q.GetRevision(), @@ -1577,7 +1559,7 @@ func (s *Server) RevisionMetadata(ctx context.Context, q *application.RevisionMe } // RevisionChartDetails returns the helm chart metadata, as fetched from the reposerver -func (s *Server) RevisionChartDetails(ctx context.Context, q *application.RevisionMetadataQuery) (*v1alpha1.ChartDetails, error) { +func (s *Server) RevisionChartDetails(ctx context.Context, q *application.RevisionMetadataQuery) (*appv1.ChartDetails, error) { a, _, err := s.getApplicationEnforceRBACInformer(ctx, rbac.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName()) if err != nil { return nil, err @@ -1599,7 +1581,7 @@ func (s *Server) RevisionChartDetails(ctx context.Context, q *application.Revisi if err != nil { return nil, fmt.Errorf("error creating repo server client: %w", err) } - defer utilio.Close(conn) + defer ioutil.Close(conn) return repoClient.GetRevisionChartDetails(ctx, &apiclient.RepoServerRevisionChartDetailsRequest{ Repo: repo, Name: source.Chart, @@ -1612,7 +1594,7 @@ func (s *Server) RevisionChartDetails(ctx context.Context, q *application.Revisi // we use the source(s) currently configured for the app. If the version ID is specified, we find the source for that // version ID. If the version ID is not found, we return an error. If the source index is out of bounds for whichever // source we choose (configured sources or sources for a specific version), we return an error. -func getAppSourceBySourceIndexAndVersionId(a *v1alpha1.Application, sourceIndexMaybe *int32, versionIdMaybe *int32) (v1alpha1.ApplicationSource, error) { +func getAppSourceBySourceIndexAndVersionId(a *appv1.Application, sourceIndexMaybe *int32, versionIdMaybe *int32) (appv1.ApplicationSource, error) { // Start with all the app's configured sources. sources := a.Spec.GetSources() @@ -1622,7 +1604,7 @@ func getAppSourceBySourceIndexAndVersionId(a *v1alpha1.Application, sourceIndexM var err error sources, err = getSourcesByVersionId(a, versionId) if err != nil { - return v1alpha1.ApplicationSource{}, fmt.Errorf("error getting source by version ID: %w", err) + return appv1.ApplicationSource{}, fmt.Errorf("error getting source by version ID: %w", err) } } @@ -1634,9 +1616,9 @@ func getAppSourceBySourceIndexAndVersionId(a *v1alpha1.Application, sourceIndexM sourceIndex = int(*sourceIndexMaybe) if sourceIndex >= len(sources) { if len(sources) == 1 { - return v1alpha1.ApplicationSource{}, fmt.Errorf("source index %d not found because there is only 1 source", sourceIndex) + return appv1.ApplicationSource{}, fmt.Errorf("source index %d not found because there is only 1 source", sourceIndex) } - return v1alpha1.ApplicationSource{}, fmt.Errorf("source index %d not found because there are only %d sources", sourceIndex, len(sources)) + return appv1.ApplicationSource{}, fmt.Errorf("source index %d not found because there are only %d sources", sourceIndex, len(sources)) } } @@ -1647,20 +1629,20 @@ func getAppSourceBySourceIndexAndVersionId(a *v1alpha1.Application, sourceIndexM // getRevisionHistoryByVersionId returns the revision history for a specific version ID. // If the version ID is not found, it returns an empty revision history and false. -func getRevisionHistoryByVersionId(histories v1alpha1.RevisionHistories, versionId int64) (v1alpha1.RevisionHistory, bool) { +func getRevisionHistoryByVersionId(histories v1alpha1.RevisionHistories, versionId int64) (appv1.RevisionHistory, bool) { for _, h := range histories { if h.ID == versionId { return h, true } } - return v1alpha1.RevisionHistory{}, false + return appv1.RevisionHistory{}, false } // getSourcesByVersionId returns the sources for a specific version ID. If there is no history, it returns an error. // If the version ID is not found, it returns an error. If the version ID is found, and there are multiple sources, // it returns the sources for that version ID. If the version ID is found, and there is only one source, it returns // a slice with just the single source. -func getSourcesByVersionId(a *v1alpha1.Application, versionId int64) ([]v1alpha1.ApplicationSource, error) { +func getSourcesByVersionId(a *appv1.Application, versionId int64) ([]appv1.ApplicationSource, error) { if len(a.Status.History) == 0 { return nil, fmt.Errorf("version ID %d not found because the app has no history", versionId) } @@ -1690,7 +1672,7 @@ func (s *Server) ManagedResources(ctx context.Context, q *application.ResourcesQ return nil, err } - items := make([]*v1alpha1.ResourceDiff, 0) + items := make([]*appv1.ResourceDiff, 0) err = s.getCachedAppState(ctx, a, func() error { return s.cache.GetAppManagedResources(a.InstanceName(s.ns), &items) }) @@ -1747,8 +1729,19 @@ func (s *Server) PodLogs(q *application.ApplicationPodLogsQuery, ws application. return err } - if err := s.enf.EnforceErr(ws.Context().Value("claims"), rbac.ResourceLogs, rbac.ActionGet, a.RBACName(s.ns)); err != nil { - return err + // Logs RBAC will be enforced only if an internal var serverRBACLogEnforceEnable (representing server.rbac.log.enforce.enable env var) + // is defined and has a "true" value + // Otherwise, no RBAC enforcement for logs will take place (meaning, PodLogs will return the logs, + // even if there is no explicit RBAC allow, or if there is an explicit RBAC deny) + serverRBACLogEnforceEnable, err := s.settingsMgr.GetServerRBACLogEnforceEnable() + if err != nil { + return fmt.Errorf("error getting RBAC log enforce enable: %w", err) + } + + if serverRBACLogEnforceEnable { + if err := s.enf.EnforceErr(ws.Context().Value("claims"), rbac.ResourceLogs, rbac.ActionGet, a.RBACName(s.ns)); err != nil { + return err + } } tree, err := s.getAppResources(ws.Context(), a) @@ -1796,7 +1789,7 @@ func (s *Server) PodLogs(q *application.ApplicationPodLogsQuery, ws application. podName := pod.Name logStream := make(chan logEntry) if err == nil { - defer utilio.Close(stream) + defer ioutil.Close(stream) } streams = append(streams, logStream) @@ -1822,13 +1815,7 @@ func (s *Server) PodLogs(q *application.ApplicationPodLogsQuery, ws application. return } if q.Filter != nil { - var lineContainsFilter bool - if q.GetMatchCase() { - lineContainsFilter = strings.Contains(entry.line, literal) - } else { - lineContainsFilter = strings.Contains(strings.ToLower(entry.line), strings.ToLower(literal)) - } - + lineContainsFilter := strings.Contains(entry.line, literal) if (inverse && lineContainsFilter) || (!inverse && !lineContainsFilter) { continue } @@ -1877,8 +1864,8 @@ func (s *Server) PodLogs(q *application.ApplicationPodLogsQuery, ws application. } // from all of the treeNodes, get the pod who meets the criteria or whose parents meets the criteria -func getSelectedPods(treeNodes []v1alpha1.ResourceNode, q *application.ApplicationPodLogsQuery) []v1alpha1.ResourceNode { - var pods []v1alpha1.ResourceNode +func getSelectedPods(treeNodes []appv1.ResourceNode, q *application.ApplicationPodLogsQuery) []appv1.ResourceNode { + var pods []appv1.ResourceNode isTheOneMap := make(map[string]bool) for _, treeNode := range treeNodes { if treeNode.Kind == kube.PodKind && treeNode.Group == "" && treeNode.UID != "" { @@ -1891,7 +1878,7 @@ func getSelectedPods(treeNodes []v1alpha1.ResourceNode, q *application.Applicati } // check is currentNode is matching with group, kind, and name, or if any of its parents matches -func isTheSelectedOne(currentNode *v1alpha1.ResourceNode, q *application.ApplicationPodLogsQuery, resourceNodes []v1alpha1.ResourceNode, isTheOneMap map[string]bool) bool { +func isTheSelectedOne(currentNode *appv1.ResourceNode, q *application.ApplicationPodLogsQuery, resourceNodes []appv1.ResourceNode, isTheOneMap map[string]bool) bool { exist, value := isTheOneMap[currentNode.UID] if exist { return value @@ -1931,7 +1918,7 @@ func isTheSelectedOne(currentNode *v1alpha1.ResourceNode, q *application.Applica } // Sync syncs an application to its target state -func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncRequest) (*v1alpha1.Application, error) { +func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncRequest) (*appv1.Application, error) { a, proj, err := s.getApplicationEnforceRBACClient(ctx, rbac.ActionGet, syncReq.GetProject(), syncReq.GetAppNamespace(), syncReq.GetName(), "") if err != nil { return nil, err @@ -1955,7 +1942,7 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR if err := s.enf.EnforceErr(ctx.Value("claims"), rbac.ResourceApplications, rbac.ActionOverride, a.RBACName(s.ns)); err != nil { return nil, err } - if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.IsAutomatedSyncEnabled() && !syncReq.GetDryRun() { + if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.Automated != nil && !syncReq.GetDryRun() { return nil, status.Error(codes.FailedPrecondition, "cannot use local sync when Automatic Sync Policy is enabled unless for dry run") } } @@ -1968,8 +1955,8 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR return nil, err } - var retry *v1alpha1.RetryStrategy - var syncOptions v1alpha1.SyncOptions + var retry *appv1.RetryStrategy + var syncOptions appv1.SyncOptions if a.Spec.SyncPolicy != nil { syncOptions = a.Spec.SyncPolicy.SyncOptions retry = a.Spec.SyncPolicy.Retry @@ -1981,16 +1968,12 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR syncOptions = syncReq.SyncOptions.Items } - if syncOptions.HasOption(common.SyncOptionReplace) && !s.syncWithReplaceAllowed { - return nil, status.Error(codes.FailedPrecondition, "sync with replace was disabled on the API Server level via the server configuration") - } - // We cannot use local manifests if we're only allowed to sync to signed commits if syncReq.Manifests != nil && len(proj.Spec.SignatureKeys) > 0 { return nil, status.Errorf(codes.FailedPrecondition, "Cannot use local sync when signature keys are required.") } - resources := []v1alpha1.SyncOperationResource{} + resources := []appv1.SyncOperationResource{} if syncReq.GetResources() != nil { for _, r := range syncReq.GetResources() { if r != nil { @@ -1998,8 +1981,8 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR } } } - op := v1alpha1.Operation{ - Sync: &v1alpha1.SyncOperation{ + op := appv1.Operation{ + Sync: &appv1.SyncOperation{ Revision: revision, Prune: syncReq.GetPrune(), DryRun: syncReq.GetDryRun(), @@ -2010,7 +1993,7 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR Sources: a.Spec.Sources, Revisions: sourceRevisions, }, - InitiatedBy: v1alpha1.OperationInitiator{Username: session.Username(ctx)}, + InitiatedBy: appv1.OperationInitiator{Username: session.Username(ctx)}, Info: syncReq.Infos, } if retry != nil { @@ -2037,11 +2020,11 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR if syncReq.Manifests != nil { reason = fmt.Sprintf("initiated %ssync locally", partial) } - s.logAppEvent(ctx, a, argo.EventReasonOperationStarted, reason) + s.logAppEvent(a, ctx, argo.EventReasonOperationStarted, reason) return a, nil } -func (s *Server) resolveSourceRevisions(ctx context.Context, a *v1alpha1.Application, syncReq *application.ApplicationSyncRequest) (string, string, []string, []string, error) { +func (s *Server) resolveSourceRevisions(ctx context.Context, a *appv1.Application, syncReq *application.ApplicationSyncRequest) (string, string, []string, []string, error) { if a.Spec.HasMultipleSources() { numOfSources := int64(len(a.Spec.GetSources())) sourceRevisions := make([]string, numOfSources) @@ -2055,7 +2038,7 @@ func (s *Server) resolveSourceRevisions(ctx context.Context, a *v1alpha1.Applica sources[pos-1].TargetRevision = syncReq.Revisions[i] } for index, source := range sources { - if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.IsAutomatedSyncEnabled() && !syncReq.GetDryRun() { + if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.Automated != nil && !syncReq.GetDryRun() { if text.FirstNonEmpty(a.Spec.GetSources()[index].TargetRevision, "HEAD") != text.FirstNonEmpty(source.TargetRevision, "HEAD") { return "", "", nil, nil, status.Errorf(codes.FailedPrecondition, "Cannot sync source %s to %s: auto-sync currently set to %s", source.RepoURL, source.TargetRevision, a.Spec.Sources[index].TargetRevision) } @@ -2070,7 +2053,7 @@ func (s *Server) resolveSourceRevisions(ctx context.Context, a *v1alpha1.Applica return "", "", sourceRevisions, displayRevisions, nil } source := a.Spec.GetSource() - if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.IsAutomatedSyncEnabled() && !syncReq.GetDryRun() { + if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.Automated != nil && !syncReq.GetDryRun() { if syncReq.GetRevision() != "" && syncReq.GetRevision() != text.FirstNonEmpty(source.TargetRevision, "HEAD") { return "", "", nil, nil, status.Errorf(codes.FailedPrecondition, "Cannot sync to %s: auto-sync currently set to %s", syncReq.GetRevision(), source.TargetRevision) } @@ -2082,7 +2065,7 @@ func (s *Server) resolveSourceRevisions(ctx context.Context, a *v1alpha1.Applica return revision, displayRevision, nil, nil, nil } -func (s *Server) Rollback(ctx context.Context, rollbackReq *application.ApplicationRollbackRequest) (*v1alpha1.Application, error) { +func (s *Server) Rollback(ctx context.Context, rollbackReq *application.ApplicationRollbackRequest) (*appv1.Application, error) { a, _, err := s.getApplicationEnforceRBACClient(ctx, rbac.ActionSync, rollbackReq.GetProject(), rollbackReq.GetAppNamespace(), rollbackReq.GetName(), "") if err != nil { return nil, err @@ -2093,11 +2076,11 @@ func (s *Server) Rollback(ctx context.Context, rollbackReq *application.Applicat if a.DeletionTimestamp != nil { return nil, status.Errorf(codes.FailedPrecondition, "application is deleting") } - if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.IsAutomatedSyncEnabled() { + if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.Automated != nil { return nil, status.Errorf(codes.FailedPrecondition, "rollback cannot be initiated when auto-sync is enabled") } - var deploymentInfo *v1alpha1.RevisionHistory + var deploymentInfo *appv1.RevisionHistory for _, info := range a.Status.History { if info.ID == rollbackReq.GetId() { deploymentInfo = &info @@ -2114,24 +2097,24 @@ func (s *Server) Rollback(ctx context.Context, rollbackReq *application.Applicat return nil, status.Errorf(codes.FailedPrecondition, "cannot rollback to revision deployed with Argo CD v0.11 or lower. sync to revision instead.") } - var syncOptions v1alpha1.SyncOptions + var syncOptions appv1.SyncOptions if a.Spec.SyncPolicy != nil { syncOptions = a.Spec.SyncPolicy.SyncOptions } // Rollback is just a convenience around Sync - op := v1alpha1.Operation{ - Sync: &v1alpha1.SyncOperation{ + op := appv1.Operation{ + Sync: &appv1.SyncOperation{ Revision: deploymentInfo.Revision, Revisions: deploymentInfo.Revisions, DryRun: rollbackReq.GetDryRun(), Prune: rollbackReq.GetPrune(), SyncOptions: syncOptions, - SyncStrategy: &v1alpha1.SyncStrategy{Apply: &v1alpha1.SyncStrategyApply{}}, + SyncStrategy: &appv1.SyncStrategy{Apply: &appv1.SyncStrategyApply{}}, Source: &deploymentInfo.Source, Sources: deploymentInfo.Sources, }, - InitiatedBy: v1alpha1.OperationInitiator{Username: session.Username(ctx)}, + InitiatedBy: appv1.OperationInitiator{Username: session.Username(ctx)}, } appName := rollbackReq.GetName() appNs := s.appNamespaceOrDefault(rollbackReq.GetAppNamespace()) @@ -2140,7 +2123,7 @@ func (s *Server) Rollback(ctx context.Context, rollbackReq *application.Applicat if err != nil { return nil, fmt.Errorf("error setting app operation: %w", err) } - s.logAppEvent(ctx, a, argo.EventReasonOperationStarted, fmt.Sprintf("initiated rollback to %d", rollbackReq.GetId())) + s.logAppEvent(a, ctx, argo.EventReasonOperationStarted, fmt.Sprintf("initiated rollback to %d", rollbackReq.GetId())) return a, nil } @@ -2175,37 +2158,46 @@ func (s *Server) ListLinks(ctx context.Context, req *application.ListAppLinksReq return finalList, nil } -func (s *Server) getObjectsForDeepLinks(ctx context.Context, app *v1alpha1.Application, proj *v1alpha1.AppProject) (cluster *unstructured.Unstructured, project *unstructured.Unstructured, err error) { +func (s *Server) getObjectsForDeepLinks(ctx context.Context, app *appv1.Application, proj *appv1.AppProject) (cluster *unstructured.Unstructured, project *unstructured.Unstructured, err error) { // sanitize project jwt tokens - proj.Status = v1alpha1.AppProjectStatus{} + proj.Status = appv1.AppProjectStatus{} project, err = kube.ToUnstructured(proj) if err != nil { return nil, nil, err } - getProjectClusters := func(project string) ([]*v1alpha1.Cluster, error) { + getProjectClusters := func(project string) ([]*appv1.Cluster, error) { return s.db.GetProjectClusters(ctx, project) } - destCluster, err := argo.GetDestinationCluster(ctx, app.Spec.Destination, s.db) - if err != nil { - log.WithFields(applog.GetAppLogFields(app)). - WithFields(map[string]any{ - "destination": app.Spec.Destination, - }).Warnf("cannot validate cluster, error=%v", err.Error()) + if err := argo.ValidateDestination(ctx, &app.Spec.Destination, s.db); err != nil { + log.WithFields(map[string]interface{}{ + "application": app.GetName(), + "ns": app.GetNamespace(), + "destination": app.Spec.Destination, + }).Warnf("cannot validate cluster, error=%v", err.Error()) return nil, nil, nil } - permitted, err := proj.IsDestinationPermitted(destCluster, app.Spec.Destination.Namespace, getProjectClusters) + permitted, err := proj.IsDestinationPermitted(app.Spec.Destination, getProjectClusters) if err != nil { return nil, nil, err } if !permitted { - return nil, nil, errors.New("error getting destination cluster") + return nil, nil, fmt.Errorf("error getting destination cluster") + } + clst, err := s.db.GetCluster(ctx, app.Spec.Destination.Server) + if err != nil { + log.WithFields(map[string]interface{}{ + "application": app.GetName(), + "ns": app.GetNamespace(), + "destination": app.Spec.Destination, + }).Warnf("cannot get cluster from db, error=%v", err.Error()) + return nil, nil, nil } // sanitize cluster, remove cluster config creds and other unwanted fields - cluster, err = deeplinks.SanitizeCluster(destCluster) + cluster, err = deeplinks.SanitizeCluster(clst) return cluster, project, err } @@ -2229,7 +2221,7 @@ func (s *Server) ListResourceLinks(ctx context.Context, req *application.Applica return nil, err } - proj, err := s.getAppProject(ctx, app, log.WithFields(applog.GetAppLogFields(app))) + proj, err := s.getAppProject(ctx, app, log.WithField("application", app.GetName())) if err != nil { return nil, err } @@ -2248,7 +2240,7 @@ func (s *Server) ListResourceLinks(ctx context.Context, req *application.Applica return finalList, nil } -func getAmbiguousRevision(app *v1alpha1.Application, syncReq *application.ApplicationSyncRequest, sourceIndex int) string { +func getAmbiguousRevision(app *appv1.Application, syncReq *application.ApplicationSyncRequest, sourceIndex int) string { ambiguousRevision := "" if app.Spec.HasMultipleSources() { for i, pos := range syncReq.SourcePositions { @@ -2270,7 +2262,7 @@ func getAmbiguousRevision(app *v1alpha1.Application, syncReq *application.Applic // resolveRevision resolves the revision specified either in the sync request, or the // application source, into a concrete revision that will be used for a sync operation. -func (s *Server) resolveRevision(ctx context.Context, app *v1alpha1.Application, syncReq *application.ApplicationSyncRequest, sourceIndex int) (string, string, error) { +func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, syncReq *application.ApplicationSyncRequest, sourceIndex int) (string, string, error) { if syncReq.Manifests != nil { return "", "", nil } @@ -2290,7 +2282,7 @@ func (s *Server) resolveRevision(ctx context.Context, app *v1alpha1.Application, if err != nil { return "", "", fmt.Errorf("error getting repo server client: %w", err) } - defer utilio.Close(conn) + defer ioutil.Close(conn) source := app.Spec.GetSourcePtrByIndex(sourceIndex) if !source.IsHelm() { @@ -2328,7 +2320,7 @@ func (s *Server) TerminateOperation(ctx context.Context, termOpReq *application. updated, err := s.appclientset.ArgoprojV1alpha1().Applications(appNs).Update(ctx, a, metav1.UpdateOptions{}) if err == nil { s.waitSync(updated) - s.logAppEvent(ctx, a, argo.EventReasonResourceUpdated, "terminated running operation") + s.logAppEvent(a, ctx, argo.EventReasonResourceUpdated, "terminated running operation") return &application.OperationTerminateResponse{}, nil } if !apierrors.IsConflict(err) { @@ -2344,18 +2336,18 @@ func (s *Server) TerminateOperation(ctx context.Context, termOpReq *application. return nil, status.Errorf(codes.Internal, "Failed to terminate app. Too many conflicts") } -func (s *Server) logAppEvent(ctx context.Context, a *v1alpha1.Application, reason string, action string) { +func (s *Server) logAppEvent(a *appv1.Application, ctx context.Context, reason string, action string) { eventInfo := argo.EventInfo{Type: corev1.EventTypeNormal, Reason: reason} user := session.Username(ctx) if user == "" { user = "Unknown user" } message := fmt.Sprintf("%s %s", user, action) - eventLabels := argo.GetAppEventLabels(ctx, a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db) + eventLabels := argo.GetAppEventLabels(a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx) s.auditLogger.LogAppEvent(a, eventInfo, message, user, eventLabels) } -func (s *Server) logResourceEvent(ctx context.Context, res *v1alpha1.ResourceNode, reason string, action string) { +func (s *Server) logResourceEvent(res *appv1.ResourceNode, ctx context.Context, reason string, action string) { eventInfo := argo.EventInfo{Type: corev1.EventTypeNormal, Reason: reason} user := session.Username(ctx) if user == "" { @@ -2379,7 +2371,7 @@ func (s *Server) ListResourceActions(ctx context.Context, q *application.Applica if err != nil { return nil, fmt.Errorf("error getting available actions: %w", err) } - actionsPtr := []*v1alpha1.ResourceAction{} + actionsPtr := []*appv1.ResourceAction{} for i := range availableActions { actionsPtr = append(actionsPtr, &availableActions[i]) } @@ -2387,7 +2379,7 @@ func (s *Server) ListResourceActions(ctx context.Context, q *application.Applica return &application.ResourceActionsListResponse{Actions: actionsPtr}, nil } -func (s *Server) getUnstructuredLiveResourceOrApp(ctx context.Context, rbacRequest string, q *application.ApplicationResourceRequest) (obj *unstructured.Unstructured, res *v1alpha1.ResourceNode, app *v1alpha1.Application, config *rest.Config, err error) { +func (s *Server) getUnstructuredLiveResourceOrApp(ctx context.Context, rbacRequest string, q *application.ApplicationResourceRequest) (obj *unstructured.Unstructured, res *appv1.ResourceNode, app *appv1.Application, config *rest.Config, err error) { if q.GetKind() == applicationType.ApplicationKind && q.GetGroup() == applicationType.Group && q.GetName() == q.GetResourceName() { app, _, err = s.getApplicationEnforceRBACInformer(ctx, rbacRequest, q.GetProject(), q.GetAppNamespace(), q.GetName()) if err != nil { @@ -2414,7 +2406,7 @@ func (s *Server) getUnstructuredLiveResourceOrApp(ctx context.Context, rbacReque return } -func (s *Server) getAvailableActions(resourceOverrides map[string]v1alpha1.ResourceOverride, obj *unstructured.Unstructured) ([]v1alpha1.ResourceAction, error) { +func (s *Server) getAvailableActions(resourceOverrides map[string]appv1.ResourceOverride, obj *unstructured.Unstructured) ([]appv1.ResourceAction, error) { luaVM := lua.VM{ ResourceOverrides: resourceOverrides, } @@ -2424,7 +2416,7 @@ func (s *Server) getAvailableActions(resourceOverrides map[string]v1alpha1.Resou return nil, fmt.Errorf("error getting Lua discovery script: %w", err) } if len(discoveryScripts) == 0 { - return []v1alpha1.ResourceAction{}, nil + return []appv1.ResourceAction{}, nil } availableActions, err := luaVM.ExecuteResourceActionDiscovery(obj, discoveryScripts) if err != nil { @@ -2468,12 +2460,12 @@ func (s *Server) RunResourceAction(ctx context.Context, q *application.ResourceA return nil, fmt.Errorf("error getting Lua resource action: %w", err) } - newObjects, err := luaVM.ExecuteResourceAction(liveObj, action.ActionLua, q.GetResourceActionParameters()) + newObjects, err := luaVM.ExecuteResourceAction(liveObj, action.ActionLua) if err != nil { return nil, fmt.Errorf("error executing Lua resource action: %w", err) } - var app *v1alpha1.Application + var app *appv1.Application // Only bother getting the app if we know we're going to need it for a resource permission check. if len(newObjects) > 0 { // No need for an RBAC check, we checked above that the user is allowed to run this action. @@ -2483,14 +2475,15 @@ func (s *Server) RunResourceAction(ctx context.Context, q *application.ResourceA } } - proj, err := s.getAppProject(ctx, a, log.WithFields(applog.GetAppLogFields(a))) + proj, err := s.getAppProject(ctx, a, log.WithField("application", a.Name)) if err != nil { return nil, err } - destCluster, err := argo.GetDestinationCluster(ctx, app.Spec.Destination, s.db) - if err != nil { - return nil, err + // Validate the destination, which has the side effect of populating the cluster name and server URL in the app + // spec. This ensures that calls to `verifyResourcePermitted` below act on a fully-populated app spec. + if err = argo.ValidateDestination(ctx, &app.Spec.Destination, s.db); err != nil { + return nil, fmt.Errorf("error validating destination cluster: %w", err) } // First, make sure all the returned resources are permitted, for each operation. @@ -2500,7 +2493,7 @@ func (s *Server) RunResourceAction(ctx context.Context, q *application.ResourceA // the dry-run for relevant apply/delete operation would have to be invoked as well. for _, impactedResource := range newObjects { newObj := impactedResource.UnstructuredObj - err := s.verifyResourcePermitted(destCluster, proj, newObj) + err := s.verifyResourcePermitted(app, proj, newObj) if err != nil { return nil, err } @@ -2541,10 +2534,10 @@ func (s *Server) RunResourceAction(ctx context.Context, q *application.ResourceA } if res == nil { - s.logAppEvent(ctx, a, argo.EventReasonResourceActionRan, "ran action "+q.GetAction()) + s.logAppEvent(a, ctx, argo.EventReasonResourceActionRan, fmt.Sprintf("ran action %s", q.GetAction())) } else { - s.logAppEvent(ctx, a, argo.EventReasonResourceActionRan, fmt.Sprintf("ran action %s on resource %s/%s/%s", q.GetAction(), res.Group, res.Kind, res.Name)) - s.logResourceEvent(ctx, res, argo.EventReasonResourceActionRan, "ran action "+q.GetAction()) + s.logAppEvent(a, ctx, argo.EventReasonResourceActionRan, fmt.Sprintf("ran action %s on resource %s/%s/%s", q.GetAction(), res.Group, res.Kind, res.Name)) + s.logResourceEvent(res, ctx, argo.EventReasonResourceActionRan, fmt.Sprintf("ran action %s", q.GetAction())) } return &application.ApplicationResponse{}, nil } @@ -2592,8 +2585,8 @@ func (s *Server) patchResource(ctx context.Context, config *rest.Config, liveObj return &application.ApplicationResponse{}, nil } -func (s *Server) verifyResourcePermitted(destCluster *v1alpha1.Cluster, proj *v1alpha1.AppProject, obj *unstructured.Unstructured) error { - permitted, err := proj.IsResourcePermitted(schema.GroupKind{Group: obj.GroupVersionKind().Group, Kind: obj.GroupVersionKind().Kind}, obj.GetNamespace(), destCluster, func(project string) ([]*v1alpha1.Cluster, error) { +func (s *Server) verifyResourcePermitted(app *appv1.Application, proj *appv1.AppProject, obj *unstructured.Unstructured) error { + permitted, err := proj.IsResourcePermitted(schema.GroupKind{Group: obj.GroupVersionKind().Group, Kind: obj.GroupVersionKind().Kind}, obj.GetNamespace(), app.Spec.Destination, func(project string) ([]*appv1.Cluster, error) { clusters, err := s.db.GetProjectClusters(context.TODO(), project) if err != nil { return nil, fmt.Errorf("failed to get project clusters: %w", err) @@ -2604,7 +2597,7 @@ func (s *Server) verifyResourcePermitted(destCluster *v1alpha1.Cluster, proj *v1 return fmt.Errorf("error checking resource permissions: %w", err) } if !permitted { - return fmt.Errorf("application is not permitted to manage %s/%s/%s in %s", obj.GroupVersionKind().Group, obj.GroupVersionKind().Kind, obj.GetName(), obj.GetNamespace()) + return fmt.Errorf("application %s is not permitted to manage %s/%s/%s in %s", app.RBACName(s.ns), obj.GroupVersionKind().Group, obj.GroupVersionKind().Kind, obj.GetName(), obj.GetNamespace()) } return nil @@ -2676,20 +2669,13 @@ func (s *Server) GetApplicationSyncWindows(ctx context.Context, q *application.A return res, nil } -func (s *Server) inferResourcesStatusHealth(app *v1alpha1.Application) { - if app.Status.ResourceHealthSource == v1alpha1.ResourceHealthLocationAppTree { - tree := &v1alpha1.ApplicationTree{} +func (s *Server) inferResourcesStatusHealth(app *appv1.Application) { + if app.Status.ResourceHealthSource == appv1.ResourceHealthLocationAppTree { + tree := &appv1.ApplicationTree{} if err := s.cache.GetAppResourcesTree(app.Name, tree); err == nil { - healthByKey := map[kube.ResourceKey]*v1alpha1.HealthStatus{} + healthByKey := map[kube.ResourceKey]*appv1.HealthStatus{} for _, node := range tree.Nodes { - if node.Health != nil { - healthByKey[kube.NewResourceKey(node.Group, node.Kind, node.Namespace, node.Name)] = node.Health - } else if node.ResourceVersion == "" && node.UID == "" && node.CreatedAt == nil { - healthByKey[kube.NewResourceKey(node.Group, node.Kind, node.Namespace, node.Name)] = &v1alpha1.HealthStatus{ - Status: health.HealthStatusMissing, - Message: "Resource has not been created", - } - } + healthByKey[kube.NewResourceKey(node.Group, node.Kind, node.Namespace, node.Name)] = node.Health } for i, res := range app.Status.Resources { res.Health = healthByKey[kube.NewResourceKey(res.Group, res.Kind, res.Namespace, res.Name)] @@ -2699,7 +2685,7 @@ func (s *Server) inferResourcesStatusHealth(app *v1alpha1.Application) { } } -func convertSyncWindows(w *v1alpha1.SyncWindows) []*application.ApplicationSyncWindow { +func convertSyncWindows(w *appv1.SyncWindows) []*application.ApplicationSyncWindow { if w != nil { var windows []*application.ApplicationSyncWindow for _, w := range *w { @@ -2721,11 +2707,11 @@ func convertSyncWindows(w *v1alpha1.SyncWindows) []*application.ApplicationSyncW func getPropagationPolicyFinalizer(policy string) string { switch strings.ToLower(policy) { case backgroundPropagationPolicy: - return v1alpha1.BackgroundPropagationPolicyFinalizer + return appv1.BackgroundPropagationPolicyFinalizer case foregroundPropagationPolicy: - return v1alpha1.ForegroundPropagationPolicyFinalizer + return appv1.ForegroundPropagationPolicyFinalizer case "": - return v1alpha1.ResourcesFinalizerName + return appv1.ResourcesFinalizerName default: return "" } diff --git a/server/application/application.proto b/server/application/application.proto index d1221f2b30..945c0c417c 100644 --- a/server/application/application.proto +++ b/server/application/application.proto @@ -1,5 +1,5 @@ syntax = "proto2"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/application"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/application"; // Application Service // @@ -9,8 +9,8 @@ package application; import "google/api/annotations.proto"; import "k8s.io/api/core/v1/generated.proto"; import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; -import "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto"; -import "github.com/argoproj/argo-cd/v3/reposerver/repository/repository.proto"; +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; +import "github.com/argoproj/argo-cd/v2/reposerver/repository/repository.proto"; // ApplicationQuery is a query for application resources. When getting multiple applications, the "projects" field acts @@ -98,13 +98,13 @@ message ApplicationManifestQueryWithFilesWrapper { message ApplicationResponse {} message ApplicationCreateRequest { - required github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Application application = 1; + required github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application application = 1; optional bool upsert = 2; optional bool validate = 3; } message ApplicationUpdateRequest { - required github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Application application = 1; + required github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application application = 1; optional bool validate = 2; optional string project = 3; } @@ -127,11 +127,11 @@ message ApplicationSyncRequest { optional string revision = 2; optional bool dryRun = 3; optional bool prune = 4; - optional github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncStrategy strategy = 5; - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncOperationResource resources = 7; + optional github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncStrategy strategy = 5; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncOperationResource resources = 7; repeated string manifests = 8; - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Info infos = 9; - optional github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RetryStrategy retryStrategy = 10; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Info infos = 9; + optional github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RetryStrategy retryStrategy = 10; optional SyncOptions syncOptions = 11; optional string appNamespace = 12; optional string project = 13; @@ -142,7 +142,7 @@ message ApplicationSyncRequest { // ApplicationUpdateSpecRequest is a request to update application spec message ApplicationUpdateSpecRequest { required string name = 1; - required github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSpec spec = 2; + required github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSpec spec = 2; optional bool validate = 3; optional string appNamespace = 4; optional string project = 5; @@ -203,11 +203,6 @@ message ApplicationResourceDeleteRequest { optional string project = 10; } -message ResourceActionParameters { - required string name = 1; - required string value = 2; -} - message ResourceActionRunRequest { required string name = 1; optional string namespace = 2; @@ -218,11 +213,10 @@ message ResourceActionRunRequest { required string action = 7; optional string appNamespace = 8; optional string project = 9; - repeated ResourceActionParameters resourceActionParameters = 10; } message ResourceActionsListResponse { - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceAction actions = 1; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceAction actions = 1; } message ApplicationResourceResponse { @@ -246,7 +240,6 @@ message ApplicationPodLogsQuery { optional bool previous = 14; optional string appNamespace = 15; optional string project = 16; - optional bool matchCase = 17; } message LogEntry { @@ -300,7 +293,7 @@ message ResourcesQuery { } message ManagedResourcesResponse { - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ResourceDiff items = 1; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceDiff items = 1; } message LinkInfo { @@ -325,7 +318,7 @@ message ListAppLinksRequest { service ApplicationService { // List returns list of applications - rpc List(ApplicationQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationList) { + rpc List(ApplicationQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationList) { option (google.api.http).get = "/api/v1/applications"; } @@ -335,12 +328,12 @@ service ApplicationService { } // Watch returns stream of application change events - rpc Watch(ApplicationQuery) returns (stream github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationWatchEvent) { + rpc Watch(ApplicationQuery) returns (stream github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationWatchEvent) { option (google.api.http).get = "/api/v1/stream/applications"; } // Create creates an application - rpc Create (ApplicationCreateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Application) { + rpc Create (ApplicationCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application) { option (google.api.http) = { post: "/api/v1/applications" body: "application" @@ -348,7 +341,7 @@ service ApplicationService { } // Get returns an application by name - rpc Get (ApplicationQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Application) { + rpc Get (ApplicationQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application) { option (google.api.http).get = "/api/v1/applications/{name}"; } @@ -358,12 +351,12 @@ service ApplicationService { } // Get the meta-data (author, date, tags, message) for a specific revision of the application - rpc RevisionMetadata (RevisionMetadataQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RevisionMetadata) { + rpc RevisionMetadata (RevisionMetadataQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RevisionMetadata) { option (google.api.http).get = "/api/v1/applications/{name}/revisions/{revision}/metadata"; } // Get the chart metadata (description, maintainers, home) for a specific revision of the application - rpc RevisionChartDetails (RevisionMetadataQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ChartDetails) { + rpc RevisionChartDetails (RevisionMetadataQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ChartDetails) { option (google.api.http).get = "/api/v1/applications/{name}/revisions/{revision}/chartdetails"; } @@ -381,7 +374,7 @@ service ApplicationService { } // Update updates an application - rpc Update(ApplicationUpdateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Application) { + rpc Update(ApplicationUpdateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application) { option (google.api.http) = { put: "/api/v1/applications/{application.metadata.name}" body: "application" @@ -389,7 +382,7 @@ service ApplicationService { } // UpdateSpec updates an application spec - rpc UpdateSpec(ApplicationUpdateSpecRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSpec) { + rpc UpdateSpec(ApplicationUpdateSpecRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSpec) { option (google.api.http) = { put: "/api/v1/applications/{name}/spec" body: "spec" @@ -397,7 +390,7 @@ service ApplicationService { } // Patch patch an application - rpc Patch(ApplicationPatchRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Application) { + rpc Patch(ApplicationPatchRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application) { option (google.api.http) = { patch: "/api/v1/applications/{name}" body: "*" @@ -410,7 +403,7 @@ service ApplicationService { } // Sync syncs an application to its target state - rpc Sync(ApplicationSyncRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Application) { + rpc Sync(ApplicationSyncRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application) { option (google.api.http) = { post: "/api/v1/applications/{name}/sync" body: "*" @@ -423,17 +416,17 @@ service ApplicationService { } // ResourceTree returns resource tree - rpc ResourceTree(ResourcesQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationTree) { + rpc ResourceTree(ResourcesQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationTree) { option (google.api.http).get = "/api/v1/applications/{applicationName}/resource-tree"; } // Watch returns stream of application resource tree - rpc WatchResourceTree(ResourcesQuery) returns (stream github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationTree) { + rpc WatchResourceTree(ResourcesQuery) returns (stream github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationTree) { option (google.api.http).get = "/api/v1/stream/applications/{applicationName}/resource-tree"; } // Rollback syncs an application to its target state - rpc Rollback(ApplicationRollbackRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Application) { + rpc Rollback(ApplicationRollbackRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application) { option (google.api.http) = { post: "/api/v1/applications/{name}/rollback" body: "*" @@ -469,7 +462,7 @@ service ApplicationService { rpc RunResourceAction(ResourceActionRunRequest) returns (ApplicationResponse) { option (google.api.http) = { post: "/api/v1/applications/{name}/resource/actions" - body: "*" + body: "action" }; } diff --git a/server/application/application_test.go b/server/application/application_test.go index d2fcff3a87..1709ce0799 100644 --- a/server/application/application_test.go +++ b/server/application/application_test.go @@ -2,7 +2,7 @@ package application import ( "context" - stderrors "errors" + coreerrors "errors" "fmt" "io" "slices" @@ -12,25 +12,25 @@ import ( "testing" "time" - "k8s.io/apimachinery/pkg/labels" - "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/argoproj/gitops-engine/pkg/utils/kube/kubetest" - "github.com/argoproj/pkg/v2/sync" - "github.com/golang-jwt/jwt/v5" + "github.com/argoproj/pkg/sync" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" - appsv1 "k8s.io/api/apps/v1" + k8sappsv1 "k8s.io/api/apps/v1" k8sbatchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" @@ -41,24 +41,27 @@ import ( "k8s.io/utils/ptr" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - apps "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - appinformer "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient/mocks" - servercache "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/server/rbacpolicy" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/assets" - "github.com/argoproj/argo-cd/v3/util/cache" - "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/grpc" - "github.com/argoproj/argo-cd/v3/util/rbac" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + 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/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/server/rbacpolicy" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/assets" + "github.com/argoproj/argo-cd/v2/util/cache" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/argoproj/argo-cd/v2/util/cache/appstate" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/grpc" + "github.com/argoproj/argo-cd/v2/util/rbac" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( @@ -72,13 +75,13 @@ type broadcasterMock struct { objects []runtime.Object } -func (b broadcasterMock) Subscribe(ch chan *v1alpha1.ApplicationWatchEvent, _ ...func(event *v1alpha1.ApplicationWatchEvent) bool) func() { +func (b broadcasterMock) Subscribe(ch chan *appv1.ApplicationWatchEvent, filters ...func(event *appv1.ApplicationWatchEvent) bool) func() { // Simulate the broadcaster notifying the subscriber of an application update. // The second parameter to Subscribe is filters. For the purposes of tests, we ignore the filters. Future tests // might require implementing those. go func() { for _, obj := range b.objects { - app, ok := obj.(*v1alpha1.Application) + app, ok := obj.(*appsv1.Application) if ok { oldVersion, err := strconv.Atoi(app.ResourceVersion) if err != nil { @@ -86,28 +89,28 @@ func (b broadcasterMock) Subscribe(ch chan *v1alpha1.ApplicationWatchEvent, _ .. } clonedApp := app.DeepCopy() clonedApp.ResourceVersion = strconv.Itoa(oldVersion + 1) - ch <- &v1alpha1.ApplicationWatchEvent{Type: watch.Added, Application: *clonedApp} + ch <- &appsv1.ApplicationWatchEvent{Type: watch.Added, Application: *clonedApp} } } }() return func() {} } -func (broadcasterMock) OnAdd(any, bool) {} -func (broadcasterMock) OnUpdate(any, any) {} -func (broadcasterMock) OnDelete(any) {} +func (broadcasterMock) OnAdd(interface{}, bool) {} +func (broadcasterMock) OnUpdate(interface{}, interface{}) {} +func (broadcasterMock) OnDelete(interface{}) {} -func fakeRepo() *v1alpha1.Repository { - return &v1alpha1.Repository{ +func fakeRepo() *appsv1.Repository { + return &appsv1.Repository{ Repo: fakeRepoURL, } } -func fakeCluster() *v1alpha1.Cluster { - return &v1alpha1.Cluster{ +func fakeCluster() *appsv1.Cluster { + return &appsv1.Cluster{ Server: "https://cluster-api.example.com", Name: "fake-cluster", - Config: v1alpha1.ClusterConfig{}, + Config: appsv1.ClusterConfig{}, } } @@ -139,12 +142,12 @@ func fakeRepoServerClient(isHelm bool) *mocks.RepoServerServiceClient { mockRepoServiceClient.On("GenerateManifest", mock.Anything, mock.Anything).Return(&apiclient.ManifestResponse{}, nil) mockRepoServiceClient.On("GetAppDetails", mock.Anything, mock.Anything).Return(&apiclient.RepoAppDetailsResponse{}, nil) mockRepoServiceClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{}, nil) - mockRepoServiceClient.On("GetRevisionMetadata", mock.Anything, mock.Anything).Return(&v1alpha1.RevisionMetadata{}, nil) + mockRepoServiceClient.On("GetRevisionMetadata", mock.Anything, mock.Anything).Return(&appsv1.RevisionMetadata{}, nil) mockWithFilesClient := &mocks.RepoServerService_GenerateManifestWithFilesClient{} mockWithFilesClient.On("Send", mock.Anything).Return(nil) mockWithFilesClient.On("CloseAndRecv").Return(&apiclient.ManifestResponse{}, nil) mockRepoServiceClient.On("GenerateManifestWithFiles", mock.Anything, mock.Anything).Return(mockWithFilesClient, nil) - mockRepoServiceClient.On("GetRevisionChartDetails", mock.Anything, mock.Anything).Return(&v1alpha1.ChartDetails{}, nil) + mockRepoServiceClient.On("GetRevisionChartDetails", mock.Anything, mock.Anything).Return(&appsv1.ChartDetails{}, nil) if isHelm { mockRepoServiceClient.On("ResolveRevision", mock.Anything, mock.Anything).Return(fakeResolveRevisionResponseHelm(), nil) @@ -167,7 +170,7 @@ func newTestAppServer(t *testing.T, 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.NewClientset(&corev1.ConfigMap{ + kubeclientset := fake.NewClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-cm", @@ -176,7 +179,7 @@ func newTestAppServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforcer), }, }, Data: additionalConfig, - }, &corev1.Secret{ + }, &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: testNamespace, @@ -186,39 +189,39 @@ func newTestAppServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforcer), "server.secretkey": []byte("test"), }, }) - ctx := t.Context() + ctx := context.Background() db := db.NewDB(testNamespace, settings.NewSettingsManager(ctx, kubeclientset, testNamespace), kubeclientset) _, err := db.CreateRepository(ctx, fakeRepo()) - require.NoError(t, err) + errors.CheckError(err) _, err = db.CreateCluster(ctx, fakeCluster()) - require.NoError(t, err) + errors.CheckError(err) mockRepoClient := &mocks.Clientset{RepoServerServiceClient: fakeRepoServerClient(false)} - defaultProj := &v1alpha1.AppProject{ + defaultProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, }, } - myProj := &v1alpha1.AppProject{ + myProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "my-proj", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, }, } - projWithSyncWindows := &v1alpha1.AppProject{ + projWithSyncWindows := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "proj-maint", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, - SyncWindows: v1alpha1.SyncWindows{}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + SyncWindows: appsv1.SyncWindows{}, }, } - matchingWindow := &v1alpha1.SyncWindow{ + matchingWindow := &appsv1.SyncWindow{ Kind: "allow", Schedule: "* * * * *", Duration: "1h", @@ -229,7 +232,7 @@ func newTestAppServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforcer), objects = append(objects, defaultProj, myProj, projWithSyncWindows) fakeAppsClientset := apps.NewSimpleClientset(objects...) - factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, appinformer.WithNamespace(""), appinformer.WithTweakListOptions(func(_ *metav1.ListOptions) {})) + factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, appinformer.WithNamespace(""), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) fakeProjLister := factory.Argoproj().V1alpha1().AppProjects().Lister().AppProjects(testNamespace) enforcer := rbac.NewEnforcer(kubeclientset, testNamespace, common.ArgoCDRBACConfigMapName, nil) @@ -241,7 +244,7 @@ func newTestAppServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforcer), // populate the app informer with the fake objects appInformer := factory.Argoproj().V1alpha1().Applications().Informer() // TODO(jessesuen): probably should return cancel function so tests can stop background informer - // ctx, cancel := context.WithCancel(t.Context()) + // ctx, cancel := context.WithCancel(context.Background()) go appInformer.Run(ctx.Done()) if !k8scache.WaitForCacheSync(ctx.Done(), appInformer.HasSynced) { panic("Timed out waiting for caches to sync") @@ -260,16 +263,16 @@ func newTestAppServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforcer), appStateCache := appstate.NewCache(cache.NewCache(cache.NewInMemoryCache(time.Hour)), time.Hour) // pre-populate the app cache for _, obj := range objects { - app, ok := obj.(*v1alpha1.Application) + app, ok := obj.(*appsv1.Application) if ok { - err := appStateCache.SetAppManagedResources(app.Name, []*v1alpha1.ResourceDiff{}) + err := appStateCache.SetAppManagedResources(app.Name, []*appsv1.ResourceDiff{}) require.NoError(t, err) // Pre-populate the resource tree based on the app's resources. - nodes := make([]v1alpha1.ResourceNode, len(app.Status.Resources)) + nodes := make([]appsv1.ResourceNode, len(app.Status.Resources)) for i, res := range app.Status.Resources { - nodes[i] = v1alpha1.ResourceNode{ - ResourceRef: v1alpha1.ResourceRef{ + nodes[i] = appsv1.ResourceNode{ + ResourceRef: appsv1.ResourceRef{ Group: res.Group, Kind: res.Kind, Version: res.Version, @@ -279,7 +282,7 @@ func newTestAppServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforcer), }, } } - err = appStateCache.SetAppResourcesTree(app.Name, &v1alpha1.ApplicationTree{ + err = appStateCache.SetAppResourcesTree(app.Name, &appsv1.ApplicationTree{ Nodes: nodes, }) require.NoError(t, err) @@ -316,7 +319,6 @@ func newTestAppServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforcer), projInformer, []string{}, testEnableEventList, - true, ) return server.(*Server) } @@ -333,7 +335,7 @@ func newTestAppServerWithBenchmark(b *testing.B, objects ...runtime.Object) *Ser func newTestAppServerWithEnforcerConfigureWithBenchmark(b *testing.B, f func(*rbac.Enforcer), objects ...runtime.Object) *Server { b.Helper() - kubeclientset := fake.NewClientset(&corev1.ConfigMap{ + kubeclientset := fake.NewClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-cm", @@ -341,7 +343,7 @@ func newTestAppServerWithEnforcerConfigureWithBenchmark(b *testing.B, f func(*rb "app.kubernetes.io/part-of": "argocd", }, }, - }, &corev1.Secret{ + }, &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: testNamespace, @@ -351,7 +353,7 @@ func newTestAppServerWithEnforcerConfigureWithBenchmark(b *testing.B, f func(*rb "server.secretkey": []byte("test"), }, }) - ctx := b.Context() + ctx := context.Background() db := db.NewDB(testNamespace, settings.NewSettingsManager(ctx, kubeclientset, testNamespace), kubeclientset) _, err := db.CreateRepository(ctx, fakeRepo()) require.NoError(b, err) @@ -360,29 +362,29 @@ func newTestAppServerWithEnforcerConfigureWithBenchmark(b *testing.B, f func(*rb mockRepoClient := &mocks.Clientset{RepoServerServiceClient: fakeRepoServerClient(false)} - defaultProj := &v1alpha1.AppProject{ + defaultProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, }, } - myProj := &v1alpha1.AppProject{ + myProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "my-proj", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, }, } - projWithSyncWindows := &v1alpha1.AppProject{ + projWithSyncWindows := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "proj-maint", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, - SyncWindows: v1alpha1.SyncWindows{}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + SyncWindows: appsv1.SyncWindows{}, }, } - matchingWindow := &v1alpha1.SyncWindow{ + matchingWindow := &appsv1.SyncWindow{ Kind: "allow", Schedule: "* * * * *", Duration: "1h", @@ -393,7 +395,7 @@ func newTestAppServerWithEnforcerConfigureWithBenchmark(b *testing.B, f func(*rb objects = append(objects, defaultProj, myProj, projWithSyncWindows) fakeAppsClientset := apps.NewSimpleClientset(objects...) - factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, appinformer.WithNamespace(""), appinformer.WithTweakListOptions(func(_ *metav1.ListOptions) {})) + factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, appinformer.WithNamespace(""), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) fakeProjLister := factory.Argoproj().V1alpha1().AppProjects().Lister().AppProjects(testNamespace) enforcer := rbac.NewEnforcer(kubeclientset, testNamespace, common.ArgoCDRBACConfigMapName, nil) @@ -423,16 +425,16 @@ func newTestAppServerWithEnforcerConfigureWithBenchmark(b *testing.B, f func(*rb appStateCache := appstate.NewCache(cache.NewCache(cache.NewInMemoryCache(time.Hour)), time.Hour) // pre-populate the app cache for _, obj := range objects { - app, ok := obj.(*v1alpha1.Application) + app, ok := obj.(*appsv1.Application) if ok { - err := appStateCache.SetAppManagedResources(app.Name, []*v1alpha1.ResourceDiff{}) + err := appStateCache.SetAppManagedResources(app.Name, []*appsv1.ResourceDiff{}) require.NoError(b, err) // Pre-populate the resource tree based on the app's resources. - nodes := make([]v1alpha1.ResourceNode, len(app.Status.Resources)) + nodes := make([]appsv1.ResourceNode, len(app.Status.Resources)) for i, res := range app.Status.Resources { - nodes[i] = v1alpha1.ResourceNode{ - ResourceRef: v1alpha1.ResourceRef{ + nodes[i] = appsv1.ResourceNode{ + ResourceRef: appsv1.ResourceRef{ Group: res.Group, Kind: res.Kind, Version: res.Version, @@ -442,7 +444,7 @@ func newTestAppServerWithEnforcerConfigureWithBenchmark(b *testing.B, f func(*rb }, } } - err = appStateCache.SetAppResourcesTree(app.Name, &v1alpha1.ApplicationTree{ + err = appStateCache.SetAppResourcesTree(app.Name, &appsv1.ApplicationTree{ Nodes: nodes, }) require.NoError(b, err) @@ -479,7 +481,6 @@ func newTestAppServerWithEnforcerConfigureWithBenchmark(b *testing.B, f func(*rb projInformer, []string{}, testEnableEventList, - true, ) return server.(*Server) } @@ -540,20 +541,20 @@ spec: server: https://cluster-api.example.com ` -func newTestAppWithDestName(opts ...func(app *v1alpha1.Application)) *v1alpha1.Application { +func newTestAppWithDestName(opts ...func(app *appsv1.Application)) *appsv1.Application { return createTestApp(fakeAppWithDestName, opts...) } -func newTestApp(opts ...func(app *v1alpha1.Application)) *v1alpha1.Application { +func newTestApp(opts ...func(app *appsv1.Application)) *appsv1.Application { return createTestApp(fakeApp, opts...) } -func newTestAppWithAnnotations(opts ...func(app *v1alpha1.Application)) *v1alpha1.Application { +func newTestAppWithAnnotations(opts ...func(app *appsv1.Application)) *appsv1.Application { return createTestApp(fakeAppWithAnnotations, opts...) } -func createTestApp(testApp string, opts ...func(app *v1alpha1.Application)) *v1alpha1.Application { - var app v1alpha1.Application +func createTestApp(testApp string, opts ...func(app *appsv1.Application)) *appsv1.Application { + var app appsv1.Application err := yaml.Unmarshal([]byte(testApp), &app) if err != nil { panic(err) @@ -585,15 +586,15 @@ func (t *TestServerStream) Context() context.Context { return t.ctx } -func (t *TestServerStream) SendMsg(_ any) error { +func (t *TestServerStream) SendMsg(m interface{}) error { return nil } -func (t *TestServerStream) RecvMsg(_ any) error { +func (t *TestServerStream) RecvMsg(m interface{}) error { return nil } -func (t *TestServerStream) SendAndClose(_ *apiclient.ManifestResponse) error { +func (t *TestServerStream) SendAndClose(r *apiclient.ManifestResponse) error { return nil } @@ -619,7 +620,7 @@ type TestResourceTreeServer struct { ctx context.Context } -func (t *TestResourceTreeServer) Send(_ *v1alpha1.ApplicationTree) error { +func (t *TestResourceTreeServer) Send(tree *appsv1.ApplicationTree) error { return nil } @@ -637,11 +638,11 @@ func (t *TestResourceTreeServer) Context() context.Context { return t.ctx } -func (t *TestResourceTreeServer) SendMsg(_ any) error { +func (t *TestResourceTreeServer) SendMsg(m interface{}) error { return nil } -func (t *TestResourceTreeServer) RecvMsg(_ any) error { +func (t *TestResourceTreeServer) RecvMsg(m interface{}) error { return nil } @@ -649,7 +650,7 @@ type TestPodLogsServer struct { ctx context.Context } -func (t *TestPodLogsServer) Send(_ *application.LogEntry) error { +func (t *TestPodLogsServer) Send(log *application.LogEntry) error { return nil } @@ -667,11 +668,11 @@ func (t *TestPodLogsServer) Context() context.Context { return t.ctx } -func (t *TestPodLogsServer) SendMsg(_ any) error { +func (t *TestPodLogsServer) SendMsg(m interface{}) error { return nil } -func (t *TestPodLogsServer) RecvMsg(_ any) error { +func (t *TestPodLogsServer) RecvMsg(m interface{}) error { return nil } @@ -693,7 +694,7 @@ func TestNoAppEnumeration(t *testing.T) { _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) enf.SetDefaultRole("role:none") } - deployment := appsv1.Deployment{ + deployment := k8sappsv1.Deployment{ TypeMeta: metav1.TypeMeta{ APIVersion: "apps/v1", Kind: "Deployment", @@ -703,9 +704,9 @@ func TestNoAppEnumeration(t *testing.T) { Namespace: "test", }, } - testApp := newTestApp(func(app *v1alpha1.Application) { + testApp := newTestApp(func(app *appsv1.Application) { app.Name = "test" - app.Status.Resources = []v1alpha1.ResourceStatus{ + app.Status.Resources = []appsv1.ResourceStatus{ { Group: deployment.GroupVersionKind().Group, Kind: deployment.GroupVersionKind().Kind, @@ -715,20 +716,20 @@ func TestNoAppEnumeration(t *testing.T) { Status: "Synced", }, } - app.Status.History = []v1alpha1.RevisionHistory{ + app.Status.History = []appsv1.RevisionHistory{ { ID: 0, - Source: v1alpha1.ApplicationSource{ + Source: appsv1.ApplicationSource{ TargetRevision: "something-old", }, }, } }) - testHelmApp := newTestApp(func(app *v1alpha1.Application) { + testHelmApp := newTestApp(func(app *appsv1.Application) { app.Name = "test-helm" app.Spec.Source.Path = "" app.Spec.Source.Chart = "test" - app.Status.Resources = []v1alpha1.ResourceStatus{ + app.Status.Resources = []appsv1.ResourceStatus{ { Group: deployment.GroupVersionKind().Group, Kind: deployment.GroupVersionKind().Kind, @@ -738,26 +739,26 @@ func TestNoAppEnumeration(t *testing.T) { Status: "Synced", }, } - app.Status.History = []v1alpha1.RevisionHistory{ + app.Status.History = []appsv1.RevisionHistory{ { ID: 0, - Source: v1alpha1.ApplicationSource{ + Source: appsv1.ApplicationSource{ TargetRevision: "something-old", }, }, } }) - testAppMulti := newTestApp(func(app *v1alpha1.Application) { + testAppMulti := newTestApp(func(app *appsv1.Application) { app.Name = "test-multi" - app.Spec.Sources = v1alpha1.ApplicationSources{ - v1alpha1.ApplicationSource{ + app.Spec.Sources = appsv1.ApplicationSources{ + appsv1.ApplicationSource{ TargetRevision: "something-old", }, - v1alpha1.ApplicationSource{ + appsv1.ApplicationSource{ TargetRevision: "something-old", }, } - app.Status.Resources = []v1alpha1.ResourceStatus{ + app.Status.Resources = []appsv1.ResourceStatus{ { Group: deployment.GroupVersionKind().Group, Kind: deployment.GroupVersionKind().Kind, @@ -767,14 +768,14 @@ func TestNoAppEnumeration(t *testing.T) { Status: "Synced", }, } - app.Status.History = []v1alpha1.RevisionHistory{ + app.Status.History = []appsv1.RevisionHistory{ { ID: 1, - Sources: v1alpha1.ApplicationSources{ - v1alpha1.ApplicationSource{ + Sources: appsv1.ApplicationSources{ + appsv1.ApplicationSource{ TargetRevision: "something-old", }, - v1alpha1.ApplicationSource{ + appsv1.ApplicationSource{ TargetRevision: "something-old", }, }, @@ -784,17 +785,21 @@ func TestNoAppEnumeration(t *testing.T) { testDeployment := kube.MustToUnstructured(&deployment) appServer := newTestAppServerWithEnforcerConfigure(t, f, map[string]string{}, testApp, testHelmApp, testAppMulti, testDeployment) - noRoleCtx := t.Context() - //nolint:staticcheck + noRoleCtx := context.Background() + // nolint:staticcheck adminCtx := context.WithValue(noRoleCtx, "claims", &jwt.MapClaims{"groups": []string{"admin"}}) t.Run("Get", func(t *testing.T) { + // nolint:staticcheck _, err := appServer.Get(adminCtx, &application.ApplicationQuery{Name: ptr.To("test")}) require.NoError(t, err) + // nolint:staticcheck _, err = appServer.Get(noRoleCtx, &application.ApplicationQuery{Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + // nolint:staticcheck _, err = appServer.Get(adminCtx, &application.ApplicationQuery{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + // nolint:staticcheck _, err = appServer.Get(adminCtx, &application.ApplicationQuery{Name: ptr.To("doest-not-exist"), Project: []string{"test"}}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -803,9 +808,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.GetManifests(adminCtx, &application.ApplicationManifestQuery{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.GetManifests(noRoleCtx, &application.ApplicationManifestQuery{Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetManifests(adminCtx, &application.ApplicationManifestQuery{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetManifests(adminCtx, &application.ApplicationManifestQuery{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -814,32 +819,32 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.ListResourceEvents(adminCtx, &application.ApplicationResourceEventsQuery{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.ListResourceEvents(noRoleCtx, &application.ApplicationResourceEventsQuery{Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceEvents(adminCtx, &application.ApplicationResourceEventsQuery{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceEvents(adminCtx, &application.ApplicationResourceEventsQuery{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("UpdateSpec", func(t *testing.T) { - _, err := appServer.UpdateSpec(adminCtx, &application.ApplicationUpdateSpecRequest{Name: ptr.To("test"), Spec: &v1alpha1.ApplicationSpec{ - Destination: v1alpha1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, - Source: &v1alpha1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, + _, err := appServer.UpdateSpec(adminCtx, &application.ApplicationUpdateSpecRequest{Name: ptr.To("test"), Spec: &appsv1.ApplicationSpec{ + Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, + Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, }}) require.NoError(t, err) - _, err = appServer.UpdateSpec(noRoleCtx, &application.ApplicationUpdateSpecRequest{Name: ptr.To("test"), Spec: &v1alpha1.ApplicationSpec{ - Destination: v1alpha1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, - Source: &v1alpha1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, + _, err = appServer.UpdateSpec(noRoleCtx, &application.ApplicationUpdateSpecRequest{Name: ptr.To("test"), Spec: &appsv1.ApplicationSpec{ + Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, + Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, }}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") - _, err = appServer.UpdateSpec(adminCtx, &application.ApplicationUpdateSpecRequest{Name: ptr.To("doest-not-exist"), Spec: &v1alpha1.ApplicationSpec{ - Destination: v1alpha1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, - Source: &v1alpha1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.UpdateSpec(adminCtx, &application.ApplicationUpdateSpecRequest{Name: ptr.To("doest-not-exist"), Spec: &appsv1.ApplicationSpec{ + Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, + Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, }}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") - _, err = appServer.UpdateSpec(adminCtx, &application.ApplicationUpdateSpecRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test"), Spec: &v1alpha1.ApplicationSpec{ - Destination: v1alpha1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, - Source: &v1alpha1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.UpdateSpec(adminCtx, &application.ApplicationUpdateSpecRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test"), Spec: &appsv1.ApplicationSpec{ + Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, + Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, }}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -848,9 +853,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.Patch(adminCtx, &application.ApplicationPatchRequest{Name: ptr.To("test"), Patch: ptr.To(`[{"op": "replace", "path": "/spec/source/path", "value": "foo"}]`)}) require.NoError(t, err) _, err = appServer.Patch(noRoleCtx, &application.ApplicationPatchRequest{Name: ptr.To("test"), Patch: ptr.To(`[{"op": "replace", "path": "/spec/source/path", "value": "foo"}]`)}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Patch(adminCtx, &application.ApplicationPatchRequest{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Patch(adminCtx, &application.ApplicationPatchRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -859,9 +864,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.GetResource(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) require.NoError(t, err) _, err = appServer.GetResource(noRoleCtx, &application.ApplicationResourceRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetResource(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("doest-not-exist"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetResource(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -870,11 +875,11 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.PatchResource(adminCtx, &application.ApplicationResourcePatchRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Patch: ptr.To(`[{"op": "replace", "path": "/spec/replicas", "value": 3}]`)}) // This will always throw an error, because the kubectl mock for PatchResource is hard-coded to return nil. // The best we can do is to confirm we get past the permission check. - assert.NotEqual(t, common.PermissionDeniedAPIError.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + assert.NotEqual(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.PatchResource(noRoleCtx, &application.ApplicationResourcePatchRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Patch: ptr.To(`[{"op": "replace", "path": "/spec/replicas", "value": 3}]`)}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.PatchResource(adminCtx, &application.ApplicationResourcePatchRequest{Name: ptr.To("doest-not-exist"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Patch: ptr.To(`[{"op": "replace", "path": "/spec/replicas", "value": 3}]`)}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.PatchResource(adminCtx, &application.ApplicationResourcePatchRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Patch: ptr.To(`[{"op": "replace", "path": "/spec/replicas", "value": 3}]`)}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -883,9 +888,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.DeleteResource(adminCtx, &application.ApplicationResourceDeleteRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) require.NoError(t, err) _, err = appServer.DeleteResource(noRoleCtx, &application.ApplicationResourceDeleteRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.DeleteResource(adminCtx, &application.ApplicationResourceDeleteRequest{Name: ptr.To("doest-not-exist"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.DeleteResource(adminCtx, &application.ApplicationResourceDeleteRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -894,9 +899,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.ResourceTree(adminCtx, &application.ResourcesQuery{ApplicationName: ptr.To("test")}) require.NoError(t, err) _, err = appServer.ResourceTree(noRoleCtx, &application.ResourcesQuery{ApplicationName: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ResourceTree(adminCtx, &application.ResourcesQuery{ApplicationName: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ResourceTree(adminCtx, &application.ResourcesQuery{ApplicationName: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -907,9 +912,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err = appServer.RevisionMetadata(adminCtx, &application.RevisionMetadataQuery{Name: ptr.To("test-multi"), SourceIndex: ptr.To(int32(0)), VersionId: ptr.To(int32(1))}) require.NoError(t, err) _, err = appServer.RevisionMetadata(noRoleCtx, &application.RevisionMetadataQuery{Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RevisionMetadata(adminCtx, &application.RevisionMetadataQuery{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RevisionMetadata(adminCtx, &application.RevisionMetadataQuery{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -918,9 +923,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.RevisionChartDetails(adminCtx, &application.RevisionMetadataQuery{Name: ptr.To("test-helm")}) require.NoError(t, err) _, err = appServer.RevisionChartDetails(noRoleCtx, &application.RevisionMetadataQuery{Name: ptr.To("test-helm")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RevisionChartDetails(adminCtx, &application.RevisionMetadataQuery{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RevisionChartDetails(adminCtx, &application.RevisionMetadataQuery{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -929,9 +934,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.ManagedResources(adminCtx, &application.ResourcesQuery{ApplicationName: ptr.To("test")}) require.NoError(t, err) _, err = appServer.ManagedResources(noRoleCtx, &application.ResourcesQuery{ApplicationName: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ManagedResources(adminCtx, &application.ResourcesQuery{ApplicationName: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ManagedResources(adminCtx, &application.ResourcesQuery{ApplicationName: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -940,9 +945,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.Sync(adminCtx, &application.ApplicationSyncRequest{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.Sync(noRoleCtx, &application.ApplicationSyncRequest{Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Sync(adminCtx, &application.ApplicationSyncRequest{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Sync(adminCtx, &application.ApplicationSyncRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -954,9 +959,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.TerminateOperation(adminCtx, &application.OperationTerminateRequest{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.TerminateOperation(noRoleCtx, &application.OperationTerminateRequest{Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.TerminateOperation(adminCtx, &application.OperationTerminateRequest{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.TerminateOperation(adminCtx, &application.OperationTerminateRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -968,9 +973,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err = appServer.Rollback(adminCtx, &application.ApplicationRollbackRequest{Name: ptr.To("test-multi"), Id: ptr.To(int64(1))}) require.NoError(t, err) _, err = appServer.Rollback(noRoleCtx, &application.ApplicationRollbackRequest{Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Rollback(adminCtx, &application.ApplicationRollbackRequest{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Rollback(adminCtx, &application.ApplicationRollbackRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -979,11 +984,11 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.ListResourceActions(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) require.NoError(t, err) _, err = appServer.ListResourceActions(noRoleCtx, &application.ApplicationResourceRequest{Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceActions(noRoleCtx, &application.ApplicationResourceRequest{Group: ptr.To("argoproj.io"), Kind: ptr.To("Application"), Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceActions(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceActions(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -992,11 +997,11 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.RunResourceAction(adminCtx, &application.ResourceActionRunRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Action: ptr.To("restart")}) require.NoError(t, err) _, err = appServer.RunResourceAction(noRoleCtx, &application.ResourceActionRunRequest{Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RunResourceAction(noRoleCtx, &application.ResourceActionRunRequest{Group: ptr.To("argoproj.io"), Kind: ptr.To("Application"), Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RunResourceAction(adminCtx, &application.ResourceActionRunRequest{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RunResourceAction(adminCtx, &application.ResourceActionRunRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -1005,9 +1010,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.GetApplicationSyncWindows(adminCtx, &application.ApplicationSyncWindowsQuery{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.GetApplicationSyncWindows(noRoleCtx, &application.ApplicationSyncWindowsQuery{Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetApplicationSyncWindows(adminCtx, &application.ApplicationSyncWindowsQuery{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetApplicationSyncWindows(adminCtx, &application.ApplicationSyncWindowsQuery{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -1016,9 +1021,9 @@ func TestNoAppEnumeration(t *testing.T) { err := appServer.GetManifestsWithFiles(&TestServerStream{ctx: adminCtx, appName: "test"}) require.NoError(t, err) err = appServer.GetManifestsWithFiles(&TestServerStream{ctx: noRoleCtx, appName: "test"}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.GetManifestsWithFiles(&TestServerStream{ctx: adminCtx, appName: "does-not-exist"}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.GetManifestsWithFiles(&TestServerStream{ctx: adminCtx, appName: "does-not-exist", project: "test"}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -1027,9 +1032,9 @@ func TestNoAppEnumeration(t *testing.T) { err := appServer.WatchResourceTree(&application.ResourcesQuery{ApplicationName: ptr.To("test")}, &TestResourceTreeServer{ctx: adminCtx}) require.NoError(t, err) err = appServer.WatchResourceTree(&application.ResourcesQuery{ApplicationName: ptr.To("test")}, &TestResourceTreeServer{ctx: noRoleCtx}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.WatchResourceTree(&application.ResourcesQuery{ApplicationName: ptr.To("does-not-exist")}, &TestResourceTreeServer{ctx: adminCtx}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.WatchResourceTree(&application.ResourcesQuery{ApplicationName: ptr.To("does-not-exist"), Project: ptr.To("test")}, &TestResourceTreeServer{ctx: adminCtx}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -1038,9 +1043,9 @@ func TestNoAppEnumeration(t *testing.T) { err := appServer.PodLogs(&application.ApplicationPodLogsQuery{Name: ptr.To("test")}, &TestPodLogsServer{ctx: adminCtx}) require.NoError(t, err) err = appServer.PodLogs(&application.ApplicationPodLogsQuery{Name: ptr.To("test")}, &TestPodLogsServer{ctx: noRoleCtx}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.PodLogs(&application.ApplicationPodLogsQuery{Name: ptr.To("does-not-exist")}, &TestPodLogsServer{ctx: adminCtx}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.PodLogs(&application.ApplicationPodLogsQuery{Name: ptr.To("does-not-exist"), Project: ptr.To("test")}, &TestPodLogsServer{ctx: adminCtx}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -1049,9 +1054,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.ListLinks(adminCtx, &application.ListAppLinksRequest{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.ListLinks(noRoleCtx, &application.ListAppLinksRequest{Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListLinks(adminCtx, &application.ListAppLinksRequest{Name: ptr.To("does-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListLinks(adminCtx, &application.ListAppLinksRequest{Name: ptr.To("does-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -1060,9 +1065,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.ListResourceLinks(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) require.NoError(t, err) _, err = appServer.ListResourceLinks(noRoleCtx, &application.ApplicationResourceRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceLinks(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("does-not-exist"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceLinks(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("does-not-exist"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -1072,9 +1077,9 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.Delete(adminCtx, &application.ApplicationDeleteRequest{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.Delete(noRoleCtx, &application.ApplicationDeleteRequest{Name: ptr.To("test")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Delete(adminCtx, &application.ApplicationDeleteRequest{Name: ptr.To("doest-not-exist")}) - require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Delete(adminCtx, &application.ApplicationDeleteRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) @@ -1084,11 +1089,11 @@ func TestNoAppEnumeration(t *testing.T) { func setSyncRunningOperationState(t *testing.T, appServer *Server) { t.Helper() appIf := appServer.appclientset.ArgoprojV1alpha1().Applications("default") - app, err := appIf.Get(t.Context(), "test", metav1.GetOptions{}) + app, err := appIf.Get(context.Background(), "test", metav1.GetOptions{}) require.NoError(t, err) // This sets the status that would be set by the controller usually. - app.Status.OperationState = &v1alpha1.OperationState{Phase: synccommon.OperationRunning, Operation: v1alpha1.Operation{Sync: &v1alpha1.SyncOperation{}}} - _, err = appIf.Update(t.Context(), app, metav1.UpdateOptions{}) + app.Status.OperationState = &appsv1.OperationState{Phase: synccommon.OperationRunning, Operation: appsv1.Operation{Sync: &appsv1.SyncOperation{}}} + _, err = appIf.Update(context.Background(), app, metav1.UpdateOptions{}) require.NoError(t, err) } @@ -1096,26 +1101,26 @@ func setSyncRunningOperationState(t *testing.T, appServer *Server) { func unsetSyncRunningOperationState(t *testing.T, appServer *Server) { t.Helper() appIf := appServer.appclientset.ArgoprojV1alpha1().Applications("default") - app, err := appIf.Get(t.Context(), "test", metav1.GetOptions{}) + app, err := appIf.Get(context.Background(), "test", metav1.GetOptions{}) require.NoError(t, err) app.Operation = nil app.Status.OperationState = nil - _, err = appIf.Update(t.Context(), app, metav1.UpdateOptions{}) + _, err = appIf.Update(context.Background(), app, metav1.UpdateOptions{}) require.NoError(t, err) } func TestListAppsInNamespaceWithLabels(t *testing.T) { - appServer := newTestAppServer(t, newTestApp(func(app *v1alpha1.Application) { + appServer := newTestAppServer(t, newTestApp(func(app *appsv1.Application) { app.Name = "App1" - app.Namespace = "test-namespace" + app.ObjectMeta.Namespace = "test-namespace" app.SetLabels(map[string]string{"key1": "value1", "key2": "value1"}) - }), newTestApp(func(app *v1alpha1.Application) { + }), newTestApp(func(app *appsv1.Application) { app.Name = "App2" - app.Namespace = "test-namespace" + app.ObjectMeta.Namespace = "test-namespace" app.SetLabels(map[string]string{"key1": "value2"}) - }), newTestApp(func(app *v1alpha1.Application) { + }), newTestApp(func(app *appsv1.Application) { app.Name = "App3" - app.Namespace = "test-namespace" + app.ObjectMeta.Namespace = "test-namespace" app.SetLabels(map[string]string{"key1": "value3"}) })) appServer.ns = "test-namespace" @@ -1126,13 +1131,13 @@ func TestListAppsInNamespaceWithLabels(t *testing.T) { } func TestListAppsInDefaultNSWithLabels(t *testing.T) { - appServer := newTestAppServer(t, newTestApp(func(app *v1alpha1.Application) { + appServer := newTestAppServer(t, newTestApp(func(app *appsv1.Application) { app.Name = "App1" app.SetLabels(map[string]string{"key1": "value1", "key2": "value1"}) - }), newTestApp(func(app *v1alpha1.Application) { + }), newTestApp(func(app *appsv1.Application) { app.Name = "App2" app.SetLabels(map[string]string{"key1": "value2"}) - }), newTestApp(func(app *v1alpha1.Application) { + }), newTestApp(func(app *appsv1.Application) { app.Name = "App3" app.SetLabels(map[string]string{"key1": "value3"}) })) @@ -1187,7 +1192,7 @@ func testListAppsWithLabels(t *testing.T, appQuery application.ApplicationQuery, for _, validTest := range validTests { t.Run(validTest.testName, func(t *testing.T) { appQuery.Selector = &validTest.label - res, err := appServer.List(t.Context(), &appQuery) + res, err := appServer.List(context.Background(), &appQuery) require.NoError(t, err) apps := []string{} for i := range res.Items { @@ -1217,34 +1222,34 @@ func testListAppsWithLabels(t *testing.T, appQuery application.ApplicationQuery, for _, invalidTest := range invalidTests { t.Run(invalidTest.testName, func(t *testing.T) { appQuery.Selector = &invalidTest.label - _, err := appServer.List(t.Context(), &appQuery) + _, err := appServer.List(context.Background(), &appQuery) assert.ErrorContains(t, err, invalidTest.errorMesage) }) } } func TestListAppWithProjects(t *testing.T) { - appServer := newTestAppServer(t, newTestApp(func(app *v1alpha1.Application) { + appServer := newTestAppServer(t, newTestApp(func(app *appsv1.Application) { app.Name = "App1" app.Spec.Project = "test-project1" - }), newTestApp(func(app *v1alpha1.Application) { + }), newTestApp(func(app *appsv1.Application) { app.Name = "App2" app.Spec.Project = "test-project2" - }), newTestApp(func(app *v1alpha1.Application) { + }), newTestApp(func(app *appsv1.Application) { app.Name = "App3" app.Spec.Project = "test-project3" })) t.Run("List all apps", func(t *testing.T) { appQuery := application.ApplicationQuery{} - appList, err := appServer.List(t.Context(), &appQuery) + appList, err := appServer.List(context.Background(), &appQuery) require.NoError(t, err) assert.Len(t, appList.Items, 3) }) t.Run("List apps with projects filter set", func(t *testing.T) { appQuery := application.ApplicationQuery{Projects: []string{"test-project1"}} - appList, err := appServer.List(t.Context(), &appQuery) + appList, err := appServer.List(context.Background(), &appQuery) require.NoError(t, err) assert.Len(t, appList.Items, 1) for _, app := range appList.Items { @@ -1254,7 +1259,7 @@ func TestListAppWithProjects(t *testing.T) { t.Run("List apps with project filter set (legacy field)", func(t *testing.T) { appQuery := application.ApplicationQuery{Project: []string{"test-project1"}} - appList, err := appServer.List(t.Context(), &appQuery) + appList, err := appServer.List(context.Background(), &appQuery) require.NoError(t, err) assert.Len(t, appList.Items, 1) for _, app := range appList.Items { @@ -1265,7 +1270,7 @@ func TestListAppWithProjects(t *testing.T) { t.Run("List apps with both projects and project filter set", func(t *testing.T) { // If the older field is present, we should use it instead of the newer field. appQuery := application.ApplicationQuery{Project: []string{"test-project1"}, Projects: []string{"test-project2"}} - appList, err := appServer.List(t.Context(), &appQuery) + appList, err := appServer.List(context.Background(), &appQuery) require.NoError(t, err) assert.Len(t, appList.Items, 1) for _, app := range appList.Items { @@ -1275,15 +1280,15 @@ func TestListAppWithProjects(t *testing.T) { } func TestListApps(t *testing.T) { - appServer := newTestAppServer(t, newTestApp(func(app *v1alpha1.Application) { + appServer := newTestAppServer(t, newTestApp(func(app *appsv1.Application) { app.Name = "bcd" - }), newTestApp(func(app *v1alpha1.Application) { + }), newTestApp(func(app *appsv1.Application) { app.Name = "abc" - }), newTestApp(func(app *v1alpha1.Application) { + }), newTestApp(func(app *appsv1.Application) { app.Name = "def" })) - res, err := appServer.List(t.Context(), &application.ApplicationQuery{}) + res, err := appServer.List(context.Background(), &application.ApplicationQuery{}) require.NoError(t, err) var names []string for i := range res.Items { @@ -1294,18 +1299,18 @@ func TestListApps(t *testing.T) { func TestCoupleAppsListApps(t *testing.T) { var objects []runtime.Object - ctx := t.Context() + ctx := context.Background() var groups []string for i := 0; i < 50; i++ { groups = append(groups, fmt.Sprintf("group-%d", i)) } - //nolint:staticcheck + // nolint:staticcheck ctx = context.WithValue(ctx, "claims", &jwt.MapClaims{"groups": groups}) for projectId := 0; projectId < 100; projectId++ { projectName := fmt.Sprintf("proj-%d", projectId) for appId := 0; appId < 100; appId++ { - objects = append(objects, newTestApp(func(app *v1alpha1.Application) { + objects = append(objects, newTestApp(func(app *appsv1.Application) { app.Name = fmt.Sprintf("app-%d-%d", projectId, appId) app.Spec.Project = projectName })) @@ -1335,10 +1340,10 @@ g, group-49, role:test3 assert.Len(t, names, 300) } -func generateTestApp(num int) []*v1alpha1.Application { - apps := []*v1alpha1.Application{} +func generateTestApp(num int) []*appsv1.Application { + apps := []*appsv1.Application{} for i := 0; i < num; i++ { - apps = append(apps, newTestApp(func(app *v1alpha1.Application) { + apps = append(apps, newTestApp(func(app *appsv1.Application) { app.Name = fmt.Sprintf("test-app%.6d", i) })) } @@ -1357,7 +1362,7 @@ func BenchmarkListMuchApps(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - _, err := appServer.List(b.Context(), &application.ApplicationQuery{}) + _, err := appServer.List(context.Background(), &application.ApplicationQuery{}) if err != nil { break } @@ -1375,7 +1380,7 @@ func BenchmarkListSomeApps(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - _, err := appServer.List(b.Context(), &application.ApplicationQuery{}) + _, err := appServer.List(context.Background(), &application.ApplicationQuery{}) if err != nil { break } @@ -1393,7 +1398,7 @@ func BenchmarkListFewApps(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - _, err := appServer.List(b.Context(), &application.ApplicationQuery{}) + _, err := appServer.List(context.Background(), &application.ApplicationQuery{}) if err != nil { break } @@ -1416,7 +1421,7 @@ func BenchmarkListMuchAppsWithName(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { app := &application.ApplicationQuery{Name: strToPtr("test-app000099")} - _, err := appServer.List(b.Context(), app) + _, err := appServer.List(context.Background(), app) if err != nil { break } @@ -1437,7 +1442,7 @@ func BenchmarkListMuchAppsWithProjects(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { app := &application.ApplicationQuery{Project: []string{"test-project1", "test-project2"}} - _, err := appServer.List(b.Context(), app) + _, err := appServer.List(context.Background(), app) if err != nil { break } @@ -1457,7 +1462,7 @@ func BenchmarkListMuchAppsWithRepo(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { app := &application.ApplicationQuery{Repo: strToPtr("https://some-fake-source")} - _, err := appServer.List(b.Context(), app) + _, err := appServer.List(context.Background(), app) if err != nil { break } @@ -1471,7 +1476,7 @@ func TestCreateApp(t *testing.T) { createReq := application.ApplicationCreateRequest{ Application: testApp, } - app, err := appServer.Create(t.Context(), &createReq) + app, err := appServer.Create(context.Background(), &createReq) require.NoError(t, err) assert.NotNil(t, app) assert.NotNil(t, app.Spec) @@ -1484,9 +1489,10 @@ func TestCreateAppWithDestName(t *testing.T) { createReq := application.ApplicationCreateRequest{ Application: testApp, } - app, err := appServer.Create(t.Context(), &createReq) + app, err := appServer.Create(context.Background(), &createReq) require.NoError(t, err) assert.NotNil(t, app) + assert.Equal(t, "https://cluster-api.example.com", app.Spec.Destination.Server) } // TestCreateAppWithOperation tests that an application created with an operation is created with the operation removed. @@ -1494,8 +1500,8 @@ func TestCreateAppWithDestName(t *testing.T) { func TestCreateAppWithOperation(t *testing.T) { appServer := newTestAppServer(t) testApp := newTestAppWithDestName() - testApp.Operation = &v1alpha1.Operation{ - Sync: &v1alpha1.SyncOperation{ + testApp.Operation = &appsv1.Operation{ + Sync: &appsv1.SyncOperation{ Manifests: []string{ "test", }, @@ -1504,7 +1510,7 @@ func TestCreateAppWithOperation(t *testing.T) { createReq := application.ApplicationCreateRequest{ Application: testApp, } - app, err := appServer.Create(t.Context(), &createReq) + app, err := appServer.Create(context.Background(), &createReq) require.NoError(t, err) require.NotNil(t, app) assert.Nil(t, app.Operation) @@ -1514,7 +1520,7 @@ func TestUpdateApp(t *testing.T) { testApp := newTestApp() appServer := newTestAppServer(t, testApp) testApp.Spec.Project = "" - app, err := appServer.Update(t.Context(), &application.ApplicationUpdateRequest{ + app, err := appServer.Update(context.Background(), &application.ApplicationUpdateRequest{ Application: testApp, }) require.NoError(t, err) @@ -1525,19 +1531,19 @@ func TestUpdateAppSpec(t *testing.T) { testApp := newTestApp() appServer := newTestAppServer(t, testApp) testApp.Spec.Project = "" - spec, err := appServer.UpdateSpec(t.Context(), &application.ApplicationUpdateSpecRequest{ + spec, err := appServer.UpdateSpec(context.Background(), &application.ApplicationUpdateSpecRequest{ Name: &testApp.Name, Spec: &testApp.Spec, }) require.NoError(t, err) assert.Equal(t, "default", spec.Project) - app, err := appServer.Get(t.Context(), &application.ApplicationQuery{Name: &testApp.Name}) + app, err := appServer.Get(context.Background(), &application.ApplicationQuery{Name: &testApp.Name}) require.NoError(t, err) assert.Equal(t, "default", app.Spec.Project) } func TestDeleteApp(t *testing.T) { - ctx := t.Context() + ctx := context.Background() appServer := newTestAppServer(t) createReq := application.ApplicationCreateRequest{ Application: newTestApp(), @@ -1554,16 +1560,16 @@ func TestDeleteApp(t *testing.T) { fakeAppCs.ReactionChain = nil patched := false deleted := false - fakeAppCs.AddReactor("patch", "applications", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + fakeAppCs.AddReactor("patch", "applications", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true return true, nil, nil }) - fakeAppCs.AddReactor("delete", "applications", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + fakeAppCs.AddReactor("delete", "applications", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { deleted = true return true, nil, nil }) - fakeAppCs.AddReactor("get", "applications", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { - return true, &v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}}}, nil + fakeAppCs.AddReactor("get", "applications", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + return true, &appsv1.Application{Spec: appsv1.ApplicationSpec{Source: &appsv1.ApplicationSource{}}}, nil }) appServer.appclientset = fakeAppCs @@ -1627,16 +1633,16 @@ func TestDeleteApp(t *testing.T) { } func TestDeleteResourcesRBAC(t *testing.T) { - ctx := t.Context() - //nolint:staticcheck + ctx := context.Background() + // nolint:staticcheck ctx = context.WithValue(ctx, "claims", &jwt.RegisteredClaims{Subject: "test-user"}) testApp := newTestApp() appServer := newTestAppServer(t, testApp) appServer.enf.SetDefaultRole("") - argoCM := map[string]string{"server.rbac.disableApplicationFineGrainedRBACInheritance": "false"} - appServerWithRBACInheritance := newTestAppServerWithEnforcerConfigure(t, func(_ *rbac.Enforcer) {}, argoCM, testApp) - appServerWithRBACInheritance.enf.SetDefaultRole("") + argoCM := map[string]string{"server.rbac.disableApplicationFineGrainedRBACInheritance": "true"} + appServerWithoutRBACInheritance := newTestAppServerWithEnforcerConfigure(t, func(_ *rbac.Enforcer) {}, argoCM, testApp) + appServerWithoutRBACInheritance.enf.SetDefaultRole("") req := application.ApplicationResourceDeleteRequest{ Name: &testApp.Name, @@ -1649,20 +1655,29 @@ func TestDeleteResourcesRBAC(t *testing.T) { expectedErrorWhenDeleteAllowed := "rpc error: code = InvalidArgument desc = PodTest fake.io my-pod-test not found as part of application test-app" + t.Run("delete with application permission without inheritance", func(t *testing.T) { + _ = appServerWithoutRBACInheritance.enf.SetBuiltinPolicy(` +p, test-user, applications, delete, default/test-app, allow +`) + _, err := appServerWithoutRBACInheritance.DeleteResource(ctx, &req) + assert.Equal(t, codes.PermissionDenied.String(), status.Code(err).String()) + }) + t.Run("delete with application permission", func(t *testing.T) { _ = appServer.enf.SetBuiltinPolicy(` p, test-user, applications, delete, default/test-app, allow `) _, err := appServer.DeleteResource(ctx, &req) - assert.Equal(t, codes.PermissionDenied.String(), status.Code(err).String()) + assert.EqualError(t, err, expectedErrorWhenDeleteAllowed) }) - t.Run("delete with application permission with inheritance", func(t *testing.T) { - _ = appServerWithRBACInheritance.enf.SetBuiltinPolicy(` + t.Run("delete with application permission but deny subresource without inheritance", func(t *testing.T) { + _ = appServerWithoutRBACInheritance.enf.SetBuiltinPolicy(` p, test-user, applications, delete, default/test-app, allow +p, test-user, applications, delete/*, default/test-app, deny `) - _, err := appServerWithRBACInheritance.DeleteResource(ctx, &req) - assert.EqualError(t, err, expectedErrorWhenDeleteAllowed) + _, err := appServerWithoutRBACInheritance.DeleteResource(ctx, &req) + assert.Equal(t, codes.PermissionDenied.String(), status.Code(err).String()) }) t.Run("delete with application permission but deny subresource", func(t *testing.T) { @@ -1671,15 +1686,6 @@ p, test-user, applications, delete, default/test-app, allow p, test-user, applications, delete/*, default/test-app, deny `) _, err := appServer.DeleteResource(ctx, &req) - assert.Equal(t, codes.PermissionDenied.String(), status.Code(err).String()) - }) - - t.Run("delete with application permission but deny subresource with inheritance", func(t *testing.T) { - _ = appServerWithRBACInheritance.enf.SetBuiltinPolicy(` -p, test-user, applications, delete, default/test-app, allow -p, test-user, applications, delete/*, default/test-app, deny -`) - _, err := appServerWithRBACInheritance.DeleteResource(ctx, &req) assert.EqualError(t, err, expectedErrorWhenDeleteAllowed) }) @@ -1691,6 +1697,15 @@ p, test-user, applications, delete/*, default/test-app, allow assert.EqualError(t, err, expectedErrorWhenDeleteAllowed) }) + t.Run("delete with subresource but deny applications without inheritance", func(t *testing.T) { + _ = appServerWithoutRBACInheritance.enf.SetBuiltinPolicy(` +p, test-user, applications, delete, default/test-app, deny +p, test-user, applications, delete/*, default/test-app, allow +`) + _, err := appServerWithoutRBACInheritance.DeleteResource(ctx, &req) + assert.EqualError(t, err, expectedErrorWhenDeleteAllowed) + }) + t.Run("delete with subresource but deny applications", func(t *testing.T) { _ = appServer.enf.SetBuiltinPolicy(` p, test-user, applications, delete, default/test-app, deny @@ -1700,15 +1715,6 @@ p, test-user, applications, delete/*, default/test-app, allow assert.EqualError(t, err, expectedErrorWhenDeleteAllowed) }) - t.Run("delete with subresource but deny applications with inheritance", func(t *testing.T) { - _ = appServerWithRBACInheritance.enf.SetBuiltinPolicy(` -p, test-user, applications, delete, default/test-app, deny -p, test-user, applications, delete/*, default/test-app, allow -`) - _, err := appServerWithRBACInheritance.DeleteResource(ctx, &req) - assert.EqualError(t, err, expectedErrorWhenDeleteAllowed) - }) - t.Run("delete with specific subresource denied", func(t *testing.T) { _ = appServer.enf.SetBuiltinPolicy(` p, test-user, applications, delete/*, default/test-app, allow @@ -1720,16 +1726,16 @@ p, test-user, applications, delete/fake.io/PodTest/*, default/test-app, deny } func TestPatchResourcesRBAC(t *testing.T) { - ctx := t.Context() - //nolint:staticcheck + ctx := context.Background() + // nolint:staticcheck ctx = context.WithValue(ctx, "claims", &jwt.RegisteredClaims{Subject: "test-user"}) testApp := newTestApp() appServer := newTestAppServer(t, testApp) appServer.enf.SetDefaultRole("") - argoCM := map[string]string{"server.rbac.disableApplicationFineGrainedRBACInheritance": "false"} - appServerWithRBACInheritance := newTestAppServerWithEnforcerConfigure(t, func(_ *rbac.Enforcer) {}, argoCM, testApp) - appServerWithRBACInheritance.enf.SetDefaultRole("") + argoCM := map[string]string{"server.rbac.disableApplicationFineGrainedRBACInheritance": "true"} + appServerWithoutRBACInheritance := newTestAppServerWithEnforcerConfigure(t, func(_ *rbac.Enforcer) {}, argoCM, testApp) + appServerWithoutRBACInheritance.enf.SetDefaultRole("") req := application.ApplicationResourcePatchRequest{ Name: &testApp.Name, @@ -1742,20 +1748,29 @@ func TestPatchResourcesRBAC(t *testing.T) { expectedErrorWhenUpdateAllowed := "rpc error: code = InvalidArgument desc = PodTest fake.io my-pod-test not found as part of application test-app" + t.Run("patch with application permission without inheritance", func(t *testing.T) { + _ = appServerWithoutRBACInheritance.enf.SetBuiltinPolicy(` +p, test-user, applications, update, default/test-app, allow +`) + _, err := appServerWithoutRBACInheritance.PatchResource(ctx, &req) + assert.Equal(t, codes.PermissionDenied.String(), status.Code(err).String()) + }) + t.Run("patch with application permission", func(t *testing.T) { _ = appServer.enf.SetBuiltinPolicy(` p, test-user, applications, update, default/test-app, allow `) _, err := appServer.PatchResource(ctx, &req) - assert.Equal(t, codes.PermissionDenied.String(), status.Code(err).String()) + assert.EqualError(t, err, expectedErrorWhenUpdateAllowed) }) - t.Run("patch with application permission with inheritance", func(t *testing.T) { - _ = appServerWithRBACInheritance.enf.SetBuiltinPolicy(` + t.Run("patch with application permission but deny subresource without inheritance", func(t *testing.T) { + _ = appServerWithoutRBACInheritance.enf.SetBuiltinPolicy(` p, test-user, applications, update, default/test-app, allow +p, test-user, applications, update/*, default/test-app, deny `) - _, err := appServerWithRBACInheritance.PatchResource(ctx, &req) - assert.EqualError(t, err, expectedErrorWhenUpdateAllowed) + _, err := appServerWithoutRBACInheritance.PatchResource(ctx, &req) + assert.Equal(t, codes.PermissionDenied.String(), status.Code(err).String()) }) t.Run("patch with application permission but deny subresource", func(t *testing.T) { @@ -1764,15 +1779,6 @@ p, test-user, applications, update, default/test-app, allow p, test-user, applications, update/*, default/test-app, deny `) _, err := appServer.PatchResource(ctx, &req) - assert.Equal(t, codes.PermissionDenied.String(), status.Code(err).String()) - }) - - t.Run("patch with application permission but deny subresource with inheritance", func(t *testing.T) { - _ = appServerWithRBACInheritance.enf.SetBuiltinPolicy(` -p, test-user, applications, update, default/test-app, allow -p, test-user, applications, update/*, default/test-app, deny -`) - _, err := appServerWithRBACInheritance.PatchResource(ctx, &req) assert.EqualError(t, err, expectedErrorWhenUpdateAllowed) }) @@ -1784,6 +1790,15 @@ p, test-user, applications, update/*, default/test-app, allow assert.EqualError(t, err, expectedErrorWhenUpdateAllowed) }) + t.Run("patch with subresource but deny applications without inheritance", func(t *testing.T) { + _ = appServerWithoutRBACInheritance.enf.SetBuiltinPolicy(` +p, test-user, applications, update, default/test-app, deny +p, test-user, applications, update/*, default/test-app, allow +`) + _, err := appServerWithoutRBACInheritance.PatchResource(ctx, &req) + assert.EqualError(t, err, expectedErrorWhenUpdateAllowed) + }) + t.Run("patch with subresource but deny applications", func(t *testing.T) { _ = appServer.enf.SetBuiltinPolicy(` p, test-user, applications, update, default/test-app, deny @@ -1793,15 +1808,6 @@ p, test-user, applications, update/*, default/test-app, allow assert.EqualError(t, err, expectedErrorWhenUpdateAllowed) }) - t.Run("patch with subresource but deny applications with inheritance", func(t *testing.T) { - _ = appServerWithRBACInheritance.enf.SetBuiltinPolicy(` -p, test-user, applications, update, default/test-app, deny -p, test-user, applications, update/*, default/test-app, allow -`) - _, err := appServerWithRBACInheritance.PatchResource(ctx, &req) - assert.EqualError(t, err, expectedErrorWhenUpdateAllowed) - }) - t.Run("patch with specific subresource denied", func(t *testing.T) { _ = appServer.enf.SetBuiltinPolicy(` p, test-user, applications, update/*, default/test-app, allow @@ -1813,7 +1819,7 @@ p, test-user, applications, update/fake.io/PodTest/*, default/test-app, deny } func TestSyncAndTerminate(t *testing.T) { - ctx := t.Context() + ctx := context.Background() appServer := newTestAppServer(t) testApp := newTestApp() testApp.Spec.Source.RepoURL = "https://github.com/argoproj/argo-cd.git" @@ -1827,19 +1833,19 @@ func TestSyncAndTerminate(t *testing.T) { assert.NotNil(t, app) assert.NotNil(t, app.Operation) - events, err := appServer.kubeclientset.CoreV1().Events(appServer.ns).List(t.Context(), metav1.ListOptions{}) + events, err := appServer.kubeclientset.CoreV1().Events(appServer.ns).List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) event := events.Items[1] assert.Regexp(t, ".*initiated sync to HEAD \\([0-9A-Fa-f]{40}\\).*", event.Message) // set status.operationState to pretend that an operation has started by controller - app.Status.OperationState = &v1alpha1.OperationState{ + app.Status.OperationState = &appsv1.OperationState{ Operation: *app.Operation, Phase: synccommon.OperationRunning, StartedAt: metav1.NewTime(time.Now()), } - _, err = appServer.appclientset.ArgoprojV1alpha1().Applications(appServer.ns).Update(t.Context(), app, metav1.UpdateOptions{}) + _, err = appServer.appclientset.ArgoprojV1alpha1().Applications(appServer.ns).Update(context.Background(), app, metav1.UpdateOptions{}) require.NoError(t, err) resp, err := appServer.TerminateOperation(ctx, &application.OperationTerminateRequest{Name: &app.Name}) @@ -1853,7 +1859,7 @@ func TestSyncAndTerminate(t *testing.T) { } func TestSyncHelm(t *testing.T) { - ctx := t.Context() + ctx := context.Background() appServer := newTestAppServer(t) testApp := newTestApp() testApp.Spec.Source.RepoURL = "https://argoproj.github.io/argo-helm" @@ -1871,13 +1877,13 @@ func TestSyncHelm(t *testing.T) { assert.NotNil(t, app) assert.NotNil(t, app.Operation) - events, err := appServer.kubeclientset.CoreV1().Events(appServer.ns).List(t.Context(), metav1.ListOptions{}) + events, err := appServer.kubeclientset.CoreV1().Events(appServer.ns).List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) assert.Equal(t, "Unknown user initiated sync to 0.7.* (0.7.2)", events.Items[1].Message) } func TestSyncGit(t *testing.T) { - ctx := t.Context() + ctx := context.Background() appServer := newTestAppServer(t) testApp := newTestApp() testApp.Spec.Source.RepoURL = "https://github.com/org/test" @@ -1899,21 +1905,21 @@ func TestSyncGit(t *testing.T) { require.NoError(t, err) assert.NotNil(t, app) assert.NotNil(t, app.Operation) - events, err := appServer.kubeclientset.CoreV1().Events(appServer.ns).List(t.Context(), metav1.ListOptions{}) + events, err := appServer.kubeclientset.CoreV1().Events(appServer.ns).List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) assert.Equal(t, "Unknown user initiated sync locally", events.Items[1].Message) } func TestRollbackApp(t *testing.T) { testApp := newTestApp() - testApp.Status.History = []v1alpha1.RevisionHistory{{ + testApp.Status.History = []appsv1.RevisionHistory{{ ID: 1, Revision: "abc", Source: *testApp.Spec.Source.DeepCopy(), }} appServer := newTestAppServer(t, testApp) - updatedApp, err := appServer.Rollback(t.Context(), &application.ApplicationRollbackRequest{ + updatedApp, err := appServer.Rollback(context.Background(), &application.ApplicationRollbackRequest{ Name: &testApp.Name, Id: ptr.To(int64(1)), }) @@ -1928,8 +1934,8 @@ func TestRollbackApp(t *testing.T) { func TestUpdateAppProject(t *testing.T) { testApp := newTestApp() - ctx := t.Context() - //nolint:staticcheck + ctx := context.Background() + // nolint:staticcheck ctx = context.WithValue(ctx, "claims", &jwt.RegisteredClaims{Subject: "admin"}) appServer := newTestAppServer(t, testApp) appServer.enf.SetDefaultRole("") @@ -1992,8 +1998,8 @@ p, admin, applications, update, my-proj/test-app, allow func TestAppJsonPatch(t *testing.T) { testApp := newTestAppWithAnnotations() - ctx := t.Context() - //nolint:staticcheck + ctx := context.Background() + // nolint:staticcheck ctx = context.WithValue(ctx, "claims", &jwt.RegisteredClaims{Subject: "admin"}) appServer := newTestAppServer(t, testApp) appServer.enf.SetDefaultRole("") @@ -2017,8 +2023,8 @@ func TestAppJsonPatch(t *testing.T) { func TestAppMergePatch(t *testing.T) { testApp := newTestApp() - ctx := t.Context() - //nolint:staticcheck + ctx := context.Background() + // nolint:staticcheck ctx = context.WithValue(ctx, "claims", &jwt.RegisteredClaims{Subject: "admin"}) appServer := newTestAppServer(t, testApp) appServer.enf.SetDefaultRole("") @@ -2036,7 +2042,7 @@ func TestServer_GetApplicationSyncWindowsState(t *testing.T) { testApp.Spec.Project = "proj-maint" appServer := newTestAppServer(t, testApp) - active, err := appServer.GetApplicationSyncWindows(t.Context(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name}) + active, err := appServer.GetApplicationSyncWindows(context.Background(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name}) require.NoError(t, err) assert.Len(t, active.ActiveWindows, 1) }) @@ -2045,7 +2051,7 @@ func TestServer_GetApplicationSyncWindowsState(t *testing.T) { testApp.Spec.Project = "default" appServer := newTestAppServer(t, testApp) - active, err := appServer.GetApplicationSyncWindows(t.Context(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name}) + active, err := appServer.GetApplicationSyncWindows(context.Background(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name}) require.NoError(t, err) assert.Empty(t, active.ActiveWindows) }) @@ -2054,7 +2060,7 @@ func TestServer_GetApplicationSyncWindowsState(t *testing.T) { testApp.Spec.Project = "none" appServer := newTestAppServer(t, testApp) - active, err := appServer.GetApplicationSyncWindows(t.Context(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name}) + active, err := appServer.GetApplicationSyncWindows(context.Background(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name}) require.ErrorContains(t, err, "not exist") assert.Nil(t, active) }) @@ -2062,9 +2068,9 @@ func TestServer_GetApplicationSyncWindowsState(t *testing.T) { func TestGetCachedAppState(t *testing.T) { testApp := newTestApp() - testApp.ResourceVersion = "1" + testApp.ObjectMeta.ResourceVersion = "1" testApp.Spec.Project = "test-proj" - testProj := &v1alpha1.AppProject{ + testProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{ Name: "test-proj", Namespace: testNamespace, @@ -2073,10 +2079,10 @@ func TestGetCachedAppState(t *testing.T) { appServer := newTestAppServer(t, testApp, testProj) fakeClientSet := appServer.appclientset.(*deepCopyAppClientset).GetUnderlyingClientSet().(*apps.Clientset) fakeClientSet.AddReactor("get", "applications", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { - return true, &v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}}}, nil + return true, &appv1.Application{Spec: appv1.ApplicationSpec{Source: &appv1.ApplicationSource{}}}, nil }) t.Run("NoError", func(t *testing.T) { - err := appServer.getCachedAppState(t.Context(), testApp, func() error { + err := appServer.getCachedAppState(context.Background(), testApp, func() error { return nil }) require.NoError(t, err) @@ -2091,23 +2097,23 @@ func TestGetCachedAppState(t *testing.T) { fakeClientSet.Lock() fakeClientSet.ReactionChain = nil fakeClientSet.WatchReactionChain = nil - fakeClientSet.AddReactor("patch", "applications", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + fakeClientSet.AddReactor("patch", "applications", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true updated := testApp.DeepCopy() updated.ResourceVersion = "2" appServer.appBroadcaster.OnUpdate(testApp, updated) return true, testApp, nil }) - fakeClientSet.AddReactor("get", "applications", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { - return true, &v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}}}, nil + fakeClientSet.AddReactor("get", "applications", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + return true, &appsv1.Application{Spec: appsv1.ApplicationSpec{Source: &appsv1.ApplicationSource{}}}, nil }) fakeClientSet.Unlock() - fakeClientSet.AddWatchReactor("applications", func(_ kubetesting.Action) (handled bool, ret watch.Interface, err error) { + fakeClientSet.AddWatchReactor("applications", func(action kubetesting.Action) (handled bool, ret watch.Interface, err error) { return true, watcher, nil }) } - err := appServer.getCachedAppState(t.Context(), testApp, func() error { + err := appServer.getCachedAppState(context.Background(), testApp, func() error { res := cache.ErrCacheMiss if retryCount == 1 { res = nil @@ -2121,8 +2127,8 @@ func TestGetCachedAppState(t *testing.T) { }) t.Run("NonCacheErrorDoesNotTriggerRefresh", func(t *testing.T) { - randomError := stderrors.New("random error") - err := appServer.getCachedAppState(t.Context(), testApp, func() error { + randomError := coreerrors.New("random error") + err := appServer.getCachedAppState(context.Background(), testApp, func() error { return randomError }) assert.Equal(t, randomError, err) @@ -2161,14 +2167,14 @@ func TestSplitStatusPatch(t *testing.T) { } func TestLogsGetSelectedPod(t *testing.T) { - deployment := v1alpha1.ResourceRef{Group: "", Version: "v1", Kind: "Deployment", Name: "deployment", UID: "1"} - rs := v1alpha1.ResourceRef{Group: "", Version: "v1", Kind: "ReplicaSet", Name: "rs", UID: "2"} - podRS := v1alpha1.ResourceRef{Group: "", Version: "v1", Kind: "Pod", Name: "podrs", UID: "3"} - pod := v1alpha1.ResourceRef{Group: "", Version: "v1", Kind: "Pod", Name: "pod", UID: "4"} - treeNodes := []v1alpha1.ResourceNode{ + deployment := appsv1.ResourceRef{Group: "", Version: "v1", Kind: "Deployment", Name: "deployment", UID: "1"} + rs := appsv1.ResourceRef{Group: "", Version: "v1", Kind: "ReplicaSet", Name: "rs", UID: "2"} + podRS := appsv1.ResourceRef{Group: "", Version: "v1", Kind: "Pod", Name: "podrs", UID: "3"} + pod := appsv1.ResourceRef{Group: "", Version: "v1", Kind: "Pod", Name: "pod", UID: "4"} + treeNodes := []appsv1.ResourceNode{ {ResourceRef: deployment, ParentRefs: nil}, - {ResourceRef: rs, ParentRefs: []v1alpha1.ResourceRef{deployment}}, - {ResourceRef: podRS, ParentRefs: []v1alpha1.ResourceRef{rs}}, + {ResourceRef: rs, ParentRefs: []appsv1.ResourceRef{deployment}}, + {ResourceRef: podRS, ParentRefs: []appsv1.ResourceRef{rs}}, {ResourceRef: pod, ParentRefs: nil}, } appName := "appName" @@ -2278,10 +2284,10 @@ func TestMaxPodLogsRender(t *testing.T) { func createAppServerWithMaxLodLogs(t *testing.T, podNumber int, maxPodLogsToRender ...int64) (*Server, context.Context) { t.Helper() runtimeObjects := make([]runtime.Object, podNumber+1) - resources := make([]v1alpha1.ResourceStatus, podNumber) + resources := make([]appsv1.ResourceStatus, podNumber) for i := 0; i < podNumber; i++ { - pod := corev1.Pod{ + pod := v1.Pod{ TypeMeta: metav1.TypeMeta{ APIVersion: "v1", Kind: "Pod", @@ -2291,7 +2297,7 @@ func createAppServerWithMaxLodLogs(t *testing.T, podNumber int, maxPodLogsToRend Namespace: "test", }, } - resources[i] = v1alpha1.ResourceStatus{ + resources[i] = appsv1.ResourceStatus{ Group: pod.GroupVersionKind().Group, Kind: pod.GroupVersionKind().Kind, Version: pod.GroupVersionKind().Version, @@ -2302,14 +2308,14 @@ func createAppServerWithMaxLodLogs(t *testing.T, podNumber int, maxPodLogsToRend runtimeObjects[i] = kube.MustToUnstructured(&pod) } - testApp := newTestApp(func(app *v1alpha1.Application) { + testApp := newTestApp(func(app *appsv1.Application) { app.Name = "test" app.Status.Resources = resources }) runtimeObjects[podNumber] = testApp - noRoleCtx := t.Context() - //nolint:staticcheck + noRoleCtx := context.Background() + // nolint:staticcheck adminCtx := context.WithValue(noRoleCtx, "claims", &jwt.MapClaims{"groups": []string{"admin"}}) if len(maxPodLogsToRender) > 0 { @@ -2320,9 +2326,10 @@ func createAppServerWithMaxLodLogs(t *testing.T, podNumber int, maxPodLogsToRend formatInt := strconv.FormatInt(maxPodLogsToRender[0], 10) appServer := newTestAppServerWithEnforcerConfigure(t, f, map[string]string{"server.maxPodLogsToRender": formatInt}, runtimeObjects...) return appServer, adminCtx + } else { + appServer := newTestAppServer(t, runtimeObjects...) + return appServer, adminCtx } - appServer := newTestAppServer(t, runtimeObjects...) - return appServer, adminCtx } // refreshAnnotationRemover runs an infinite loop until it detects and removes refresh annotation or given context is done @@ -2332,11 +2339,11 @@ func refreshAnnotationRemover(t *testing.T, ctx context.Context, patched *int32, aName, appNs := argo.ParseFromQualifiedName(appName, appServer.ns) a, err := appServer.appLister.Applications(appNs).Get(aName) require.NoError(t, err) - if a.GetAnnotations() != nil && a.GetAnnotations()[v1alpha1.AnnotationKeyRefresh] != "" { + if a.GetAnnotations() != nil && a.GetAnnotations()[appsv1.AnnotationKeyRefresh] != "" { a.SetAnnotations(map[string]string{}) a.SetResourceVersion("999") _, err = appServer.appclientset.ArgoprojV1alpha1().Applications(a.Namespace).Update( - t.Context(), a, metav1.UpdateOptions{}) + context.Background(), a, metav1.UpdateOptions{}) require.NoError(t, err) atomic.AddInt32(patched, 1) ch <- "" @@ -2346,10 +2353,10 @@ func refreshAnnotationRemover(t *testing.T, ctx context.Context, patched *int32, } func TestGetAppRefresh_NormalRefresh(t *testing.T) { - ctx, cancel := context.WithCancel(t.Context()) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() testApp := newTestApp() - testApp.ResourceVersion = "1" + testApp.ObjectMeta.ResourceVersion = "1" appServer := newTestAppServer(t, testApp) var patched int32 @@ -2358,9 +2365,9 @@ func TestGetAppRefresh_NormalRefresh(t *testing.T) { go refreshAnnotationRemover(t, ctx, &patched, appServer, testApp.Name, ch) - _, err := appServer.Get(t.Context(), &application.ApplicationQuery{ + _, err := appServer.Get(context.Background(), &application.ApplicationQuery{ Name: &testApp.Name, - Refresh: ptr.To(string(v1alpha1.RefreshTypeNormal)), + Refresh: ptr.To(string(appsv1.RefreshTypeNormal)), }) require.NoError(t, err) @@ -2373,10 +2380,10 @@ func TestGetAppRefresh_NormalRefresh(t *testing.T) { } func TestGetAppRefresh_HardRefresh(t *testing.T) { - ctx, cancel := context.WithCancel(t.Context()) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() testApp := newTestApp() - testApp.ResourceVersion = "1" + testApp.ObjectMeta.ResourceVersion = "1" appServer := newTestAppServer(t, testApp) var getAppDetailsQuery *apiclient.RepoServerAppDetailsQuery @@ -2393,9 +2400,9 @@ func TestGetAppRefresh_HardRefresh(t *testing.T) { go refreshAnnotationRemover(t, ctx, &patched, appServer, testApp.Name, ch) - _, err := appServer.Get(t.Context(), &application.ApplicationQuery{ + _, err := appServer.Get(context.Background(), &application.ApplicationQuery{ Name: &testApp.Name, - Refresh: ptr.To(string(v1alpha1.RefreshTypeHard)), + Refresh: ptr.To(string(appsv1.RefreshTypeHard)), }) require.NoError(t, err) require.NotNil(t, getAppDetailsQuery) @@ -2412,11 +2419,11 @@ func TestGetAppRefresh_HardRefresh(t *testing.T) { } func TestInferResourcesStatusHealth(t *testing.T) { - cacheClient := cache.NewCache(cache.NewInMemoryCache(1 * time.Hour)) + cacheClient := cacheutil.NewCache(cacheutil.NewInMemoryCache(1 * time.Hour)) testApp := newTestApp() - testApp.Status.ResourceHealthSource = v1alpha1.ResourceHealthLocationAppTree - testApp.Status.Resources = []v1alpha1.ResourceStatus{{ + testApp.Status.ResourceHealthSource = appsv1.ResourceHealthLocationAppTree + testApp.Status.Resources = []appsv1.ResourceStatus{{ Group: "apps", Kind: "Deployment", Name: "guestbook", @@ -2429,14 +2436,14 @@ func TestInferResourcesStatusHealth(t *testing.T) { }} appServer := newTestAppServer(t, testApp) appStateCache := appstate.NewCache(cacheClient, time.Minute) - err := appStateCache.SetAppResourcesTree(testApp.Name, &v1alpha1.ApplicationTree{Nodes: []v1alpha1.ResourceNode{{ - ResourceRef: v1alpha1.ResourceRef{ + err := appStateCache.SetAppResourcesTree(testApp.Name, &appsv1.ApplicationTree{Nodes: []appsv1.ResourceNode{{ + ResourceRef: appsv1.ResourceRef{ Group: "apps", Kind: "Deployment", Name: "guestbook", Namespace: "default", }, - Health: &v1alpha1.HealthStatus{ + Health: &appsv1.HealthStatus{ Status: health.HealthStatusDegraded, }, }}}) @@ -2452,7 +2459,7 @@ func TestInferResourcesStatusHealth(t *testing.T) { } func TestRunNewStyleResourceAction(t *testing.T) { - cacheClient := cache.NewCache(cache.NewInMemoryCache(1 * time.Hour)) + cacheClient := cacheutil.NewCache(cacheutil.NewInMemoryCache(1 * time.Hour)) group := "batch" kind := "CronJob" @@ -2462,7 +2469,7 @@ func TestRunNewStyleResourceAction(t *testing.T) { action := "create-job" uid := "1" - resources := []v1alpha1.ResourceStatus{{ + resources := []appsv1.ResourceStatus{{ Group: group, Kind: kind, Name: resourceName, @@ -2472,8 +2479,8 @@ func TestRunNewStyleResourceAction(t *testing.T) { appStateCache := appstate.NewCache(cacheClient, time.Minute) - nodes := []v1alpha1.ResourceNode{{ - ResourceRef: v1alpha1.ResourceRef{ + nodes := []appsv1.ResourceNode{{ + ResourceRef: appsv1.ResourceRef{ Group: group, Kind: kind, Version: version, @@ -2483,11 +2490,11 @@ func TestRunNewStyleResourceAction(t *testing.T) { }, }} - createJobDenyingProj := &v1alpha1.AppProject{ + createJobDenyingProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "createJobDenyingProj", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, NamespaceResourceWhitelist: []metav1.GroupKind{{Group: "never", Kind: "mind"}}, }, } @@ -2529,16 +2536,16 @@ func TestRunNewStyleResourceAction(t *testing.T) { t.Run("CreateOperationNotPermitted", func(t *testing.T) { testApp := newTestApp() testApp.Spec.Project = "createJobDenyingProj" - testApp.Status.ResourceHealthSource = v1alpha1.ResourceHealthLocationAppTree + testApp.Status.ResourceHealthSource = appsv1.ResourceHealthLocationAppTree testApp.Status.Resources = resources appServer := newTestAppServer(t, testApp, createJobDenyingProj, kube.MustToUnstructured(&cronJob)) appServer.cache = servercache.NewCache(appStateCache, time.Minute, time.Minute, time.Minute) - err := appStateCache.SetAppResourcesTree(testApp.Name, &v1alpha1.ApplicationTree{Nodes: nodes}) + err := appStateCache.SetAppResourcesTree(testApp.Name, &appsv1.ApplicationTree{Nodes: nodes}) require.NoError(t, err) - appResponse, runErr := appServer.RunResourceAction(t.Context(), &application.ResourceActionRunRequest{ + appResponse, runErr := appServer.RunResourceAction(context.Background(), &application.ResourceActionRunRequest{ Name: &testApp.Name, Namespace: &namespace, Action: &action, @@ -2555,16 +2562,16 @@ func TestRunNewStyleResourceAction(t *testing.T) { t.Run("CreateOperationPermitted", func(t *testing.T) { testApp := newTestApp() - testApp.Status.ResourceHealthSource = v1alpha1.ResourceHealthLocationAppTree + testApp.Status.ResourceHealthSource = appsv1.ResourceHealthLocationAppTree testApp.Status.Resources = resources appServer := newTestAppServer(t, testApp, kube.MustToUnstructured(&cronJob)) appServer.cache = servercache.NewCache(appStateCache, time.Minute, time.Minute, time.Minute) - err := appStateCache.SetAppResourcesTree(testApp.Name, &v1alpha1.ApplicationTree{Nodes: nodes}) + err := appStateCache.SetAppResourcesTree(testApp.Name, &appsv1.ApplicationTree{Nodes: nodes}) require.NoError(t, err) - appResponse, runErr := appServer.RunResourceAction(t.Context(), &application.ResourceActionRunRequest{ + appResponse, runErr := appServer.RunResourceAction(context.Background(), &application.ResourceActionRunRequest{ Name: &testApp.Name, Namespace: &namespace, Action: &action, @@ -2581,7 +2588,7 @@ func TestRunNewStyleResourceAction(t *testing.T) { } func TestRunOldStyleResourceAction(t *testing.T) { - cacheClient := cache.NewCache(cache.NewInMemoryCache(1 * time.Hour)) + cacheClient := cacheutil.NewCache(cacheutil.NewInMemoryCache(1 * time.Hour)) group := "apps" kind := "Deployment" @@ -2591,7 +2598,7 @@ func TestRunOldStyleResourceAction(t *testing.T) { action := "pause" uid := "2" - resources := []v1alpha1.ResourceStatus{{ + resources := []appsv1.ResourceStatus{{ Group: group, Kind: kind, Name: resourceName, @@ -2601,8 +2608,8 @@ func TestRunOldStyleResourceAction(t *testing.T) { appStateCache := appstate.NewCache(cacheClient, time.Minute) - nodes := []v1alpha1.ResourceNode{{ - ResourceRef: v1alpha1.ResourceRef{ + nodes := []appsv1.ResourceNode{{ + ResourceRef: appsv1.ResourceRef{ Group: group, Kind: kind, Version: version, @@ -2612,7 +2619,7 @@ func TestRunOldStyleResourceAction(t *testing.T) { }, }} - deployment := appsv1.Deployment{ + deployment := k8sappsv1.Deployment{ TypeMeta: metav1.TypeMeta{ APIVersion: "apps/v1", Kind: "Deployment", @@ -2625,17 +2632,17 @@ func TestRunOldStyleResourceAction(t *testing.T) { t.Run("DefaultPatchOperation", func(t *testing.T) { testApp := newTestApp() - testApp.Status.ResourceHealthSource = v1alpha1.ResourceHealthLocationAppTree + testApp.Status.ResourceHealthSource = appsv1.ResourceHealthLocationAppTree testApp.Status.Resources = resources // appServer := newTestAppServer(t, testApp, returnDeployment()) appServer := newTestAppServer(t, testApp, kube.MustToUnstructured(&deployment)) appServer.cache = servercache.NewCache(appStateCache, time.Minute, time.Minute, time.Minute) - err := appStateCache.SetAppResourcesTree(testApp.Name, &v1alpha1.ApplicationTree{Nodes: nodes}) + err := appStateCache.SetAppResourcesTree(testApp.Name, &appsv1.ApplicationTree{Nodes: nodes}) require.NoError(t, err) - appResponse, runErr := appServer.RunResourceAction(t.Context(), &application.ResourceActionRunRequest{ + appResponse, runErr := appServer.RunResourceAction(context.Background(), &application.ResourceActionRunRequest{ Name: &testApp.Name, Namespace: &namespace, Action: &action, @@ -2710,7 +2717,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { t.Parallel() testApp := newTestApp() appServer := newTestAppServer(t, testApp) - apps, err := appServer.List(t.Context(), &application.ApplicationQuery{}) + apps, err := appServer.List(context.TODO(), &application.ApplicationQuery{}) require.NoError(t, err) require.Len(t, apps.Items, 1) }) @@ -2720,7 +2727,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp1 := newTestApp() testApp1.Namespace = "argocd-1" appServer := newTestAppServer(t, testApp1) - apps, err := appServer.List(t.Context(), &application.ApplicationQuery{}) + apps, err := appServer.List(context.TODO(), &application.ApplicationQuery{}) require.NoError(t, err) require.Empty(t, apps.Items) }) @@ -2731,7 +2738,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp2 := newTestApp() testApp2.Namespace = "argocd-1" appServer := newTestAppServer(t, testApp1, testApp2) - apps, err := appServer.List(t.Context(), &application.ApplicationQuery{AppNamespace: ptr.To("argocd-1")}) + apps, err := appServer.List(context.TODO(), &application.ApplicationQuery{AppNamespace: ptr.To("argocd-1")}) require.NoError(t, err) require.Empty(t, apps.Items) }) @@ -2742,7 +2749,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp1.Namespace = "argocd-1" appServer := newTestAppServer(t, testApp1) appServer.enabledNamespaces = []string{"argocd-1"} - apps, err := appServer.List(t.Context(), &application.ApplicationQuery{}) + apps, err := appServer.List(context.TODO(), &application.ApplicationQuery{}) require.NoError(t, err) require.Len(t, apps.Items, 1) }) @@ -2751,7 +2758,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { t.Parallel() testApp := newTestApp() appServer := newTestAppServer(t, testApp) - app, err := appServer.Get(t.Context(), &application.ApplicationQuery{ + app, err := appServer.Get(context.TODO(), &application.ApplicationQuery{ Name: ptr.To("test-app"), }) require.NoError(t, err) @@ -2762,7 +2769,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp := newTestApp() testApp.Namespace = "argocd-1" appServer := newTestAppServer(t, testApp) - app, err := appServer.Get(t.Context(), &application.ApplicationQuery{ + app, err := appServer.Get(context.TODO(), &application.ApplicationQuery{ Name: ptr.To("test-app"), AppNamespace: ptr.To("argocd-1"), }) @@ -2774,17 +2781,17 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" - otherNsProj := &v1alpha1.AppProject{ + otherNsProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, SourceNamespaces: []string{"argocd-1"}, }, } appServer := newTestAppServer(t, testApp, otherNsProj) appServer.enabledNamespaces = []string{"argocd-1"} - app, err := appServer.Get(t.Context(), &application.ApplicationQuery{ + app, err := appServer.Get(context.TODO(), &application.ApplicationQuery{ Name: ptr.To("test-app"), AppNamespace: ptr.To("argocd-1"), }) @@ -2798,17 +2805,17 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" - otherNsProj := &v1alpha1.AppProject{ + otherNsProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, SourceNamespaces: []string{"argocd-2"}, }, } appServer := newTestAppServer(t, testApp, otherNsProj) appServer.enabledNamespaces = []string{"argocd-1"} - app, err := appServer.Get(t.Context(), &application.ApplicationQuery{ + app, err := appServer.Get(context.TODO(), &application.ApplicationQuery{ Name: ptr.To("test-app"), AppNamespace: ptr.To("argocd-1"), }) @@ -2821,17 +2828,17 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" - otherNsProj := &v1alpha1.AppProject{ + otherNsProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, SourceNamespaces: []string{"argocd-1"}, }, } appServer := newTestAppServer(t, otherNsProj) appServer.enabledNamespaces = []string{"argocd-1"} - app, err := appServer.Create(t.Context(), &application.ApplicationCreateRequest{ + app, err := appServer.Create(context.TODO(), &application.ApplicationCreateRequest{ Application: testApp, }) require.NoError(t, err) @@ -2845,17 +2852,17 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" - otherNsProj := &v1alpha1.AppProject{ + otherNsProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, SourceNamespaces: []string{}, }, } appServer := newTestAppServer(t, otherNsProj) appServer.enabledNamespaces = []string{"argocd-1"} - app, err := appServer.Create(t.Context(), &application.ApplicationCreateRequest{ + app, err := appServer.Create(context.TODO(), &application.ApplicationCreateRequest{ Application: testApp, }) require.Error(t, err) @@ -2868,17 +2875,17 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" - otherNsProj := &v1alpha1.AppProject{ + otherNsProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, SourceNamespaces: []string{"argocd-1"}, }, } appServer := newTestAppServer(t, otherNsProj) appServer.enabledNamespaces = []string{"argocd-2"} - app, err := appServer.Create(t.Context(), &application.ApplicationCreateRequest{ + app, err := appServer.Create(context.TODO(), &application.ApplicationCreateRequest{ Application: testApp, }) require.Error(t, err) @@ -2890,17 +2897,17 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" - otherNsProj := &v1alpha1.AppProject{ + otherNsProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, SourceNamespaces: []string{"argocd-1"}, }, } appServer := newTestAppServer(t, testApp, otherNsProj) appServer.enabledNamespaces = []string{"argocd-1"} - active, err := appServer.GetApplicationSyncWindows(t.Context(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name, AppNamespace: &testApp.Namespace}) + active, err := appServer.GetApplicationSyncWindows(context.TODO(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name, AppNamespace: &testApp.Namespace}) require.NoError(t, err) assert.Empty(t, active.ActiveWindows) }) @@ -2909,17 +2916,17 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" - otherNsProj := &v1alpha1.AppProject{ + otherNsProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, SourceNamespaces: []string{"argocd-2"}, }, } appServer := newTestAppServer(t, testApp, otherNsProj) appServer.enabledNamespaces = []string{"argocd-1"} - active, err := appServer.GetApplicationSyncWindows(t.Context(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name, AppNamespace: &testApp.Namespace}) + active, err := appServer.GetApplicationSyncWindows(context.TODO(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name, AppNamespace: &testApp.Namespace}) require.Error(t, err) require.Nil(t, active) require.ErrorContains(t, err, "app is not allowed in project") @@ -2929,17 +2936,17 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" - otherNsProj := &v1alpha1.AppProject{ + otherNsProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, SourceNamespaces: []string{"argocd-2"}, }, } appServer := newTestAppServer(t, testApp, otherNsProj) appServer.enabledNamespaces = []string{"argocd-1"} - links, err := appServer.ListLinks(t.Context(), &application.ListAppLinksRequest{ + links, err := appServer.ListLinks(context.TODO(), &application.ListAppLinksRequest{ Name: ptr.To("test-app"), Namespace: ptr.To("argocd-1"), }) @@ -2952,17 +2959,17 @@ func TestAppNamespaceRestrictions(t *testing.T) { testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" - otherNsProj := &v1alpha1.AppProject{ + otherNsProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"}, - Spec: v1alpha1.AppProjectSpec{ + Spec: appsv1.AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}, + Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, SourceNamespaces: []string{"argocd-1"}, }, } appServer := newTestAppServer(t, testApp, otherNsProj) appServer.enabledNamespaces = []string{"argocd-1"} - links, err := appServer.ListLinks(t.Context(), &application.ListAppLinksRequest{ + links, err := appServer.ListLinks(context.TODO(), &application.ListAppLinksRequest{ Name: ptr.To("test-app"), Namespace: ptr.To("argocd-1"), }) @@ -2972,9 +2979,9 @@ func TestAppNamespaceRestrictions(t *testing.T) { } func TestGetAmbiguousRevision_MultiSource(t *testing.T) { - app := &v1alpha1.Application{ - Spec: v1alpha1.ApplicationSpec{ - Sources: []v1alpha1.ApplicationSource{ + app := &appv1.Application{ + Spec: appv1.ApplicationSpec{ + Sources: []appv1.ApplicationSource{ { TargetRevision: "revision1", }, @@ -3000,8 +3007,8 @@ func TestGetAmbiguousRevision_MultiSource(t *testing.T) { assert.Equal(t, expected, result, "Expected ambiguous revision to be %s, but got %s", expected, result) // Test when app.Spec.HasMultipleSources() is false - app.Spec = v1alpha1.ApplicationSpec{ - Source: &v1alpha1.ApplicationSource{ + app.Spec = appv1.ApplicationSpec{ + Source: &appv1.ApplicationSource{ TargetRevision: "revision3", }, Sources: nil, @@ -3015,9 +3022,9 @@ func TestGetAmbiguousRevision_MultiSource(t *testing.T) { } func TestGetAmbiguousRevision_SingleSource(t *testing.T) { - app := &v1alpha1.Application{ - Spec: v1alpha1.ApplicationSpec{ - Source: &v1alpha1.ApplicationSource{ + app := &appv1.Application{ + Spec: appv1.ApplicationSpec{ + Source: &appv1.ApplicationSource{ TargetRevision: "revision1", }, }, @@ -3036,10 +3043,10 @@ func TestGetAmbiguousRevision_SingleSource(t *testing.T) { func TestServer_ResolveSourceRevisions_MultiSource(t *testing.T) { s := newTestAppServer(t) - ctx := t.Context() - a := &v1alpha1.Application{ - Spec: v1alpha1.ApplicationSpec{ - Sources: []v1alpha1.ApplicationSource{ + ctx := context.Background() + a := &appv1.Application{ + Spec: appv1.ApplicationSpec{ + Sources: []appv1.ApplicationSource{ { RepoURL: "https://github.com/example/repo.git", }, @@ -3055,8 +3062,8 @@ func TestServer_ResolveSourceRevisions_MultiSource(t *testing.T) { revision, displayRevision, sourceRevisions, displayRevisions, err := s.resolveSourceRevisions(ctx, a, syncReq) require.NoError(t, err) - assert.Empty(t, revision) - assert.Empty(t, displayRevision) + assert.Equal(t, "", revision) + assert.Equal(t, "", displayRevision) assert.Equal(t, []string{fakeResolveRevisionResponse().Revision}, sourceRevisions) assert.Equal(t, []string{fakeResolveRevisionResponse().AmbiguousRevision}, displayRevisions) } @@ -3064,10 +3071,10 @@ func TestServer_ResolveSourceRevisions_MultiSource(t *testing.T) { func TestServer_ResolveSourceRevisions_SingleSource(t *testing.T) { s := newTestAppServer(t) - ctx := t.Context() - a := &v1alpha1.Application{ - Spec: v1alpha1.ApplicationSpec{ - Source: &v1alpha1.ApplicationSource{ + ctx := context.Background() + a := &appv1.Application{ + Spec: appv1.ApplicationSpec{ + Source: &appv1.ApplicationSource{ RepoURL: "https://github.com/example/repo.git", }, }, @@ -3091,8 +3098,8 @@ func Test_RevisionMetadata(t *testing.T) { singleSourceApp := newTestApp() singleSourceApp.Name = "single-source-app" - singleSourceApp.Spec = v1alpha1.ApplicationSpec{ - Source: &v1alpha1.ApplicationSource{ + singleSourceApp.Spec = appv1.ApplicationSpec{ + Source: &appv1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", Path: "helm-guestbook", TargetRevision: "HEAD", @@ -3101,8 +3108,8 @@ func Test_RevisionMetadata(t *testing.T) { multiSourceApp := newTestApp() multiSourceApp.Name = "multi-source-app" - multiSourceApp.Spec = v1alpha1.ApplicationSpec{ - Sources: []v1alpha1.ApplicationSource{ + multiSourceApp.Spec = appv1.ApplicationSpec{ + Sources: []appv1.ApplicationSource{ { RepoURL: "https://github.com/argoproj/argocd-example-apps.git", Path: "helm-guestbook", @@ -3116,14 +3123,14 @@ func Test_RevisionMetadata(t *testing.T) { }, } - singleSourceHistory := []v1alpha1.RevisionHistory{ + singleSourceHistory := []appv1.RevisionHistory{ { ID: 1, Source: singleSourceApp.Spec.GetSource(), Revision: "a", }, } - multiSourceHistory := []v1alpha1.RevisionHistory{ + multiSourceHistory := []appv1.RevisionHistory{ { ID: 1, Sources: multiSourceApp.Spec.GetSources(), @@ -3342,7 +3349,7 @@ func Test_RevisionMetadata(t *testing.T) { VersionId: tcc.versionId, } - _, err := s.RevisionMetadata(t.Context(), request) + _, err := s.RevisionMetadata(context.Background(), request) if tcc.expectErrorContains != nil { require.ErrorContains(t, err, *tcc.expectErrorContains) } else { @@ -3357,38 +3364,38 @@ func Test_DeepCopyInformers(t *testing.T) { namespace := "test-namespace" var ro []runtime.Object - appOne := newTestApp(func(app *v1alpha1.Application) { + appOne := newTestApp(func(app *appsv1.Application) { app.Name = "appOne" - app.Namespace = namespace - app.Spec = v1alpha1.ApplicationSpec{} + app.ObjectMeta.Namespace = namespace + app.Spec = appsv1.ApplicationSpec{} }) - appTwo := newTestApp(func(app *v1alpha1.Application) { + appTwo := newTestApp(func(app *appsv1.Application) { app.Name = "appTwo" - app.Namespace = namespace - app.Spec = v1alpha1.ApplicationSpec{} + app.ObjectMeta.Namespace = namespace + app.Spec = appsv1.ApplicationSpec{} }) - appThree := newTestApp(func(app *v1alpha1.Application) { + appThree := newTestApp(func(app *appsv1.Application) { app.Name = "appThree" - app.Namespace = namespace - app.Spec = v1alpha1.ApplicationSpec{} + app.ObjectMeta.Namespace = namespace + app.Spec = appsv1.ApplicationSpec{} }) ro = append(ro, appOne, appTwo, appThree) - appls := []v1alpha1.Application{*appOne, *appTwo, *appThree} + appls := []appsv1.Application{*appOne, *appTwo, *appThree} - appSetOne := &v1alpha1.ApplicationSet{ + appSetOne := &appsv1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{Name: "appSetOne", Namespace: namespace}, - Spec: v1alpha1.ApplicationSetSpec{}, + Spec: appsv1.ApplicationSetSpec{}, } - appSetTwo := &v1alpha1.ApplicationSet{ + appSetTwo := &appsv1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{Name: "appSetTwo", Namespace: namespace}, - Spec: v1alpha1.ApplicationSetSpec{}, + Spec: appsv1.ApplicationSetSpec{}, } - appSetThree := &v1alpha1.ApplicationSet{ + appSetThree := &appsv1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{Name: "appSetThree", Namespace: namespace}, - Spec: v1alpha1.ApplicationSetSpec{}, + Spec: appsv1.ApplicationSetSpec{}, } ro = append(ro, appSetOne, appSetTwo, appSetThree) - appSets := []v1alpha1.ApplicationSet{*appSetOne, *appSetTwo, *appSetThree} + appSets := []appsv1.ApplicationSet{*appSetOne, *appSetTwo, *appSetThree} appProjects := createAppProject("projOne", "projTwo", "projThree") for i := range appProjects { @@ -3397,60 +3404,228 @@ func Test_DeepCopyInformers(t *testing.T) { s := newTestAppServer(t, ro...) - appList, err := s.appclientset.ArgoprojV1alpha1().Applications(namespace).List(t.Context(), metav1.ListOptions{}) + appList, err := s.appclientset.ArgoprojV1alpha1().Applications(namespace).List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) assert.ElementsMatch(t, appls, appList.Items) sAppList := appList.Items - slices.SortFunc(sAppList, func(a, b v1alpha1.Application) int { + slices.SortFunc(sAppList, func(a, b appsv1.Application) int { return strings.Compare(a.Name, b.Name) }) - slices.SortFunc(appls, func(a, b v1alpha1.Application) int { + slices.SortFunc(appls, func(a, b appsv1.Application) int { return strings.Compare(a.Name, b.Name) }) // ensure there is a deep copy for i := range appls { assert.NotSame(t, &appls[i], &sAppList[i]) assert.NotSame(t, &appls[i].Spec, &sAppList[i].Spec) - a, err := s.appclientset.ArgoprojV1alpha1().Applications(namespace).Get(t.Context(), sAppList[i].Name, metav1.GetOptions{}) + a, err := s.appclientset.ArgoprojV1alpha1().Applications(namespace).Get(context.Background(), sAppList[i].Name, metav1.GetOptions{}) require.NoError(t, err) assert.NotSame(t, a, &sAppList[i]) } - appSetList, err := s.appclientset.ArgoprojV1alpha1().ApplicationSets(namespace).List(t.Context(), metav1.ListOptions{}) + appSetList, err := s.appclientset.ArgoprojV1alpha1().ApplicationSets(namespace).List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) assert.ElementsMatch(t, appSets, appSetList.Items) sAppSetList := appSetList.Items - slices.SortFunc(sAppSetList, func(a, b v1alpha1.ApplicationSet) int { + slices.SortFunc(sAppSetList, func(a, b appsv1.ApplicationSet) int { return strings.Compare(a.Name, b.Name) }) - slices.SortFunc(appSets, func(a, b v1alpha1.ApplicationSet) int { + slices.SortFunc(appSets, func(a, b appsv1.ApplicationSet) int { return strings.Compare(a.Name, b.Name) }) for i := range appSets { assert.NotSame(t, &appSets[i], &sAppSetList[i]) assert.NotSame(t, &appSets[i].Spec, &sAppSetList[i].Spec) - a, err := s.appclientset.ArgoprojV1alpha1().ApplicationSets(namespace).Get(t.Context(), + a, err := s.appclientset.ArgoprojV1alpha1().ApplicationSets(namespace).Get(context.Background(), sAppSetList[i].Name, metav1.GetOptions{}) require.NoError(t, err) assert.NotSame(t, a, &sAppSetList[i]) } - projList, err := s.appclientset.ArgoprojV1alpha1().AppProjects("deep-copy-ns").List(t.Context(), metav1.ListOptions{}) + projList, err := s.appclientset.ArgoprojV1alpha1().AppProjects("deep-copy-ns").List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) assert.ElementsMatch(t, appProjects, projList.Items) spList := projList.Items - slices.SortFunc(spList, func(a, b v1alpha1.AppProject) int { + slices.SortFunc(spList, func(a, b appsv1.AppProject) int { return strings.Compare(a.Name, b.Name) }) - slices.SortFunc(appProjects, func(a, b v1alpha1.AppProject) int { + slices.SortFunc(appProjects, func(a, b appsv1.AppProject) int { return strings.Compare(a.Name, b.Name) }) for i := range appProjects { assert.NotSame(t, &appProjects[i], &spList[i]) assert.NotSame(t, &appProjects[i].Spec, &spList[i].Spec) - p, err := s.appclientset.ArgoprojV1alpha1().AppProjects("deep-copy-ns").Get(t.Context(), + p, err := s.appclientset.ArgoprojV1alpha1().AppProjects("deep-copy-ns").Get(context.Background(), spList[i].Name, metav1.GetOptions{}) require.NoError(t, err) assert.NotSame(t, p, &spList[i]) } } + +func Test_RunResourceActionDestinationInference(t *testing.T) { + t.Parallel() + deployment := k8sappsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + } + + testServer := newTestApp(func(app *appsv1.Application) { + app.ObjectMeta.Namespace = "default" + app.Name = "test-server" + app.Status.Resources = []appsv1.ResourceStatus{ + { + Group: deployment.GroupVersionKind().Group, + Kind: deployment.GroupVersionKind().Kind, + Version: deployment.GroupVersionKind().Version, + Name: deployment.Name, + Namespace: deployment.Namespace, + Status: "Synced", + }, + } + app.Status.History = []appsv1.RevisionHistory{ + { + ID: 0, + Source: appsv1.ApplicationSource{ + TargetRevision: "something-old", + }, + }, + } + app.Spec.Destination = appsv1.ApplicationDestination{ + Server: "https://cluster-api.example.com", + Namespace: "default", + Name: "", + } + }) + testName := newTestApp(func(app *appsv1.Application) { + app.ObjectMeta.Namespace = "default" + app.Name = "test-name" + app.Status.Resources = []appsv1.ResourceStatus{ + { + Group: deployment.GroupVersionKind().Group, + Kind: deployment.GroupVersionKind().Kind, + Version: deployment.GroupVersionKind().Version, + Name: deployment.Name, + Namespace: deployment.Namespace, + Status: "Synced", + }, + } + app.Status.History = []appsv1.RevisionHistory{ + { + ID: 0, + Source: appsv1.ApplicationSource{ + TargetRevision: "something-old", + }, + }, + } + app.Spec.Destination = appsv1.ApplicationDestination{ + Server: "", + Namespace: "default", + Name: "fake-cluster", + } + }) + testBoth := newTestApp(func(app *appsv1.Application) { + app.ObjectMeta.Namespace = "default" + app.Name = "test-both" + app.Status.Resources = []appsv1.ResourceStatus{ + { + Group: deployment.GroupVersionKind().Group, + Kind: deployment.GroupVersionKind().Kind, + Version: deployment.GroupVersionKind().Version, + Name: deployment.Name, + Namespace: deployment.Namespace, + Status: "Synced", + }, + } + app.Status.History = []appsv1.RevisionHistory{ + { + ID: 0, + Source: appsv1.ApplicationSource{ + TargetRevision: "something-old", + }, + }, + } + app.Spec.Destination = appsv1.ApplicationDestination{ + Server: "https://cluster-api.example.com", + Namespace: "default", + Name: "fake-cluster", + } + }) + testDeployment := kube.MustToUnstructured(&deployment) + server := newTestAppServer(t, testServer, testName, testBoth, testDeployment) + // nolint:staticcheck + adminCtx := context.WithValue(context.Background(), "claims", &jwt.MapClaims{"groups": []string{"admin"}}) + + type fields struct { + Server + } + type args struct { + q *application.ResourceActionRunRequest + } + tests := []struct { + name string + fields fields + args args + want *application.ApplicationResponse + wantErr assert.ErrorAssertionFunc + }{ + { + name: "InferServerUrl", fields: fields{*server}, args: args{ + q: &application.ResourceActionRunRequest{ + Name: ptr.To(testName.Name), + Namespace: ptr.To(testName.Namespace), + ResourceName: ptr.To(deployment.Name), + Group: ptr.To(deployment.GroupVersionKind().Group), + Kind: ptr.To(deployment.GroupVersionKind().Kind), + Version: ptr.To(deployment.GroupVersionKind().Version), + Action: ptr.To("restart"), + }, + }, + want: &application.ApplicationResponse{}, wantErr: assert.NoError, + }, + { + name: "InferName", fields: fields{*server}, args: args{ + q: &application.ResourceActionRunRequest{ + Name: ptr.To(testServer.Name), + Namespace: ptr.To(testServer.Namespace), + ResourceName: ptr.To(deployment.Name), + Group: ptr.To(deployment.GroupVersionKind().Group), + Kind: ptr.To(deployment.GroupVersionKind().Kind), + Version: ptr.To(deployment.GroupVersionKind().Version), + Action: ptr.To("restart"), + }, + }, + want: &application.ApplicationResponse{}, wantErr: assert.NoError, + }, + { + name: "ErrorOnBoth", fields: fields{*server}, args: args{ + q: &application.ResourceActionRunRequest{ + Name: ptr.To(testBoth.Name), + Namespace: ptr.To(testBoth.Namespace), + ResourceName: ptr.To(deployment.Name), + Group: ptr.To(deployment.GroupVersionKind().Group), + Kind: ptr.To(deployment.GroupVersionKind().Kind), + Version: ptr.To(deployment.GroupVersionKind().Version), + Action: ptr.To("restart"), + }, + }, + want: nil, wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return assert.ErrorContains(t, err, "application destination can't have both name and server defined") + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.fields.Server.RunResourceAction(adminCtx, tt.args.q) + if !tt.wantErr(t, err, fmt.Sprintf("RunResourceAction(%v)", tt.args.q)) { + return + } + assert.Equalf(t, tt.want, got, "RunResourceAction(%v)", tt.args.q) + }) + } +} diff --git a/server/application/broadcaster.go b/server/application/broadcaster.go index 2c29787d34..c8a562123a 100644 --- a/server/application/broadcaster.go +++ b/server/application/broadcaster.go @@ -6,8 +6,7 @@ import ( log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/watch" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - applog "github.com/argoproj/argo-cd/v3/util/app/log" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) type subscriber struct { @@ -27,9 +26,9 @@ func (s *subscriber) matches(event *appv1.ApplicationWatchEvent) bool { // Broadcaster is an interface for broadcasting application informer watch events to multiple subscribers. type Broadcaster interface { Subscribe(ch chan *appv1.ApplicationWatchEvent, filters ...func(event *appv1.ApplicationWatchEvent) bool) func() - OnAdd(any, bool) - OnUpdate(any, any) - OnDelete(any) + OnAdd(interface{}, bool) + OnUpdate(interface{}, interface{}) + OnDelete(interface{}) } type broadcasterHandler struct { @@ -51,7 +50,7 @@ func (b *broadcasterHandler) notify(event *appv1.ApplicationWatchEvent) { case s.ch <- event: default: // drop event if cannot send right away - log.WithFields(applog.GetAppLogFields(&event.Application)).Warn("unable to send event notification") + log.WithField("application", event.Application.Name).Warn("unable to send event notification") } } } @@ -77,19 +76,19 @@ func (b *broadcasterHandler) Subscribe(ch chan *appv1.ApplicationWatchEvent, fil } } -func (b *broadcasterHandler) OnAdd(obj any, _ bool) { +func (b *broadcasterHandler) OnAdd(obj interface{}, _ bool) { if app, ok := obj.(*appv1.Application); ok { b.notify(&appv1.ApplicationWatchEvent{Application: *app, Type: watch.Added}) } } -func (b *broadcasterHandler) OnUpdate(_, newObj any) { +func (b *broadcasterHandler) OnUpdate(_, newObj interface{}) { if app, ok := newObj.(*appv1.Application); ok { b.notify(&appv1.ApplicationWatchEvent{Application: *app, Type: watch.Modified}) } } -func (b *broadcasterHandler) OnDelete(obj any) { +func (b *broadcasterHandler) OnDelete(obj interface{}) { if app, ok := obj.(*appv1.Application); ok { b.notify(&appv1.ApplicationWatchEvent{Application: *app, Type: watch.Deleted}) } diff --git a/server/application/broadcaster_test.go b/server/application/broadcaster_test.go index 2c4e6b6109..32af5f60ca 100644 --- a/server/application/broadcaster_test.go +++ b/server/application/broadcaster_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestBroadcasterHandler_SubscribeUnsubscribe(t *testing.T) { diff --git a/server/application/deepinformer.go b/server/application/deepinformer.go index bceaea1db4..58638774c4 100644 --- a/server/application/deepinformer.go +++ b/server/application/deepinformer.go @@ -6,11 +6,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/rest" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - argoprojv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1" - applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + argoprojv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util" "k8s.io/apimachinery/pkg/labels" ) diff --git a/server/application/deepinformer_test.go b/server/application/deepinformer_test.go index fb317196fd..c7b1c666a4 100644 --- a/server/application/deepinformer_test.go +++ b/server/application/deepinformer_test.go @@ -1,6 +1,7 @@ package application import ( + "context" "errors" "fmt" "testing" @@ -10,10 +11,10 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/rest" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - clientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1/mocks" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + clientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1/mocks" ) func Test_deepCopyAppProjectClient_Get(t *testing.T) { @@ -40,7 +41,7 @@ func Test_deepCopyAppProjectClient_Get(t *testing.T) { fields: fields{ AppProjectInterface: func() clientset.AppProjectInterface { appProject := mocks.AppProjectInterface{} - appProject.On("Get", t.Context(), "appproject2", metav1.GetOptions{}).Return(nil, errors.New("error")) + appProject.On("Get", context.Background(), "appproject2", metav1.GetOptions{}).Return(nil, errors.New("error")) return &appProject }(), }, @@ -56,7 +57,7 @@ func Test_deepCopyAppProjectClient_Get(t *testing.T) { d := &deepCopyAppProjectClient{ AppProjectInterface: tt.fields.AppProjectInterface, } - got, err := d.Get(t.Context(), tt.args.name, metav1.GetOptions{}) + got, err := d.Get(context.Background(), tt.args.name, metav1.GetOptions{}) if !tt.wantErr(t, err, fmt.Sprintf("Get(%v)", tt.args.name)) { return } @@ -85,7 +86,7 @@ func Test_deepCopyAppProjectClient_List(t *testing.T) { {name: "Error listing app project", fields: fields{ AppProjectInterface: func() clientset.AppProjectInterface { appProject := mocks.AppProjectInterface{} - appProject.On("List", t.Context(), metav1.ListOptions{}).Return(nil, errors.New("error")) + appProject.On("List", context.Background(), metav1.ListOptions{}).Return(nil, errors.New("error")) return &appProject }(), }, want: nil, wantErr: assert.Error}, @@ -95,7 +96,7 @@ func Test_deepCopyAppProjectClient_List(t *testing.T) { d := &deepCopyAppProjectClient{ AppProjectInterface: tt.fields.AppProjectInterface, } - got, err := d.List(t.Context(), metav1.ListOptions{}) + got, err := d.List(context.Background(), metav1.ListOptions{}) if !tt.wantErr(t, err, "List") { return } diff --git a/server/application/logs_test.go b/server/application/logs_test.go index fad125b33a..7a565e37ef 100644 --- a/server/application/logs_test.go +++ b/server/application/logs_test.go @@ -76,7 +76,7 @@ func TestMergeLogStreams(t *testing.T) { assert.Equal(t, []string{"1", "2", "3", "4"}, lines) } -func TestMergeLogStreams_RaceCondition(_ *testing.T) { +func TestMergeLogStreams_RaceCondition(t *testing.T) { // Test for regression of this issue: https://github.com/argoproj/argo-cd/issues/7006 for i := 0; i < 5000; i++ { first := make(chan logEntry) diff --git a/server/application/mocks/Broadcaster.go b/server/application/mocks/Broadcaster.go index 94d64057e9..87a4867e18 100644 --- a/server/application/mocks/Broadcaster.go +++ b/server/application/mocks/Broadcaster.go @@ -1,14 +1,59 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" mock "github.com/stretchr/testify/mock" ) +// Broadcaster is an autogenerated mock type for the Broadcaster type +type Broadcaster struct { + mock.Mock +} + +// OnAdd provides a mock function with given fields: _a0, _a1 +func (_m *Broadcaster) OnAdd(_a0 interface{}, _a1 bool) { + _m.Called(_a0, _a1) +} + +// OnDelete provides a mock function with given fields: _a0 +func (_m *Broadcaster) OnDelete(_a0 interface{}) { + _m.Called(_a0) +} + +// OnUpdate provides a mock function with given fields: _a0, _a1 +func (_m *Broadcaster) OnUpdate(_a0 interface{}, _a1 interface{}) { + _m.Called(_a0, _a1) +} + +// Subscribe provides a mock function with given fields: ch, filters +func (_m *Broadcaster) Subscribe(ch chan *v1alpha1.ApplicationWatchEvent, filters ...func(*v1alpha1.ApplicationWatchEvent) bool) func() { + _va := make([]interface{}, len(filters)) + for _i := range filters { + _va[_i] = filters[_i] + } + var _ca []interface{} + _ca = append(_ca, ch) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for Subscribe") + } + + var r0 func() + if rf, ok := ret.Get(0).(func(chan *v1alpha1.ApplicationWatchEvent, ...func(*v1alpha1.ApplicationWatchEvent) bool) func()); ok { + r0 = rf(ch, filters...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(func()) + } + } + + return r0 +} + // NewBroadcaster creates a new instance of Broadcaster. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewBroadcaster(t interface { @@ -22,183 +67,3 @@ func NewBroadcaster(t interface { return mock } - -// Broadcaster is an autogenerated mock type for the Broadcaster type -type Broadcaster struct { - mock.Mock -} - -type Broadcaster_Expecter struct { - mock *mock.Mock -} - -func (_m *Broadcaster) EXPECT() *Broadcaster_Expecter { - return &Broadcaster_Expecter{mock: &_m.Mock} -} - -// OnAdd provides a mock function for the type Broadcaster -func (_mock *Broadcaster) OnAdd(v any, b bool) { - _mock.Called(v, b) - return -} - -// Broadcaster_OnAdd_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OnAdd' -type Broadcaster_OnAdd_Call struct { - *mock.Call -} - -// OnAdd is a helper method to define mock.On call -// - v -// - b -func (_e *Broadcaster_Expecter) OnAdd(v interface{}, b interface{}) *Broadcaster_OnAdd_Call { - return &Broadcaster_OnAdd_Call{Call: _e.mock.On("OnAdd", v, b)} -} - -func (_c *Broadcaster_OnAdd_Call) Run(run func(v any, b bool)) *Broadcaster_OnAdd_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(any), args[1].(bool)) - }) - return _c -} - -func (_c *Broadcaster_OnAdd_Call) Return() *Broadcaster_OnAdd_Call { - _c.Call.Return() - return _c -} - -func (_c *Broadcaster_OnAdd_Call) RunAndReturn(run func(v any, b bool)) *Broadcaster_OnAdd_Call { - _c.Run(run) - return _c -} - -// OnDelete provides a mock function for the type Broadcaster -func (_mock *Broadcaster) OnDelete(v any) { - _mock.Called(v) - return -} - -// Broadcaster_OnDelete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OnDelete' -type Broadcaster_OnDelete_Call struct { - *mock.Call -} - -// OnDelete is a helper method to define mock.On call -// - v -func (_e *Broadcaster_Expecter) OnDelete(v interface{}) *Broadcaster_OnDelete_Call { - return &Broadcaster_OnDelete_Call{Call: _e.mock.On("OnDelete", v)} -} - -func (_c *Broadcaster_OnDelete_Call) Run(run func(v any)) *Broadcaster_OnDelete_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(any)) - }) - return _c -} - -func (_c *Broadcaster_OnDelete_Call) Return() *Broadcaster_OnDelete_Call { - _c.Call.Return() - return _c -} - -func (_c *Broadcaster_OnDelete_Call) RunAndReturn(run func(v any)) *Broadcaster_OnDelete_Call { - _c.Run(run) - return _c -} - -// OnUpdate provides a mock function for the type Broadcaster -func (_mock *Broadcaster) OnUpdate(v any, v1 any) { - _mock.Called(v, v1) - return -} - -// Broadcaster_OnUpdate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OnUpdate' -type Broadcaster_OnUpdate_Call struct { - *mock.Call -} - -// OnUpdate is a helper method to define mock.On call -// - v -// - v1 -func (_e *Broadcaster_Expecter) OnUpdate(v interface{}, v1 interface{}) *Broadcaster_OnUpdate_Call { - return &Broadcaster_OnUpdate_Call{Call: _e.mock.On("OnUpdate", v, v1)} -} - -func (_c *Broadcaster_OnUpdate_Call) Run(run func(v any, v1 any)) *Broadcaster_OnUpdate_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(any), args[1].(any)) - }) - return _c -} - -func (_c *Broadcaster_OnUpdate_Call) Return() *Broadcaster_OnUpdate_Call { - _c.Call.Return() - return _c -} - -func (_c *Broadcaster_OnUpdate_Call) RunAndReturn(run func(v any, v1 any)) *Broadcaster_OnUpdate_Call { - _c.Run(run) - return _c -} - -// Subscribe provides a mock function for the type Broadcaster -func (_mock *Broadcaster) Subscribe(ch chan *v1alpha1.ApplicationWatchEvent, filters ...func(event *v1alpha1.ApplicationWatchEvent) bool) func() { - // func(event *v1alpha1.ApplicationWatchEvent) bool - _va := make([]interface{}, len(filters)) - for _i := range filters { - _va[_i] = filters[_i] - } - var _ca []interface{} - _ca = append(_ca, ch) - _ca = append(_ca, _va...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for Subscribe") - } - - var r0 func() - if returnFunc, ok := ret.Get(0).(func(chan *v1alpha1.ApplicationWatchEvent, ...func(event *v1alpha1.ApplicationWatchEvent) bool) func()); ok { - r0 = returnFunc(ch, filters...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(func()) - } - } - return r0 -} - -// Broadcaster_Subscribe_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Subscribe' -type Broadcaster_Subscribe_Call struct { - *mock.Call -} - -// Subscribe is a helper method to define mock.On call -// - ch -// - filters -func (_e *Broadcaster_Expecter) Subscribe(ch interface{}, filters ...interface{}) *Broadcaster_Subscribe_Call { - return &Broadcaster_Subscribe_Call{Call: _e.mock.On("Subscribe", - append([]interface{}{ch}, filters...)...)} -} - -func (_c *Broadcaster_Subscribe_Call) Run(run func(ch chan *v1alpha1.ApplicationWatchEvent, filters ...func(event *v1alpha1.ApplicationWatchEvent) bool)) *Broadcaster_Subscribe_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]func(event *v1alpha1.ApplicationWatchEvent) bool, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(func(event *v1alpha1.ApplicationWatchEvent) bool) - } - } - run(args[0].(chan *v1alpha1.ApplicationWatchEvent), variadicArgs...) - }) - return _c -} - -func (_c *Broadcaster_Subscribe_Call) Return(fn func()) *Broadcaster_Subscribe_Call { - _c.Call.Return(fn) - return _c -} - -func (_c *Broadcaster_Subscribe_Call) RunAndReturn(run func(ch chan *v1alpha1.ApplicationWatchEvent, filters ...func(event *v1alpha1.ApplicationWatchEvent) bool) func()) *Broadcaster_Subscribe_Call { - _c.Call.Return(run) - return _c -} diff --git a/server/application/terminal.go b/server/application/terminal.go index c42c180850..59aa90acae 100644 --- a/server/application/terminal.go +++ b/server/application/terminal.go @@ -11,22 +11,22 @@ import ( corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "k8s.io/client-go/tools/remotecommand" - cmdutil "k8s.io/kubectl/pkg/cmd/util" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - servercache "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/rbac" - "github.com/argoproj/argo-cd/v3/util/security" - util_session "github.com/argoproj/argo-cd/v3/util/session" - "github.com/argoproj/argo-cd/v3/util/settings" + util_session "github.com/argoproj/argo-cd/v2/util/session" + + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/rbac" + "github.com/argoproj/argo-cd/v2/util/security" + sessionmgr "github.com/argoproj/argo-cd/v2/util/session" + "github.com/argoproj/argo-cd/v2/util/settings" ) type terminalHandler struct { @@ -47,7 +47,7 @@ type TerminalOptions struct { } // NewHandler returns a new terminal handler. -func NewHandler(appLister applisters.ApplicationLister, namespace string, enabledNamespaces []string, db db.ArgoDB, cache *servercache.Cache, appResourceTree AppResourceTreeFn, allowedShells []string, sessionManager *util_session.SessionManager, terminalOptions *TerminalOptions) *terminalHandler { +func NewHandler(appLister applisters.ApplicationLister, namespace string, enabledNamespaces []string, db db.ArgoDB, cache *servercache.Cache, appResourceTree AppResourceTreeFn, allowedShells []string, sessionManager *sessionmgr.SessionManager, terminalOptions *TerminalOptions) *terminalHandler { return &terminalHandler{ appLister: appLister, db: db, @@ -62,11 +62,14 @@ func NewHandler(appLister applisters.ApplicationLister, namespace string, enable } func (s *terminalHandler) getApplicationClusterRawConfig(ctx context.Context, a *appv1.Application) (*rest.Config, error) { - destCluster, err := argo.GetDestinationCluster(ctx, a.Spec.Destination, s.db) + if err := argo.ValidateDestination(ctx, &a.Spec.Destination, s.db); err != nil { + return nil, err + } + clst, err := s.db.GetCluster(ctx, a.Spec.Destination.Server) if err != nil { return nil, err } - rawConfig, err := destCluster.RawRestConfig() + rawConfig, err := clst.RawRestConfig() if err != nil { return nil, err } @@ -160,7 +163,7 @@ func (s *terminalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } fieldLog := log.WithFields(log.Fields{ - "application": app, "userName": util_session.Username(ctx), "container": container, + "application": app, "userName": sessionmgr.Username(ctx), "container": container, "podName": podName, "namespace": namespace, "project": project, "appNamespace": appNamespace, }) @@ -319,19 +322,6 @@ func startProcess(k8sClient kubernetes.Interface, cfg *rest.Config, namespace, p return err } - // Fallback executor is default, unless feature flag is explicitly disabled. - // Reuse environment variable for kubectl to disable the feature flag, default is enabled. - if !cmdutil.RemoteCommandWebsockets.IsDisabled() { - // WebSocketExecutor must be "GET" method as described in RFC 6455 Sec. 4.1 (page 17). - websocketExec, err := remotecommand.NewWebSocketExecutor(cfg, "GET", req.URL().String()) - if err != nil { - return err - } - exec, err = remotecommand.NewFallbackExecutor(websocketExec, exec, httpstream.IsUpgradeFailure) - if err != nil { - return err - } - } return exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ Stdin: ptyHandler, Stdout: ptyHandler, diff --git a/server/application/terminal_test.go b/server/application/terminal_test.go index e571194d97..fb55dd478f 100644 --- a/server/application/terminal_test.go +++ b/server/application/terminal_test.go @@ -9,9 +9,9 @@ import ( "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/stretchr/testify/assert" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/security" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/security" ) func TestPodExists(t *testing.T) { diff --git a/server/application/websocket.go b/server/application/websocket.go index 346f0555bf..33edcb9a3a 100644 --- a/server/application/websocket.go +++ b/server/application/websocket.go @@ -8,10 +8,10 @@ import ( "sync" "time" - "github.com/argoproj/argo-cd/v3/common" - httputil "github.com/argoproj/argo-cd/v3/util/http" - "github.com/argoproj/argo-cd/v3/util/rbac" - util_session "github.com/argoproj/argo-cd/v3/util/session" + "github.com/argoproj/argo-cd/v2/common" + httputil "github.com/argoproj/argo-cd/v2/util/http" + "github.com/argoproj/argo-cd/v2/util/rbac" + util_session "github.com/argoproj/argo-cd/v2/util/session" "github.com/gorilla/websocket" log "github.com/sirupsen/logrus" @@ -144,7 +144,7 @@ func (t *terminalSession) validatePermissions(p []byte) (int, error) { if err != nil { log.Errorf("permission denied message err: %v", err) } - return copy(p, EndOfTransmission), common.PermissionDeniedAPIError + return copy(p, EndOfTransmission), permissionDeniedErr } if err := t.terminalOpts.Enf.EnforceErr(t.ctx.Value("claims"), rbac.ResourceExec, rbac.ActionCreate, t.appRBACName); err != nil { @@ -152,7 +152,7 @@ func (t *terminalSession) validatePermissions(p []byte) (int, error) { if err != nil { log.Errorf("permission denied message err: %v", err) } - return copy(p, EndOfTransmission), common.PermissionDeniedAPIError + return copy(p, EndOfTransmission), permissionDeniedErr } return 0, nil } @@ -189,11 +189,7 @@ func (t *terminalSession) Read(p []byte) (int, error) { _, message, err := t.wsConn.ReadMessage() t.readLock.Unlock() if err != nil { - if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) { - log.Errorf("unexpected closer error: %v", err) - return copy(p, EndOfTransmission), err - } - log.Errorf("read message error: %v", err) + log.Errorf("read message err: %v", err) return copy(p, EndOfTransmission), err } var msg TerminalMessage diff --git a/server/application/websocket_test.go b/server/application/websocket_test.go index 6aeed8a44c..25ff759f32 100644 --- a/server/application/websocket_test.go +++ b/server/application/websocket_test.go @@ -8,15 +8,15 @@ import ( "strings" "testing" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/assets" - "github.com/argoproj/argo-cd/v3/util/rbac" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/assets" + "github.com/argoproj/argo-cd/v2/util/rbac" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" "github.com/gorilla/websocket" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -34,7 +34,7 @@ func newTestTerminalSession(w http.ResponseWriter, r *http.Request) terminalSess func newEnforcer() *rbac.Enforcer { additionalConfig := make(map[string]string, 0) - kubeclientset := fake.NewClientset(&corev1.ConfigMap{ + kubeclientset := fake.NewClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-cm", @@ -43,7 +43,7 @@ func newEnforcer() *rbac.Enforcer { }, }, Data: additionalConfig, - }, &corev1.Secret{ + }, &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: testNamespace, @@ -130,14 +130,14 @@ func TestValidateWithAdminPermissions(t *testing.T) { enf := newEnforcer() _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) enf.SetDefaultRole("role:admin") - enf.SetClaimsEnforcerFunc(func(_ jwt.Claims, _ ...any) bool { + enf.SetClaimsEnforcerFunc(func(claims jwt.Claims, rvals ...interface{}) bool { return true }) ts := newTestTerminalSession(w, r) ts.terminalOpts = &TerminalOptions{Enf: enf} ts.appRBACName = "test" - //nolint:staticcheck - ts.ctx = context.WithValue(t.Context(), "claims", &jwt.MapClaims{"groups": []string{"admin"}}) + // nolint:staticcheck + ts.ctx = context.WithValue(context.Background(), "claims", &jwt.MapClaims{"groups": []string{"admin"}}) _, err := ts.validatePermissions([]byte{}) require.NoError(t, err) } @@ -150,65 +150,18 @@ func TestValidateWithoutPermissions(t *testing.T) { enf := newEnforcer() _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) enf.SetDefaultRole("role:test") - enf.SetClaimsEnforcerFunc(func(_ jwt.Claims, _ ...any) bool { + enf.SetClaimsEnforcerFunc(func(claims jwt.Claims, rvals ...interface{}) bool { return false }) ts := newTestTerminalSession(w, r) ts.terminalOpts = &TerminalOptions{Enf: enf} ts.appRBACName = "test" - //nolint:staticcheck - ts.ctx = context.WithValue(t.Context(), "claims", &jwt.MapClaims{"groups": []string{"test"}}) + // nolint:staticcheck + ts.ctx = context.WithValue(context.Background(), "claims", &jwt.MapClaims{"groups": []string{"test"}}) _, err := ts.validatePermissions([]byte{}) require.Error(t, err) - assert.EqualError(t, err, common.PermissionDeniedAPIError.Error()) + assert.EqualError(t, err, permissionDeniedErr.Error()) } testServerConnection(t, validate, true) } - -func TestTerminalSession_Write(t *testing.T) { - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - upgrader := websocket.Upgrader{} - conn, err := upgrader.Upgrade(w, r, nil) - require.NoError(t, err) - defer conn.Close() - - for { - // Read the message from the WebSocket connection - messageType, message, err := conn.ReadMessage() - if err != nil { - return - } - // Respond back the same message - err = conn.WriteMessage(messageType, message) - require.NoError(t, err) - } - })) - defer server.Close() - - u := "ws" + strings.TrimPrefix(server.URL, "http") - wsConn, _, err := websocket.DefaultDialer.Dial(u, nil) - require.NoError(t, err) - defer wsConn.Close() - - ts := terminalSession{ - wsConn: wsConn, - } - - testData := []byte("hello world") - expectedMessage, err := json.Marshal(TerminalMessage{ - Operation: "stdout", - Data: string(testData), - }) - require.NoError(t, err) - - n, err := ts.Write(testData) - require.NoError(t, err) - - assert.Equal(t, len(testData), n) - - _, receivedMessage, err := wsConn.ReadMessage() - require.NoError(t, err) - - assert.Equal(t, expectedMessage, receivedMessage) -} diff --git a/server/applicationset/applicationset.go b/server/applicationset/applicationset.go index dbf4410d53..9d4f627a79 100644 --- a/server/applicationset/applicationset.go +++ b/server/applicationset/applicationset.go @@ -11,7 +11,7 @@ import ( "strings" "time" - "github.com/argoproj/pkg/v2/sync" + "github.com/argoproj/pkg/sync" log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -24,24 +24,24 @@ import ( "k8s.io/client-go/tools/cache" "sigs.k8s.io/controller-runtime/pkg/client" - appsettemplate "github.com/argoproj/argo-cd/v3/applicationset/controllers/template" - "github.com/argoproj/argo-cd/v3/applicationset/generators" - "github.com/argoproj/argo-cd/v3/applicationset/services" - appsetstatus "github.com/argoproj/argo-cd/v3/applicationset/status" - appsetutils "github.com/argoproj/argo-cd/v3/applicationset/utils" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/applicationset" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - repoapiclient "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/collections" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/github_app" - "github.com/argoproj/argo-cd/v3/util/rbac" - "github.com/argoproj/argo-cd/v3/util/security" - "github.com/argoproj/argo-cd/v3/util/session" - "github.com/argoproj/argo-cd/v3/util/settings" + appsettemplate "github.com/argoproj/argo-cd/v2/applicationset/controllers/template" + "github.com/argoproj/argo-cd/v2/applicationset/generators" + "github.com/argoproj/argo-cd/v2/applicationset/services" + appsetstatus "github.com/argoproj/argo-cd/v2/applicationset/status" + appsetutils "github.com/argoproj/argo-cd/v2/applicationset/utils" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/applicationset" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + repoapiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/collections" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/github_app" + "github.com/argoproj/argo-cd/v2/util/rbac" + "github.com/argoproj/argo-cd/v2/util/security" + "github.com/argoproj/argo-cd/v2/util/session" + "github.com/argoproj/argo-cd/v2/util/settings" ) type Server struct { @@ -224,7 +224,7 @@ func (s *Server) Create(ctx context.Context, q *applicationset.ApplicationSetCre created, err := s.appclientset.ArgoprojV1alpha1().ApplicationSets(namespace).Create(ctx, appset, metav1.CreateOptions{}) if err == nil { - s.logAppSetEvent(ctx, created, argo.EventReasonResourceCreated, "created ApplicationSet") + s.logAppSetEvent(created, ctx, argo.EventReasonResourceCreated, "created ApplicationSet") s.waitSync(created) return created, nil } @@ -255,7 +255,7 @@ func (s *Server) Create(ctx context.Context, q *applicationset.ApplicationSetCre if err = s.enf.EnforceErr(ctx.Value("claims"), rbac.ResourceApplicationSets, rbac.ActionUpdate, appset.RBACName(s.ns)); err != nil { return nil, err } - updated, err := s.updateAppSet(ctx, existing, appset, true) + updated, err := s.updateAppSet(existing, appset, ctx, true) if err != nil { return nil, fmt.Errorf("error updating ApplicationSets: %w", err) } @@ -266,7 +266,15 @@ func (s *Server) generateApplicationSetApps(ctx context.Context, logEntry *log.E argoCDDB := s.db scmConfig := generators.NewSCMConfig(s.ScmRootCAPath, s.AllowedScmProviders, s.EnableScmProviders, github_app.NewAuthCredentials(argoCDDB.(db.RepoCredsDB)), true) - argoCDService := services.NewArgoCDService(s.db, s.GitSubmoduleEnabled, s.repoClientSet, s.EnableNewGitFileGlobbing) + + getRepository := func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { + return s.db.GetRepository(ctx, url, project) + } + argoCDService, err := services.NewArgoCDService(getRepository, s.GitSubmoduleEnabled, s.repoClientSet, s.EnableNewGitFileGlobbing) + if err != nil { + return nil, fmt.Errorf("error creating ArgoCDService: %w", err) + } + appSetGenerators := generators.GetGenerators(ctx, s.client, s.k8sClient, namespace, argoCDService, s.dynamicClient, scmConfig) apps, _, err := appsettemplate.GenerateApplications(logEntry, appset, appSetGenerators, &appsetutils.Render{}, s.client) @@ -276,7 +284,7 @@ func (s *Server) generateApplicationSetApps(ctx context.Context, logEntry *log.E return apps, nil } -func (s *Server) updateAppSet(ctx context.Context, appset *v1alpha1.ApplicationSet, newAppset *v1alpha1.ApplicationSet, merge bool) (*v1alpha1.ApplicationSet, error) { +func (s *Server) updateAppSet(appset *v1alpha1.ApplicationSet, newAppset *v1alpha1.ApplicationSet, ctx context.Context, merge bool) (*v1alpha1.ApplicationSet, error) { if appset != nil && appset.Spec.Template.Spec.Project != newAppset.Spec.Template.Spec.Project { // When changing projects, caller must have applicationset create and update privileges in new project // NOTE: the update check was already verified in the caller to this function @@ -301,7 +309,7 @@ func (s *Server) updateAppSet(ctx context.Context, appset *v1alpha1.ApplicationS res, err := s.appclientset.ArgoprojV1alpha1().ApplicationSets(s.ns).Update(ctx, appset, metav1.UpdateOptions{}) if err == nil { - s.logAppSetEvent(ctx, appset, argo.EventReasonResourceUpdated, "updated ApplicationSets spec") + s.logAppSetEvent(appset, ctx, argo.EventReasonResourceUpdated, "updated ApplicationSets spec") s.waitSync(res) return res, nil } @@ -336,7 +344,7 @@ func (s *Server) Delete(ctx context.Context, q *applicationset.ApplicationSetDel if err != nil { return nil, fmt.Errorf("error deleting ApplicationSets: %w", err) } - s.logAppSetEvent(ctx, appset, argo.EventReasonResourceDeleted, "deleted ApplicationSets") + s.logAppSetEvent(appset, ctx, argo.EventReasonResourceDeleted, "deleted ApplicationSets") return &applicationset.ApplicationSetResponse{}, nil } @@ -486,7 +494,7 @@ func (s *Server) waitSync(appset *v1alpha1.ApplicationSet) { logCtx.Warnf("waitSync failed: timed out") } -func (s *Server) logAppSetEvent(ctx context.Context, a *v1alpha1.ApplicationSet, reason string, action string) { +func (s *Server) logAppSetEvent(a *v1alpha1.ApplicationSet, ctx context.Context, reason string, action string) { eventInfo := argo.EventInfo{Type: corev1.EventTypeNormal, Reason: reason} user := session.Username(ctx) if user == "" { diff --git a/server/applicationset/applicationset.proto b/server/applicationset/applicationset.proto index 87881e0d3b..8d1cb74a76 100644 --- a/server/applicationset/applicationset.proto +++ b/server/applicationset/applicationset.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/applicationset"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/applicationset"; // ApplicationSet Service @@ -8,7 +8,7 @@ option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/applicationset package applicationset; import "google/api/annotations.proto"; -import "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto"; +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; // ApplicationSetGetQuery is a query for applicationset resources message ApplicationSetGetQuery { @@ -30,12 +30,12 @@ message ApplicationSetListQuery { message ApplicationSetResponse { string project = 1; - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSet applicationset = 2; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSet applicationset = 2; } message ApplicationSetCreateRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSet applicationset = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSet applicationset = 1; bool upsert = 2; bool dryRun = 3; } @@ -56,18 +56,18 @@ message ApplicationSetTreeQuery { // ApplicationSetGetQuery is a query for applicationset resources message ApplicationSetGenerateRequest { // the applicationsets - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSet applicationSet = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSet applicationSet = 1; } // ApplicationSetGenerateResponse is a response for applicationset generate request message ApplicationSetGenerateResponse { - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Application applications = 1; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application applications = 1; } // ApplicationSetService service ApplicationSetService { // Get returns an applicationset by name - rpc Get (ApplicationSetGetQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSet) { + rpc Get (ApplicationSetGetQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSet) { option (google.api.http).get = "/api/v1/applicationsets/{name}"; } @@ -80,12 +80,12 @@ service ApplicationSetService { } //List returns list of applicationset - rpc List (ApplicationSetListQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetList) { + rpc List (ApplicationSetListQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetList) { option (google.api.http).get = "/api/v1/applicationsets"; } //Create creates an applicationset - rpc Create (ApplicationSetCreateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSet) { + rpc Create (ApplicationSetCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSet) { option (google.api.http) = { post: "/api/v1/applicationsets" body: "applicationset" @@ -98,7 +98,7 @@ service ApplicationSetService { } // ResourceTree returns resource tree - rpc ResourceTree(ApplicationSetTreeQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSetTree) { + rpc ResourceTree(ApplicationSetTreeQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetTree) { option (google.api.http).get = "/api/v1/applicationsets/{name}/resource-tree"; } diff --git a/server/applicationset/applicationset_test.go b/server/applicationset/applicationset_test.go index 46838f3ed3..8f16d415de 100644 --- a/server/applicationset/applicationset_test.go +++ b/server/applicationset/applicationset_test.go @@ -1,31 +1,33 @@ package applicationset import ( + "context" "sort" "testing" "github.com/argoproj/gitops-engine/pkg/health" - "github.com/argoproj/pkg/v2/sync" + "github.com/argoproj/pkg/sync" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/fake" k8scache "k8s.io/client-go/tools/cache" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/applicationset" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - apps "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - appinformer "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions" - "github.com/argoproj/argo-cd/v3/server/rbacpolicy" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/assets" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/rbac" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/applicationset" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + 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" + "github.com/argoproj/argo-cd/v2/util/rbac" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( @@ -50,30 +52,27 @@ func fakeCluster() *appsv1.Cluster { } // return an ApplicationServiceServer which returns fake data -func newTestAppSetServer(t *testing.T, objects ...runtime.Object) *Server { - t.Helper() +func newTestAppSetServer(objects ...runtime.Object) *Server { f := func(enf *rbac.Enforcer) { _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) enf.SetDefaultRole("role:admin") } scopedNamespaces := "" - return newTestAppSetServerWithEnforcerConfigure(t, f, scopedNamespaces, objects...) + return newTestAppSetServerWithEnforcerConfigure(f, scopedNamespaces, objects...) } // return an ApplicationServiceServer which returns fake data -func newTestNamespacedAppSetServer(t *testing.T, objects ...runtime.Object) *Server { - t.Helper() +func newTestNamespacedAppSetServer(objects ...runtime.Object) *Server { f := func(enf *rbac.Enforcer) { _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) enf.SetDefaultRole("role:admin") } scopedNamespaces := "argocd" - return newTestAppSetServerWithEnforcerConfigure(t, f, scopedNamespaces, objects...) + return newTestAppSetServerWithEnforcerConfigure(f, scopedNamespaces, objects...) } -func newTestAppSetServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforcer), namespace string, objects ...runtime.Object) *Server { - t.Helper() - kubeclientset := fake.NewClientset(&corev1.ConfigMap{ +func newTestAppSetServerWithEnforcerConfigure(f func(*rbac.Enforcer), namespace string, objects ...runtime.Object) *Server { + kubeclientset := fake.NewClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-cm", @@ -81,7 +80,7 @@ func newTestAppSetServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforce "app.kubernetes.io/part-of": "argocd", }, }, - }, &corev1.Secret{ + }, &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: testNamespace, @@ -91,12 +90,12 @@ func newTestAppSetServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforce "server.secretkey": []byte("test"), }, }) - ctx := t.Context() + ctx := context.Background() db := db.NewDB(testNamespace, settings.NewSettingsManager(ctx, kubeclientset, testNamespace), kubeclientset) _, err := db.CreateRepository(ctx, fakeRepo()) - require.NoError(t, err) + errors.CheckError(err) _, err = db.CreateCluster(ctx, fakeCluster()) - require.NoError(t, err) + errors.CheckError(err) defaultProj := &appsv1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "default"}, @@ -116,7 +115,7 @@ func newTestAppSetServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforce objects = append(objects, defaultProj, myProj) fakeAppsClientset := apps.NewSimpleClientset(objects...) - factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, appinformer.WithNamespace(namespace), appinformer.WithTweakListOptions(func(_ *metav1.ListOptions) {})) + factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, appinformer.WithNamespace(namespace), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) fakeProjLister := factory.Argoproj().V1alpha1().AppProjects().Lister().AppProjects(testNamespace) enforcer := rbac.NewEnforcer(kubeclientset, testNamespace, common.ArgoCDRBACConfigMapName, nil) @@ -237,7 +236,7 @@ func testListAppsetsWithLabels(t *testing.T, appsetQuery applicationset.Applicat for _, validTest := range validTests { t.Run(validTest.testName, func(t *testing.T) { appsetQuery.Selector = validTest.label - res, err := appServer.List(t.Context(), &appsetQuery) + res, err := appServer.List(context.Background(), &appsetQuery) require.NoError(t, err) apps := []string{} for i := range res.Items { @@ -267,7 +266,7 @@ func testListAppsetsWithLabels(t *testing.T, appsetQuery applicationset.Applicat for _, invalidTest := range invalidTests { t.Run(invalidTest.testName, func(t *testing.T) { appsetQuery.Selector = invalidTest.label - _, err := appServer.List(t.Context(), &appsetQuery) + _, err := appServer.List(context.Background(), &appsetQuery) assert.ErrorContains(t, err, invalidTest.errorMesage) }) } @@ -275,17 +274,17 @@ func testListAppsetsWithLabels(t *testing.T, appsetQuery applicationset.Applicat func TestListAppSetsInNamespaceWithLabels(t *testing.T) { testNamespace := "test-namespace" - appSetServer := newTestAppSetServer(t, newTestAppSet(func(appset *appsv1.ApplicationSet) { + appSetServer := newTestAppSetServer(newTestAppSet(func(appset *appsv1.ApplicationSet) { appset.Name = "AppSet1" - appset.Namespace = testNamespace + appset.ObjectMeta.Namespace = testNamespace appset.SetLabels(map[string]string{"key1": "value1", "key2": "value1"}) }), newTestAppSet(func(appset *appsv1.ApplicationSet) { appset.Name = "AppSet2" - appset.Namespace = testNamespace + appset.ObjectMeta.Namespace = testNamespace appset.SetLabels(map[string]string{"key1": "value2"}) }), newTestAppSet(func(appset *appsv1.ApplicationSet) { appset.Name = "AppSet3" - appset.Namespace = testNamespace + appset.ObjectMeta.Namespace = testNamespace appset.SetLabels(map[string]string{"key1": "value3"}) })) appSetServer.enabledNamespaces = []string{testNamespace} @@ -295,7 +294,7 @@ func TestListAppSetsInNamespaceWithLabels(t *testing.T) { } func TestListAppSetsInDefaultNSWithLabels(t *testing.T) { - appSetServer := newTestAppSetServer(t, newTestAppSet(func(appset *appsv1.ApplicationSet) { + appSetServer := newTestAppSetServer(newTestAppSet(func(appset *appsv1.ApplicationSet) { appset.Name = "AppSet1" appset.SetLabels(map[string]string{"key1": "value1", "key2": "value1"}) }), newTestAppSet(func(appset *appsv1.ApplicationSet) { @@ -315,30 +314,30 @@ func TestListAppSetsInDefaultNSWithLabels(t *testing.T) { // default namespace must be used and not all the namespaces func TestListAppSetsWithoutNamespace(t *testing.T) { testNamespace := "test-namespace" - appSetServer := newTestNamespacedAppSetServer(t, newTestAppSet(func(appset *appsv1.ApplicationSet) { + appSetServer := newTestNamespacedAppSetServer(newTestAppSet(func(appset *appsv1.ApplicationSet) { appset.Name = "AppSet1" - appset.Namespace = testNamespace + appset.ObjectMeta.Namespace = testNamespace appset.SetLabels(map[string]string{"key1": "value1", "key2": "value1"}) }), newTestAppSet(func(appset *appsv1.ApplicationSet) { appset.Name = "AppSet2" - appset.Namespace = testNamespace + appset.ObjectMeta.Namespace = testNamespace appset.SetLabels(map[string]string{"key1": "value2"}) }), newTestAppSet(func(appset *appsv1.ApplicationSet) { appset.Name = "AppSet3" - appset.Namespace = testNamespace + appset.ObjectMeta.Namespace = testNamespace appset.SetLabels(map[string]string{"key1": "value3"}) })) appSetServer.enabledNamespaces = []string{testNamespace} appsetQuery := applicationset.ApplicationSetListQuery{} - res, err := appSetServer.List(t.Context(), &appsetQuery) + res, err := appSetServer.List(context.Background(), &appsetQuery) require.NoError(t, err) assert.Empty(t, res.Items) } func TestCreateAppSet(t *testing.T) { testAppSet := newTestAppSet() - appServer := newTestAppSetServer(t) + appServer := newTestAppSetServer() testAppSet.Spec.Generators = []appsv1.ApplicationSetGenerator{ { List: &appsv1.ListGenerator{}, @@ -347,36 +346,36 @@ func TestCreateAppSet(t *testing.T) { createReq := applicationset.ApplicationSetCreateRequest{ Applicationset: testAppSet, } - _, err := appServer.Create(t.Context(), &createReq) + _, err := appServer.Create(context.Background(), &createReq) require.NoError(t, err) } func TestCreateAppSetTemplatedProject(t *testing.T) { testAppSet := newTestAppSet() - appServer := newTestAppSetServer(t) + appServer := newTestAppSetServer() testAppSet.Spec.Template.Spec.Project = "{{ .project }}" createReq := applicationset.ApplicationSetCreateRequest{ Applicationset: testAppSet, } - _, err := appServer.Create(t.Context(), &createReq) + _, err := appServer.Create(context.Background(), &createReq) assert.EqualError(t, err, "error validating ApplicationSets: the Argo CD API does not currently support creating ApplicationSets with templated `project` fields") } func TestCreateAppSetWrongNamespace(t *testing.T) { testAppSet := newTestAppSet() - appServer := newTestAppSetServer(t) - testAppSet.Namespace = "NOT-ALLOWED" + appServer := newTestAppSetServer() + testAppSet.ObjectMeta.Namespace = "NOT-ALLOWED" createReq := applicationset.ApplicationSetCreateRequest{ Applicationset: testAppSet, } - _, err := appServer.Create(t.Context(), &createReq) + _, err := appServer.Create(context.Background(), &createReq) assert.EqualError(t, err, "namespace 'NOT-ALLOWED' is not permitted") } func TestCreateAppSetDryRun(t *testing.T) { testAppSet := newTestAppSet() - appServer := newTestAppSetServer(t) + appServer := newTestAppSetServer() testAppSet.Spec.Template.Name = "{{name}}" testAppSet.Spec.Generators = []appsv1.ApplicationSetGenerator{ { @@ -389,7 +388,7 @@ func TestCreateAppSetDryRun(t *testing.T) { Applicationset: testAppSet, DryRun: true, } - result, err := appServer.Create(t.Context(), &createReq) + result, err := appServer.Create(context.Background(), &createReq) require.NoError(t, err) assert.Len(t, result.Status.Resources, 2) @@ -407,7 +406,7 @@ func TestCreateAppSetDryRun(t *testing.T) { func TestCreateAppSetDryRunWithDuplicate(t *testing.T) { testAppSet := newTestAppSet() - appServer := newTestAppSetServer(t) + appServer := newTestAppSetServer() testAppSet.Spec.Template.Name = "{{name}}" testAppSet.Spec.Generators = []appsv1.ApplicationSetGenerator{ { @@ -420,7 +419,7 @@ func TestCreateAppSetDryRunWithDuplicate(t *testing.T) { Applicationset: testAppSet, DryRun: true, } - result, err := appServer.Create(t.Context(), &createReq) + result, err := appServer.Create(context.Background(), &createReq) require.NoError(t, err) assert.Len(t, result.Status.Resources, 1) @@ -442,31 +441,31 @@ func TestGetAppSet(t *testing.T) { }) t.Run("Get in default namespace", func(t *testing.T) { - appSetServer := newTestAppSetServer(t, appSet1, appSet2, appSet3) + appSetServer := newTestAppSetServer(appSet1, appSet2, appSet3) appsetQuery := applicationset.ApplicationSetGetQuery{Name: "AppSet1"} - res, err := appSetServer.Get(t.Context(), &appsetQuery) + res, err := appSetServer.Get(context.Background(), &appsetQuery) require.NoError(t, err) assert.Equal(t, "AppSet1", res.Name) }) t.Run("Get in named namespace", func(t *testing.T) { - appSetServer := newTestAppSetServer(t, appSet1, appSet2, appSet3) + appSetServer := newTestAppSetServer(appSet1, appSet2, appSet3) appsetQuery := applicationset.ApplicationSetGetQuery{Name: "AppSet1", AppsetNamespace: testNamespace} - res, err := appSetServer.Get(t.Context(), &appsetQuery) + res, err := appSetServer.Get(context.Background(), &appsetQuery) require.NoError(t, err) assert.Equal(t, "AppSet1", res.Name) }) t.Run("Get in not allowed namespace", func(t *testing.T) { - appSetServer := newTestAppSetServer(t, appSet1, appSet2, appSet3) + appSetServer := newTestAppSetServer(appSet1, appSet2, appSet3) appsetQuery := applicationset.ApplicationSetGetQuery{Name: "AppSet1", AppsetNamespace: "NOT-ALLOWED"} - _, err := appSetServer.Get(t.Context(), &appsetQuery) + _, err := appSetServer.Get(context.Background(), &appsetQuery) assert.EqualError(t, err, "namespace 'NOT-ALLOWED' is not permitted") }) } @@ -485,21 +484,21 @@ func TestDeleteAppSet(t *testing.T) { }) t.Run("Delete in default namespace", func(t *testing.T) { - appSetServer := newTestAppSetServer(t, appSet1, appSet2, appSet3) + appSetServer := newTestAppSetServer(appSet1, appSet2, appSet3) appsetQuery := applicationset.ApplicationSetDeleteRequest{Name: "AppSet1"} - res, err := appSetServer.Delete(t.Context(), &appsetQuery) + res, err := appSetServer.Delete(context.Background(), &appsetQuery) require.NoError(t, err) assert.Equal(t, &applicationset.ApplicationSetResponse{}, res) }) t.Run("Delete in named namespace", func(t *testing.T) { - appSetServer := newTestAppSetServer(t, appSet1, appSet2, appSet3) + appSetServer := newTestAppSetServer(appSet1, appSet2, appSet3) appsetQuery := applicationset.ApplicationSetDeleteRequest{Name: "AppSet1", AppsetNamespace: testNamespace} - res, err := appSetServer.Delete(t.Context(), &appsetQuery) + res, err := appSetServer.Delete(context.Background(), &appsetQuery) require.NoError(t, err) assert.Equal(t, &applicationset.ApplicationSetResponse{}, res) }) @@ -507,29 +506,29 @@ func TestDeleteAppSet(t *testing.T) { func TestUpdateAppSet(t *testing.T) { appSet := newTestAppSet(func(appset *appsv1.ApplicationSet) { - appset.Annotations = map[string]string{ + appset.ObjectMeta.Annotations = map[string]string{ "annotation-key1": "annotation-value1", "annotation-key2": "annotation-value2", } - appset.Labels = map[string]string{ + appset.ObjectMeta.Labels = map[string]string{ "label-key1": "label-value1", "label-key2": "label-value2", } }) newAppSet := newTestAppSet(func(appset *appsv1.ApplicationSet) { - appset.Annotations = map[string]string{ + appset.ObjectMeta.Annotations = map[string]string{ "annotation-key1": "annotation-value1-updated", } - appset.Labels = map[string]string{ + appset.ObjectMeta.Labels = map[string]string{ "label-key1": "label-value1-updated", } }) t.Run("Update merge", func(t *testing.T) { - appServer := newTestAppSetServer(t, appSet) + appServer := newTestAppSetServer(appSet) - updated, err := appServer.updateAppSet(t.Context(), appSet, newAppSet, true) + updated, err := appServer.updateAppSet(appSet, newAppSet, context.Background(), true) require.NoError(t, err) assert.Equal(t, map[string]string{ @@ -543,9 +542,9 @@ func TestUpdateAppSet(t *testing.T) { }) t.Run("Update no merge", func(t *testing.T) { - appServer := newTestAppSetServer(t, appSet) + appServer := newTestAppSetServer(appSet) - updated, err := appServer.updateAppSet(t.Context(), appSet, newAppSet, false) + updated, err := appServer.updateAppSet(appSet, newAppSet, context.Background(), false) require.NoError(t, err) assert.Equal(t, map[string]string{ @@ -612,31 +611,31 @@ func TestResourceTree(t *testing.T) { } t.Run("ResourceTree in default namespace", func(t *testing.T) { - appSetServer := newTestAppSetServer(t, appSet1, appSet2, appSet3) + appSetServer := newTestAppSetServer(appSet1, appSet2, appSet3) appsetQuery := applicationset.ApplicationSetTreeQuery{Name: "AppSet1"} - res, err := appSetServer.ResourceTree(t.Context(), &appsetQuery) + res, err := appSetServer.ResourceTree(context.Background(), &appsetQuery) require.NoError(t, err) assert.Equal(t, expectedTree, res) }) t.Run("ResourceTree in named namespace", func(t *testing.T) { - appSetServer := newTestAppSetServer(t, appSet1, appSet2, appSet3) + appSetServer := newTestAppSetServer(appSet1, appSet2, appSet3) appsetQuery := applicationset.ApplicationSetTreeQuery{Name: "AppSet1", AppsetNamespace: testNamespace} - res, err := appSetServer.ResourceTree(t.Context(), &appsetQuery) + res, err := appSetServer.ResourceTree(context.Background(), &appsetQuery) require.NoError(t, err) assert.Equal(t, expectedTree, res) }) t.Run("ResourceTree in not allowed namespace", func(t *testing.T) { - appSetServer := newTestAppSetServer(t, appSet1, appSet2, appSet3) + appSetServer := newTestAppSetServer(appSet1, appSet2, appSet3) appsetQuery := applicationset.ApplicationSetTreeQuery{Name: "AppSet1", AppsetNamespace: "NOT-ALLOWED"} - _, err := appSetServer.ResourceTree(t.Context(), &appsetQuery) + _, err := appSetServer.ResourceTree(context.Background(), &appsetQuery) assert.EqualError(t, err, "namespace 'NOT-ALLOWED' is not permitted") }) } diff --git a/server/badge/badge.go b/server/badge/badge.go index a2fb1a3b75..bc599e61ca 100644 --- a/server/badge/badge.go +++ b/server/badge/badge.go @@ -10,15 +10,15 @@ import ( healthutil "github.com/argoproj/gitops-engine/pkg/health" "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/validation" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + validation "k8s.io/apimachinery/pkg/api/validation" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/assets" - "github.com/argoproj/argo-cd/v3/util/security" - "github.com/argoproj/argo-cd/v3/util/settings" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/assets" + "github.com/argoproj/argo-cd/v2/util/security" + "github.com/argoproj/argo-cd/v2/util/settings" ) // NewHandler creates handler serving to do api/badge endpoint @@ -108,35 +108,37 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { reqNs := "" if ns, ok := r.URL.Query()["namespace"]; ok && enabled { - if !argo.IsValidNamespaceName(ns[0]) { + if argo.IsValidNamespaceName(ns[0]) { + if security.IsNamespaceEnabled(ns[0], h.namespace, h.enabledNamespaces) { + reqNs = ns[0] + } else { + notFound = true + } + } else { w.WriteHeader(http.StatusBadRequest) return } - if security.IsNamespaceEnabled(ns[0], h.namespace, h.enabledNamespaces) { - reqNs = ns[0] - } else { - notFound = true - } } else { reqNs = h.namespace } // Sample url: http://localhost:8080/api/badge?name=123 if name, ok := r.URL.Query()["name"]; ok && enabled && !notFound { - if !argo.IsValidAppName(name[0]) { + if argo.IsValidAppName(name[0]) { + if app, err := h.appClientset.ArgoprojV1alpha1().Applications(reqNs).Get(context.Background(), name[0], v1.GetOptions{}); err == nil { + health = app.Status.Health.Status + status = app.Status.Sync.Status + applicationName = name[0] + if app.Status.OperationState != nil && app.Status.OperationState.SyncResult != nil { + revision = app.Status.OperationState.SyncResult.Revision + } + } else if errors.IsNotFound(err) { + notFound = true + } + } else { w.WriteHeader(http.StatusBadRequest) return } - if app, err := h.appClientset.ArgoprojV1alpha1().Applications(reqNs).Get(context.Background(), name[0], metav1.GetOptions{}); err == nil { - health = app.Status.Health.Status - status = app.Status.Sync.Status - applicationName = name[0] - if app.Status.OperationState != nil && app.Status.OperationState.SyncResult != nil { - revision = app.Status.OperationState.SyncResult.Revision - } - } else if errors.IsNotFound(err) { - notFound = true - } } // Sample url: http://localhost:8080/api/badge?project=default if projects, ok := r.URL.Query()["project"]; ok && enabled && !notFound { @@ -146,7 +148,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } } - if apps, err := h.appClientset.ArgoprojV1alpha1().Applications(reqNs).List(context.Background(), metav1.ListOptions{}); err == nil { + if apps, err := h.appClientset.ArgoprojV1alpha1().Applications(reqNs).List(context.Background(), v1.ListOptions{}); err == nil { applicationSet := argo.FilterByProjects(apps.Items, projects) for _, a := range applicationSet { if a.Status.Sync.Status != appv1.SyncStatusCodeSynced { @@ -204,7 +206,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { adjustWidth = true displayedRevision = revision - if keepFullRevisionParam, ok := r.URL.Query()["keepFullRevision"]; (!ok || !strings.EqualFold(keepFullRevisionParam[0], "true")) && len(revision) > 7 { + if keepFullRevisionParam, ok := r.URL.Query()["keepFullRevision"]; !(ok && strings.EqualFold(keepFullRevisionParam[0], "true")) && len(revision) > 7 { displayedRevision = revision[:7] svgWidth = svgWidthWithRevision } else { @@ -240,7 +242,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if displayAppName && applicationName != "" { titleRectWidth := len(applicationName) * widthPerChar - longerWidth := max(titleRectWidth, svgWidth) + var longerWidth int = max(titleRectWidth, svgWidth) rightRectWidth := longerWidth - leftRectWidth badge = titleRectWidthPattern.ReplaceAllString(badge, fmt.Sprintf(`$1"%d"`, longerWidth)) badge = rightRectWidthPattern.ReplaceAllString(badge, fmt.Sprintf(`$1"%d"`, rightRectWidth)) diff --git a/server/badge/badge_test.go b/server/badge/badge_test.go index be822ffd5f..47ebde8f5a 100644 --- a/server/badge/badge_test.go +++ b/server/badge/badge_test.go @@ -1,6 +1,7 @@ package badge import ( + "context" "fmt" "image/color" "net/http" @@ -8,22 +9,22 @@ import ( "strings" "testing" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + "github.com/argoproj/argo-cd/v2/util/settings" "github.com/argoproj/gitops-engine/pkg/health" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/fake" ) func argoCDSecret() *corev1.Secret { return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{Name: "argocd-secret", Namespace: "default"}, + ObjectMeta: v1.ObjectMeta{Name: "argocd-secret", Namespace: "default"}, Data: map[string][]byte{ "admin.password": []byte("test"), "server.secretkey": []byte("test"), @@ -33,7 +34,7 @@ func argoCDSecret() *corev1.Secret { func argoCDCm() *corev1.ConfigMap { return &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "argocd-cm", Namespace: "default", Labels: map[string]string{ @@ -48,10 +49,10 @@ func argoCDCm() *corev1.ConfigMap { func testApp() *v1alpha1.Application { return &v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: "test-app", Namespace: "default"}, + ObjectMeta: v1.ObjectMeta{Name: "test-app", Namespace: "default"}, Status: v1alpha1.ApplicationStatus{ Sync: v1alpha1.SyncStatus{Status: v1alpha1.SyncStatusCodeSynced}, - Health: v1alpha1.AppHealthStatus{Status: health.HealthStatusHealthy}, + Health: v1alpha1.HealthStatus{Status: health.HealthStatusHealthy}, OperationState: &v1alpha1.OperationState{ SyncResult: &v1alpha1.SyncOperationResult{ Revision: "aa29b85", @@ -63,10 +64,10 @@ func testApp() *v1alpha1.Application { func testApp2() *v1alpha1.Application { return &v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: "test-app", Namespace: "argocd-test"}, + ObjectMeta: v1.ObjectMeta{Name: "test-app", Namespace: "argocd-test"}, Status: v1alpha1.ApplicationStatus{ Sync: v1alpha1.SyncStatus{Status: v1alpha1.SyncStatusCodeSynced}, - Health: v1alpha1.AppHealthStatus{Status: health.HealthStatusHealthy}, + Health: v1alpha1.HealthStatus{Status: health.HealthStatusHealthy}, OperationState: &v1alpha1.OperationState{ SyncResult: &v1alpha1.SyncOperationResult{ Revision: "aa29b85", @@ -78,10 +79,10 @@ func testApp2() *v1alpha1.Application { func testApp3() *v1alpha1.Application { return &v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: "test-app", Namespace: "argocd-test"}, + ObjectMeta: v1.ObjectMeta{Name: "test-app", Namespace: "argocd-test"}, Status: v1alpha1.ApplicationStatus{ Sync: v1alpha1.SyncStatus{Status: v1alpha1.SyncStatusCodeSynced}, - Health: v1alpha1.AppHealthStatus{Status: health.HealthStatusHealthy}, + Health: v1alpha1.HealthStatus{Status: health.HealthStatusHealthy}, OperationState: &v1alpha1.OperationState{ SyncResult: &v1alpha1.SyncOperationResult{ Revision: "aa29b85ababababababab", @@ -93,13 +94,13 @@ func testApp3() *v1alpha1.Application { func testProject() *v1alpha1.AppProject { return &v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{Name: "test-project", Namespace: "default"}, + ObjectMeta: v1.ObjectMeta{Name: "test-project", Namespace: "default"}, Spec: v1alpha1.AppProjectSpec{}, } } func TestHandlerFeatureIsEnabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp()), settingsMgr, "default", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app", nil) require.NoError(t, err) @@ -194,10 +195,10 @@ func TestHandlerFeatureProjectIsEnabled(t *testing.T) { for _, tt := range projectTests { argoCDCm := argoCDCm() argoCDSecret := argoCDSecret() - argoCDCm.Namespace = tt.namespace - argoCDSecret.Namespace = tt.namespace + argoCDCm.ObjectMeta.Namespace = tt.namespace + argoCDSecret.ObjectMeta.Namespace = tt.namespace - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewClientset(argoCDCm, argoCDSecret), tt.namespace) + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm, argoCDSecret), tt.namespace) objects := []runtime.Object{testProject()} for _, v := range tt.testApp { objects = append(objects, v) @@ -224,7 +225,7 @@ func TestHandlerFeatureProjectIsEnabled(t *testing.T) { func TestHandlerNamespacesIsEnabled(t *testing.T) { t.Run("Application in allowed namespace", func(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp2()), settingsMgr, "default", []string{"argocd-test"}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&namespace=argocd-test", nil) require.NoError(t, err) @@ -245,7 +246,7 @@ func TestHandlerNamespacesIsEnabled(t *testing.T) { }) t.Run("Application in disallowed namespace", func(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp2()), settingsMgr, "default", []string{"argocd-test"}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&namespace=kube-system", nil) require.NoError(t, err) @@ -258,11 +259,11 @@ func TestHandlerNamespacesIsEnabled(t *testing.T) { assert.Equal(t, toRGBString(Purple), leftRectColorPattern.FindStringSubmatch(response)[1]) assert.Equal(t, toRGBString(Purple), rightRectColorPattern.FindStringSubmatch(response)[1]) assert.Equal(t, "Not Found", leftTextPattern.FindStringSubmatch(response)[1]) - assert.Empty(t, rightTextPattern.FindStringSubmatch(response)[1]) + assert.Equal(t, "", rightTextPattern.FindStringSubmatch(response)[1]) }) t.Run("Request with illegal namespace", func(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp2()), settingsMgr, "default", []string{"argocd-test"}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&namespace=kube()system", nil) require.NoError(t, err) @@ -275,7 +276,7 @@ func TestHandlerNamespacesIsEnabled(t *testing.T) { } func TestHandlerFeatureIsEnabledKeepFullRevisionIsEnabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp3()), settingsMgr, "argocd-test", []string{""}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true&keepFullRevision=true", nil) require.NoError(t, err) @@ -296,7 +297,7 @@ func TestHandlerFeatureIsEnabledKeepFullRevisionIsEnabled(t *testing.T) { } func TestHandlerFeatureIsEnabledKeepFullRevisionIsDisabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp3()), settingsMgr, "argocd-test", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true&keepFullRevision=false", nil) require.NoError(t, err) @@ -317,7 +318,7 @@ func TestHandlerFeatureIsEnabledKeepFullRevisionIsDisabled(t *testing.T) { } func TestHandlerFeatureIsEnabledKeepFullRevisionAndWidthIsEnabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp3()), settingsMgr, "argocd-test", []string{""}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true&keepFullRevision=true&width=500", nil) require.NoError(t, err) @@ -340,10 +341,10 @@ func TestHandlerFeatureIsEnabledKeepFullRevisionAndWidthIsEnabled(t *testing.T) func createApplicationFeatureProjectIsEnabled(healthStatus health.HealthStatusCode, syncStatus v1alpha1.SyncStatusCode, appName, projectName, namespace string) *v1alpha1.Application { return &v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: appName, Namespace: namespace}, + ObjectMeta: v1.ObjectMeta{Name: appName, Namespace: namespace}, Status: v1alpha1.ApplicationStatus{ Sync: v1alpha1.SyncStatus{Status: syncStatus}, - Health: v1alpha1.AppHealthStatus{Status: healthStatus}, + Health: v1alpha1.HealthStatus{Status: healthStatus}, OperationState: &v1alpha1.OperationState{ SyncResult: &v1alpha1.SyncOperationResult{}, }, @@ -391,7 +392,7 @@ func createApplicationsWithName(appCombo, projectName []string, namespace string } func TestHandlerFeatureIsEnabledRevisionIsEnabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp()), settingsMgr, "default", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true", nil) require.NoError(t, err) @@ -415,7 +416,7 @@ func TestHandlerRevisionIsEnabledNoOperationState(t *testing.T) { app := testApp() app.Status.OperationState = nil - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(app), settingsMgr, "default", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true", nil) require.NoError(t, err) @@ -439,7 +440,7 @@ func TestHandlerRevisionIsEnabledShortCommitSHA(t *testing.T) { app := testApp() app.Status.OperationState.SyncResult.Revision = "abc" - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(app), settingsMgr, "default", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true", nil) require.NoError(t, err) @@ -455,7 +456,7 @@ func TestHandlerFeatureIsDisabled(t *testing.T) { argoCDCmDisabled := argoCDCm() delete(argoCDCmDisabled.Data, "statusbadge.enabled") - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewSimpleClientset(argoCDCmDisabled, argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCmDisabled, argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp()), settingsMgr, "default", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app", nil) require.NoError(t, err) @@ -476,7 +477,7 @@ func TestHandlerFeatureIsDisabled(t *testing.T) { } func TestHandlerApplicationNameInBadgeIsEnabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp()), settingsMgr, "default", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&showAppName=true", nil) require.NoError(t, err) @@ -503,7 +504,7 @@ func TestHandlerApplicationNameInBadgeIsEnabled(t *testing.T) { } func TestHandlerApplicationNameInBadgeIsDisabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp()), settingsMgr, "default", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app", nil) require.NoError(t, err) diff --git a/server/badge/color.go b/server/badge/color.go index c86042b536..b9edb82227 100644 --- a/server/badge/color.go +++ b/server/badge/color.go @@ -4,7 +4,7 @@ import ( "fmt" "image/color" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/gitops-engine/pkg/health" ) diff --git a/server/cache/cache.go b/server/cache/cache.go index 2d13b6a01e..1fd326c596 100644 --- a/server/cache/cache.go +++ b/server/cache/cache.go @@ -8,10 +8,10 @@ import ( "github.com/spf13/cobra" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/env" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + 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/env" ) var ErrCacheMiss = appstatecache.ErrCacheMiss diff --git a/server/cache/cache_test.go b/server/cache/cache_test.go index f22d760177..9104305a60 100644 --- a/server/cache/cache_test.go +++ b/server/cache/cache_test.go @@ -8,9 +8,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" ) type fixtures struct { @@ -43,6 +43,9 @@ func TestCache_GetRepoConnectionState(t *testing.T) { // populate cache err = cache.SetRepoConnectionState("my-repo", "some-project", &ConnectionState{Status: "my-project-state"}) require.NoError(t, err) + // cache miss + _, err = cache.GetRepoConnectionState("other-repo", "") + assert.Equal(t, ErrCacheMiss, err) // cache hit value, err := cache.GetRepoConnectionState("my-repo", "") require.NoError(t, err) diff --git a/server/certificate/certificate.go b/server/certificate/certificate.go index 0e406de308..8b17828c95 100644 --- a/server/certificate/certificate.go +++ b/server/certificate/certificate.go @@ -3,11 +3,11 @@ package certificate import ( "context" - certificatepkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/certificate" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/rbac" + certificatepkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/certificate" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/rbac" ) // Server provides a Certificate service diff --git a/server/certificate/certificate.proto b/server/certificate/certificate.proto index 63a440ec9e..7ffad3ef42 100644 --- a/server/certificate/certificate.proto +++ b/server/certificate/certificate.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/certificate"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/certificate"; // Certificate Service // @@ -8,7 +8,7 @@ option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/certificate"; package certificate; import "google/api/annotations.proto"; -import "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto"; +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; // Message to query the server for configured repository certificates message RepositoryCertificateQuery { @@ -23,7 +23,7 @@ message RepositoryCertificateQuery { // Request to create a set of certificates message RepositoryCertificateCreateRequest { // List of certificates to be created - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepositoryCertificateList certificates = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepositoryCertificateList certificates = 1; // Whether to upsert already existing certificates bool upsert = 2; } @@ -32,12 +32,12 @@ message RepositoryCertificateResponse {} service CertificateService { // List all available repository certificates - rpc ListCertificates(RepositoryCertificateQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepositoryCertificateList) { + rpc ListCertificates(RepositoryCertificateQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepositoryCertificateList) { option (google.api.http).get = "/api/v1/certificates"; } // Creates repository certificates on the server - rpc CreateCertificate(RepositoryCertificateCreateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepositoryCertificateList) { + rpc CreateCertificate(RepositoryCertificateCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepositoryCertificateList) { option (google.api.http) = { post: "/api/v1/certificates" body: "certificates" @@ -45,7 +45,7 @@ service CertificateService { } // Delete the certificates that match the RepositoryCertificateQuery - rpc DeleteCertificate(RepositoryCertificateQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepositoryCertificateList) { + rpc DeleteCertificate(RepositoryCertificateQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepositoryCertificateList) { option (google.api.http).delete = "/api/v1/certificates"; } } \ No newline at end of file diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go index 135a68c981..a00f7574f1 100644 --- a/server/cluster/cluster.go +++ b/server/cluster/cluster.go @@ -14,14 +14,14 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/kubernetes" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - servercache "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/clusterauth" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/rbac" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/clusterauth" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/rbac" ) // Server provides a Cluster service @@ -158,22 +158,22 @@ func (s *Server) Create(ctx context.Context, q *cluster.ClusterCreateRequest) (* clust, err := s.db.CreateCluster(ctx, c) if err != nil { - if status.Convert(err).Code() != codes.AlreadyExists { - return nil, fmt.Errorf("error creating cluster: %w", err) - } - // act idempotent if existing spec matches new spec - existing, getErr := s.db.GetCluster(ctx, c.Server) - if getErr != nil { - return nil, status.Errorf(codes.Internal, "unable to check existing cluster details: %v", getErr) - } + if status.Convert(err).Code() == codes.AlreadyExists { + // act idempotent if existing spec matches new spec + existing, getErr := s.db.GetCluster(ctx, c.Server) + if getErr != nil { + return nil, status.Errorf(codes.Internal, "unable to check existing cluster details: %v", getErr) + } - switch { - case existing.Equals(c): - clust = existing - case q.Upsert: - return s.Update(ctx, &cluster.ClusterUpdateRequest{Cluster: c}) - default: - return nil, status.Error(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("cluster", existing, c)) + if existing.Equals(c) { + clust = existing + } else if q.Upsert { + return s.Update(ctx, &cluster.ClusterUpdateRequest{Cluster: c}) + } else { + return nil, status.Error(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("cluster", existing, c)) + } + } else { + return nil, fmt.Errorf("error creating cluster: %w", err) } } @@ -201,11 +201,11 @@ func (s *Server) Get(ctx context.Context, q *cluster.ClusterQuery) (*appv1.Clust } func (s *Server) getClusterWith403IfNotExist(ctx context.Context, q *cluster.ClusterQuery) (*appv1.Cluster, error) { - c, err := s.getCluster(ctx, q) - if err != nil || c == nil { + repo, err := s.getCluster(ctx, q) + if err != nil || repo == nil { return nil, common.PermissionDeniedAPIError } - return c, nil + return repo, nil } func (s *Server) getClusterAndVerifyAccess(ctx context.Context, q *cluster.ClusterQuery, action string) (*appv1.Cluster, error) { @@ -361,12 +361,12 @@ func (s *Server) Delete(ctx context.Context, q *cluster.ClusterQuery) (*cluster. return nil, common.PermissionDeniedAPIError } for _, server := range servers { - if err := enforceAndDelete(ctx, s, server, c.Project); err != nil { + if err := enforceAndDelete(s, ctx, server, c.Project); err != nil { return nil, fmt.Errorf("failed to enforce and delete cluster server: %w", err) } } } else { - if err := enforceAndDelete(ctx, s, q.Server, c.Project); err != nil { + if err := enforceAndDelete(s, ctx, q.Server, c.Project); err != nil { return nil, fmt.Errorf("failed to enforce and delete cluster server: %w", err) } } @@ -374,7 +374,7 @@ func (s *Server) Delete(ctx context.Context, q *cluster.ClusterQuery) (*cluster. return &cluster.ClusterResponse{}, nil } -func enforceAndDelete(ctx context.Context, s *Server, server, project string) error { +func enforceAndDelete(s *Server, ctx context.Context, server, project string) error { if err := s.enf.EnforceErr(ctx.Value("claims"), rbac.ResourceClusters, rbac.ActionDelete, CreateClusterRBACObject(project, server)); err != nil { log.WithField("cluster", server).Warnf("encountered permissions issue while processing request: %v", err) return common.PermissionDeniedAPIError @@ -475,7 +475,7 @@ func (s *Server) toAPIResponse(clust *appv1.Cluster) *appv1.Cluster { clust.Config.Password = "" clust.Config.BearerToken = "" - clust.Config.KeyData = nil + clust.Config.TLSClientConfig.KeyData = nil if clust.Config.ExecProviderConfig != nil { // We can't know what the user has put into args or // env vars on the exec provider that might be sensitive @@ -485,9 +485,9 @@ func (s *Server) toAPIResponse(clust *appv1.Cluster) *appv1.Cluster { clust.Config.ExecProviderConfig.Args = nil } // populate deprecated fields for backward compatibility - //nolint:staticcheck + // nolint:staticcheck clust.ServerVersion = clust.Info.ServerVersion - //nolint:staticcheck + // nolint:staticcheck clust.ConnectionState = clust.Info.ConnectionState return clust } diff --git a/server/cluster/cluster.proto b/server/cluster/cluster.proto index a24547adaf..741d9618fd 100644 --- a/server/cluster/cluster.proto +++ b/server/cluster/cluster.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster"; // Cluster Service // @@ -7,7 +7,7 @@ option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster"; package cluster; import "google/api/annotations.proto"; -import "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto"; +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; // ClusterID holds a cluster server URL or cluster name message ClusterID { @@ -27,12 +27,12 @@ message ClusterQuery { message ClusterResponse {} message ClusterCreateRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Cluster cluster = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Cluster cluster = 1; bool upsert = 2; } message ClusterUpdateRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Cluster cluster = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Cluster cluster = 1; repeated string updatedFields = 2; ClusterID id = 3; } @@ -41,12 +41,12 @@ message ClusterUpdateRequest { service ClusterService { // List returns list of clusters - rpc List(ClusterQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ClusterList) { + rpc List(ClusterQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ClusterList) { option (google.api.http).get = "/api/v1/clusters"; } // Create creates a cluster - rpc Create(ClusterCreateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Cluster) { + rpc Create(ClusterCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Cluster) { option (google.api.http) = { post: "/api/v1/clusters" body: "cluster" @@ -54,12 +54,12 @@ service ClusterService { } // Get returns a cluster by server address - rpc Get(ClusterQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Cluster) { + rpc Get(ClusterQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Cluster) { option (google.api.http).get = "/api/v1/clusters/{id.value}"; } // Update updates a cluster - rpc Update(ClusterUpdateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Cluster) { + rpc Update(ClusterUpdateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Cluster) { option (google.api.http) = { put: "/api/v1/clusters/{id.value}" body: "cluster" @@ -77,7 +77,7 @@ service ClusterService { } // InvalidateCache invalidates cluster cache - rpc InvalidateCache(ClusterQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Cluster) { + rpc InvalidateCache(ClusterQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Cluster) { option (google.api.http).post = "/api/v1/clusters/{id.value}/invalidate-cache"; } diff --git a/server/cluster/cluster_test.go b/server/cluster/cluster_test.go index 2e1863e4e9..f917ba0151 100644 --- a/server/cluster/cluster_test.go +++ b/server/cluster/cluster_test.go @@ -8,9 +8,9 @@ import ( "testing" "time" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" - "github.com/argoproj/argo-cd/v3/util/assets" + "github.com/argoproj/argo-cd/v2/util/assets" "github.com/argoproj/gitops-engine/pkg/utils/kube/kubetest" "github.com/stretchr/testify/assert" @@ -22,17 +22,18 @@ import ( "k8s.io/client-go/kubernetes/fake" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - servercache "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/test" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/db" - dbmocks "github.com/argoproj/argo-cd/v3/util/db/mocks" - "github.com/argoproj/argo-cd/v3/util/rbac" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/test" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" + "github.com/argoproj/argo-cd/v2/util/db" + dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" + "github.com/argoproj/argo-cd/v2/util/rbac" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( @@ -235,7 +236,7 @@ p, role:test, clusters, *, allowed-project/*, allow`) cc := c t.Run(cc.name, func(t *testing.T) { t.Parallel() - out, err := server.Update(t.Context(), &cc.request) + out, err := server.Update(context.Background(), &cc.request) require.Nil(t, out) assert.ErrorIs(t, err, common.PermissionDeniedAPIError) }) @@ -261,7 +262,7 @@ func TestGetCluster_UrlEncodedName(t *testing.T) { server := NewServer(db, newNoopEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{}) - localCluster, err := server.Get(t.Context(), &cluster.ClusterQuery{ + localCluster, err := server.Get(context.Background(), &cluster.ClusterQuery{ Id: &cluster.ClusterID{ Type: "name_escaped", Value: "test%2fing", @@ -291,7 +292,7 @@ func TestGetCluster_NameWithUrlEncodingButShouldNotBeUnescaped(t *testing.T) { server := NewServer(db, newNoopEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{}) - localCluster, err := server.Get(t.Context(), &cluster.ClusterQuery{ + localCluster, err := server.Get(context.Background(), &cluster.ClusterQuery{ Id: &cluster.ClusterID{ Type: "name", Value: "test%2fing", @@ -318,20 +319,20 @@ func TestGetCluster_CannotSetCADataAndInsecureTrue(t *testing.T) { }, } clientset := getClientset(nil, testNamespace) - db := db.NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + 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(t.Context(), &cluster.ClusterCreateRequest{ + _, err := server.Create(context.Background(), &cluster.ClusterCreateRequest{ Cluster: localCluster, }) - assert.EqualError(t, err, `error getting REST config: unable to apply K8s REST config defaults: specifying a root certificates file with the insecure flag is not allowed`) + assert.EqualError(t, err, `error getting REST config: Unable to apply K8s REST config defaults: specifying a root certificates file with the insecure flag is not allowed`) }) - localCluster.Config.CAData = nil + localCluster.Config.TLSClientConfig.CAData = nil t.Run("Create Succeeds When CAData is nil and Insecure is True", func(t *testing.T) { - _, err := server.Create(t.Context(), &cluster.ClusterCreateRequest{ + _, err := server.Create(context.Background(), &cluster.ClusterCreateRequest{ Cluster: localCluster, }) require.NoError(t, err) @@ -363,7 +364,7 @@ func TestUpdateCluster_NoFieldsPaths(t *testing.T) { server := NewServer(db, newNoopEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{}) - _, err := server.Update(t.Context(), &cluster.ClusterUpdateRequest{ + _, err := server.Update(context.Background(), &cluster.ClusterUpdateRequest{ Cluster: &v1alpha1.Cluster{ Name: "minikube", Namespaces: []string{"default", "kube-system"}, @@ -391,7 +392,7 @@ func TestUpdateCluster_FieldsPathSet(t *testing.T) { server := NewServer(db, newNoopEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{}) - _, err := server.Update(t.Context(), &cluster.ClusterUpdateRequest{ + _, err := server.Update(context.Background(), &cluster.ClusterUpdateRequest{ Cluster: &v1alpha1.Cluster{ Server: "https://127.0.0.1", Shard: ptr.To(int64(1)), @@ -408,7 +409,7 @@ func TestUpdateCluster_FieldsPathSet(t *testing.T) { labelEnv := map[string]string{ "env": "qa", } - _, err = server.Update(t.Context(), &cluster.ClusterUpdateRequest{ + _, err = server.Update(context.Background(), &cluster.ClusterUpdateRequest{ Cluster: &v1alpha1.Cluster{ Server: "https://127.0.0.1", Labels: labelEnv, @@ -425,7 +426,7 @@ func TestUpdateCluster_FieldsPathSet(t *testing.T) { annotationEnv := map[string]string{ "env": "qa", } - _, err = server.Update(t.Context(), &cluster.ClusterUpdateRequest{ + _, err = server.Update(context.Background(), &cluster.ClusterUpdateRequest{ Cluster: &v1alpha1.Cluster{ Server: "https://127.0.0.1", Annotations: annotationEnv, @@ -439,7 +440,7 @@ func TestUpdateCluster_FieldsPathSet(t *testing.T) { assert.Equal(t, []string{"default", "kube-system"}, updated.Namespaces) assert.Equal(t, updated.Annotations, annotationEnv) - _, err = server.Update(t.Context(), &cluster.ClusterUpdateRequest{ + _, err = server.Update(context.Background(), &cluster.ClusterUpdateRequest{ Cluster: &v1alpha1.Cluster{ Server: "https://127.0.0.1", Project: "new-project", @@ -473,11 +474,11 @@ func TestDeleteClusterByName(t *testing.T) { "config": []byte("{}"), }, }) - db := db.NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + db := db.NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) server := NewServer(db, newNoopEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{}) t.Run("Delete Fails When Deleting by Unknown Name", func(t *testing.T) { - _, err := server.Delete(t.Context(), &cluster.ClusterQuery{ + _, err := server.Delete(context.Background(), &cluster.ClusterQuery{ Name: "foo", }) @@ -485,12 +486,12 @@ func TestDeleteClusterByName(t *testing.T) { }) t.Run("Delete Succeeds When Deleting by Name", func(t *testing.T) { - _, err := server.Delete(t.Context(), &cluster.ClusterQuery{ + _, err := server.Delete(context.Background(), &cluster.ClusterQuery{ Name: "my-cluster-name", }) require.NoError(t, err) - _, err = db.GetCluster(t.Context(), "https://my-cluster-server") + _, err = db.GetCluster(context.Background(), "https://my-cluster-server") assert.EqualError(t, err, `rpc error: code = NotFound desc = cluster "https://my-cluster-server" not found`) }) } @@ -550,11 +551,11 @@ func TestRotateAuth(t *testing.T) { }, }) - db := db.NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + db := db.NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) server := NewServer(db, newNoopEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{}) t.Run("RotateAuth by Unknown Name", func(t *testing.T) { - _, err := server.RotateAuth(t.Context(), &cluster.ClusterQuery{ + _, err := server.RotateAuth(context.Background(), &cluster.ClusterQuery{ Name: "foo", }) @@ -565,7 +566,7 @@ func TestRotateAuth(t *testing.T) { // demonstrate the proper mapping of cluster names/server to server info (i.e. my-cluster-name // results in https://my-cluster-name info being used and https://my-cluster-name results in https://my-cluster-name). t.Run("RotateAuth by Name - Error from no such host", func(t *testing.T) { - _, err := server.RotateAuth(t.Context(), &cluster.ClusterQuery{ + _, err := server.RotateAuth(context.Background(), &cluster.ClusterQuery{ Name: "my-cluster-name", }) @@ -573,7 +574,7 @@ func TestRotateAuth(t *testing.T) { }) t.Run("RotateAuth by Server - Error from no such host", func(t *testing.T) { - _, err := server.RotateAuth(t.Context(), &cluster.ClusterQuery{ + _, err := server.RotateAuth(context.Background(), &cluster.ClusterQuery{ Server: "https://my-cluster-name", }) @@ -636,7 +637,7 @@ func TestListCluster(t *testing.T) { tests := []struct { name string q *cluster.ClusterQuery - want *v1alpha1.ClusterList + want *appv1.ClusterList wantErr bool }{ { @@ -705,7 +706,7 @@ func TestListCluster(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Parallel() - got, err := s.List(t.Context(), tt.q) + got, err := s.List(context.Background(), tt.q) if tt.wantErr { assert.Error(t, err, "Server.List()") } else { @@ -735,7 +736,7 @@ func TestGetClusterAndVerifyAccess(t *testing.T) { db.On("ListClusters", mock.Anything).Return(&mockClusterList, nil) server := NewServer(db, newNoopEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{}) - localCluster, err := server.getClusterAndVerifyAccess(t.Context(), &cluster.ClusterQuery{ + localCluster, err := server.getClusterAndVerifyAccess(context.Background(), &cluster.ClusterQuery{ Name: "test/not-exists", }, rbac.ActionGet) @@ -761,7 +762,7 @@ func TestGetClusterAndVerifyAccess(t *testing.T) { db.On("ListClusters", mock.Anything).Return(&mockClusterList, nil) server := NewServer(db, newEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{}) - localCluster, err := server.getClusterAndVerifyAccess(t.Context(), &cluster.ClusterQuery{ + localCluster, err := server.getClusterAndVerifyAccess(context.Background(), &cluster.ClusterQuery{ Name: "test/ing", }, rbac.ActionGet) @@ -791,26 +792,26 @@ func TestNoClusterEnumeration(t *testing.T) { server := NewServer(db, newEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{}) t.Run("Get", func(t *testing.T) { - _, err := server.Get(t.Context(), &cluster.ClusterQuery{ + _, err := server.Get(context.Background(), &cluster.ClusterQuery{ Name: "cluster-not-exists", }) require.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") - _, err = server.Get(t.Context(), &cluster.ClusterQuery{ + _, err = server.Get(context.Background(), &cluster.ClusterQuery{ Name: "test/ing", }) assert.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") }) t.Run("Update", func(t *testing.T) { - _, err := server.Update(t.Context(), &cluster.ClusterUpdateRequest{ + _, err := server.Update(context.Background(), &cluster.ClusterUpdateRequest{ Cluster: &v1alpha1.Cluster{ Name: "cluster-not-exists", }, }) require.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") - _, err = server.Update(t.Context(), &cluster.ClusterUpdateRequest{ + _, err = server.Update(context.Background(), &cluster.ClusterUpdateRequest{ Cluster: &v1alpha1.Cluster{ Name: "test/ing", }, @@ -819,36 +820,36 @@ func TestNoClusterEnumeration(t *testing.T) { }) t.Run("Delete", func(t *testing.T) { - _, err := server.Delete(t.Context(), &cluster.ClusterQuery{ + _, err := server.Delete(context.Background(), &cluster.ClusterQuery{ Server: "https://127.0.0.2", }) require.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") - _, err = server.Delete(t.Context(), &cluster.ClusterQuery{ + _, err = server.Delete(context.Background(), &cluster.ClusterQuery{ Server: "https://127.0.0.1", }) assert.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") }) t.Run("RotateAuth", func(t *testing.T) { - _, err := server.RotateAuth(t.Context(), &cluster.ClusterQuery{ + _, err := server.RotateAuth(context.Background(), &cluster.ClusterQuery{ Server: "https://127.0.0.2", }) require.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") - _, err = server.RotateAuth(t.Context(), &cluster.ClusterQuery{ + _, err = server.RotateAuth(context.Background(), &cluster.ClusterQuery{ Server: "https://127.0.0.1", }) assert.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") }) t.Run("InvalidateCache", func(t *testing.T) { - _, err := server.InvalidateCache(t.Context(), &cluster.ClusterQuery{ + _, err := server.InvalidateCache(context.Background(), &cluster.ClusterQuery{ Server: "https://127.0.0.2", }) require.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") - _, err = server.InvalidateCache(t.Context(), &cluster.ClusterQuery{ + _, err = server.InvalidateCache(context.Background(), &cluster.ClusterQuery{ Server: "https://127.0.0.1", }) assert.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") diff --git a/server/deeplinks/deeplinks.go b/server/deeplinks/deeplinks.go index f79a528ba4..933dcde42d 100644 --- a/server/deeplinks/deeplinks.go +++ b/server/deeplinks/deeplinks.go @@ -11,9 +11,9 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/settings" ) var sprigFuncMap = sprig.GenericFuncMap() // a singleton for better performance @@ -62,8 +62,8 @@ func SanitizeCluster(cluster *v1alpha1.Cluster) (*unstructured.Unstructured, err }) } -func CreateDeepLinksObject(resourceObj *unstructured.Unstructured, app *unstructured.Unstructured, cluster *unstructured.Unstructured, project *unstructured.Unstructured) map[string]any { - deeplinkObj := map[string]any{} +func CreateDeepLinksObject(resourceObj *unstructured.Unstructured, app *unstructured.Unstructured, cluster *unstructured.Unstructured, project *unstructured.Unstructured) map[string]interface{} { + deeplinkObj := map[string]interface{}{} if resourceObj != nil { deeplinkObj[ResourceDeepLinkKey] = resourceObj.Object } @@ -80,7 +80,7 @@ func CreateDeepLinksObject(resourceObj *unstructured.Unstructured, app *unstruct return deeplinkObj } -func EvaluateDeepLinksResponse(obj map[string]any, name string, links []settings.DeepLink) (*application.LinksResponse, []string) { +func EvaluateDeepLinksResponse(obj map[string]interface{}, name string, links []settings.DeepLink) (*application.LinksResponse, []string) { finalLinks := []*application.LinkInfo{} errors := []string{} for _, link := range links { diff --git a/server/deeplinks/deeplinks_test.go b/server/deeplinks/deeplinks_test.go index c88fcfec04..217b8b93b7 100644 --- a/server/deeplinks/deeplinks_test.go +++ b/server/deeplinks/deeplinks_test.go @@ -8,14 +8,14 @@ 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/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/settings" ) type deepLinkTC struct { @@ -43,7 +43,7 @@ func TestDeepLinks(t *testing.T) { }, }) require.NoError(t, err) - resourceObj, err := kube.ToUnstructured(&corev1.ConfigMap{ + resourceObj, err := kube.ToUnstructured(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "test-cm", Namespace: "test-cm", diff --git a/server/extension/extension.go b/server/extension/extension.go index aca535d252..5fce929df4 100644 --- a/server/extension/extension.go +++ b/server/extension/extension.go @@ -16,16 +16,16 @@ import ( log "github.com/sirupsen/logrus" "gopkg.in/yaml.v3" - "github.com/argoproj/argo-cd/v3/util/rbac" + "github.com/argoproj/argo-cd/v2/util/rbac" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/server/rbacpolicy" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/security" - "github.com/argoproj/argo-cd/v3/util/session" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/server/rbacpolicy" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/security" + "github.com/argoproj/argo-cd/v2/util/session" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( @@ -345,7 +345,6 @@ type Manager struct { settings SettingsGetter application ApplicationGetter project ProjectGetter - cluster argo.ClusterGetter rbac RbacEnforcer registry ExtensionRegistry metricsReg ExtensionMetricsRegistry @@ -365,14 +364,13 @@ type ExtensionMetricsRegistry interface { } // NewManager will initialize a new manager. -func NewManager(log *log.Entry, namespace string, sg SettingsGetter, ag ApplicationGetter, pg ProjectGetter, cg argo.ClusterGetter, 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, - cluster: cg, rbac: rbac, userGetter: ug, } @@ -697,11 +695,7 @@ func (m *Manager) authorize(ctx context.Context, rr *RequestResources, extName s if proj == nil { return nil, fmt.Errorf("invalid project provided in the %q header", HeaderArgoCDProjectName) } - destCluster, err := argo.GetDestinationCluster(ctx, app.Spec.Destination, m.cluster) - if err != nil { - return nil, fmt.Errorf("error getting destination cluster: %w", err) - } - permitted, err := proj.IsDestinationPermitted(destCluster, app.Spec.Destination.Namespace, m.project.GetClusters) + permitted, err := proj.IsDestinationPermitted(app.Spec.Destination, m.project.GetClusters) if err != nil { return nil, fmt.Errorf("error validating project destinations: %w", err) } @@ -783,14 +777,7 @@ func (m *Manager) CallExtension() func(http.ResponseWriter, *http.Request) { user := m.userGetter.GetUser(r.Context()) groups := m.userGetter.GetGroups(r.Context()) prepareRequest(r, m.namespace, extName, app, user, groups) - m.log.WithFields(log.Fields{ - HeaderArgoCDUsername: user, - HeaderArgoCDGroups: strings.Join(groups, ","), - HeaderArgoCDNamespace: m.namespace, - HeaderArgoCDApplicationName: fmt.Sprintf("%s:%s", app.GetNamespace(), app.GetName()), - "extension": extName, - "path": r.URL.Path, - }).Info("sending proxy extension request") + m.log.Debugf("proxing request for extension %q", extName) // httpsnoop package is used to properly wrap the responseWriter // and avoid optional intefaces issue: // https://github.com/felixge/httpsnoop#why-this-package-exists diff --git a/server/extension/extension_test.go b/server/extension/extension_test.go index 8ea3eb7b11..a23eeef25a 100644 --- a/server/extension/extension_test.go +++ b/server/extension/extension_test.go @@ -1,6 +1,7 @@ package extension_test import ( + "context" "errors" "fmt" "io" @@ -16,13 +17,12 @@ import ( "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/util/rbac" + "github.com/argoproj/argo-cd/v2/util/rbac" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/server/extension" - "github.com/argoproj/argo-cd/v3/server/extension/mocks" - dbmocks "github.com/argoproj/argo-cd/v3/util/db/mocks" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/server/extension" + "github.com/argoproj/argo-cd/v2/server/extension/mocks" + "github.com/argoproj/argo-cd/v2/util/settings" ) func TestValidateHeaders(t *testing.T) { @@ -136,8 +136,8 @@ func TestRegisterExtensions(t *testing.T) { settMock := &mocks.SettingsGetter{} logger, _ := test.NewNullLogger() - logEntry := logger.WithContext(t.Context()) - m := extension.NewManager(logEntry, "", settMock, nil, nil, nil, nil, nil) + logEntry := logger.WithContext(context.Background()) + m := extension.NewManager(logEntry, "", settMock, nil, nil, nil, nil) return &fixture{ settingsGetterMock: settMock, @@ -252,18 +252,14 @@ func TestCallExtension(t *testing.T) { metricsMock := &mocks.ExtensionMetricsRegistry{} userMock := &mocks.UserGetter{} - dbMock := &dbmocks.ArgoDB{} - dbMock.On("GetClusterServersByName", mock.Anything, mock.Anything).Return([]string{"cluster1"}, nil) - dbMock.On("GetCluster", mock.Anything, mock.Anything).Return(&v1alpha1.Cluster{Server: "some-url", Name: "cluster1"}, nil) - logger, _ := test.NewNullLogger() - logEntry := logger.WithContext(t.Context()) - m := extension.NewManager(logEntry, defaultServerNamespace, settMock, appMock, projMock, dbMock, rbacMock, userMock) + logEntry := logger.WithContext(context.Background()) + m := extension.NewManager(logEntry, defaultServerNamespace, settMock, appMock, projMock, rbacMock, userMock) m.AddMetricsRegistry(metricsMock) mux := http.NewServeMux() extHandler := http.HandlerFunc(m.CallExtension()) - mux.Handle(extension.URLPrefix+"/", extHandler) + mux.Handle(fmt.Sprintf("%s/", extension.URLPrefix), extHandler) return &fixture{ mux: mux, @@ -398,7 +394,8 @@ func TestCallExtension(t *testing.T) { f := setup() backendResponse := "some data" backendEndpoint := "some-backend" - clusterURL := "some-url" + clusterName := "clusterName" + clusterURL := "clusterURL" backendSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { for k, v := range r.Header { w.Header().Add(k, strings.Join(v, ",")) @@ -412,7 +409,7 @@ func TestCallExtension(t *testing.T) { ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/%s/", ts.URL, backendEndpoint)) - app := getApp("", clusterURL, defaultProjectName) + app := getApp(clusterName, clusterURL, defaultProjectName) proj := getProjectWithDestinations("project-name", nil, []string{clusterURL}) f.appGetterMock.On("Get", mock.Anything, mock.Anything).Return(app, nil) withProject(proj, f) @@ -420,12 +417,12 @@ func TestCallExtension(t *testing.T) { wg.Add(2) f.metricsMock. On("IncExtensionRequestCounter", mock.Anything, mock.Anything). - Run(func(_ mock.Arguments) { + Run(func(args mock.Arguments) { wg.Done() }) f.metricsMock. On("ObserveExtensionRequestDuration", mock.Anything, mock.Anything). - Run(func(_ mock.Arguments) { + Run(func(args mock.Arguments) { wg.Done() }) @@ -512,9 +509,9 @@ func TestCallExtension(t *testing.T) { req := newExtensionRequest(t, http.MethodGet, url) req.Header.Del(extension.HeaderArgoCDApplicationName) - req1 := req.Clone(t.Context()) + req1 := req.Clone(context.Background()) req1.Header.Add(extension.HeaderArgoCDApplicationName, "ns1:app1") - req2 := req.Clone(t.Context()) + req2 := req.Clone(context.Background()) req2.Header.Add(extension.HeaderArgoCDApplicationName, "ns2:app2") // when @@ -665,7 +662,7 @@ func TestCallExtension(t *testing.T) { require.NotNil(t, resp) assert.Equal(t, http.StatusUnauthorized, resp.StatusCode) }) - t.Run("will return 401 if application defines name and server destination", func(t *testing.T) { + t.Run("will return 400 if application defines name and server destination", func(t *testing.T) { // This test is to validate a security risk with malicious application // trying to gain access to execute extensions in clusters it doesn't // have access. @@ -691,7 +688,7 @@ func TestCallExtension(t *testing.T) { url := fmt.Sprintf("%s/extensions/%s/", ts.URL, extName) req := newExtensionRequest(t, http.MethodGet, url) req.Header.Del(extension.HeaderArgoCDApplicationName) - req1 := req.Clone(t.Context()) + req1 := req.Clone(context.Background()) req1.Header.Add(extension.HeaderArgoCDApplicationName, "ns1:app1") // when @@ -700,11 +697,11 @@ func TestCallExtension(t *testing.T) { // then require.NotNil(t, resp1) - assert.Equal(t, http.StatusUnauthorized, resp1.StatusCode) + assert.Equal(t, http.StatusBadRequest, resp1.StatusCode) body, err := io.ReadAll(resp1.Body) require.NoError(t, err) actual := strings.TrimSuffix(string(body), "\n") - assert.Equal(t, "Unauthorized extension request", actual) + assert.Equal(t, "invalid extension", actual) }) t.Run("will return 400 if no extension name is provided", func(t *testing.T) { // given @@ -720,7 +717,7 @@ func TestCallExtension(t *testing.T) { withUser(f, "some-user", []string{"group1", "group2"}) ts := startTestServer(t, f) defer ts.Close() - r := newExtensionRequest(t, "Get", ts.URL+"/extensions/") + r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/", ts.URL)) f.appGetterMock.On("Get", mock.Anything, mock.Anything).Return(getApp("", "", differentProject), nil) // when diff --git a/server/extension/mocks/ApplicationGetter.go b/server/extension/mocks/ApplicationGetter.go index 949005f299..e4858d08bc 100644 --- a/server/extension/mocks/ApplicationGetter.go +++ b/server/extension/mocks/ApplicationGetter.go @@ -1,14 +1,47 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" mock "github.com/stretchr/testify/mock" ) +// ApplicationGetter is an autogenerated mock type for the ApplicationGetter type +type ApplicationGetter struct { + mock.Mock +} + +// Get provides a mock function with given fields: ns, name +func (_m *ApplicationGetter) Get(ns string, name string) (*v1alpha1.Application, error) { + ret := _m.Called(ns, name) + + if len(ret) == 0 { + panic("no return value specified for Get") + } + + var r0 *v1alpha1.Application + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*v1alpha1.Application, error)); ok { + return rf(ns, name) + } + if rf, ok := ret.Get(0).(func(string, string) *v1alpha1.Application); ok { + r0 = rf(ns, name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Application) + } + } + + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(ns, name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewApplicationGetter creates a new instance of ApplicationGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewApplicationGetter(t interface { @@ -22,73 +55,3 @@ func NewApplicationGetter(t interface { return mock } - -// ApplicationGetter is an autogenerated mock type for the ApplicationGetter type -type ApplicationGetter struct { - mock.Mock -} - -type ApplicationGetter_Expecter struct { - mock *mock.Mock -} - -func (_m *ApplicationGetter) EXPECT() *ApplicationGetter_Expecter { - return &ApplicationGetter_Expecter{mock: &_m.Mock} -} - -// Get provides a mock function for the type ApplicationGetter -func (_mock *ApplicationGetter) Get(ns string, name string) (*v1alpha1.Application, error) { - ret := _mock.Called(ns, name) - - if len(ret) == 0 { - panic("no return value specified for Get") - } - - var r0 *v1alpha1.Application - var r1 error - if returnFunc, ok := ret.Get(0).(func(string, string) (*v1alpha1.Application, error)); ok { - return returnFunc(ns, name) - } - if returnFunc, ok := ret.Get(0).(func(string, string) *v1alpha1.Application); ok { - r0 = returnFunc(ns, name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Application) - } - } - if returnFunc, ok := ret.Get(1).(func(string, string) error); ok { - r1 = returnFunc(ns, name) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ApplicationGetter_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' -type ApplicationGetter_Get_Call struct { - *mock.Call -} - -// Get is a helper method to define mock.On call -// - ns -// - name -func (_e *ApplicationGetter_Expecter) Get(ns interface{}, name interface{}) *ApplicationGetter_Get_Call { - return &ApplicationGetter_Get_Call{Call: _e.mock.On("Get", ns, name)} -} - -func (_c *ApplicationGetter_Get_Call) Run(run func(ns string, name string)) *ApplicationGetter_Get_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) - }) - return _c -} - -func (_c *ApplicationGetter_Get_Call) Return(application *v1alpha1.Application, err error) *ApplicationGetter_Get_Call { - _c.Call.Return(application, err) - return _c -} - -func (_c *ApplicationGetter_Get_Call) RunAndReturn(run func(ns string, name string) (*v1alpha1.Application, error)) *ApplicationGetter_Get_Call { - _c.Call.Return(run) - return _c -} diff --git a/server/extension/mocks/ExtensionMetricsRegistry.go b/server/extension/mocks/ExtensionMetricsRegistry.go index b1a1ea3b10..d2765f604c 100644 --- a/server/extension/mocks/ExtensionMetricsRegistry.go +++ b/server/extension/mocks/ExtensionMetricsRegistry.go @@ -1,15 +1,28 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "time" + time "time" mock "github.com/stretchr/testify/mock" ) +// ExtensionMetricsRegistry is an autogenerated mock type for the ExtensionMetricsRegistry type +type ExtensionMetricsRegistry struct { + mock.Mock +} + +// IncExtensionRequestCounter provides a mock function with given fields: _a0, status +func (_m *ExtensionMetricsRegistry) IncExtensionRequestCounter(_a0 string, status int) { + _m.Called(_a0, status) +} + +// ObserveExtensionRequestDuration provides a mock function with given fields: _a0, duration +func (_m *ExtensionMetricsRegistry) ObserveExtensionRequestDuration(_a0 string, duration time.Duration) { + _m.Called(_a0, duration) +} + // NewExtensionMetricsRegistry creates a new instance of ExtensionMetricsRegistry. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewExtensionMetricsRegistry(t interface { @@ -23,86 +36,3 @@ func NewExtensionMetricsRegistry(t interface { return mock } - -// ExtensionMetricsRegistry is an autogenerated mock type for the ExtensionMetricsRegistry type -type ExtensionMetricsRegistry struct { - mock.Mock -} - -type ExtensionMetricsRegistry_Expecter struct { - mock *mock.Mock -} - -func (_m *ExtensionMetricsRegistry) EXPECT() *ExtensionMetricsRegistry_Expecter { - return &ExtensionMetricsRegistry_Expecter{mock: &_m.Mock} -} - -// IncExtensionRequestCounter provides a mock function for the type ExtensionMetricsRegistry -func (_mock *ExtensionMetricsRegistry) IncExtensionRequestCounter(extension string, status int) { - _mock.Called(extension, status) - return -} - -// ExtensionMetricsRegistry_IncExtensionRequestCounter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IncExtensionRequestCounter' -type ExtensionMetricsRegistry_IncExtensionRequestCounter_Call struct { - *mock.Call -} - -// IncExtensionRequestCounter is a helper method to define mock.On call -// - extension -// - status -func (_e *ExtensionMetricsRegistry_Expecter) IncExtensionRequestCounter(extension interface{}, status interface{}) *ExtensionMetricsRegistry_IncExtensionRequestCounter_Call { - return &ExtensionMetricsRegistry_IncExtensionRequestCounter_Call{Call: _e.mock.On("IncExtensionRequestCounter", extension, status)} -} - -func (_c *ExtensionMetricsRegistry_IncExtensionRequestCounter_Call) Run(run func(extension string, status int)) *ExtensionMetricsRegistry_IncExtensionRequestCounter_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(int)) - }) - return _c -} - -func (_c *ExtensionMetricsRegistry_IncExtensionRequestCounter_Call) Return() *ExtensionMetricsRegistry_IncExtensionRequestCounter_Call { - _c.Call.Return() - return _c -} - -func (_c *ExtensionMetricsRegistry_IncExtensionRequestCounter_Call) RunAndReturn(run func(extension string, status int)) *ExtensionMetricsRegistry_IncExtensionRequestCounter_Call { - _c.Run(run) - return _c -} - -// ObserveExtensionRequestDuration provides a mock function for the type ExtensionMetricsRegistry -func (_mock *ExtensionMetricsRegistry) ObserveExtensionRequestDuration(extension string, duration time.Duration) { - _mock.Called(extension, duration) - return -} - -// ExtensionMetricsRegistry_ObserveExtensionRequestDuration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ObserveExtensionRequestDuration' -type ExtensionMetricsRegistry_ObserveExtensionRequestDuration_Call struct { - *mock.Call -} - -// ObserveExtensionRequestDuration is a helper method to define mock.On call -// - extension -// - duration -func (_e *ExtensionMetricsRegistry_Expecter) ObserveExtensionRequestDuration(extension interface{}, duration interface{}) *ExtensionMetricsRegistry_ObserveExtensionRequestDuration_Call { - return &ExtensionMetricsRegistry_ObserveExtensionRequestDuration_Call{Call: _e.mock.On("ObserveExtensionRequestDuration", extension, duration)} -} - -func (_c *ExtensionMetricsRegistry_ObserveExtensionRequestDuration_Call) Run(run func(extension string, duration time.Duration)) *ExtensionMetricsRegistry_ObserveExtensionRequestDuration_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(time.Duration)) - }) - return _c -} - -func (_c *ExtensionMetricsRegistry_ObserveExtensionRequestDuration_Call) Return() *ExtensionMetricsRegistry_ObserveExtensionRequestDuration_Call { - _c.Call.Return() - return _c -} - -func (_c *ExtensionMetricsRegistry_ObserveExtensionRequestDuration_Call) RunAndReturn(run func(extension string, duration time.Duration)) *ExtensionMetricsRegistry_ObserveExtensionRequestDuration_Call { - _c.Run(run) - return _c -} diff --git a/server/extension/mocks/ProjectGetter.go b/server/extension/mocks/ProjectGetter.go index 1cb3f855e9..6fbe416923 100644 --- a/server/extension/mocks/ProjectGetter.go +++ b/server/extension/mocks/ProjectGetter.go @@ -1,14 +1,77 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" mock "github.com/stretchr/testify/mock" ) +// ProjectGetter is an autogenerated mock type for the ProjectGetter type +type ProjectGetter struct { + mock.Mock +} + +// Get provides a mock function with given fields: name +func (_m *ProjectGetter) Get(name string) (*v1alpha1.AppProject, error) { + ret := _m.Called(name) + + if len(ret) == 0 { + panic("no return value specified for Get") + } + + var r0 *v1alpha1.AppProject + var r1 error + if rf, ok := ret.Get(0).(func(string) (*v1alpha1.AppProject, error)); ok { + return rf(name) + } + if rf, ok := ret.Get(0).(func(string) *v1alpha1.AppProject); ok { + r0 = rf(name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.AppProject) + } + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetClusters provides a mock function with given fields: project +func (_m *ProjectGetter) GetClusters(project string) ([]*v1alpha1.Cluster, error) { + ret := _m.Called(project) + + if len(ret) == 0 { + panic("no return value specified for GetClusters") + } + + var r0 []*v1alpha1.Cluster + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*v1alpha1.Cluster, error)); ok { + return rf(project) + } + if rf, ok := ret.Get(0).(func(string) []*v1alpha1.Cluster); ok { + r0 = rf(project) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1alpha1.Cluster) + } + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(project) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewProjectGetter creates a new instance of ProjectGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewProjectGetter(t interface { @@ -22,128 +85,3 @@ func NewProjectGetter(t interface { return mock } - -// ProjectGetter is an autogenerated mock type for the ProjectGetter type -type ProjectGetter struct { - mock.Mock -} - -type ProjectGetter_Expecter struct { - mock *mock.Mock -} - -func (_m *ProjectGetter) EXPECT() *ProjectGetter_Expecter { - return &ProjectGetter_Expecter{mock: &_m.Mock} -} - -// Get provides a mock function for the type ProjectGetter -func (_mock *ProjectGetter) Get(name string) (*v1alpha1.AppProject, error) { - ret := _mock.Called(name) - - if len(ret) == 0 { - panic("no return value specified for Get") - } - - var r0 *v1alpha1.AppProject - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) (*v1alpha1.AppProject, error)); ok { - return returnFunc(name) - } - if returnFunc, ok := ret.Get(0).(func(string) *v1alpha1.AppProject); ok { - r0 = returnFunc(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.AppProject) - } - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(name) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ProjectGetter_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' -type ProjectGetter_Get_Call struct { - *mock.Call -} - -// Get is a helper method to define mock.On call -// - name -func (_e *ProjectGetter_Expecter) Get(name interface{}) *ProjectGetter_Get_Call { - return &ProjectGetter_Get_Call{Call: _e.mock.On("Get", name)} -} - -func (_c *ProjectGetter_Get_Call) Run(run func(name string)) *ProjectGetter_Get_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *ProjectGetter_Get_Call) Return(appProject *v1alpha1.AppProject, err error) *ProjectGetter_Get_Call { - _c.Call.Return(appProject, err) - return _c -} - -func (_c *ProjectGetter_Get_Call) RunAndReturn(run func(name string) (*v1alpha1.AppProject, error)) *ProjectGetter_Get_Call { - _c.Call.Return(run) - return _c -} - -// GetClusters provides a mock function for the type ProjectGetter -func (_mock *ProjectGetter) GetClusters(project string) ([]*v1alpha1.Cluster, error) { - ret := _mock.Called(project) - - if len(ret) == 0 { - panic("no return value specified for GetClusters") - } - - var r0 []*v1alpha1.Cluster - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) ([]*v1alpha1.Cluster, error)); ok { - return returnFunc(project) - } - if returnFunc, ok := ret.Get(0).(func(string) []*v1alpha1.Cluster); ok { - r0 = returnFunc(project) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*v1alpha1.Cluster) - } - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(project) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ProjectGetter_GetClusters_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetClusters' -type ProjectGetter_GetClusters_Call struct { - *mock.Call -} - -// GetClusters is a helper method to define mock.On call -// - project -func (_e *ProjectGetter_Expecter) GetClusters(project interface{}) *ProjectGetter_GetClusters_Call { - return &ProjectGetter_GetClusters_Call{Call: _e.mock.On("GetClusters", project)} -} - -func (_c *ProjectGetter_GetClusters_Call) Run(run func(project string)) *ProjectGetter_GetClusters_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *ProjectGetter_GetClusters_Call) Return(clusters []*v1alpha1.Cluster, err error) *ProjectGetter_GetClusters_Call { - _c.Call.Return(clusters, err) - return _c -} - -func (_c *ProjectGetter_GetClusters_Call) RunAndReturn(run func(project string) ([]*v1alpha1.Cluster, error)) *ProjectGetter_GetClusters_Call { - _c.Call.Return(run) - return _c -} diff --git a/server/extension/mocks/RbacEnforcer.go b/server/extension/mocks/RbacEnforcer.go index 3bc9b20625..a5f705b80d 100644 --- a/server/extension/mocks/RbacEnforcer.go +++ b/server/extension/mocks/RbacEnforcer.go @@ -1,12 +1,33 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks -import ( - mock "github.com/stretchr/testify/mock" -) +import mock "github.com/stretchr/testify/mock" + +// RbacEnforcer is an autogenerated mock type for the RbacEnforcer type +type RbacEnforcer struct { + mock.Mock +} + +// EnforceErr provides a mock function with given fields: rvals +func (_m *RbacEnforcer) EnforceErr(rvals ...interface{}) error { + var _ca []interface{} + _ca = append(_ca, rvals...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for EnforceErr") + } + + var r0 error + if rf, ok := ret.Get(0).(func(...interface{}) error); ok { + r0 = rf(rvals...) + } else { + r0 = ret.Error(0) + } + + return r0 +} // NewRbacEnforcer creates a new instance of RbacEnforcer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. @@ -21,70 +42,3 @@ func NewRbacEnforcer(t interface { return mock } - -// RbacEnforcer is an autogenerated mock type for the RbacEnforcer type -type RbacEnforcer struct { - mock.Mock -} - -type RbacEnforcer_Expecter struct { - mock *mock.Mock -} - -func (_m *RbacEnforcer) EXPECT() *RbacEnforcer_Expecter { - return &RbacEnforcer_Expecter{mock: &_m.Mock} -} - -// EnforceErr provides a mock function for the type RbacEnforcer -func (_mock *RbacEnforcer) EnforceErr(rvals ...any) error { - var _ca []interface{} - _ca = append(_ca, rvals...) - ret := _mock.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for EnforceErr") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(...any) error); ok { - r0 = returnFunc(rvals...) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// RbacEnforcer_EnforceErr_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EnforceErr' -type RbacEnforcer_EnforceErr_Call struct { - *mock.Call -} - -// EnforceErr is a helper method to define mock.On call -// - rvals -func (_e *RbacEnforcer_Expecter) EnforceErr(rvals ...interface{}) *RbacEnforcer_EnforceErr_Call { - return &RbacEnforcer_EnforceErr_Call{Call: _e.mock.On("EnforceErr", - append([]interface{}{}, rvals...)...)} -} - -func (_c *RbacEnforcer_EnforceErr_Call) Run(run func(rvals ...any)) *RbacEnforcer_EnforceErr_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]any, len(args)-0) - for i, a := range args[0:] { - if a != nil { - variadicArgs[i] = a.(any) - } - } - run(variadicArgs...) - }) - return _c -} - -func (_c *RbacEnforcer_EnforceErr_Call) Return(err error) *RbacEnforcer_EnforceErr_Call { - _c.Call.Return(err) - return _c -} - -func (_c *RbacEnforcer_EnforceErr_Call) RunAndReturn(run func(rvals ...any) error) *RbacEnforcer_EnforceErr_Call { - _c.Call.Return(run) - return _c -} diff --git a/server/extension/mocks/SettingsGetter.go b/server/extension/mocks/SettingsGetter.go index ca4842a042..fe8cd13477 100644 --- a/server/extension/mocks/SettingsGetter.go +++ b/server/extension/mocks/SettingsGetter.go @@ -1,14 +1,47 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "github.com/argoproj/argo-cd/v3/util/settings" + settings "github.com/argoproj/argo-cd/v2/util/settings" mock "github.com/stretchr/testify/mock" ) +// SettingsGetter is an autogenerated mock type for the SettingsGetter type +type SettingsGetter struct { + mock.Mock +} + +// Get provides a mock function with no fields +func (_m *SettingsGetter) Get() (*settings.ArgoCDSettings, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Get") + } + + var r0 *settings.ArgoCDSettings + var r1 error + if rf, ok := ret.Get(0).(func() (*settings.ArgoCDSettings, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() *settings.ArgoCDSettings); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*settings.ArgoCDSettings) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewSettingsGetter creates a new instance of SettingsGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewSettingsGetter(t interface { @@ -22,71 +55,3 @@ func NewSettingsGetter(t interface { return mock } - -// SettingsGetter is an autogenerated mock type for the SettingsGetter type -type SettingsGetter struct { - mock.Mock -} - -type SettingsGetter_Expecter struct { - mock *mock.Mock -} - -func (_m *SettingsGetter) EXPECT() *SettingsGetter_Expecter { - return &SettingsGetter_Expecter{mock: &_m.Mock} -} - -// Get provides a mock function for the type SettingsGetter -func (_mock *SettingsGetter) Get() (*settings.ArgoCDSettings, error) { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for Get") - } - - var r0 *settings.ArgoCDSettings - var r1 error - if returnFunc, ok := ret.Get(0).(func() (*settings.ArgoCDSettings, error)); ok { - return returnFunc() - } - if returnFunc, ok := ret.Get(0).(func() *settings.ArgoCDSettings); ok { - r0 = returnFunc() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*settings.ArgoCDSettings) - } - } - if returnFunc, ok := ret.Get(1).(func() error); ok { - r1 = returnFunc() - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// SettingsGetter_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' -type SettingsGetter_Get_Call struct { - *mock.Call -} - -// Get is a helper method to define mock.On call -func (_e *SettingsGetter_Expecter) Get() *SettingsGetter_Get_Call { - return &SettingsGetter_Get_Call{Call: _e.mock.On("Get")} -} - -func (_c *SettingsGetter_Get_Call) Run(run func()) *SettingsGetter_Get_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *SettingsGetter_Get_Call) Return(argoCDSettings *settings.ArgoCDSettings, err error) *SettingsGetter_Get_Call { - _c.Call.Return(argoCDSettings, err) - return _c -} - -func (_c *SettingsGetter_Get_Call) RunAndReturn(run func() (*settings.ArgoCDSettings, error)) *SettingsGetter_Get_Call { - _c.Call.Return(run) - return _c -} diff --git a/server/extension/mocks/UserGetter.go b/server/extension/mocks/UserGetter.go index 878cb9be62..29604e2fe5 100644 --- a/server/extension/mocks/UserGetter.go +++ b/server/extension/mocks/UserGetter.go @@ -1,15 +1,56 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" + context "context" mock "github.com/stretchr/testify/mock" ) +// UserGetter is an autogenerated mock type for the UserGetter type +type UserGetter struct { + mock.Mock +} + +// GetGroups provides a mock function with given fields: ctx +func (_m *UserGetter) GetGroups(ctx context.Context) []string { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetGroups") + } + + var r0 []string + if rf, ok := ret.Get(0).(func(context.Context) []string); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + return r0 +} + +// GetUser provides a mock function with given fields: ctx +func (_m *UserGetter) GetUser(ctx context.Context) string { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetUser") + } + + var r0 string + if rf, ok := ret.Get(0).(func(context.Context) string); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + // NewUserGetter creates a new instance of UserGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewUserGetter(t interface { @@ -23,108 +64,3 @@ func NewUserGetter(t interface { return mock } - -// UserGetter is an autogenerated mock type for the UserGetter type -type UserGetter struct { - mock.Mock -} - -type UserGetter_Expecter struct { - mock *mock.Mock -} - -func (_m *UserGetter) EXPECT() *UserGetter_Expecter { - return &UserGetter_Expecter{mock: &_m.Mock} -} - -// GetGroups provides a mock function for the type UserGetter -func (_mock *UserGetter) GetGroups(ctx context.Context) []string { - ret := _mock.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for GetGroups") - } - - var r0 []string - if returnFunc, ok := ret.Get(0).(func(context.Context) []string); ok { - r0 = returnFunc(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - return r0 -} - -// UserGetter_GetGroups_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGroups' -type UserGetter_GetGroups_Call struct { - *mock.Call -} - -// GetGroups is a helper method to define mock.On call -// - ctx -func (_e *UserGetter_Expecter) GetGroups(ctx interface{}) *UserGetter_GetGroups_Call { - return &UserGetter_GetGroups_Call{Call: _e.mock.On("GetGroups", ctx)} -} - -func (_c *UserGetter_GetGroups_Call) Run(run func(ctx context.Context)) *UserGetter_GetGroups_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *UserGetter_GetGroups_Call) Return(strings []string) *UserGetter_GetGroups_Call { - _c.Call.Return(strings) - return _c -} - -func (_c *UserGetter_GetGroups_Call) RunAndReturn(run func(ctx context.Context) []string) *UserGetter_GetGroups_Call { - _c.Call.Return(run) - return _c -} - -// GetUser provides a mock function for the type UserGetter -func (_mock *UserGetter) GetUser(ctx context.Context) string { - ret := _mock.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for GetUser") - } - - var r0 string - if returnFunc, ok := ret.Get(0).(func(context.Context) string); ok { - r0 = returnFunc(ctx) - } else { - r0 = ret.Get(0).(string) - } - return r0 -} - -// UserGetter_GetUser_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetUser' -type UserGetter_GetUser_Call struct { - *mock.Call -} - -// GetUser is a helper method to define mock.On call -// - ctx -func (_e *UserGetter_Expecter) GetUser(ctx interface{}) *UserGetter_GetUser_Call { - return &UserGetter_GetUser_Call{Call: _e.mock.On("GetUser", ctx)} -} - -func (_c *UserGetter_GetUser_Call) Run(run func(ctx context.Context)) *UserGetter_GetUser_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *UserGetter_GetUser_Call) Return(s string) *UserGetter_GetUser_Call { - _c.Call.Return(s) - return _c -} - -func (_c *UserGetter_GetUser_Call) RunAndReturn(run func(ctx context.Context) string) *UserGetter_GetUser_Call { - _c.Call.Return(run) - return _c -} diff --git a/server/gpgkey/gpgkey.go b/server/gpgkey/gpgkey.go index 3d1855bac6..23f45e41e8 100644 --- a/server/gpgkey/gpgkey.go +++ b/server/gpgkey/gpgkey.go @@ -6,12 +6,12 @@ import ( "fmt" "strings" - gpgkeypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/gpgkey" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/gpg" - "github.com/argoproj/argo-cd/v3/util/rbac" + gpgkeypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/gpgkey" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/gpg" + "github.com/argoproj/argo-cd/v2/util/rbac" ) // Server provides a service of type GPGKeyService @@ -72,10 +72,10 @@ func (s *Server) Get(ctx context.Context, q *gpgkeypkg.GnuPGPublicKeyQuery) (*ap return key, nil } - return nil, fmt.Errorf("no such key: %s", keyID) + return nil, fmt.Errorf("No such key: %s", keyID) } -// Create adds one or more GPG public keys to the server's configuration +// CreateGnuPGPublicKey adds one or more GPG public keys to the server's configuration func (s *Server) Create(ctx context.Context, q *gpgkeypkg.GnuPGPublicKeyCreateRequest) (*gpgkeypkg.GnuPGPublicKeyCreateResponse, error) { if err := s.enf.EnforceErr(ctx.Value("claims"), rbac.ResourceGPGKeys, rbac.ActionCreate, ""); err != nil { return nil, err @@ -83,7 +83,7 @@ func (s *Server) Create(ctx context.Context, q *gpgkeypkg.GnuPGPublicKeyCreateRe keyData := strings.TrimSpace(q.Publickey.KeyData) if keyData == "" { - return nil, errors.New("submitted key data is empty") + return nil, errors.New("Submitted key data is empty") } added, skipped, err := s.db.AddGPGPublicKey(ctx, q.Publickey.KeyData) diff --git a/server/gpgkey/gpgkey.proto b/server/gpgkey/gpgkey.proto index 96677fa1d2..6309f7dc49 100644 --- a/server/gpgkey/gpgkey.proto +++ b/server/gpgkey/gpgkey.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/gpgkey"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/gpgkey"; // GPG public key service // @@ -7,7 +7,7 @@ option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/gpgkey"; package gpgkey; import "google/api/annotations.proto"; -import "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto"; +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; // Message to query the server for configured GPG public keys message GnuPGPublicKeyQuery { @@ -18,7 +18,7 @@ message GnuPGPublicKeyQuery { // Request to create one or more public keys on the server message GnuPGPublicKeyCreateRequest { // Raw key data of the GPG key(s) to create - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.GnuPGPublicKey publickey = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.GnuPGPublicKey publickey = 1; // Whether to upsert already existing public keys bool upsert = 2; } @@ -26,7 +26,7 @@ message GnuPGPublicKeyCreateRequest { // Response to a public key creation request message GnuPGPublicKeyCreateResponse { // List of GPG public keys that have been created - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.GnuPGPublicKeyList created = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.GnuPGPublicKeyList created = 1; // List of key IDs that haven been skipped because they already exist on the server repeated string skipped = 2; } @@ -37,12 +37,12 @@ message GnuPGPublicKeyResponse {} // GPGKeyService implements API for managing GPG public keys on the server service GPGKeyService { // List all available repository certificates - rpc List(GnuPGPublicKeyQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.GnuPGPublicKeyList) { + rpc List(GnuPGPublicKeyQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.GnuPGPublicKeyList) { option (google.api.http).get = "/api/v1/gpgkeys"; } // Get information about specified GPG public key from the server - rpc Get(GnuPGPublicKeyQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.GnuPGPublicKey) { + rpc Get(GnuPGPublicKeyQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.GnuPGPublicKey) { option (google.api.http).get = "/api/v1/gpgkeys/{keyID}"; } diff --git a/server/logout/logout.go b/server/logout/logout.go index 4a068df555..6129e2f9a8 100644 --- a/server/logout/logout.go +++ b/server/logout/logout.go @@ -2,20 +2,21 @@ package logout import ( "context" + "fmt" "net/http" "regexp" "strings" "time" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - httputil "github.com/argoproj/argo-cd/v3/util/http" - jwtutil "github.com/argoproj/argo-cd/v3/util/jwt" - "github.com/argoproj/argo-cd/v3/util/session" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + httputil "github.com/argoproj/argo-cd/v2/util/http" + jwtutil "github.com/argoproj/argo-cd/v2/util/jwt" + "github.com/argoproj/argo-cd/v2/util/session" + "github.com/argoproj/argo-cd/v2/util/settings" ) // NewHandler creates handler serving to do api/logout endpoint @@ -60,7 +61,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { argoCDSettings, err := h.settingsMgr.GetSettings() if err != nil { w.WriteHeader(http.StatusInternalServerError) - http.Error(w, "Failed to retrieve argoCD settings: "+err.Error(), http.StatusInternalServerError) + http.Error(w, "Failed to retrieve argoCD settings: "+fmt.Sprintf("%s", err), http.StatusInternalServerError) return } @@ -72,7 +73,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // golang does not provide any easy way to determine scheme of current request // so redirecting ot http which will auto-redirect too https if necessary host := strings.TrimRight(r.Host, "/") - argoURL = "http://" + host + "/" + strings.TrimRight(strings.TrimLeft(h.rootPath, "/"), "/") + argoURL = fmt.Sprintf("http://%s", host) + "/" + strings.TrimRight(strings.TrimLeft(h.rootPath, "/"), "/") } logoutRedirectURL := strings.TrimRight(strings.TrimLeft(argoURL, "/"), "/") @@ -81,7 +82,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { tokenString, err = httputil.JoinCookies(common.AuthCookieName, cookies) if tokenString == "" || err != nil { w.WriteHeader(http.StatusBadRequest) - http.Error(w, "Failed to retrieve ArgoCD auth token: "+err.Error(), http.StatusBadRequest) + http.Error(w, "Failed to retrieve ArgoCD auth token: "+fmt.Sprintf("%s", err), http.StatusBadRequest) return } @@ -95,7 +96,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { Value: "", } - argocdCookie.Path = "/" + strings.TrimRight(strings.TrimLeft(h.baseHRef, "/"), "/") + argocdCookie.Path = fmt.Sprintf("/%s", strings.TrimRight(strings.TrimLeft(h.baseHRef, "/"), "/")) w.Header().Add("Set-Cookie", argocdCookie.String()) } diff --git a/server/logout/logout_test.go b/server/logout/logout_test.go index 6eaa0c5232..83bf8ee5d9 100644 --- a/server/logout/logout_test.go +++ b/server/logout/logout_test.go @@ -1,6 +1,7 @@ package logout import ( + "context" "errors" "net/http" "net/http/httptest" @@ -8,13 +9,13 @@ import ( "strconv" "testing" - "github.com/argoproj/argo-cd/v3/common" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/session" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/session" + "github.com/argoproj/argo-cd/v2/util/settings" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" @@ -237,11 +238,11 @@ func TestHandlerConstructLogoutURL(t *testing.T) { }, ) - settingsManagerWithOIDCConfig := settings.NewSettingsManager(t.Context(), kubeClientWithOIDCConfig, "default") - settingsManagerWithoutOIDCConfig := settings.NewSettingsManager(t.Context(), kubeClientWithoutOIDCConfig, "default") - settingsManagerWithOIDCConfigButNoLogoutURL := settings.NewSettingsManager(t.Context(), kubeClientWithOIDCConfigButNoLogoutURL, "default") - settingsManagerWithoutOIDCAndMultipleURLs := settings.NewSettingsManager(t.Context(), kubeClientWithoutOIDCAndMultipleURLs, "default") - settingsManagerWithOIDCConfigButNoURL := settings.NewSettingsManager(t.Context(), kubeClientWithOIDCConfigButNoURL, "default") + settingsManagerWithOIDCConfig := settings.NewSettingsManager(context.Background(), kubeClientWithOIDCConfig, "default") + settingsManagerWithoutOIDCConfig := settings.NewSettingsManager(context.Background(), kubeClientWithoutOIDCConfig, "default") + settingsManagerWithOIDCConfigButNoLogoutURL := settings.NewSettingsManager(context.Background(), kubeClientWithOIDCConfigButNoLogoutURL, "default") + settingsManagerWithoutOIDCAndMultipleURLs := settings.NewSettingsManager(context.Background(), kubeClientWithoutOIDCAndMultipleURLs, "default") + settingsManagerWithOIDCConfigButNoURL := settings.NewSettingsManager(context.Background(), kubeClientWithOIDCConfigButNoURL, "default") sessionManager := session.NewSessionManager(settingsManagerWithOIDCConfig, test.NewFakeProjLister(), "", nil, session.NewUserStateStorage(nil)) diff --git a/server/metrics/metrics.go b/server/metrics/metrics.go index 8c881fca97..3056a4e3e9 100644 --- a/server/metrics/metrics.go +++ b/server/metrics/metrics.go @@ -9,9 +9,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/metrics/kubectl" - "github.com/argoproj/argo-cd/v3/util/profile" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/profile" ) type MetricsServer struct { @@ -81,10 +80,6 @@ func NewMetricsServer(host string, port int) *MetricsServer { registry.MustRegister(extensionRequestDuration) registry.MustRegister(argoVersion) - kubectlMetricsServer := kubectl.NewKubectlMetrics() - kubectlMetricsServer.RegisterWithClientGo() - kubectl.RegisterWithPrometheus(registry) - return &MetricsServer{ Server: &http.Server{ Addr: fmt.Sprintf("%s:%d", host, port), diff --git a/server/notification/notification.go b/server/notification/notification.go index d17e925845..7b8f6589fc 100644 --- a/server/notification/notification.go +++ b/server/notification/notification.go @@ -4,10 +4,10 @@ import ( "context" "github.com/argoproj/notifications-engine/pkg/api" - apierrors "k8s.io/apimachinery/pkg/api/errors" + apierr "k8s.io/apimachinery/pkg/api/errors" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/notification" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/notification" ) // Server provides an Application service @@ -22,10 +22,10 @@ func NewServer(apiFactory api.Factory) notification.NotificationServiceServer { } // List returns list of notification triggers -func (s *Server) ListTriggers(_ context.Context, _ *notification.TriggersListRequest) (*notification.TriggerList, error) { +func (s *Server) ListTriggers(ctx context.Context, q *notification.TriggersListRequest) (*notification.TriggerList, error) { api, err := s.apiFactory.GetAPI() if err != nil { - if apierrors.IsNotFound(err) { + if apierr.IsNotFound(err) { return ¬ification.TriggerList{}, nil } } @@ -37,10 +37,10 @@ func (s *Server) ListTriggers(_ context.Context, _ *notification.TriggersListReq } // List returns list of notification services -func (s *Server) ListServices(_ context.Context, _ *notification.ServicesListRequest) (*notification.ServiceList, error) { +func (s *Server) ListServices(ctx context.Context, q *notification.ServicesListRequest) (*notification.ServiceList, error) { api, err := s.apiFactory.GetAPI() if err != nil { - if apierrors.IsNotFound(err) { + if apierr.IsNotFound(err) { return ¬ification.ServiceList{}, nil } return nil, err @@ -53,10 +53,10 @@ func (s *Server) ListServices(_ context.Context, _ *notification.ServicesListReq } // List returns list of notification templates -func (s *Server) ListTemplates(_ context.Context, _ *notification.TemplatesListRequest) (*notification.TemplateList, error) { +func (s *Server) ListTemplates(ctx context.Context, q *notification.TemplatesListRequest) (*notification.TemplateList, error) { api, err := s.apiFactory.GetAPI() if err != nil { - if apierrors.IsNotFound(err) { + if apierr.IsNotFound(err) { return ¬ification.TemplateList{}, nil } return nil, err diff --git a/server/notification/notification.proto b/server/notification/notification.proto index 9818a9fb00..fbd46a8994 100644 --- a/server/notification/notification.proto +++ b/server/notification/notification.proto @@ -1,5 +1,5 @@ syntax = "proto2"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/notification"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/notification"; // Notification Service // diff --git a/server/notification/notification_test.go b/server/notification/notification_test.go index 144e3ac30f..38467e7d59 100644 --- a/server/notification/notification_test.go +++ b/server/notification/notification_test.go @@ -1,6 +1,7 @@ package notification import ( + "context" "os" "testing" @@ -10,13 +11,13 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/notification" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient/mocks" - service "github.com/argoproj/argo-cd/v3/util/notification/argocd" - "github.com/argoproj/argo-cd/v3/util/notification/k8s" - "github.com/argoproj/argo-cd/v3/util/notification/settings" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/notification" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" + service "github.com/argoproj/argo-cd/v2/util/notification/argocd" + "github.com/argoproj/argo-cd/v2/util/notification/k8s" + "github.com/argoproj/argo-cd/v2/util/notification/settings" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" k8scache "k8s.io/client-go/tools/cache" "k8s.io/kubectl/pkg/scheme" @@ -35,7 +36,7 @@ func TestNotificationServer(t *testing.T) { cm.Namespace = testNamespace kubeclientset := fake.NewClientset(&corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-notifications-cm", }, @@ -46,14 +47,14 @@ func TestNotificationServer(t *testing.T) { }, }, &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "argocd-notifications-secret", Namespace: testNamespace, }, Data: map[string][]byte{}, }) - ctx := t.Context() + ctx := context.Background() secretInformer := k8s.NewSecretInformer(kubeclientset, testNamespace, "argocd-notifications-secret") configMapInformer := k8s.NewConfigMapInformer(kubeclientset, testNamespace, "argocd-notifications-cm") go secretInformer.Run(ctx.Done()) diff --git a/server/project/project.go b/server/project/project.go index 156a1326b4..bdeb51b2fb 100644 --- a/server/project/project.go +++ b/server/project/project.go @@ -7,8 +7,8 @@ import ( "strings" "github.com/argoproj/gitops-engine/pkg/utils/kube" - "github.com/argoproj/pkg/v2/sync" - "github.com/golang-jwt/jwt/v5" + "github.com/argoproj/pkg/sync" + "github.com/golang-jwt/jwt/v4" "github.com/google/uuid" log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" @@ -21,19 +21,19 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/retry" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/project" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - listersv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/server/deeplinks" - "github.com/argoproj/argo-cd/v3/server/rbacpolicy" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/db" - jwtutil "github.com/argoproj/argo-cd/v3/util/jwt" - "github.com/argoproj/argo-cd/v3/util/rbac" - "github.com/argoproj/argo-cd/v3/util/session" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/project" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + listersv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/server/deeplinks" + "github.com/argoproj/argo-cd/v2/server/rbacpolicy" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/db" + jwtutil "github.com/argoproj/argo-cd/v2/util/jwt" + "github.com/argoproj/argo-cd/v2/util/rbac" + "github.com/argoproj/argo-cd/v2/util/session" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( @@ -157,7 +157,7 @@ func (s *Server) createToken(ctx context.Context, q *project.ProjectTokenCreateR if err != nil { return nil, err } - s.logEvent(ctx, prj, argo.EventReasonResourceCreated, "created token") + s.logEvent(prj, ctx, argo.EventReasonResourceCreated, "created token") return &project.ProjectTokenResponse{Token: jwtToken}, nil } @@ -241,7 +241,7 @@ func (s *Server) deleteToken(ctx context.Context, q *project.ProjectTokenDeleteR if err != nil { return nil, err } - s.logEvent(ctx, prj, argo.EventReasonResourceDeleted, "deleted token") + s.logEvent(prj, ctx, argo.EventReasonResourceDeleted, "deleted token") return &project.EmptyResponse{}, nil } @@ -265,20 +265,21 @@ func (s *Server) Create(ctx context.Context, q *project.ProjectCreateRequest) (* if getErr != nil { return nil, status.Errorf(codes.Internal, "unable to check existing project details: %v", getErr) } - if !q.GetUpsert() { + if q.GetUpsert() { + if err := s.enf.EnforceErr(ctx.Value("claims"), rbac.ResourceProjects, rbac.ActionUpdate, q.GetProject().Name); err != nil { + return nil, err + } + existing.Spec = q.GetProject().Spec + res, err = s.appclientset.ArgoprojV1alpha1().AppProjects(s.ns).Update(ctx, existing, metav1.UpdateOptions{}) + } else { if !reflect.DeepEqual(existing.Spec, q.GetProject().Spec) { return nil, status.Error(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("project", existing.Spec, q.GetProject().Spec)) } return existing, nil } - if err := s.enf.EnforceErr(ctx.Value("claims"), rbac.ResourceProjects, rbac.ActionUpdate, q.GetProject().Name); err != nil { - return nil, err - } - existing.Spec = q.GetProject().Spec - res, err = s.appclientset.ArgoprojV1alpha1().AppProjects(s.ns).Update(ctx, existing, metav1.UpdateOptions{}) } if err == nil { - s.logEvent(ctx, res, argo.EventReasonResourceCreated, "created project") + s.logEvent(res, ctx, argo.EventReasonResourceCreated, "created project") } return res, err } @@ -304,7 +305,7 @@ func (s *Server) GetDetailedProject(ctx context.Context, q *project.ProjectQuery if err := s.enf.EnforceErr(ctx.Value("claims"), rbac.ResourceProjects, rbac.ActionGet, q.Name); err != nil { return nil, err } - proj, repositories, clusters, err := argo.GetAppProjectWithScopedResources(ctx, q.Name, listersv1alpha1.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db) + proj, repositories, clusters, err := argo.GetAppProjectWithScopedResources(q.Name, listersv1alpha1.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx) if err != nil { return nil, err } @@ -409,20 +410,13 @@ func (s *Server) Update(ctx context.Context, q *project.ProjectUpdateRequest) (* invalidSrcCount++ } - destCluster, err := argo.GetDestinationCluster(ctx, a.Spec.Destination, s.db) - if err != nil { - if err.Error() != argo.ErrDestinationMissing { - return nil, err - } - invalidDstCount++ - } - dstPermitted, err := oldProj.IsDestinationPermitted(destCluster, a.Spec.Destination.Namespace, getProjectClusters) + dstPermitted, err := oldProj.IsDestinationPermitted(a.Spec.Destination, getProjectClusters) if err != nil { return nil, err } if dstPermitted { - dstPermitted, err = q.Project.IsDestinationPermitted(destCluster, a.Spec.Destination.Namespace, getProjectClusters) + dstPermitted, err := q.Project.IsDestinationPermitted(a.Spec.Destination, getProjectClusters) if err != nil { return nil, err } @@ -445,7 +439,7 @@ func (s *Server) Update(ctx context.Context, q *project.ProjectUpdateRequest) (* res, err := s.appclientset.ArgoprojV1alpha1().AppProjects(s.ns).Update(ctx, q.Project, metav1.UpdateOptions{}) if err == nil { - s.logEvent(ctx, res, argo.EventReasonResourceUpdated, "updated project") + s.logEvent(res, ctx, argo.EventReasonResourceUpdated, "updated project") } return res, err } @@ -477,7 +471,7 @@ func (s *Server) Delete(ctx context.Context, q *project.ProjectQuery) (*project. } err = s.appclientset.ArgoprojV1alpha1().AppProjects(s.ns).Delete(ctx, q.Name, metav1.DeleteOptions{}) if err == nil { - s.logEvent(ctx, p, argo.EventReasonResourceDeleted, "deleted project") + s.logEvent(p, ctx, argo.EventReasonResourceDeleted, "deleted project") } return &project.EmptyResponse{}, err } @@ -498,7 +492,7 @@ func (s *Server) ListEvents(ctx context.Context, q *project.ProjectQuery) (*core return s.kubeclientset.CoreV1().Events(s.ns).List(ctx, metav1.ListOptions{FieldSelector: fieldSelector}) } -func (s *Server) logEvent(ctx context.Context, a *v1alpha1.AppProject, reason string, action string) { +func (s *Server) logEvent(a *v1alpha1.AppProject, ctx context.Context, reason string, action string) { eventInfo := argo.EventInfo{Type: corev1.EventTypeNormal, Reason: reason} user := session.Username(ctx) if user == "" { diff --git a/server/project/project.proto b/server/project/project.proto index c18e82c80c..5cf4bc977a 100644 --- a/server/project/project.proto +++ b/server/project/project.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/project"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/project"; // Project Service // @@ -8,12 +8,12 @@ package project; import "google/api/annotations.proto"; import "k8s.io/api/core/v1/generated.proto"; -import "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto"; -import "github.com/argoproj/argo-cd/v3/server/application/application.proto"; +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; +import "github.com/argoproj/argo-cd/v2/server/application/application.proto"; // ProjectCreateRequest defines project creation parameters. message ProjectCreateRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProject project = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProject project = 1; bool upsert = 2; } @@ -46,7 +46,7 @@ message ProjectQuery { } message ProjectUpdateRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProject project = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProject project = 1; } message EmptyResponse {} @@ -56,18 +56,18 @@ message SyncWindowsQuery { } message SyncWindowsResponse { - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.SyncWindow windows = 1; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncWindow windows = 1; } message GlobalProjectsResponse { - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProject items = 1; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProject items = 1; } message DetailedProjectsResponse { - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProject globalProjects = 1; - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProject project = 2; - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repositories = 3; - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Cluster clusters = 4; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProject globalProjects = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProject project = 2; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repositories = 3; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Cluster clusters = 4; } message ListProjectLinksRequest { @@ -91,7 +91,7 @@ service ProjectService { } // Create a new project - rpc Create(ProjectCreateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProject) { + rpc Create(ProjectCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProject) { option (google.api.http) = { post: "/api/v1/projects" body: "*" @@ -99,7 +99,7 @@ service ProjectService { } // List returns list of projects - rpc List(ProjectQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProjectList) { + rpc List(ProjectQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProjectList) { option (google.api.http).get = "/api/v1/projects"; } @@ -109,7 +109,7 @@ service ProjectService { } // Get returns a project by name - rpc Get(ProjectQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProject) { + rpc Get(ProjectQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProject) { option (google.api.http).get = "/api/v1/projects/{name}"; } @@ -119,7 +119,7 @@ service ProjectService { } // Update updates a project - rpc Update(ProjectUpdateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.AppProject) { + rpc Update(ProjectUpdateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.AppProject) { option (google.api.http) = { put: "/api/v1/projects/{project.metadata.name}" body: "*" diff --git a/server/project/project_test.go b/server/project/project_test.go index d7b641d4aa..d4d9c3e40e 100644 --- a/server/project/project_test.go +++ b/server/project/project_test.go @@ -6,11 +6,11 @@ import ( "strings" "testing" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/db" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/db" - "github.com/argoproj/pkg/v2/sync" - "github.com/golang-jwt/jwt/v5" + "github.com/argoproj/pkg/sync" + "github.com/golang-jwt/jwt/v4" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -18,21 +18,22 @@ import ( "google.golang.org/grpc/status" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" k8scache "k8s.io/client-go/tools/cache" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/project" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - apps "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - informer "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions" - "github.com/argoproj/argo-cd/v3/server/rbacpolicy" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/assets" - jwtutil "github.com/argoproj/argo-cd/v3/util/jwt" - "github.com/argoproj/argo-cd/v3/util/rbac" - "github.com/argoproj/argo-cd/v3/util/session" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/project" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + apps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + informer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions" + "github.com/argoproj/argo-cd/v2/server/rbacpolicy" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/assets" + jwtutil "github.com/argoproj/argo-cd/v2/util/jwt" + "github.com/argoproj/argo-cd/v2/util/rbac" + "github.com/argoproj/argo-cd/v2/util/session" + "github.com/argoproj/argo-cd/v2/util/settings" ) const testNamespace = "default" @@ -41,7 +42,7 @@ var testEnableEventList = argo.DefaultEnableEventList() func TestProjectServer(t *testing.T) { kubeclientset := fake.NewClientset(&corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-cm", Labels: map[string]string{ @@ -49,7 +50,7 @@ func TestProjectServer(t *testing.T) { }, }, }, &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "argocd-secret", Namespace: testNamespace, }, @@ -57,47 +58,11 @@ func TestProjectServer(t *testing.T) { "admin.password": []byte("test"), "server.secretkey": []byte("test"), }, - }, &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "cluster-1", - Namespace: testNamespace, - Labels: map[string]string{ - common.LabelKeySecretType: common.LabelValueSecretTypeCluster, - }, - }, - Data: map[string][]byte{ - "name": []byte("server1"), - "server": []byte("https://server1"), - }, - }, &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "cluster-2", - Namespace: testNamespace, - Labels: map[string]string{ - common.LabelKeySecretType: common.LabelValueSecretTypeCluster, - }, - }, - Data: map[string][]byte{ - "name": []byte("server2"), - "server": []byte("https://server2"), - }, - }, &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "cluster-3", - Namespace: testNamespace, - Labels: map[string]string{ - common.LabelKeySecretType: common.LabelValueSecretTypeCluster, - }, - }, - Data: map[string][]byte{ - "name": []byte("server3"), - "server": []byte("https://server3"), - }, }) - settingsMgr := settings.NewSettingsManager(t.Context(), kubeclientset, testNamespace) + settingsMgr := settings.NewSettingsManager(context.Background(), kubeclientset, testNamespace) enforcer := newEnforcer(kubeclientset) existingProj := v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: testNamespace}, + ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: testNamespace}, Spec: v1alpha1.AppProjectSpec{ Destinations: []v1alpha1.ApplicationDestination{ {Namespace: "ns1", Server: "https://server1"}, @@ -107,15 +72,15 @@ func TestProjectServer(t *testing.T) { }, } existingApp := v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"}, + ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}, Project: "test", Destination: v1alpha1.ApplicationDestination{Namespace: "ns3", Server: "https://server3"}}, } policyTemplate := "p, proj:%s:%s, applications, %s, %s/%s, %s" - ctx := t.Context() + ctx := context.Background() fakeAppsClientset := apps.NewSimpleClientset() - factory := informer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, informer.WithNamespace(""), informer.WithTweakListOptions(func(_ *metav1.ListOptions) {})) + factory := informer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, informer.WithNamespace(""), informer.WithTweakListOptions(func(options *metav1.ListOptions) {})) projInformer := factory.Argoproj().V1alpha1().AppProjects().Informer() go projInformer.Run(ctx.Done()) if !k8scache.WaitForCacheSync(ctx.Done(), projInformer.HasSynced) { @@ -133,7 +98,7 @@ func TestProjectServer(t *testing.T) { err := projectServer.NormalizeProjs() require.NoError(t, err) - appList, err := projectServer.appclientset.ArgoprojV1alpha1().AppProjects(projectWithRole.Namespace).List(t.Context(), metav1.ListOptions{}) + appList, err := projectServer.appclientset.ArgoprojV1alpha1().AppProjects(projectWithRole.Namespace).List(context.Background(), v1.ListOptions{}) require.NoError(t, err) assert.Equal(t, int64(1), appList.Items[0].Status.JWTTokensByRole[roleName].Items[0].IssuedAt) assert.ElementsMatch(t, appList.Items[0].Status.JWTTokensByRole[roleName].Items, appList.Items[0].Spec.Roles[0].JWTTokens) @@ -148,7 +113,7 @@ func TestProjectServer(t *testing.T) { updatedProj := existingProj.DeepCopy() updatedProj.Spec.Destinations = nil - _, err := projectServer.Update(t.Context(), &project.ProjectUpdateRequest{Project: updatedProj}) + _, err := projectServer.Update(context.Background(), &project.ProjectUpdateRequest{Project: updatedProj}) assert.Equal(t, status.Error(codes.PermissionDenied, "permission denied: clusters, update, https://server1"), err) }) @@ -162,7 +127,7 @@ func TestProjectServer(t *testing.T) { updatedProj := existingProj.DeepCopy() updatedProj.Spec.SourceRepos = nil - _, err := projectServer.Update(t.Context(), &project.ProjectUpdateRequest{Project: updatedProj}) + _, err := projectServer.Update(context.Background(), &project.ProjectUpdateRequest{Project: updatedProj}) assert.Equal(t, status.Error(codes.PermissionDenied, "permission denied: repositories, update, https://github.com/argoproj/argo-cd.git"), err) }) @@ -176,7 +141,7 @@ func TestProjectServer(t *testing.T) { updatedProj := existingProj.DeepCopy() updatedProj.Spec.ClusterResourceWhitelist = []metav1.GroupKind{{}} - _, err := projectServer.Update(t.Context(), &project.ProjectUpdateRequest{Project: updatedProj}) + _, err := projectServer.Update(context.Background(), &project.ProjectUpdateRequest{Project: updatedProj}) assert.Equal(t, status.Error(codes.PermissionDenied, "permission denied: clusters, update, https://server1"), err) }) @@ -190,7 +155,7 @@ func TestProjectServer(t *testing.T) { updatedProj := existingProj.DeepCopy() updatedProj.Spec.NamespaceResourceBlacklist = []metav1.GroupKind{{}} - _, err := projectServer.Update(t.Context(), &project.ProjectUpdateRequest{Project: updatedProj}) + _, err := projectServer.Update(context.Background(), &project.ProjectUpdateRequest{Project: updatedProj}) assert.Equal(t, status.Error(codes.PermissionDenied, "permission denied: clusters, update, https://server1"), err) }) @@ -199,7 +164,7 @@ func TestProjectServer(t *testing.T) { t.Run("TestRemoveDestinationSuccessful", func(t *testing.T) { existingApp := v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"}, + ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}, Project: "test", Destination: v1alpha1.ApplicationDestination{Namespace: "ns3", Server: "https://server3"}}, } @@ -209,14 +174,14 @@ func TestProjectServer(t *testing.T) { updatedProj := existingProj.DeepCopy() updatedProj.Spec.Destinations = updatedProj.Spec.Destinations[1:] - _, err := projectServer.Update(t.Context(), &project.ProjectUpdateRequest{Project: updatedProj}) + _, err := projectServer.Update(context.Background(), &project.ProjectUpdateRequest{Project: updatedProj}) require.NoError(t, err) }) t.Run("TestRemoveDestinationUsedByApp", func(t *testing.T) { existingApp := v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"}, + ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}, Project: "test", Destination: v1alpha1.ApplicationDestination{Namespace: "ns1", Server: "https://server1"}}, } @@ -226,7 +191,7 @@ func TestProjectServer(t *testing.T) { updatedProj := existingProj.DeepCopy() updatedProj.Spec.Destinations = updatedProj.Spec.Destinations[1:] - _, err := projectServer.Update(t.Context(), &project.ProjectUpdateRequest{Project: updatedProj}) + _, err := projectServer.Update(context.Background(), &project.ProjectUpdateRequest{Project: updatedProj}) require.Error(t, err) statusCode, _ := status.FromError(err) @@ -236,8 +201,8 @@ func TestProjectServer(t *testing.T) { t.Run("TestRemoveSourceSuccessful", func(t *testing.T) { existingApp := v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"}, - Spec: v1alpha1.ApplicationSpec{Destination: v1alpha1.ApplicationDestination{Server: "https://server1"}, Source: &v1alpha1.ApplicationSource{}, Project: "test"}, + ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, + Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}, Project: "test"}, } argoDB := db.NewDB("default", settingsMgr, kubeclientset) @@ -246,15 +211,15 @@ func TestProjectServer(t *testing.T) { updatedProj := existingProj.DeepCopy() updatedProj.Spec.SourceRepos = []string{} - _, err := projectServer.Update(t.Context(), &project.ProjectUpdateRequest{Project: updatedProj}) + _, err := projectServer.Update(context.Background(), &project.ProjectUpdateRequest{Project: updatedProj}) require.NoError(t, err) }) t.Run("TestRemoveSourceUsedByApp", func(t *testing.T) { existingApp := v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"}, - Spec: v1alpha1.ApplicationSpec{Destination: v1alpha1.ApplicationDestination{Name: "server1"}, Project: "test", Source: &v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd.git"}}, + ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, + Spec: v1alpha1.ApplicationSpec{Project: "test", Source: &v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd.git"}}, } argoDB := db.NewDB("default", settingsMgr, kubeclientset) @@ -263,11 +228,11 @@ func TestProjectServer(t *testing.T) { updatedProj := existingProj.DeepCopy() updatedProj.Spec.SourceRepos = []string{} - _, err := projectServer.Update(t.Context(), &project.ProjectUpdateRequest{Project: updatedProj}) + _, err := projectServer.Update(context.Background(), &project.ProjectUpdateRequest{Project: updatedProj}) require.Error(t, err) statusCode, _ := status.FromError(err) - assert.Equalf(t, codes.InvalidArgument, statusCode.Code(), "Got unexpected error code with error: %v", err) + assert.Equal(t, codes.InvalidArgument, statusCode.Code()) assert.Equal(t, "as a result of project update 1 applications source became invalid", statusCode.Message()) }) @@ -275,8 +240,8 @@ func TestProjectServer(t *testing.T) { proj := existingProj.DeepCopy() proj.Spec.SourceRepos = []string{"https://github.com/argoproj/argo-cd.git", "https://github.com/argoproj/*"} existingApp := v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"}, - Spec: v1alpha1.ApplicationSpec{Destination: v1alpha1.ApplicationDestination{Server: "https://server1"}, Project: "test", Source: &v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd.git"}}, + ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, + 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, testEnableEventList) @@ -284,7 +249,7 @@ func TestProjectServer(t *testing.T) { updatedProj := proj.DeepCopy() updatedProj.Spec.SourceRepos = []string{"https://github.com/argoproj/*"} - res, err := projectServer.Update(t.Context(), &project.ProjectUpdateRequest{Project: updatedProj}) + res, err := projectServer.Update(context.Background(), &project.ProjectUpdateRequest{Project: updatedProj}) require.NoError(t, err) assert.ElementsMatch(t, res.Spec.SourceRepos, updatedProj.Spec.SourceRepos) @@ -297,7 +262,7 @@ func TestProjectServer(t *testing.T) { {Namespace: "org1-*", Server: "https://server1"}, } existingApp := v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"}, + ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}, Project: "test", Destination: v1alpha1.ApplicationDestination{ Server: "https://server1", Namespace: "org1-team1", @@ -313,7 +278,7 @@ func TestProjectServer(t *testing.T) { {Namespace: "org1-*", Server: "https://server1"}, } - res, err := projectServer.Update(t.Context(), &project.ProjectUpdateRequest{Project: updatedProj}) + res, err := projectServer.Update(context.Background(), &project.ProjectUpdateRequest{Project: updatedProj}) require.NoError(t, err) assert.ElementsMatch(t, res.Spec.Destinations, updatedProj.Spec.Destinations) @@ -323,34 +288,34 @@ func TestProjectServer(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, testEnableEventList) - _, err := projectServer.Delete(t.Context(), &project.ProjectQuery{Name: "test"}) + _, err := projectServer.Delete(context.Background(), &project.ProjectQuery{Name: "test"}) require.NoError(t, err) }) t.Run("TestDeleteDefaultProjectFailure", func(t *testing.T) { defaultProj := v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "default"}, + ObjectMeta: v1.ObjectMeta{Name: "default", Namespace: "default"}, 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, testEnableEventList) - _, err := projectServer.Delete(t.Context(), &project.ProjectQuery{Name: defaultProj.Name}) + _, err := projectServer.Delete(context.Background(), &project.ProjectQuery{Name: defaultProj.Name}) statusCode, _ := status.FromError(err) assert.Equal(t, codes.InvalidArgument, statusCode.Code()) }) t.Run("TestDeleteProjectReferencedByApp", func(t *testing.T) { existingApp := v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"}, + ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, Spec: v1alpha1.ApplicationSpec{Project: "test"}, } argoDB := db.NewDB("default", settingsMgr, kubeclientset) projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) - _, err := projectServer.Delete(t.Context(), &project.ProjectQuery{Name: "test"}) + _, err := projectServer.Delete(context.Background(), &project.ProjectQuery{Name: "test"}) require.Error(t, err) statusCode, _ := status.FromError(err) @@ -362,8 +327,8 @@ func TestProjectServer(t *testing.T) { enforcer = newEnforcer(kubeclientset) _ = enforcer.SetBuiltinPolicy(`p, *, *, *, *, deny`) enforcer.SetClaimsEnforcerFunc(nil) - //nolint:staticcheck - ctx = context.WithValue(t.Context(), "claims", &jwt.MapClaims{"groups": []string{"my-group"}}) + // nolint:staticcheck + ctx = context.WithValue(context.Background(), "claims", &jwt.MapClaims{"groups": []string{"my-group"}}) policyEnf := rbacpolicy.NewRBACPolicyEnforcer(enforcer, nil) policyEnf.SetScopes([]string{"groups"}) @@ -401,7 +366,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, testEnableEventList) - tokenResponse, err := projectServer.CreateToken(t.Context(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 100}) + 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) require.NoError(t, err) @@ -422,7 +387,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, testEnableEventList) - tokenResponse, err := projectServer.CreateToken(t.Context(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1, Id: id}) + 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) require.NoError(t, err) @@ -443,7 +408,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, testEnableEventList) - tokenResponse, err := projectServer.CreateToken(t.Context(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1, Id: id}) + 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) @@ -456,7 +421,7 @@ func TestProjectServer(t *testing.T) { assert.Equal(t, expectedSubject, subject) require.NoError(t, err) - _, err1 := projectServer.CreateToken(t.Context(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1, Id: id}) + _, err1 := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1, Id: id}) expectedErr := fmt.Sprintf("rpc error: code = InvalidArgument desc = rpc error: code = InvalidArgument desc = Token id '%s' has been used. ", id) assert.EqualError(t, err1, expectedErr) }) @@ -503,7 +468,7 @@ p, role:admin, projects, update, *, allow`) 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(t.Context(), &project.ProjectQuery{Name: projWithToken.Name}) + projWithoutToken, err := projectServer.Get(context.Background(), &project.ProjectQuery{Name: projWithToken.Name}) require.NoError(t, err) assert.Len(t, projWithoutToken.Spec.Roles, 1) assert.Len(t, projWithoutToken.Spec.Roles[0].JWTTokens, 1) @@ -527,7 +492,7 @@ p, role:admin, projects, update, *, allow`) 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(t.Context(), &project.ProjectQuery{Name: projWithToken.Name}) + projWithoutToken, err := projectServer.Get(context.Background(), &project.ProjectQuery{Name: projWithToken.Name}) require.NoError(t, err) assert.Len(t, projWithoutToken.Spec.Roles, 1) assert.Len(t, projWithoutToken.Spec.Roles[0].JWTTokens, 1) @@ -544,9 +509,9 @@ p, role:admin, projects, update, *, allow`) 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, testEnableEventList) - _, err := projectServer.CreateToken(t.Context(), &project.ProjectTokenCreateRequest{Project: projWithToken.Name, Role: tokenName}) + _, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projWithToken.Name, Role: tokenName}) require.NoError(t, err) - projWithTwoTokens, err := projectServer.Get(t.Context(), &project.ProjectQuery{Name: projWithToken.Name}) + projWithTwoTokens, err := projectServer.Get(context.Background(), &project.ProjectQuery{Name: projWithToken.Name}) require.NoError(t, err) assert.Len(t, projWithTwoTokens.Spec.Roles, 1) assert.Len(t, projWithTwoTokens.Spec.Roles[0].JWTTokens, 2) @@ -559,7 +524,7 @@ p, role:admin, projects, update, *, allow`) argoDB := db.NewDB("default", settingsMgr, kubeclientset) 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(t.Context(), request) + updatedProj, err := projectServer.Update(context.Background(), request) require.NoError(t, err) assert.Equal(t, wildSourceRepo, updatedProj.Spec.SourceRepos[1]) }) @@ -578,7 +543,7 @@ p, role:admin, projects, update, *, allow`) argoDB := db.NewDB("default", settingsMgr, kubeclientset) 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(t.Context(), request) + _, err := projectServer.Update(context.Background(), request) require.NoError(t, err) t.Log(projWithRole.Spec.Roles[0].Policies[0]) expectedPolicy := fmt.Sprintf(policyTemplate, projWithRole.Name, role.Name, action, projWithRole.Name, object, effect) @@ -600,7 +565,7 @@ p, role:admin, projects, update, *, allow`) argoDB := db.NewDB("default", settingsMgr, kubeclientset) 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(t.Context(), request) + _, err := projectServer.Update(context.Background(), request) expectedErr := fmt.Sprintf("rpc error: code = AlreadyExists desc = policy '%s' already exists for role '%s'", policy, roleName) assert.EqualError(t, err, expectedErr) }) @@ -620,7 +585,7 @@ p, role:admin, projects, update, *, allow`) argoDB := db.NewDB("default", settingsMgr, kubeclientset) 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(t.Context(), request) + _, err := projectServer.Update(context.Background(), request) assert.ErrorContains(t, err, "object must be of form 'test/*', 'test[/]/' or 'test/'") }) @@ -639,7 +604,7 @@ p, role:admin, projects, update, *, allow`) argoDB := db.NewDB("default", settingsMgr, kubeclientset) 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(t.Context(), request) + _, err := projectServer.Update(context.Background(), request) assert.ErrorContains(t, err, "policy subject must be: 'proj:test:testRole'") }) @@ -658,7 +623,7 @@ p, role:admin, projects, update, *, allow`) argoDB := db.NewDB("default", settingsMgr, kubeclientset) 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(t.Context(), request) + _, err := projectServer.Update(context.Background(), request) assert.ErrorContains(t, err, "policy subject must be: 'proj:test:testRole'") }) @@ -676,7 +641,7 @@ p, role:admin, projects, update, *, allow`) argoDB := db.NewDB("default", settingsMgr, kubeclientset) 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(t.Context(), request) + _, err := projectServer.Update(context.Background(), request) assert.ErrorContains(t, err, "effect must be: 'allow' or 'deny'") }) @@ -695,7 +660,7 @@ p, role:admin, projects, update, *, allow`) argoDB := db.NewDB("default", settingsMgr, kubeclientset) 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(t.Context(), request) + updateProj, err := projectServer.Update(context.Background(), request) require.NoError(t, err) expectedPolicy := fmt.Sprintf(policyTemplate, projWithRole.Name, roleName, action, projWithRole.Name, object, effect) assert.Equal(t, expectedPolicy, updateProj.Spec.Roles[0].Policies[0]) @@ -731,8 +696,8 @@ p, role:admin, projects, update, *, allow`) enforcer = newEnforcer(kubeclientset) _ = enforcer.SetBuiltinPolicy(`p, *, *, *, *, deny`) enforcer.SetClaimsEnforcerFunc(nil) - //nolint:staticcheck - ctx := context.WithValue(t.Context(), "claims", &jwt.MapClaims{"groups": []string{"my-group"}}) + // nolint:staticcheck + ctx := context.WithValue(context.Background(), "claims", &jwt.MapClaims{"groups": []string{"my-group"}}) sessionMgr := session.NewSessionManager(settingsMgr, test.NewFakeProjLister(), "", nil, session.NewUserStateStorage(nil)) projectWithSyncWindows := existingProj.DeepCopy() @@ -749,7 +714,7 @@ func newEnforcer(kubeclientset *fake.Clientset) *rbac.Enforcer { enforcer := rbac.NewEnforcer(kubeclientset, testNamespace, common.ArgoCDRBACConfigMapName, nil) _ = enforcer.SetBuiltinPolicy(assets.BuiltinPolicyCSV) enforcer.SetDefaultRole("role:admin") - enforcer.SetClaimsEnforcerFunc(func(_ jwt.Claims, _ ...any) bool { + enforcer.SetClaimsEnforcerFunc(func(claims jwt.Claims, rvals ...interface{}) bool { return true }) return enforcer diff --git a/server/rbacpolicy/rbacpolicy.go b/server/rbacpolicy/rbacpolicy.go index 545f363676..f15c33f5ca 100644 --- a/server/rbacpolicy/rbacpolicy.go +++ b/server/rbacpolicy/rbacpolicy.go @@ -3,14 +3,13 @@ package rbacpolicy import ( "strings" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - applister "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - claimsutil "github.com/argoproj/argo-cd/v3/util/claims" - jwtutil "github.com/argoproj/argo-cd/v3/util/jwt" - "github.com/argoproj/argo-cd/v3/util/rbac" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + applister "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + jwtutil "github.com/argoproj/argo-cd/v2/util/jwt" + "github.com/argoproj/argo-cd/v2/util/rbac" ) // RBACPolicyEnforcer provides an RBAC Claims Enforcer which additionally consults AppProject @@ -57,17 +56,13 @@ func GetProjectRoleFromSubject(subject string) (string, string, bool) { } // EnforceClaims is an RBAC claims enforcer specific to the Argo CD API server -func (p *RBACPolicyEnforcer) EnforceClaims(claims jwt.Claims, rvals ...any) bool { +func (p *RBACPolicyEnforcer) EnforceClaims(claims jwt.Claims, rvals ...interface{}) bool { mapClaims, err := jwtutil.MapClaims(claims) if err != nil { return false } - argoClaims, err := claimsutil.MapClaimsToArgoClaims(mapClaims) - if err != nil { - return false - } - subject := argoClaims.GetUserIdentifier() + subject := jwtutil.StringField(mapClaims, "sub") // Check if the request is for an application resource. We have special enforcement which takes // into consideration the project's token and group bindings var runtimePolicy string @@ -86,7 +81,7 @@ func (p *RBACPolicyEnforcer) EnforceClaims(claims jwt.Claims, rvals ...any) bool // Check the subject. This is typically the 'admin' case. // NOTE: the call to EnforceWithCustomEnforcer will also consider the default role - vals := append([]any{subject}, rvals[1:]...) + vals := append([]interface{}{subject}, rvals[1:]...) if p.enf.EnforceWithCustomEnforcer(enforcer, vals...) { return true } @@ -108,7 +103,7 @@ func (p *RBACPolicyEnforcer) EnforceClaims(claims jwt.Claims, rvals ...any) bool for gpidx := range groupingPolicies { // Prefilter user groups by groups defined in the model if groupingPolicies[gpidx][0] == groups[gidx] { - vals := append([]any{groups[gidx]}, rvals[1:]...) + vals := append([]interface{}{groups[gidx]}, rvals[1:]...) if p.enf.EnforceWithCustomEnforcer(enforcer, vals...) { return true } @@ -123,7 +118,7 @@ func (p *RBACPolicyEnforcer) EnforceClaims(claims jwt.Claims, rvals ...any) bool // getProjectFromRequest parses the project name from the RBAC request and returns the associated // project (if it exists) -func (p *RBACPolicyEnforcer) getProjectFromRequest(rvals ...any) *v1alpha1.AppProject { +func (p *RBACPolicyEnforcer) getProjectFromRequest(rvals ...interface{}) *v1alpha1.AppProject { if len(rvals) != 4 { return nil } @@ -137,7 +132,7 @@ func (p *RBACPolicyEnforcer) getProjectFromRequest(rvals ...any) *v1alpha1.AppPr if res, ok := rvals[1].(string); ok { if obj, ok := rvals[3].(string); ok { switch res { - case rbac.ResourceApplications, rbac.ResourceRepositories, rbac.ResourceClusters, rbac.ResourceLogs, rbac.ResourceExec: + case rbac.ResourceApplicationSets, rbac.ResourceApplications, rbac.ResourceRepositories, rbac.ResourceClusters, rbac.ResourceLogs, rbac.ResourceExec: if objSplit := strings.Split(obj, "/"); len(objSplit) >= 2 { return getProjectByName(objSplit[0]) } @@ -151,7 +146,7 @@ func (p *RBACPolicyEnforcer) getProjectFromRequest(rvals ...any) *v1alpha1.AppPr } // enforceProjectToken will check to see the valid token has not yet been revoked in the project -func (p *RBACPolicyEnforcer) enforceProjectToken(subject string, proj *v1alpha1.AppProject, rvals ...any) bool { +func (p *RBACPolicyEnforcer) enforceProjectToken(subject string, proj *v1alpha1.AppProject, rvals ...interface{}) bool { subjectSplit := strings.Split(subject, ":") if len(subjectSplit) != 3 { return false @@ -162,6 +157,6 @@ func (p *RBACPolicyEnforcer) enforceProjectToken(subject string, proj *v1alpha1. return false } - vals := append([]any{subject}, rvals[1:]...) + vals := append([]interface{}{subject}, rvals[1:]...) return p.enf.EnforceRuntimePolicy(proj.Name, proj.ProjectPoliciesString(), vals...) } diff --git a/server/rbacpolicy/rbacpolicy_test.go b/server/rbacpolicy/rbacpolicy_test.go index 9f1f32dc48..1887ceeade 100644 --- a/server/rbacpolicy/rbacpolicy_test.go +++ b/server/rbacpolicy/rbacpolicy_test.go @@ -4,15 +4,16 @@ import ( "fmt" "testing" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/common" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/rbac" + "github.com/argoproj/argo-cd/v2/common" + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/rbac" ) func newFakeProj() *argoappv1.AppProject { @@ -68,11 +69,6 @@ func TestEnforceAllPolicies(t *testing.T) { assert.True(t, enf.Enforce(claims, "logs", "get", "my-proj/my-app")) assert.True(t, enf.Enforce(claims, "exec", "create", "my-proj/my-app")) - claims = jwt.MapClaims{"sub": "qwertyuiop", "federated_claims": map[string]any{"user_id": "bob"}} - assert.True(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app")) - assert.True(t, enf.Enforce(claims, "logs", "get", "my-proj/my-app")) - assert.True(t, enf.Enforce(claims, "exec", "create", "my-proj/my-app")) - claims = jwt.MapClaims{"sub": "proj:my-proj:my-role", "iat": 1234} assert.True(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app")) assert.True(t, enf.Enforce(claims, "logs", "get", "my-proj/my-app")) @@ -187,11 +183,46 @@ func TestGetScopes_CustomScopes(t *testing.T) { } func Test_getProjectFromRequest(t *testing.T) { - fp := newFakeProj() - projLister := test.NewFakeProjLister(fp) + tests := []struct { + name string + resource string + action string + arg string + }{ + { + name: "valid project/repo string", + resource: "repositories", + action: "create", + arg: newFakeProj().Name + "/https://github.com/argoproj/argocd-example-apps", + }, + { + name: "applicationsets with project/repo string", + resource: "applicationsets", + action: "create", + arg: newFakeProj().Name + "/https://github.com/argoproj/argocd-example-apps", + }, + { + name: "applicationsets with project/repo string", + resource: "applicationsets", + action: "*", + arg: newFakeProj().Name + "/https://github.com/argoproj/argocd-example-apps", + }, + { + name: "applicationsets with project/repo string", + resource: "applicationsets", + action: "get", + arg: newFakeProj().Name + "/https://github.com/argoproj/argocd-example-apps", + }, + } - rbacEnforcer := NewRBACPolicyEnforcer(nil, projLister) - project := rbacEnforcer.getProjectFromRequest("", "repositories", "create", fp.Name+"/https://github.com/argoproj/argocd-example-apps") + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fp := newFakeProj() + projLister := test.NewFakeProjLister(fp) + rbacEnforcer := NewRBACPolicyEnforcer(nil, projLister) - assert.Equal(t, project.Name, fp.Name) + project := rbacEnforcer.getProjectFromRequest("", tt.resource, tt.action, tt.arg) + require.Equal(t, fp.Name, project.Name) + }) + } } diff --git a/server/repocreds/repocreds.go b/server/repocreds/repocreds.go index 0bbd864733..ba7cc5adbe 100644 --- a/server/repocreds/repocreds.go +++ b/server/repocreds/repocreds.go @@ -4,17 +4,17 @@ import ( "context" "reflect" - "github.com/argoproj/argo-cd/v3/util/argo" + "github.com/argoproj/argo-cd/v2/util/argo" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - repocredspkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repocreds" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/rbac" - "github.com/argoproj/argo-cd/v3/util/settings" + repocredspkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repocreds" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/rbac" + "github.com/argoproj/argo-cd/v2/util/settings" ) // Server provides a Repository service diff --git a/server/repocreds/repocreds.proto b/server/repocreds/repocreds.proto index 4d8aa954c4..59151b2644 100644 --- a/server/repocreds/repocreds.proto +++ b/server/repocreds/repocreds.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/repocreds"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/repocreds"; // Repository Service // @@ -7,7 +7,7 @@ option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/repocreds"; package repocreds; import "google/api/annotations.proto"; -import "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto"; +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; // RepoCredsQuery is a query for RepoCreds resources message RepoCredsQuery { @@ -25,31 +25,31 @@ message RepoCredsResponse {} // RepoCreateRequest is a request for creating repository credentials config message RepoCredsCreateRequest { // Repository definition - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepoCreds creds = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds creds = 1; // Whether to create in upsert mode bool upsert = 2; } // RepoCredsUpdateRequest is a request for updating existing repository credentials config message RepoCredsUpdateRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepoCreds creds = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds creds = 1; } // RepoCredsService implements CRUD actions for managing repository credentials config service RepoCredsService { // ListRepositoryCredentials gets a list of all configured repository credential sets - rpc ListRepositoryCredentials(RepoCredsQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepoCredsList) { + rpc ListRepositoryCredentials(RepoCredsQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCredsList) { option (google.api.http).get = "/api/v1/repocreds"; } //ListWriteRepositoryCredentials gets a list of all configured repository credential sets that have write access - rpc ListWriteRepositoryCredentials(RepoCredsQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepoCredsList) { + rpc ListWriteRepositoryCredentials(RepoCredsQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCredsList) { option (google.api.http).get = "/api/v1/write-repocreds"; } // CreateRepositoryCredentials creates a new repository credential set - rpc CreateRepositoryCredentials(RepoCredsCreateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepoCreds) { + rpc CreateRepositoryCredentials(RepoCredsCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds) { option (google.api.http) = { post: "/api/v1/repocreds" body: "creds" @@ -57,7 +57,7 @@ service RepoCredsService { } // CreateWriteRepositoryCredentials creates a new repository credential set with write access - rpc CreateWriteRepositoryCredentials(RepoCredsCreateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepoCreds) { + rpc CreateWriteRepositoryCredentials(RepoCredsCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds) { option (google.api.http) = { post: "/api/v1/write-repocreds" body: "creds" @@ -65,7 +65,7 @@ service RepoCredsService { } // UpdateRepositoryCredentials updates a repository credential set - rpc UpdateRepositoryCredentials(RepoCredsUpdateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepoCreds) { + rpc UpdateRepositoryCredentials(RepoCredsUpdateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds) { option (google.api.http) = { put: "/api/v1/repocreds/{creds.url}" body: "creds" @@ -73,7 +73,7 @@ service RepoCredsService { } // UpdateWriteRepositoryCredentials updates a repository credential set with write access - rpc UpdateWriteRepositoryCredentials(RepoCredsUpdateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepoCreds) { + rpc UpdateWriteRepositoryCredentials(RepoCredsUpdateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds) { option (google.api.http) = { put: "/api/v1/write-repocreds/{creds.url}" body: "creds" diff --git a/server/repository/repository.go b/server/repository/repository.go index cb7f1eeb9a..d671188b65 100644 --- a/server/repository/repository.go +++ b/server/repository/repository.go @@ -16,19 +16,19 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/cache" - "github.com/argoproj/argo-cd/v3/common" - repositorypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repository" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - servercache "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/git" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/rbac" - "github.com/argoproj/argo-cd/v3/util/settings" + repositorypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/rbac" + "github.com/argoproj/argo-cd/v2/util/settings" ) // Server provides a Repository service @@ -69,18 +69,20 @@ func NewServer( } } -func (s *Server) getRepo(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { +var errPermissionDenied = status.Error(codes.PermissionDenied, "permission denied") + +func (s *Server) getRepo(ctx context.Context, url, project string) (*appsv1.Repository, error) { repo, err := s.db.GetRepository(ctx, url, project) if err != nil { - return nil, common.PermissionDeniedAPIError + return nil, errPermissionDenied } return repo, nil } -func (s *Server) getWriteRepo(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { +func (s *Server) getWriteRepo(ctx context.Context, url, project string) (*appsv1.Repository, error) { repo, err := s.db.GetWriteRepository(ctx, url, project) if err != nil { - return nil, common.PermissionDeniedAPIError + return nil, errPermissionDenied } return repo, nil } @@ -95,15 +97,15 @@ func createRBACObject(project string, repo string) string { // Get the connection state for a given repository URL by connecting to the // repo and evaluate the results. Unless forceRefresh is set to true, the // result may be retrieved out of the cache. -func (s *Server) getConnectionState(ctx context.Context, url string, project string, forceRefresh bool) v1alpha1.ConnectionState { +func (s *Server) getConnectionState(ctx context.Context, url string, project string, forceRefresh bool) appsv1.ConnectionState { if !forceRefresh { if connectionState, err := s.cache.GetRepoConnectionState(url, project); err == nil { return connectionState } } now := metav1.Now() - connectionState := v1alpha1.ConnectionState{ - Status: v1alpha1.ConnectionStatusSuccessful, + connectionState := appsv1.ConnectionState{ + Status: appsv1.ConnectionStatusSuccessful, ModifiedAt: &now, } var err error @@ -112,7 +114,7 @@ func (s *Server) getConnectionState(ctx context.Context, url string, project str err = s.testRepo(ctx, repo) } if err != nil { - connectionState.Status = v1alpha1.ConnectionStatusFailed + connectionState.Status = appsv1.ConnectionStatusFailed if errors.IsCredentialsConfigurationError(err) { connectionState.Message = "Configuration error - please check the server logs" log.Warnf("could not retrieve repo: %s", err.Error()) @@ -129,12 +131,12 @@ func (s *Server) getConnectionState(ctx context.Context, url string, project str // List returns list of repositories // Deprecated: Use ListRepositories instead -func (s *Server) List(ctx context.Context, q *repositorypkg.RepoQuery) (*v1alpha1.RepositoryList, error) { +func (s *Server) List(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.RepositoryList, error) { return s.ListRepositories(ctx, q) } // Get return the requested configured repository by URL and the state of its connections. -func (s *Server) Get(ctx context.Context, q *repositorypkg.RepoQuery) (*v1alpha1.Repository, error) { +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 { @@ -156,7 +158,7 @@ func (s *Server) Get(ctx context.Context, q *repositorypkg.RepoQuery) (*v1alpha1 return repo, nil } -func (s *Server) GetWrite(ctx context.Context, q *repositorypkg.RepoQuery) (*v1alpha1.Repository, error) { +func (s *Server) GetWrite(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.Repository, error) { if !s.hydratorEnabled { return nil, status.Error(codes.Unimplemented, "hydrator is disabled") } @@ -182,7 +184,7 @@ func (s *Server) GetWrite(ctx context.Context, q *repositorypkg.RepoQuery) (*v1a } // ListRepositories returns a list of all configured repositories and the state of their connections -func (s *Server) ListRepositories(ctx context.Context, q *repositorypkg.RepoQuery) (*v1alpha1.RepositoryList, error) { +func (s *Server) ListRepositories(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.RepositoryList, error) { repos, err := s.db.ListRepositories(ctx) if err != nil { return nil, err @@ -191,12 +193,12 @@ func (s *Server) ListRepositories(ctx context.Context, q *repositorypkg.RepoQuer if err != nil { return nil, err } - return &v1alpha1.RepositoryList{Items: items}, nil + return &appsv1.RepositoryList{Items: items}, nil } // ListWriteRepositories returns a list of all configured repositories where the user has write access and the state of // their connections -func (s *Server) ListWriteRepositories(ctx context.Context, q *repositorypkg.RepoQuery) (*v1alpha1.RepositoryList, error) { +func (s *Server) ListWriteRepositories(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.RepositoryList, error) { if !s.hydratorEnabled { return nil, status.Error(codes.Unimplemented, "hydrator is disabled") } @@ -209,18 +211,18 @@ func (s *Server) ListWriteRepositories(ctx context.Context, q *repositorypkg.Rep if err != nil { return nil, err } - return &v1alpha1.RepositoryList{Items: items}, nil + return &appsv1.RepositoryList{Items: items}, nil } // ListRepositoriesByAppProject returns a list of all configured repositories and the state of their connections. It // normalizes, sanitizes, and filters out repositories that the user does not have access to in the specified project. // It also sorts the repositories by project and repo name. -func (s *Server) prepareRepoList(ctx context.Context, resourceType string, repos []*v1alpha1.Repository, forceRefresh bool) (v1alpha1.Repositories, error) { - items := v1alpha1.Repositories{} +func (s *Server) prepareRepoList(ctx context.Context, resourceType string, repos []*appsv1.Repository, forceRefresh bool) (appsv1.Repositories, error) { + items := appsv1.Repositories{} for _, repo := range repos { items = append(items, repo.Normalize().Sanitized()) } - items = items.Filter(func(r *v1alpha1.Repository) bool { + items = items.Filter(func(r *appsv1.Repository) bool { return s.enf.Enforce(ctx.Value("claims"), resourceType, rbac.ActionGet, createRBACObject(r.Project, r.Repo)) }) err := kube.RunAllAsync(len(items), func(i int) error { @@ -252,7 +254,7 @@ func (s *Server) ListRefs(ctx context.Context, q *repositorypkg.RepoQuery) (*api if err != nil { return nil, err } - defer utilio.Close(conn) + defer io.Close(conn) return repoClient.ListRefs(ctx, &apiclient.ListRefsRequest{ Repo: repo, @@ -278,7 +280,7 @@ func (s *Server) ListApps(ctx context.Context, q *repositorypkg.RepoAppsQuery) ( appRBACresource := fmt.Sprintf("%s/%s", q.AppProject, q.AppName) if !s.enf.Enforce(claims, rbac.ResourceApplications, rbac.ActionCreate, appRBACresource) && !s.enf.Enforce(claims, rbac.ResourceApplications, rbac.ActionUpdate, appRBACresource) { - return nil, common.PermissionDeniedAPIError + return nil, errPermissionDenied } // Also ensure the repo is actually allowed in the project in question if err := s.isRepoPermittedInProject(ctx, q.Repo, q.AppProject); err != nil { @@ -290,7 +292,7 @@ func (s *Server) ListApps(ctx context.Context, q *repositorypkg.RepoAppsQuery) ( if err != nil { return nil, err } - defer utilio.Close(conn) + defer io.Close(conn) apps, err := repoClient.ListApps(ctx, &apiclient.ListAppsRequest{ Repo: repo, @@ -337,11 +339,11 @@ func (s *Server) GetAppDetails(ctx context.Context, q *repositorypkg.RepoAppDeta } else { // if we get here we are returning repo details of an existing app if q.AppProject != app.Spec.Project { - return nil, common.PermissionDeniedAPIError + return nil, errPermissionDenied } // verify caller is not making a request with arbitrary source values which were not in our history if !isSourceInHistory(app, *q.Source, q.SourceIndex, q.VersionId) { - return nil, common.PermissionDeniedAPIError + return nil, errPermissionDenied } } // Ensure the repo is actually allowed in the project in question @@ -353,7 +355,7 @@ func (s *Server) GetAppDetails(ctx context.Context, q *repositorypkg.RepoAppDeta if err != nil { return nil, err } - defer utilio.Close(conn) + defer io.Close(conn) helmRepos, err := s.db.ListHelmRepositories(ctx) if err != nil { return nil, err @@ -371,7 +373,7 @@ func (s *Server) GetAppDetails(ctx context.Context, q *repositorypkg.RepoAppDeta return nil, err } - refSources := make(v1alpha1.RefTargetRevisionMapping) + refSources := make(appsv1.RefTargetRevisionMapping) if app != nil && app.Spec.HasMultipleSources() { // Store the map of all sources having ref field into a map for applications with sources field refSources, err = argo.GetRefSources(ctx, app.Spec.Sources, q.AppProject, s.db.GetRepository, []string{}, false) @@ -404,18 +406,18 @@ func (s *Server) GetHelmCharts(ctx context.Context, q *repositorypkg.RepoQuery) if err != nil { return nil, err } - defer utilio.Close(conn) + defer io.Close(conn) return repoClient.GetHelmCharts(ctx, &apiclient.HelmChartsRequest{Repo: repo}) } // Create creates a repository or repository credential set // Deprecated: Use CreateRepository() instead -func (s *Server) Create(ctx context.Context, q *repositorypkg.RepoCreateRequest) (*v1alpha1.Repository, error) { +func (s *Server) Create(ctx context.Context, q *repositorypkg.RepoCreateRequest) (*appsv1.Repository, error) { return s.CreateRepository(ctx, q) } // CreateRepository creates a repository configuration -func (s *Server) CreateRepository(ctx context.Context, q *repositorypkg.RepoCreateRequest) (*v1alpha1.Repository, error) { +func (s *Server) CreateRepository(ctx context.Context, q *repositorypkg.RepoCreateRequest) (*appsv1.Repository, error) { if q.Repo == nil { return nil, status.Errorf(codes.InvalidArgument, "missing payload in request") } @@ -424,7 +426,7 @@ func (s *Server) CreateRepository(ctx context.Context, q *repositorypkg.RepoCrea return nil, err } - var repo *v1alpha1.Repository + var repo *appsv1.Repository var err error // check we can connect to the repo, copying any existing creds (not supported for project scoped repositories) @@ -445,7 +447,7 @@ func (s *Server) CreateRepository(ctx context.Context, q *repositorypkg.RepoCrea } r := q.Repo - r.ConnectionState = v1alpha1.ConnectionState{Status: v1alpha1.ConnectionStatusSuccessful} + r.ConnectionState = appsv1.ConnectionState{Status: appsv1.ConnectionStatusSuccessful} repo, err = s.db.CreateRepository(ctx, r) if status.Convert(err).Code() == codes.AlreadyExists { // act idempotent if existing spec matches new spec @@ -470,11 +472,11 @@ func (s *Server) CreateRepository(ctx context.Context, q *repositorypkg.RepoCrea if err != nil { return nil, err } - return &v1alpha1.Repository{Repo: repo.Repo, Type: repo.Type, Name: repo.Name}, nil + return &appsv1.Repository{Repo: repo.Repo, Type: repo.Type, Name: repo.Name}, nil } // CreateWriteRepository creates a repository configuration with write credentials -func (s *Server) CreateWriteRepository(ctx context.Context, q *repositorypkg.RepoCreateRequest) (*v1alpha1.Repository, error) { +func (s *Server) CreateWriteRepository(ctx context.Context, q *repositorypkg.RepoCreateRequest) (*appsv1.Repository, error) { if !s.hydratorEnabled { return nil, status.Error(codes.Unimplemented, "hydrator is disabled") } @@ -515,17 +517,17 @@ func (s *Server) CreateWriteRepository(ctx context.Context, q *repositorypkg.Rep if err != nil { return nil, err } - return &v1alpha1.Repository{Repo: repo.Repo, Type: repo.Type, Name: repo.Name}, nil + return &appsv1.Repository{Repo: repo.Repo, Type: repo.Type, Name: repo.Name}, nil } // Update updates a repository or credential set // Deprecated: Use UpdateRepository() instead -func (s *Server) Update(ctx context.Context, q *repositorypkg.RepoUpdateRequest) (*v1alpha1.Repository, error) { +func (s *Server) Update(ctx context.Context, q *repositorypkg.RepoUpdateRequest) (*appsv1.Repository, error) { return s.UpdateRepository(ctx, q) } // UpdateRepository updates a repository configuration -func (s *Server) UpdateRepository(ctx context.Context, q *repositorypkg.RepoUpdateRequest) (*v1alpha1.Repository, error) { +func (s *Server) UpdateRepository(ctx context.Context, q *repositorypkg.RepoUpdateRequest) (*appsv1.Repository, error) { if q.Repo == nil { return nil, status.Errorf(codes.InvalidArgument, "missing payload in request") } @@ -544,11 +546,11 @@ func (s *Server) UpdateRepository(ctx context.Context, q *repositorypkg.RepoUpda return nil, err } _, err = s.db.UpdateRepository(ctx, q.Repo) - return &v1alpha1.Repository{Repo: q.Repo.Repo, Type: q.Repo.Type, Name: q.Repo.Name}, err + return &appsv1.Repository{Repo: q.Repo.Repo, Type: q.Repo.Type, Name: q.Repo.Name}, err } // UpdateWriteRepository updates a repository configuration with write credentials -func (s *Server) UpdateWriteRepository(ctx context.Context, q *repositorypkg.RepoUpdateRequest) (*v1alpha1.Repository, error) { +func (s *Server) UpdateWriteRepository(ctx context.Context, q *repositorypkg.RepoUpdateRequest) (*appsv1.Repository, error) { if !s.hydratorEnabled { return nil, status.Error(codes.Unimplemented, "hydrator is disabled") } @@ -571,7 +573,7 @@ func (s *Server) UpdateWriteRepository(ctx context.Context, q *repositorypkg.Rep return nil, err } _, err = s.db.UpdateWriteRepository(ctx, q.Repo) - return &v1alpha1.Repository{Repo: q.Repo.Repo, Type: q.Repo.Type, Name: q.Repo.Name}, err + return &appsv1.Repository{Repo: q.Repo.Repo, Type: q.Repo.Type, Name: q.Repo.Name}, err } // Delete removes a repository from the configuration @@ -622,7 +624,7 @@ func (s *Server) DeleteWriteRepository(ctx context.Context, q *repositorypkg.Rep // getRepository fetches a single repository which the user has access to. If only one repository can be found which // matches the same URL, that will be returned (this is for backward compatibility reasons). If multiple repositories // are matched, a repository is only returned if it matches the app project of the incoming request. -func getRepository(ctx context.Context, listRepositories func(context.Context, *repositorypkg.RepoQuery) (*v1alpha1.RepositoryList, error), q *repositorypkg.RepoQuery) (*v1alpha1.Repository, error) { +func getRepository(ctx context.Context, listRepositories func(context.Context, *repositorypkg.RepoQuery) (*v1alpha1.RepositoryList, error), q *repositorypkg.RepoQuery) (*appsv1.Repository, error) { repositories, err := listRepositories(ctx, q) if err != nil { return nil, err @@ -636,7 +638,7 @@ func getRepository(ctx context.Context, listRepositories func(context.Context, * } if len(foundRepos) == 0 { - return nil, common.PermissionDeniedAPIError + return nil, errPermissionDenied } var foundRepo *v1alpha1.Repository @@ -665,13 +667,12 @@ func (s *Server) ValidateAccess(ctx context.Context, q *repositorypkg.RepoAccess return nil, err } - repo := &v1alpha1.Repository{ + repo := &appsv1.Repository{ Repo: q.Repo, Type: q.Type, Name: q.Name, Username: q.Username, Password: q.Password, - BearerToken: q.BearerToken, SSHPrivateKey: q.SshPrivateKey, Insecure: q.Insecure, TLSClientCertData: q.TlsClientCertData, @@ -714,13 +715,12 @@ func (s *Server) ValidateWriteAccess(ctx context.Context, q *repositorypkg.RepoA return nil, err } - repo := &v1alpha1.Repository{ + repo := &appsv1.Repository{ Repo: q.Repo, Type: q.Type, Name: q.Name, Username: q.Username, Password: q.Password, - BearerToken: q.BearerToken, SSHPrivateKey: q.SshPrivateKey, Insecure: q.Insecure, TLSClientCertData: q.TlsClientCertData, @@ -741,12 +741,12 @@ func (s *Server) ValidateWriteAccess(ctx context.Context, q *repositorypkg.RepoA return &repositorypkg.RepoResponse{}, nil } -func (s *Server) testRepo(ctx context.Context, repo *v1alpha1.Repository) error { +func (s *Server) testRepo(ctx context.Context, repo *appsv1.Repository) error { conn, repoClient, err := s.repoClientset.NewRepoServerClient() if err != nil { return fmt.Errorf("failed to connect to repo-server: %w", err) } - defer utilio.Close(conn) + defer io.Close(conn) _, err = repoClient.TestRepository(ctx, &apiclient.TestRepositoryRequest{ Repo: repo, @@ -755,11 +755,11 @@ func (s *Server) testRepo(ctx context.Context, repo *v1alpha1.Repository) error } func (s *Server) isRepoPermittedInProject(ctx context.Context, repo string, projName string) error { - proj, err := argo.GetAppProjectByName(ctx, projName, applisters.NewAppProjectLister(s.projLister.GetIndexer()), s.namespace, s.settings, s.db) + proj, err := argo.GetAppProjectByName(projName, applisters.NewAppProjectLister(s.projLister.GetIndexer()), s.namespace, s.settings, s.db, ctx) if err != nil { return err } - if !proj.IsSourcePermitted(v1alpha1.ApplicationSource{RepoURL: repo}) { + if !proj.IsSourcePermitted(appsv1.ApplicationSource{RepoURL: repo}) { return status.Errorf(codes.PermissionDenied, "repository '%s' not permitted in project '%s'", repo, projName) } return nil diff --git a/server/repository/repository.proto b/server/repository/repository.proto index 9af9aea8b7..678cb7ecc5 100644 --- a/server/repository/repository.proto +++ b/server/repository/repository.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/repository"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository"; // Repository Service // @@ -7,8 +7,8 @@ option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/repository"; package repository; import "google/api/annotations.proto"; -import "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto"; -import "github.com/argoproj/argo-cd/v3/reposerver/repository/repository.proto"; +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; +import "github.com/argoproj/argo-cd/v2/reposerver/repository/repository.proto"; // RepoAppsQuery is a query for Repository apps message RepoAppsQuery { @@ -27,7 +27,7 @@ message AppInfo { // RepoAppDetailsQuery contains query information for app details request message RepoAppDetailsQuery { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ApplicationSource source = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSource source = 1; string appName = 2; string appProject = 3; // source index (for multi source apps) @@ -89,10 +89,6 @@ message RepoAccessQuery { string gcpServiceAccountKey = 18; // Whether to force HTTP basic auth bool forceHttpBasicAuth = 19; - // Whether to use azure workload identity for authentication - bool useAzureWorkloadIdentity = 20; - // BearerToken contains the bearer token used for Git auth at the repo server - string bearerToken = 21; } message RepoResponse {} @@ -100,7 +96,7 @@ message RepoResponse {} // RepoCreateRequest is a request for creating repository config message RepoCreateRequest { // Repository definition - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; // Whether to create in upsert mode bool upsert = 2; // Whether to operate on credential set instead of repository @@ -108,35 +104,35 @@ message RepoCreateRequest { } message RepoUpdateRequest { - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository repo = 1; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; } // RepositoryService service RepositoryService { // List returns list of repos or repository credentials - rpc List(RepoQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepositoryList) { + rpc List(RepoQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepositoryList) { option (google.api.http).get = "/api/v1/repositories"; option deprecated = true; } // Get returns a repository or its credentials - rpc Get(RepoQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository) { + rpc Get(RepoQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { option (google.api.http).get = "/api/v1/repositories/{repo}"; } // GetWrite returns a repository or its write credentials - rpc GetWrite(RepoQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository) { + rpc GetWrite(RepoQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { option (google.api.http).get = "/api/v1/write-repositories/{repo}"; } // ListRepositories gets a list of all configured repositories - rpc ListRepositories(RepoQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepositoryList) { + rpc ListRepositories(RepoQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepositoryList) { option (google.api.http).get = "/api/v1/repositories"; } // ListWriteRepositories gets a list of all configured write repositories - rpc ListWriteRepositories(RepoQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RepositoryList) { + rpc ListWriteRepositories(RepoQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepositoryList) { option (google.api.http).get = "/api/v1/write-repositories"; } @@ -163,7 +159,7 @@ service RepositoryService { } // Create creates a repo or a repo credential set - rpc Create(RepoCreateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository) { + rpc Create(RepoCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { option (google.api.http) = { post: "/api/v1/repositories" body: "repo" @@ -172,7 +168,7 @@ service RepositoryService { } // CreateRepository creates a new repository configuration - rpc CreateRepository(RepoCreateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository) { + rpc CreateRepository(RepoCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { option (google.api.http) = { post: "/api/v1/repositories" body: "repo" @@ -180,7 +176,7 @@ service RepositoryService { } // CreateWriteRepository creates a new write repository configuration - rpc CreateWriteRepository(RepoCreateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository) { + rpc CreateWriteRepository(RepoCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { option (google.api.http) = { post: "/api/v1/write-repositories" body: "repo" @@ -188,7 +184,7 @@ service RepositoryService { } // Update updates a repo or repo credential set - rpc Update(RepoUpdateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository) { + rpc Update(RepoUpdateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { option (google.api.http) = { put: "/api/v1/repositories/{repo.repo}" body: "repo" @@ -197,7 +193,7 @@ service RepositoryService { } // UpdateRepository updates a repository configuration - rpc UpdateRepository(RepoUpdateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository) { + rpc UpdateRepository(RepoUpdateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { option (google.api.http) = { put: "/api/v1/repositories/{repo.repo}" body: "repo" @@ -205,7 +201,7 @@ service RepositoryService { } // UpdateWriteRepository updates a write repository configuration - rpc UpdateWriteRepository(RepoUpdateRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Repository) { + rpc UpdateWriteRepository(RepoUpdateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { option (google.api.http) = { put: "/api/v1/write-repositories/{repo.repo}" body: "repo" diff --git a/server/repository/repository_test.go b/server/repository/repository_test.go index d6ed9d5cd3..7b4b77bca2 100644 --- a/server/repository/repository_test.go +++ b/server/repository/repository_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -14,35 +14,37 @@ import ( "google.golang.org/grpc/status" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/fake" k8scache "k8s.io/client-go/tools/cache" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/repository" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - fakeapps "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - appinformer "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions" - applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient/mocks" - "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/util/assets" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/db" - dbmocks "github.com/argoproj/argo-cd/v3/util/db/mocks" - "github.com/argoproj/argo-cd/v3/util/rbac" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository" + repositorypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + fakeapps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" + "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/util/assets" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" + "github.com/argoproj/argo-cd/v2/util/db" + dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" + "github.com/argoproj/argo-cd/v2/util/rbac" + "github.com/argoproj/argo-cd/v2/util/settings" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) const testNamespace = "default" var ( argocdCM = corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-cm", Labels: map[string]string{ @@ -51,7 +53,7 @@ var ( }, } argocdSecret = corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "argocd-secret", Namespace: testNamespace, }, @@ -232,7 +234,7 @@ var ( func newAppAndProjLister(objects ...runtime.Object) (applisters.ApplicationLister, k8scache.SharedIndexInformer) { fakeAppsClientset := fakeapps.NewSimpleClientset(objects...) - factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, appinformer.WithNamespace(""), appinformer.WithTweakListOptions(func(_ *metav1.ListOptions) {})) + factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, appinformer.WithNamespace(""), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) projInformer := factory.Argoproj().V1alpha1().AppProjects() appsInformer := factory.Argoproj().V1alpha1().Applications() for _, obj := range objects { @@ -256,7 +258,7 @@ func Test_createRBACObject(t *testing.T) { func TestRepositoryServer(t *testing.T) { kubeclientset := fake.NewSimpleClientset(&argocdCM, &argocdSecret) - settingsMgr := settings.NewSettingsManager(t.Context(), kubeclientset, testNamespace) + settingsMgr := settings.NewSettingsManager(context.Background(), kubeclientset, testNamespace) enforcer := newEnforcer(kubeclientset) appLister, projInformer := newAppAndProjLister(defaultProj) argoDB := db.NewDB("default", settingsMgr, kubeclientset) @@ -267,7 +269,7 @@ func TestRepositoryServer(t *testing.T) { s := NewServer(&repoServerClientset, argoDB, enforcer, nil, appLister, projInformer, testNamespace, settingsMgr, false) url := "https://test" - repo, _ := s.getRepo(t.Context(), url, "") + repo, _ := s.getRepo(context.TODO(), url, "") assert.Equal(t, repo.Repo, url) }) @@ -278,7 +280,7 @@ func TestRepositoryServer(t *testing.T) { s := NewServer(&repoServerClientset, argoDB, enforcer, nil, appLister, projInformer, testNamespace, settingsMgr, false) url := "https://test" - _, err := s.ValidateAccess(t.Context(), &repository.RepoAccessQuery{ + _, err := s.ValidateAccess(context.TODO(), &repository.RepoAccessQuery{ Repo: url, }) require.NoError(t, err) @@ -291,12 +293,12 @@ func TestRepositoryServer(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("ListRepositories", t.Context()).Return([]*appsv1.Repository{{Repo: url}}, nil) - db.On("GetRepository", t.Context(), url, "").Return(&appsv1.Repository{Repo: url}, nil) - db.On("RepositoryExists", t.Context(), url, "").Return(true, nil) + db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{{Repo: url}}, nil) + db.On("GetRepository", context.TODO(), url, "").Return(&appsv1.Repository{Repo: url}, nil) + db.On("RepositoryExists", context.TODO(), url, "").Return(true, nil) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) - repo, err := s.Get(t.Context(), &repository.RepoQuery{ + repo, err := s.Get(context.TODO(), &repository.RepoQuery{ Repo: url, }) require.NoError(t, err) @@ -316,12 +318,12 @@ func TestRepositoryServer(t *testing.T) { Username: "foo", InheritedCreds: true, } - db.On("ListRepositories", t.Context()).Return([]*appsv1.Repository{testRepo}, nil) - db.On("GetRepository", t.Context(), url, "").Return(testRepo, nil) - db.On("RepositoryExists", t.Context(), url, "").Return(true, nil) + db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{testRepo}, nil) + db.On("GetRepository", context.TODO(), url, "").Return(testRepo, nil) + db.On("RepositoryExists", context.TODO(), url, "").Return(true, nil) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) - repo, err := s.Get(t.Context(), &repository.RepoQuery{ + repo, err := s.Get(context.TODO(), &repository.RepoQuery{ Repo: url, }) require.NoError(t, err) @@ -337,16 +339,16 @@ func TestRepositoryServer(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("ListRepositories", t.Context()).Return(nil, nil) - db.On("GetRepository", t.Context(), url, "").Return(nil, errors.New("some error")) - db.On("RepositoryExists", t.Context(), url, "").Return(true, nil) + db.On("ListRepositories", context.TODO()).Return(nil, nil) + db.On("GetRepository", context.TODO(), url, "").Return(nil, errors.New("some error")) + db.On("RepositoryExists", context.TODO(), url, "").Return(true, nil) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) - repo, err := s.Get(t.Context(), &repository.RepoQuery{ + repo, err := s.Get(context.TODO(), &repository.RepoQuery{ Repo: url, }) assert.Nil(t, repo) - assert.Equal(t, err, common.PermissionDeniedAPIError) + assert.Equal(t, err, errPermissionDenied) }) t.Run("Test_GetWithNotExistRepoShouldReturn404", func(t *testing.T) { @@ -356,12 +358,12 @@ func TestRepositoryServer(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("ListRepositories", t.Context()).Return([]*appsv1.Repository{{Repo: url}}, nil) - db.On("GetRepository", t.Context(), url, "").Return(&appsv1.Repository{Repo: url}, nil) - db.On("RepositoryExists", t.Context(), url, "").Return(false, nil) + 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(false, nil) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) - repo, err := s.Get(t.Context(), &repository.RepoQuery{ + repo, err := s.Get(context.TODO(), &repository.RepoQuery{ Repo: url, }) assert.Nil(t, repo) @@ -375,12 +377,12 @@ func TestRepositoryServer(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("ListRepositories", t.Context()).Return([]*appsv1.Repository{{Repo: url, Username: "test", Password: "it's a secret", GitHubAppEnterpriseBaseURL: "https://ghe.example.com/api/v3", GithubAppId: 123456, GithubAppInstallationId: 789}}, nil) - db.On("GetRepository", t.Context(), url, "").Return(&appsv1.Repository{Repo: url, Username: "test", Password: "it's a secret"}, nil) - db.On("RepositoryExists", t.Context(), url, "").Return(true, nil) + db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{{Repo: url, Username: "test", Password: "it's a secret", GitHubAppEnterpriseBaseURL: "https://ghe.example.com/api/v3", GithubAppId: 123456, GithubAppInstallationId: 789}}, nil) + db.On("GetRepository", context.TODO(), url, "").Return(&appsv1.Repository{Repo: url, Username: "test", Password: "it's a secret"}, nil) + db.On("RepositoryExists", context.TODO(), url, "").Return(true, nil) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) - repo, err := s.Get(t.Context(), &repository.RepoQuery{ + repo, err := s.Get(context.TODO(), &repository.RepoQuery{ Repo: url, }) require.NoError(t, err) @@ -398,12 +400,12 @@ func TestRepositoryServer(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("ListRepositories", t.Context()).Return([]*appsv1.Repository{{Repo: url}}, nil) - db.On("GetRepository", t.Context(), url, "").Return(&appsv1.Repository{Repo: url, Username: "test"}, nil) - db.On("RepositoryExists", t.Context(), url, "").Return(true, nil) + db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{{Repo: url}}, nil) + db.On("GetRepository", context.TODO(), url, "").Return(&appsv1.Repository{Repo: url, Username: "test"}, nil) + db.On("RepositoryExists", context.TODO(), url, "").Return(true, nil) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) - repo, err := s.Get(t.Context(), &repository.RepoQuery{ + repo, err := s.Get(context.TODO(), &repository.RepoQuery{ Repo: url, }) require.NoError(t, err) @@ -420,12 +422,12 @@ func TestRepositoryServer(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("ListRepositories", t.Context()).Return([]*appsv1.Repository{{Repo: url}}, nil) - db.On("GetRepository", t.Context(), url, "").Return(&appsv1.Repository{Repo: url}, nil) - db.On("RepositoryExists", t.Context(), url, "").Return(true, nil) + db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{{Repo: url}}, nil) + db.On("GetRepository", context.TODO(), url, "").Return(&appsv1.Repository{Repo: url}, nil) + db.On("RepositoryExists", context.TODO(), url, "").Return(true, nil) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) - repo, err := s.Get(t.Context(), &repository.RepoQuery{ + repo, err := s.Get(context.TODO(), &repository.RepoQuery{ Repo: url, }) require.NoError(t, err) @@ -439,14 +441,14 @@ func TestRepositoryServer(t *testing.T) { repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient} db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), "test").Return(nil, errors.New("not found")) - db.On("CreateRepository", t.Context(), mock.Anything).Return(&apiclient.TestRepositoryResponse{}).Return(&appsv1.Repository{ + db.On("GetRepository", context.TODO(), "test").Return(nil, errors.New("not found")) + db.On("CreateRepository", context.TODO(), mock.Anything).Return(&apiclient.TestRepositoryResponse{}).Return(&appsv1.Repository{ Repo: "repo", Project: "proj", }, nil) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) - repo, err := s.CreateRepository(t.Context(), &repository.RepoCreateRequest{ + repo, err := s.CreateRepository(context.TODO(), &repository.RepoCreateRequest{ Repo: &appsv1.Repository{ Repo: "test", Username: "test", @@ -467,15 +469,15 @@ func TestRepositoryServer(t *testing.T) { } db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), "test", "").Return(&appsv1.Repository{ + db.On("GetRepository", context.TODO(), "test", "").Return(&appsv1.Repository{ Repo: "test", Username: "test", }, nil) - db.On("CreateRepository", t.Context(), mock.Anything).Return(nil, status.Errorf(codes.AlreadyExists, "repository already exists")) - db.On("UpdateRepository", t.Context(), mock.Anything).Return(r, nil) + db.On("CreateRepository", context.TODO(), mock.Anything).Return(nil, status.Errorf(codes.AlreadyExists, "repository already exists")) + db.On("UpdateRepository", context.TODO(), mock.Anything).Return(r, nil) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) - repo, err := s.CreateRepository(t.Context(), &repository.RepoCreateRequest{ + repo, err := s.CreateRepository(context.TODO(), &repository.RepoCreateRequest{ Repo: r, Upsert: true, }) @@ -493,12 +495,12 @@ func TestRepositoryServer(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), url, "argocd").Return(nil, nil) - db.On("ListHelmRepositories", t.Context(), mock.Anything).Return(nil, nil) - db.On("ListRepositories", t.Context()).Return([]*appsv1.Repository{&fakeRepo, &fakeRepo}, nil) + db.On("GetRepository", context.TODO(), url, "argocd").Return(nil, nil) + db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(nil, nil) + db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{&fakeRepo, &fakeRepo}, nil) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) - resp, err := s.ListRepositories(t.Context(), &repository.RepoQuery{}) + resp, err := s.ListRepositories(context.TODO(), &repository.RepoQuery{}) require.NoError(t, err) assert.Len(t, resp.Items, 2) }) @@ -506,7 +508,7 @@ func TestRepositoryServer(t *testing.T) { func TestRepositoryServerListApps(t *testing.T) { kubeclientset := fake.NewSimpleClientset(&argocdCM, &argocdSecret) - settingsMgr := settings.NewSettingsManager(t.Context(), kubeclientset, testNamespace) + settingsMgr := settings.NewSettingsManager(context.Background(), kubeclientset, testNamespace) t.Run("Test_WithoutAppCreateUpdatePrivileges", func(t *testing.T) { repoServerClient := mocks.RepoServerServiceClient{} @@ -516,18 +518,18 @@ func TestRepositoryServerListApps(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) appLister, projLister := newAppAndProjLister(defaultProj) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.ListApps(t.Context(), &repository.RepoAppsQuery{ + resp, err := s.ListApps(context.TODO(), &repository.RepoAppsQuery{ Repo: "https://test", Revision: "HEAD", AppName: "foo", AppProject: "default", }) assert.Nil(t, resp) - assert.Equal(t, err, common.PermissionDeniedAPIError) + assert.Equal(t, err, errPermissionDenied) }) t.Run("Test_WithAppCreateUpdatePrivileges", func(t *testing.T) { @@ -539,17 +541,17 @@ func TestRepositoryServerListApps(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) - db.On("GetProjectRepositories", "default").Return(nil, nil) - db.On("GetProjectClusters", t.Context(), "default").Return(nil, nil) - repoServerClient.On("ListApps", t.Context(), mock.Anything).Return(&apiclient.AppList{ + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetProjectRepositories", context.TODO(), "default").Return(nil, nil) + db.On("GetProjectClusters", context.TODO(), "default").Return(nil, nil) + repoServerClient.On("ListApps", context.TODO(), mock.Anything).Return(&apiclient.AppList{ Apps: map[string]string{ "path/to/dir": "Kustomize", }, }, nil) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.ListApps(t.Context(), &repository.RepoAppsQuery{ + resp, err := s.ListApps(context.TODO(), &repository.RepoAppsQuery{ Repo: "https://test", Revision: "HEAD", AppName: "foo", @@ -570,17 +572,17 @@ func TestRepositoryServerListApps(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) - db.On("GetProjectRepositories", "default").Return(nil, nil) - db.On("GetProjectClusters", t.Context(), "default").Return(nil, nil) - repoServerClient.On("ListApps", t.Context(), mock.Anything).Return(&apiclient.AppList{ + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetProjectRepositories", context.TODO(), "default").Return(nil, nil) + db.On("GetProjectClusters", context.TODO(), "default").Return(nil, nil) + repoServerClient.On("ListApps", context.TODO(), mock.Anything).Return(&apiclient.AppList{ Apps: map[string]string{ "path/to/dir": "Kustomize", }, }, nil) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.ListApps(t.Context(), &repository.RepoAppsQuery{ + resp, err := s.ListApps(context.TODO(), &repository.RepoAppsQuery{ Repo: "https://test", Revision: "HEAD", AppName: "foo", @@ -593,7 +595,7 @@ func TestRepositoryServerListApps(t *testing.T) { func TestRepositoryServerGetAppDetails(t *testing.T) { kubeclientset := fake.NewSimpleClientset(&argocdCM, &argocdSecret) - settingsMgr := settings.NewSettingsManager(t.Context(), kubeclientset, testNamespace) + settingsMgr := settings.NewSettingsManager(context.Background(), kubeclientset, testNamespace) t.Run("Test_WithoutRepoReadPrivileges", func(t *testing.T) { repoServerClient := mocks.RepoServerServiceClient{} @@ -603,11 +605,11 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) appLister, projLister := newAppAndProjLister(defaultProj) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &appsv1.ApplicationSource{ RepoURL: url, }, @@ -626,11 +628,11 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) appLister, projLister := newAppAndProjLister(defaultProj) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &appsv1.ApplicationSource{ RepoURL: url, }, @@ -648,11 +650,11 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) appLister, projLister := newAppAndProjLister(defaultProj) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &appsv1.ApplicationSource{ RepoURL: url, }, @@ -669,16 +671,16 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("ListHelmRepositories", t.Context(), mock.Anything).Return(nil, nil) - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) - db.On("GetProjectRepositories", "default").Return(nil, nil) - db.On("GetProjectClusters", t.Context(), "default").Return(nil, nil) + db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(nil, nil) + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetProjectRepositories", context.TODO(), "default").Return(nil, nil) + db.On("GetProjectClusters", context.TODO(), "default").Return(nil, nil) expectedResp := apiclient.RepoAppDetailsResponse{Type: "Directory"} - repoServerClient.On("GetAppDetails", t.Context(), mock.Anything).Return(&expectedResp, nil) + repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil) appLister, projLister := newAppAndProjLister(defaultProj) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &appsv1.ApplicationSource{ RepoURL: url, }, @@ -695,15 +697,15 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) - db.On("GetProjectRepositories", "default").Return(nil, nil) - db.On("GetProjectClusters", t.Context(), "default").Return(nil, nil) + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetProjectRepositories", context.TODO(), "default").Return(nil, nil) + db.On("GetProjectClusters", context.TODO(), "default").Return(nil, nil) expectedResp := apiclient.RepoAppDetailsResponse{Type: "Directory"} - repoServerClient.On("GetAppDetails", t.Context(), mock.Anything).Return(&expectedResp, nil) + repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil) appLister, projLister := newAppAndProjLister(defaultProjNoSources) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &appsv1.ApplicationSource{ RepoURL: url, }, @@ -720,16 +722,16 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("ListHelmRepositories", t.Context(), mock.Anything).Return(nil, nil) - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) - db.On("GetProjectRepositories", "default").Return(nil, nil) - db.On("GetProjectClusters", t.Context(), "default").Return(nil, nil) + db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(nil, nil) + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetProjectRepositories", context.TODO(), "default").Return(nil, nil) + db.On("GetProjectClusters", context.TODO(), "default").Return(nil, nil) expectedResp := apiclient.RepoAppDetailsResponse{Type: "Directory"} - repoServerClient.On("GetAppDetails", t.Context(), mock.Anything).Return(&expectedResp, nil) + repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil) appLister, projLister := newAppAndProjLister(defaultProj, guestbookApp) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: guestbookApp.Spec.GetSourcePtrByIndex(0), AppName: "guestbook", AppProject: "default", @@ -745,18 +747,18 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url := "https://helm.elastic.co" helmRepos := []*appsv1.Repository{{Repo: url}, {Repo: url}} db := &dbmocks.ArgoDB{} - db.On("ListHelmRepositories", t.Context(), mock.Anything).Return(helmRepos, nil) - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) - db.On("GetProjectRepositories", "default").Return(nil, nil) - db.On("GetProjectClusters", t.Context(), "default").Return(nil, nil) + db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(helmRepos, nil) + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetProjectRepositories", context.TODO(), "default").Return(nil, nil) + db.On("GetProjectClusters", context.TODO(), "default").Return(nil, nil) expectedResp := apiclient.RepoAppDetailsResponse{Type: "Helm"} - repoServerClient.On("GetAppDetails", t.Context(), mock.Anything).Return(&expectedResp, nil) + repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil) appLister, projLister := newAppAndProjLister(defaultProj, multiSourceApp001) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) sources := multiSourceApp001.Spec.GetSources() assert.Len(t, sources, 2) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &sources[0], AppName: multiSourceApp001AppName, AppProject: "default", @@ -765,7 +767,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { assert.Equal(t, expectedResp, *resp) assert.Equal(t, "Helm", resp.Type) // Next source - resp, err = s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err = s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &sources[1], AppName: multiSourceApp001AppName, AppProject: "default", @@ -783,22 +785,22 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url1 := "https://helm.elastic.co" helmRepos := []*appsv1.Repository{{Repo: url0}, {Repo: url1}} db := &dbmocks.ArgoDB{} - db.On("ListHelmRepositories", t.Context(), mock.Anything).Return(helmRepos, nil) - db.On("GetRepository", t.Context(), url0, "default").Return(&appsv1.Repository{Repo: url0}, nil) - db.On("GetRepository", t.Context(), url1, "default").Return(&appsv1.Repository{Repo: url1}, nil) - db.On("GetProjectRepositories", "default").Return(nil, nil) - db.On("GetProjectClusters", t.Context(), "default").Return(nil, nil) + db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(helmRepos, nil) + db.On("GetRepository", context.TODO(), url0, "default").Return(&appsv1.Repository{Repo: url0}, nil) + db.On("GetRepository", context.TODO(), url1, "default").Return(&appsv1.Repository{Repo: url1}, nil) + db.On("GetProjectRepositories", context.TODO(), "default").Return(nil, nil) + db.On("GetProjectClusters", context.TODO(), "default").Return(nil, nil) expectedResp0 := apiclient.RepoAppDetailsResponse{Type: "Plugin"} expectedResp1 := apiclient.RepoAppDetailsResponse{Type: "Helm"} - repoServerClient.On("GetAppDetails", t.Context(), mock.MatchedBy(func(req *apiclient.RepoServerAppDetailsQuery) bool { return req.Source.RepoURL == url0 })).Return(&expectedResp0, nil) - repoServerClient.On("GetAppDetails", t.Context(), mock.MatchedBy(func(req *apiclient.RepoServerAppDetailsQuery) bool { return req.Source.RepoURL == url1 })).Return(&expectedResp1, nil) + repoServerClient.On("GetAppDetails", context.TODO(), mock.MatchedBy(func(req *apiclient.RepoServerAppDetailsQuery) bool { return req.Source.RepoURL == url0 })).Return(&expectedResp0, nil) + repoServerClient.On("GetAppDetails", context.TODO(), mock.MatchedBy(func(req *apiclient.RepoServerAppDetailsQuery) bool { return req.Source.RepoURL == url1 })).Return(&expectedResp1, nil) appLister, projLister := newAppAndProjLister(defaultProj, multiSourceApp002) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) sources := multiSourceApp002.Spec.GetSources() assert.Len(t, sources, 2) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &sources[0], AppName: multiSourceApp002AppName, AppProject: "default", @@ -807,7 +809,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { assert.Equal(t, "Plugin", resp.Type) assert.Equal(t, expectedResp0, *resp) // Next source - resp, err = s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err = s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &sources[1], AppName: multiSourceApp002AppName, AppProject: "default", @@ -823,16 +825,16 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), url, "mismatch").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetRepository", context.TODO(), url, "mismatch").Return(&appsv1.Repository{Repo: url}, nil) appLister, projLister := newAppAndProjLister(defaultProj, guestbookApp) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: guestbookApp.Spec.GetSourcePtrByIndex(0), AppName: "guestbook", AppProject: "mismatch", }) - assert.Equal(t, err, common.PermissionDeniedAPIError) + assert.Equal(t, errPermissionDenied, err) assert.Nil(t, resp) }) t.Run("Test_ExistingAppSourceNotInHistory", func(t *testing.T) { @@ -842,18 +844,18 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) appLister, projLister := newAppAndProjLister(defaultProj, guestbookApp) differentSource := guestbookApp.Spec.Source.DeepCopy() differentSource.Helm.ValueFiles = []string{"/etc/passwd"} s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: differentSource, AppName: "guestbook", AppProject: "default", }) - assert.Equal(t, err, common.PermissionDeniedAPIError) + assert.Equal(t, errPermissionDenied, err) assert.Nil(t, resp) }) t.Run("Test_ExistingAppSourceInHistory", func(t *testing.T) { @@ -863,18 +865,18 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url := "https://test" db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) - db.On("ListHelmRepositories", t.Context(), mock.Anything).Return(nil, nil) - db.On("GetProjectRepositories", "default").Return(nil, nil) - db.On("GetProjectClusters", t.Context(), "default").Return(nil, nil) + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(nil, nil) + db.On("GetProjectRepositories", context.TODO(), "default").Return(nil, nil) + db.On("GetProjectClusters", context.TODO(), "default").Return(nil, nil) expectedResp := apiclient.RepoAppDetailsResponse{Type: "Directory"} - repoServerClient.On("GetAppDetails", t.Context(), mock.Anything).Return(&expectedResp, nil) + repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil) appLister, projLister := newAppAndProjLister(defaultProj, guestbookApp) previousSource := guestbookApp.Status.History[0].Source.DeepCopy() previousSource.TargetRevision = guestbookApp.Status.History[0].Revision s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: previousSource, AppName: "guestbook", AppProject: "default", @@ -891,26 +893,26 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url := "https://helm.elastic.co" helmRepos := []*appsv1.Repository{{Repo: url}, {Repo: url}} db := &dbmocks.ArgoDB{} - db.On("ListHelmRepositories", t.Context(), mock.Anything).Return(helmRepos, nil) - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) - db.On("GetProjectRepositories", "default").Return(nil, nil) - db.On("GetProjectClusters", t.Context(), "default").Return(nil, nil) + db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(helmRepos, nil) + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("GetProjectRepositories", context.TODO(), "default").Return(nil, nil) + db.On("GetProjectClusters", context.TODO(), "default").Return(nil, nil) expectedResp := apiclient.RepoAppDetailsResponse{Type: "Helm"} - repoServerClient.On("GetAppDetails", t.Context(), mock.Anything).Return(&expectedResp, nil) + repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil) appLister, projLister := newAppAndProjLister(defaultProj, multiSourceApp001) differentSource := multiSourceApp001.Spec.Sources[0].DeepCopy() differentSource.Helm.ValueFiles = []string{"/etc/passwd"} s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: differentSource, AppName: multiSourceApp001AppName, AppProject: "default", SourceIndex: 0, VersionId: 1, }) - assert.Equal(t, err, common.PermissionDeniedAPIError) + assert.Equal(t, errPermissionDenied, err) assert.Nil(t, resp) }) t.Run("Test_ExistingAppMultiSourceInHistory", func(t *testing.T) { @@ -920,18 +922,18 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { url := "https://helm.elastic.co" db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) - db.On("ListHelmRepositories", t.Context(), mock.Anything).Return(nil, nil) - db.On("GetProjectRepositories", "default").Return(nil, nil) - db.On("GetProjectClusters", t.Context(), "default").Return(nil, nil) + db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) + db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(nil, nil) + db.On("GetProjectRepositories", context.TODO(), "default").Return(nil, nil) + db.On("GetProjectClusters", context.TODO(), "default").Return(nil, nil) expectedResp := apiclient.RepoAppDetailsResponse{Type: "Directory"} - repoServerClient.On("GetAppDetails", t.Context(), mock.Anything).Return(&expectedResp, nil) + repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil) appLister, projLister := newAppAndProjLister(defaultProj, multiSourceApp001) previousSource := multiSourceApp001.Status.History[0].Sources[0].DeepCopy() previousSource.TargetRevision = multiSourceApp001.Status.History[0].Revisions[0] s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.GetAppDetails(t.Context(), &repository.RepoAppDetailsQuery{ + resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: previousSource, AppName: multiSourceApp001AppName, AppProject: "default", @@ -963,7 +965,7 @@ func newEnforcer(kubeclientset *fake.Clientset) *rbac.Enforcer { enforcer := rbac.NewEnforcer(kubeclientset, testNamespace, common.ArgoCDRBACConfigMapName, nil) _ = enforcer.SetBuiltinPolicy(assets.BuiltinPolicyCSV) enforcer.SetDefaultRole("role:admin") - enforcer.SetClaimsEnforcerFunc(func(_ jwt.Claims, _ ...any) bool { + enforcer.SetClaimsEnforcerFunc(func(claims jwt.Claims, rvals ...interface{}) bool { return true }) return enforcer @@ -984,8 +986,8 @@ func TestGetRepository(t *testing.T) { { name: "empty project and no repos", args: args{ - ctx: t.Context(), - listRepositories: func(_ context.Context, _ *repository.RepoQuery) (*appsv1.RepositoryList, error) { + ctx: context.TODO(), + listRepositories: func(ctx context.Context, query *repository.RepoQuery) (*appsv1.RepositoryList, error) { return &appsv1.RepositoryList{ Items: []*appsv1.Repository{ {Repo: "something-else"}, @@ -995,13 +997,13 @@ func TestGetRepository(t *testing.T) { q: &repository.RepoQuery{}, }, want: nil, - error: common.PermissionDeniedAPIError, + error: status.Error(codes.PermissionDenied, "permission denied"), }, { name: "empty project and no matching repos", args: args{ - ctx: t.Context(), - listRepositories: func(_ context.Context, _ *repository.RepoQuery) (*appsv1.RepositoryList, error) { + ctx: context.TODO(), + listRepositories: func(ctx context.Context, query *repository.RepoQuery) (*appsv1.RepositoryList, error) { return &appsv1.RepositoryList{}, nil }, q: &repository.RepoQuery{ @@ -1009,13 +1011,13 @@ func TestGetRepository(t *testing.T) { }, }, want: nil, - error: common.PermissionDeniedAPIError, + error: status.Error(codes.PermissionDenied, "permission denied"), }, { name: "empty project + matching repo with an empty project", args: args{ - ctx: t.Context(), - listRepositories: func(_ context.Context, _ *repository.RepoQuery) (*appsv1.RepositoryList, error) { + ctx: context.TODO(), + listRepositories: func(ctx context.Context, query *repository.RepoQuery) (*appsv1.RepositoryList, error) { return &appsv1.RepositoryList{ Items: []*appsv1.Repository{ {Repo: "foobar", Project: ""}, @@ -1036,8 +1038,8 @@ func TestGetRepository(t *testing.T) { { name: "empty project + matching repo with a non-empty project", args: args{ - ctx: t.Context(), - listRepositories: func(_ context.Context, _ *repository.RepoQuery) (*appsv1.RepositoryList, error) { + ctx: context.TODO(), + listRepositories: func(ctx context.Context, query *repository.RepoQuery) (*appsv1.RepositoryList, error) { return &appsv1.RepositoryList{ Items: []*appsv1.Repository{ {Repo: "foobar", Project: "foobar"}, @@ -1058,8 +1060,8 @@ func TestGetRepository(t *testing.T) { { name: "non-empty project + matching repo with an empty project", args: args{ - ctx: t.Context(), - listRepositories: func(_ context.Context, _ *repository.RepoQuery) (*appsv1.RepositoryList, error) { + ctx: context.TODO(), + listRepositories: func(ctx context.Context, query *repository.RepoQuery) (*appsv1.RepositoryList, error) { return &appsv1.RepositoryList{ Items: []*appsv1.Repository{ {Repo: "foobar", Project: ""}, @@ -1077,8 +1079,8 @@ func TestGetRepository(t *testing.T) { { name: "non-empty project + matching repo with a matching project", args: args{ - ctx: t.Context(), - listRepositories: func(_ context.Context, _ *repository.RepoQuery) (*appsv1.RepositoryList, error) { + ctx: context.TODO(), + listRepositories: func(ctx context.Context, query *repository.RepoQuery) (*appsv1.RepositoryList, error) { return &appsv1.RepositoryList{ Items: []*appsv1.Repository{ {Repo: "foobar", Project: "foobar"}, @@ -1099,8 +1101,8 @@ func TestGetRepository(t *testing.T) { { name: "non-empty project + matching repo with a non-matching project", args: args{ - ctx: t.Context(), - listRepositories: func(_ context.Context, _ *repository.RepoQuery) (*appsv1.RepositoryList, error) { + ctx: context.TODO(), + listRepositories: func(ctx context.Context, query *repository.RepoQuery) (*appsv1.RepositoryList, error) { return &appsv1.RepositoryList{ Items: []*appsv1.Repository{ {Repo: "foobar", Project: "something-else"}, @@ -1133,7 +1135,7 @@ func TestDeleteRepository(t *testing.T) { } kubeclientset := fake.NewSimpleClientset(&argocdCM, &argocdSecret) - settingsMgr := settings.NewSettingsManager(t.Context(), kubeclientset, testNamespace) + settingsMgr := settings.NewSettingsManager(context.Background(), kubeclientset, testNamespace) for name, repo := range repositories { t.Run(name, func(t *testing.T) { @@ -1144,15 +1146,15 @@ func TestDeleteRepository(t *testing.T) { enforcer := newEnforcer(kubeclientset) db := &dbmocks.ArgoDB{} - db.On("DeleteRepository", t.Context(), repo, "default").Return(nil) - db.On("ListRepositories", t.Context()).Return([]*appsv1.Repository{{Repo: repo, Project: "default"}}, nil) - db.On("GetRepository", t.Context(), repo, "default").Return(&appsv1.Repository{Repo: repo, Project: "default"}, nil) + db.On("DeleteRepository", context.TODO(), repo, "default").Return(nil) + db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{{Repo: repo, Project: "default"}}, nil) + db.On("GetRepository", context.TODO(), repo, "default").Return(&appsv1.Repository{Repo: repo, Project: "default"}, nil) appLister, projLister := newAppAndProjLister(defaultProj) s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) - resp, err := s.DeleteRepository(t.Context(), &repository.RepoQuery{Repo: repo, AppProject: "default"}) + resp, err := s.DeleteRepository(context.TODO(), &repository.RepoQuery{Repo: repo, AppProject: "default"}) require.NoError(t, err) - assert.Equal(t, repository.RepoResponse{}, *resp) + assert.Equal(t, repositorypkg.RepoResponse{}, *resp) }) } } diff --git a/server/rootpath_test.go b/server/rootpath_test.go deleted file mode 100644 index 1187402945..0000000000 --- a/server/rootpath_test.go +++ /dev/null @@ -1,123 +0,0 @@ -package server - -import ( - "net/http" - "net/http/httptest" - "testing" - - "github.com/stretchr/testify/assert" -) - -// TestWithRootPathEmptyRootPath tests that withRootPath returns the original handler when RootPath is empty -func TestWithRootPathEmptyRootPath(t *testing.T) { - // Create a simple handler - originalHandler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - w.WriteHeader(http.StatusOK) - }) - - // Create a server with empty RootPath - server := &ArgoCDServer{ - ArgoCDServerOpts: ArgoCDServerOpts{ - RootPath: "", - }, - } - - // Call withRootPath - handler := withRootPath(originalHandler, server) - - // Verify that the returned handler is the original handler - // Since we can't directly compare function references, we'll use a type assertion - _, isServeMux := handler.(*http.ServeMux) - assert.False(t, isServeMux, "When RootPath is empty, withRootPath should return the original handler, not a ServeMux") -} - -// TestWithRootPathNonEmptyRootPath tests that withRootPath returns a ServeMux when RootPath is not empty -func TestWithRootPathNonEmptyRootPath(t *testing.T) { - // Create a simple handler - originalHandler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - w.WriteHeader(http.StatusOK) - }) - - // Create a server with non-empty RootPath - server := &ArgoCDServer{ - ArgoCDServerOpts: ArgoCDServerOpts{ - RootPath: "/argocd", - }, - } - - // Call withRootPath - handler := withRootPath(originalHandler, server) - - // Verify that the returned handler is a ServeMux - _, isServeMux := handler.(*http.ServeMux) - assert.True(t, isServeMux, "When RootPath is not empty, withRootPath should return a ServeMux") -} - -// TestNewRedirectServerEmptyRootPath tests that newRedirectServer correctly handles empty rootPath -func TestNewRedirectServerEmptyRootPath(t *testing.T) { - // Call newRedirectServer with empty rootPath - server := newRedirectServer(8080, "") - - // Verify the server address - assert.Equal(t, "localhost:8080", server.Addr, "When rootPath is empty, server address should be 'localhost:8080'") - - // Test the redirect handler - req := httptest.NewRequest(http.MethodGet, "/applications", nil) - req.Host = "example.com:8080" - w := httptest.NewRecorder() - - server.Handler.ServeHTTP(w, req) - - // Verify the redirect URL - assert.Equal(t, http.StatusTemporaryRedirect, w.Code, "Should return a 307 Temporary Redirect status code") - redirectURL := w.Header().Get("Location") - expectedURL := "https://example.com:8080/applications" - assert.Equal(t, expectedURL, redirectURL, "Redirect URL should not include rootPath when rootPath is empty") -} - -// TestNewRedirectServerNonEmptyRootPath tests that newRedirectServer correctly handles non-empty rootPath -func TestNewRedirectServerNonEmptyRootPath(t *testing.T) { - // Call newRedirectServer with non-empty rootPath - server := newRedirectServer(8080, "/argocd") - - // Verify the server address - assert.Equal(t, "localhost:8080/argocd", server.Addr, "When rootPath is '/argocd', server address should be 'localhost:8080/argocd'") - - // Test the redirect handler - req := httptest.NewRequest(http.MethodGet, "/applications", nil) - req.Host = "example.com:8080" - w := httptest.NewRecorder() - - server.Handler.ServeHTTP(w, req) - - // Verify the redirect URL - assert.Equal(t, http.StatusTemporaryRedirect, w.Code, "Should return a 307 Temporary Redirect status code") - redirectURL := w.Header().Get("Location") - expectedURL := "https://example.com:8080/argocd/applications" - assert.Equal(t, expectedURL, redirectURL, "Redirect URL should include rootPath when rootPath is not empty") -} - -// TestNewRedirectServerRootPathDuplication tests that newRedirectServer does not duplicate rootPath in the redirect URL -func TestNewRedirectServerRootPathDuplication(t *testing.T) { - // Call newRedirectServer with non-empty rootPath - server := newRedirectServer(8080, "/argocd") - - // Test the redirect handler with a request path that already includes rootPath - req := httptest.NewRequest(http.MethodGet, "/argocd/applications", nil) - req.Host = "example.com:8080" - w := httptest.NewRecorder() - - server.Handler.ServeHTTP(w, req) - - // Verify the redirect URL - assert.Equal(t, http.StatusTemporaryRedirect, w.Code, "Should return a 307 Temporary Redirect status code") - redirectURL := w.Header().Get("Location") - - // The URL should not have duplicated rootPath - duplicatedURL := "https://example.com:8080/argocd/argocd/applications" - assert.NotEqual(t, duplicatedURL, redirectURL, "Redirect URL should not have duplicated rootPath") - - // The correct URL should be - correctURL := "https://example.com:8080/argocd/applications" - assert.Equal(t, correctURL, redirectURL, "Redirect URL should be correct without duplicated rootPath") -} diff --git a/server/server.go b/server/server.go index 4894561d20..91007bfd34 100644 --- a/server/server.go +++ b/server/server.go @@ -26,19 +26,21 @@ import ( "syscall" "time" + // nolint:staticcheck + golang_proto "github.com/golang/protobuf/proto" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" + "github.com/argoproj/notifications-engine/pkg/api" - "github.com/argoproj/pkg/v2/sync" - "github.com/golang-jwt/jwt/v5" - golang_proto "github.com/golang/protobuf/proto" //nolint:staticcheck + "github.com/argoproj/pkg/sync" + "github.com/golang-jwt/jwt/v4" "github.com/gorilla/handlers" - grpc_prometheus "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors" - grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery" + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth" + grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/improbable-eng/grpc-web/go/grpcweb" - "github.com/prometheus/client_golang/prometheus" "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" "github.com/soheilhy/cmux" @@ -52,82 +54,79 @@ import ( "google.golang.org/grpc/reflection" "google.golang.org/grpc/status" "gopkg.in/yaml.v2" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/selection" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient" - accountpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/account" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - applicationsetpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/applicationset" - certificatepkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/certificate" - clusterpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster" - gpgkeypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/gpgkey" - notificationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/notification" - projectpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/project" - repocredspkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repocreds" - repositorypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repository" - sessionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" - settingspkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/settings" - versionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/version" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - appinformer "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions" - applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - repoapiclient "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - repocache "github.com/argoproj/argo-cd/v3/reposerver/cache" - "github.com/argoproj/argo-cd/v3/server/account" - "github.com/argoproj/argo-cd/v3/server/application" - "github.com/argoproj/argo-cd/v3/server/applicationset" - "github.com/argoproj/argo-cd/v3/server/badge" - servercache "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/server/certificate" - "github.com/argoproj/argo-cd/v3/server/cluster" - "github.com/argoproj/argo-cd/v3/server/extension" - "github.com/argoproj/argo-cd/v3/server/gpgkey" - "github.com/argoproj/argo-cd/v3/server/logout" - "github.com/argoproj/argo-cd/v3/server/metrics" - "github.com/argoproj/argo-cd/v3/server/notification" - "github.com/argoproj/argo-cd/v3/server/project" - "github.com/argoproj/argo-cd/v3/server/rbacpolicy" - "github.com/argoproj/argo-cd/v3/server/repocreds" - "github.com/argoproj/argo-cd/v3/server/repository" - "github.com/argoproj/argo-cd/v3/server/session" - "github.com/argoproj/argo-cd/v3/server/settings" - "github.com/argoproj/argo-cd/v3/server/version" - "github.com/argoproj/argo-cd/v3/ui" - "github.com/argoproj/argo-cd/v3/util/assets" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - claimsutil "github.com/argoproj/argo-cd/v3/util/claims" - "github.com/argoproj/argo-cd/v3/util/db" - dexutil "github.com/argoproj/argo-cd/v3/util/dex" - "github.com/argoproj/argo-cd/v3/util/env" - errorsutil "github.com/argoproj/argo-cd/v3/util/errors" - grpc_util "github.com/argoproj/argo-cd/v3/util/grpc" - "github.com/argoproj/argo-cd/v3/util/healthz" - httputil "github.com/argoproj/argo-cd/v3/util/http" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/io/files" - jwtutil "github.com/argoproj/argo-cd/v3/util/jwt" - kubeutil "github.com/argoproj/argo-cd/v3/util/kube" - service "github.com/argoproj/argo-cd/v3/util/notification/argocd" - "github.com/argoproj/argo-cd/v3/util/notification/k8s" - settings_notif "github.com/argoproj/argo-cd/v3/util/notification/settings" - "github.com/argoproj/argo-cd/v3/util/oidc" - "github.com/argoproj/argo-cd/v3/util/rbac" - util_session "github.com/argoproj/argo-cd/v3/util/session" - settings_util "github.com/argoproj/argo-cd/v3/util/settings" - "github.com/argoproj/argo-cd/v3/util/swagger" - tlsutil "github.com/argoproj/argo-cd/v3/util/tls" - "github.com/argoproj/argo-cd/v3/util/webhook" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient" + accountpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/account" + applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + applicationsetpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/applicationset" + certificatepkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/certificate" + clusterpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster" + gpgkeypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/gpgkey" + notificationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/notification" + projectpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/project" + repocredspkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repocreds" + repositorypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository" + sessionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" + settingspkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/settings" + versionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/version" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + repoapiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + repocache "github.com/argoproj/argo-cd/v2/reposerver/cache" + "github.com/argoproj/argo-cd/v2/server/account" + "github.com/argoproj/argo-cd/v2/server/application" + "github.com/argoproj/argo-cd/v2/server/applicationset" + "github.com/argoproj/argo-cd/v2/server/badge" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/server/certificate" + "github.com/argoproj/argo-cd/v2/server/cluster" + "github.com/argoproj/argo-cd/v2/server/extension" + "github.com/argoproj/argo-cd/v2/server/gpgkey" + "github.com/argoproj/argo-cd/v2/server/logout" + "github.com/argoproj/argo-cd/v2/server/metrics" + "github.com/argoproj/argo-cd/v2/server/notification" + "github.com/argoproj/argo-cd/v2/server/project" + "github.com/argoproj/argo-cd/v2/server/rbacpolicy" + "github.com/argoproj/argo-cd/v2/server/repocreds" + "github.com/argoproj/argo-cd/v2/server/repository" + "github.com/argoproj/argo-cd/v2/server/session" + "github.com/argoproj/argo-cd/v2/server/settings" + "github.com/argoproj/argo-cd/v2/server/version" + "github.com/argoproj/argo-cd/v2/ui" + "github.com/argoproj/argo-cd/v2/util/assets" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/argoproj/argo-cd/v2/util/db" + dexutil "github.com/argoproj/argo-cd/v2/util/dex" + "github.com/argoproj/argo-cd/v2/util/env" + errorsutil "github.com/argoproj/argo-cd/v2/util/errors" + grpc_util "github.com/argoproj/argo-cd/v2/util/grpc" + "github.com/argoproj/argo-cd/v2/util/healthz" + httputil "github.com/argoproj/argo-cd/v2/util/http" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/io/files" + jwtutil "github.com/argoproj/argo-cd/v2/util/jwt" + kubeutil "github.com/argoproj/argo-cd/v2/util/kube" + service "github.com/argoproj/argo-cd/v2/util/notification/argocd" + "github.com/argoproj/argo-cd/v2/util/notification/k8s" + settings_notif "github.com/argoproj/argo-cd/v2/util/notification/settings" + "github.com/argoproj/argo-cd/v2/util/oidc" + "github.com/argoproj/argo-cd/v2/util/rbac" + util_session "github.com/argoproj/argo-cd/v2/util/session" + settings_util "github.com/argoproj/argo-cd/v2/util/settings" + "github.com/argoproj/argo-cd/v2/util/swagger" + tlsutil "github.com/argoproj/argo-cd/v2/util/tls" + "github.com/argoproj/argo-cd/v2/util/webhook" ) const ( @@ -154,7 +153,7 @@ var backoff = wait.Backoff{ } var ( - clientConstraint = ">= " + common.MinClientVersion + clientConstraint = fmt.Sprintf(">= %s", common.MinClientVersion) baseHRefRegex = regexp.MustCompile(``) // limits number of concurrent login requests to prevent password brute forcing. If set to 0 then no limit is enforced. maxConcurrentLoginRequestsCount = 50 @@ -239,7 +238,6 @@ type ArgoCDServerOpts struct { WebhookParallelism int EnableK8sEvent []string HydratorEnabled bool - SyncWithReplaceAllowed bool } type ApplicationSetOpts struct { @@ -306,8 +304,8 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts, appsetOpts Applicatio if len(opts.ApplicationNamespaces) > 0 { appInformerNs = "" } - projFactory := appinformer.NewSharedInformerFactoryWithOptions(opts.AppClientset, 0, appinformer.WithNamespace(opts.Namespace), appinformer.WithTweakListOptions(func(_ *metav1.ListOptions) {})) - appFactory := appinformer.NewSharedInformerFactoryWithOptions(opts.AppClientset, 0, appinformer.WithNamespace(appInformerNs), appinformer.WithTweakListOptions(func(_ *metav1.ListOptions) {})) + projFactory := appinformer.NewSharedInformerFactoryWithOptions(opts.AppClientset, 0, appinformer.WithNamespace(opts.Namespace), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) + appFactory := appinformer.NewSharedInformerFactoryWithOptions(opts.AppClientset, 0, appinformer.WithNamespace(appInformerNs), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) projInformer := projFactory.Argoproj().V1alpha1().AppProjects().Informer() projLister := projFactory.Argoproj().V1alpha1().AppProjects().Lister().AppProjects(opts.Namespace) @@ -329,18 +327,9 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts, appsetOpts Applicatio policyEnf := rbacpolicy.NewRBACPolicyEnforcer(enf, projLister) enf.SetClaimsEnforcerFunc(policyEnf.EnforceClaims) - staticFS, err := fs.Sub(ui.Embedded, "dist/app") - errorsutil.CheckError(err) - - root, err := os.OpenRoot(opts.StaticAssetsDir) - if err != nil { - if os.IsNotExist(err) { - log.Warnf("Static assets directory %q does not exist, using only embedded assets", opts.StaticAssetsDir) - } else { - errorsutil.CheckError(err) - } - } else { - staticFS = utilio.NewComposableFS(staticFS, root.FS()) + var staticFS fs.FS = io.NewSubDirFS("dist/app", ui.Embedded) + if opts.StaticAssetsDir != "" { + staticFS = io.NewComposableFS(staticFS, os.DirFS(opts.StaticAssetsDir)) } argocdService, err := service.NewArgoCDService(opts.KubeClientset, opts.Namespace, opts.RepoClientset) @@ -358,7 +347,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, opts.Namespace, sg, ag, pg, dbInstance, enf, ug) + em := extension.NewManager(logger, opts.Namespace, sg, ag, pg, enf, ug) noopShutdown := func() { log.Error("API Server Shutdown function called but server is not started yet.") } @@ -403,15 +392,15 @@ const ( notObjectErrMsg = "object does not implement the Object interfaces" ) -func (server *ArgoCDServer) healthCheck(r *http.Request) error { - if server.terminateRequested.Load() { - return errors.New("API Server is terminating and unable to serve requests") +func (a *ArgoCDServer) healthCheck(r *http.Request) error { + if a.terminateRequested.Load() { + return errors.New("API Server is terminating and unable to serve requests.") } - if !server.available.Load() { - return errors.New("API Server is not available: it either hasn't started or is restarting") + if !a.available.Load() { + return errors.New("API Server is not available. It either hasn't started or is restarting.") } if val, ok := r.URL.Query()["full"]; ok && len(val) > 0 && val[0] == "true" { - argoDB := db.NewDB(server.Namespace, server.settingsMgr, server.KubeClientset) + argoDB := db.NewDB(a.Namespace, a.settingsMgr, a.KubeClientset) _, err := argoDB.ListClusters(r.Context()) if err != nil && strings.Contains(err.Error(), notObjectErrMsg) { return err @@ -449,18 +438,18 @@ func (l *Listeners) Close() error { } // logInClusterWarnings checks the in-cluster configuration and prints out any warnings. -func (server *ArgoCDServer) logInClusterWarnings() error { +func (a *ArgoCDServer) logInClusterWarnings() error { labelSelector := labels.NewSelector() req, err := labels.NewRequirement(common.LabelKeySecretType, selection.Equals, []string{common.LabelValueSecretTypeCluster}) if err != nil { return fmt.Errorf("failed to construct cluster-type label selector: %w", err) } labelSelector = labelSelector.Add(*req) - secretsLister, err := server.settingsMgr.GetSecretsLister() + secretsLister, err := a.settingsMgr.GetSecretsLister() if err != nil { return fmt.Errorf("failed to get secrets lister: %w", err) } - clusterSecrets, err := secretsLister.Secrets(server.ArgoCDServerOpts.Namespace).List(labelSelector) + clusterSecrets, err := secretsLister.Secrets(a.ArgoCDServerOpts.Namespace).List(labelSelector) if err != nil { return fmt.Errorf("failed to list cluster secrets: %w", err) } @@ -476,7 +465,7 @@ func (server *ArgoCDServer) logInClusterWarnings() error { } if len(inClusterSecrets) > 0 { // Don't make this call unless we actually have in-cluster secrets, to save time. - dbSettings, err := server.settingsMgr.GetSettings() + dbSettings, err := a.settingsMgr.GetSettings() if err != nil { return fmt.Errorf("could not get DB settings: %w", err) } @@ -502,14 +491,14 @@ func startListener(host string, port int) (net.Listener, error) { return conn, realErr } -func (server *ArgoCDServer) Listen() (*Listeners, error) { - mainLn, err := startListener(server.ListenHost, server.ListenPort) +func (a *ArgoCDServer) Listen() (*Listeners, error) { + mainLn, err := startListener(a.ListenHost, a.ListenPort) if err != nil { return nil, err } - metricsLn, err := startListener(server.ListenHost, server.MetricsPort) + metricsLn, err := startListener(a.ListenHost, a.MetricsPort) if err != nil { - utilio.Close(mainLn) + io.Close(mainLn) return nil, err } var dOpts []grpc.DialOption @@ -517,14 +506,14 @@ func (server *ArgoCDServer) Listen() (*Listeners, error) { dOpts = append(dOpts, grpc.WithUserAgent(fmt.Sprintf("%s/%s", common.ArgoCDUserAgentName, common.GetVersion().Version))) dOpts = append(dOpts, grpc.WithUnaryInterceptor(grpc_util.OTELUnaryClientInterceptor())) dOpts = append(dOpts, grpc.WithStreamInterceptor(grpc_util.OTELStreamClientInterceptor())) - if server.useTLS() { + if a.useTLS() { // The following sets up the dial Options for grpc-gateway to talk to gRPC server over TLS. // grpc-gateway is just translating HTTP/HTTPS requests as gRPC requests over localhost, // so we need to supply the same certificates to establish the connections that a normal, // external gRPC client would need. - tlsConfig := server.settings.TLSConfig() - if server.TLSConfigCustomizer != nil { - server.TLSConfigCustomizer(tlsConfig) + tlsConfig := a.settings.TLSConfig() + if a.TLSConfigCustomizer != nil { + a.TLSConfigCustomizer(tlsConfig) } tlsConfig.InsecureSkipVerify = true dCreds := credentials.NewTLS(tlsConfig) @@ -532,62 +521,62 @@ func (server *ArgoCDServer) Listen() (*Listeners, error) { } else { dOpts = append(dOpts, grpc.WithTransportCredentials(insecure.NewCredentials())) } - //nolint:staticcheck - conn, err := grpc.Dial(fmt.Sprintf("localhost:%d", server.ListenPort), dOpts...) + // nolint:staticcheck + conn, err := grpc.Dial(fmt.Sprintf("localhost:%d", a.ListenPort), dOpts...) if err != nil { - utilio.Close(mainLn) - utilio.Close(metricsLn) + io.Close(mainLn) + io.Close(metricsLn) return nil, err } return &Listeners{Main: mainLn, Metrics: metricsLn, GatewayConn: conn}, nil } // Init starts informers used by the API server -func (server *ArgoCDServer) Init(ctx context.Context) { - go server.projInformer.Run(ctx.Done()) - go server.appInformer.Run(ctx.Done()) - go server.appsetInformer.Run(ctx.Done()) - go server.configMapInformer.Run(ctx.Done()) - go server.secretInformer.Run(ctx.Done()) +func (a *ArgoCDServer) Init(ctx context.Context) { + go a.projInformer.Run(ctx.Done()) + go a.appInformer.Run(ctx.Done()) + go a.appsetInformer.Run(ctx.Done()) + go a.configMapInformer.Run(ctx.Done()) + go a.secretInformer.Run(ctx.Done()) } // Run runs the API Server // We use k8s.io/code-generator/cmd/go-to-protobuf to generate the .proto files from the API types. // k8s.io/ go-to-protobuf uses protoc-gen-gogo, which comes from gogo/protobuf (a fork of // golang/protobuf). -func (server *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { +func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { defer func() { if r := recover(); r != nil { log.WithField("trace", string(debug.Stack())).Error("Recovered from panic: ", r) - server.terminateRequested.Store(true) - server.shutdown() + a.terminateRequested.Store(true) + a.shutdown() } }() - server.userStateStorage.Init(ctx) + a.userStateStorage.Init(ctx) - metricsServ := metrics.NewMetricsServer(server.MetricsHost, server.MetricsPort) - if server.RedisClient != nil { - cacheutil.CollectMetrics(server.RedisClient, metricsServ, server.userStateStorage.GetLockObject()) + metricsServ := metrics.NewMetricsServer(a.MetricsHost, a.MetricsPort) + if a.RedisClient != nil { + cacheutil.CollectMetrics(a.RedisClient, metricsServ, a.userStateStorage.GetLockObject()) } - svcSet := newArgoCDServiceSet(server) - server.serviceSet = svcSet - grpcS, appResourceTreeFn := server.newGRPCServer() + svcSet := newArgoCDServiceSet(a) + a.serviceSet = svcSet + grpcS, appResourceTreeFn := a.newGRPCServer() grpcWebS := grpcweb.WrapServer(grpcS) var httpS *http.Server var httpsS *http.Server - if server.useTLS() { - httpS = newRedirectServer(server.ListenPort, server.RootPath) - httpsS = server.newHTTPServer(ctx, server.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn, metricsServ) + if a.useTLS() { + httpS = newRedirectServer(a.ListenPort, a.RootPath) + httpsS = a.newHTTPServer(ctx, a.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn, metricsServ) } else { - httpS = server.newHTTPServer(ctx, server.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn, metricsServ) + httpS = a.newHTTPServer(ctx, a.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn, metricsServ) } - if server.RootPath != "" { - httpS.Handler = withRootPath(httpS.Handler, server) + if a.RootPath != "" { + httpS.Handler = withRootPath(httpS.Handler, a) if httpsS != nil { - httpsS.Handler = withRootPath(httpsS.Handler, server) + httpsS.Handler = withRootPath(httpsS.Handler, a) } } httpS.Handler = &bug21955Workaround{handler: httpS.Handler} @@ -601,7 +590,7 @@ func (server *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { var grpcL net.Listener var httpL net.Listener var httpsL net.Listener - if !server.useTLS() { + if !a.useTLS() { httpL = tcpm.Match(cmux.HTTP1Fast("PATCH")) grpcL = tcpm.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc")) } else { @@ -617,11 +606,11 @@ func (server *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { // gRPC clients know we support http2 for their communication. NextProtos: []string{"http/1.1", "h2"}, } - tlsConfig.GetCertificate = func(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { - return server.settings.Certificate, nil + tlsConfig.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + return a.settings.Certificate, nil } - if server.TLSConfigCustomizer != nil { - server.TLSConfigCustomizer(&tlsConfig) + if a.TLSConfigCustomizer != nil { + a.TLSConfigCustomizer(&tlsConfig) } tlsl = tls.NewListener(tlsl, &tlsConfig) @@ -633,26 +622,26 @@ func (server *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { // Start the muxed listeners for our servers log.Infof("argocd %s serving on port %d (url: %s, tls: %v, namespace: %s, sso: %v)", - common.GetVersion(), server.ListenPort, server.settings.URL, server.useTLS(), server.Namespace, server.settings.IsSSOConfigured()) - log.Infof("Enabled application namespace patterns: %s", server.allowedApplicationNamespacesAsString()) + common.GetVersion(), a.ListenPort, a.settings.URL, a.useTLS(), a.Namespace, a.settings.IsSSOConfigured()) + log.Infof("Enabled application namespace patterns: %s", a.allowedApplicationNamespacesAsString()) - go func() { server.checkServeErr("grpcS", grpcS.Serve(grpcL)) }() - go func() { server.checkServeErr("httpS", httpS.Serve(httpL)) }() - if server.useTLS() { - go func() { server.checkServeErr("httpsS", httpsS.Serve(httpsL)) }() - go func() { server.checkServeErr("tlsm", tlsm.Serve()) }() + go func() { a.checkServeErr("grpcS", grpcS.Serve(grpcL)) }() + go func() { a.checkServeErr("httpS", httpS.Serve(httpL)) }() + if a.useTLS() { + go func() { a.checkServeErr("httpsS", httpsS.Serve(httpsL)) }() + go func() { a.checkServeErr("tlsm", tlsm.Serve()) }() } - go server.watchSettings() - go server.rbacPolicyLoader(ctx) - go func() { server.checkServeErr("tcpm", tcpm.Serve()) }() - go func() { server.checkServeErr("metrics", metricsServ.Serve(listeners.Metrics)) }() - if !cache.WaitForCacheSync(ctx.Done(), server.projInformer.HasSynced, server.appInformer.HasSynced) { + go a.watchSettings() + go a.rbacPolicyLoader(ctx) + go func() { a.checkServeErr("tcpm", tcpm.Serve()) }() + go func() { a.checkServeErr("metrics", metricsServ.Serve(listeners.Metrics)) }() + if !cache.WaitForCacheSync(ctx.Done(), a.projInformer.HasSynced, a.appInformer.HasSynced) { log.Fatal("Timed out waiting for project cache to sync") } shutdownFunc := func() { log.Info("API Server shutdown initiated. Shutting down servers...") - server.available.Store(false) + a.available.Store(false) shutdownCtx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() var wg gosync.WaitGroup @@ -667,7 +656,7 @@ func (server *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { } }() - if server.useTLS() { + if a.useTLS() { // Shutdown https server wg.Add(1) go func() { @@ -696,7 +685,7 @@ func (server *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { } }() - if server.useTLS() { + if a.useTLS() { // Shutdown tls server wg.Add(1) go func() { @@ -727,37 +716,37 @@ func (server *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { log.Warn("Graceful shutdown timeout. Exiting...") } } - server.shutdown = shutdownFunc - signal.Notify(server.stopCh, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - server.available.Store(true) + a.shutdown = shutdownFunc + signal.Notify(a.stopCh, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + a.available.Store(true) select { - case signal := <-server.stopCh: + case signal := <-a.stopCh: log.Infof("API Server received signal: %s", signal.String()) gracefulRestartSignal := GracefulRestartSignal{} if signal != gracefulRestartSignal { - server.terminateRequested.Store(true) + a.terminateRequested.Store(true) } - server.shutdown() + a.shutdown() case <-ctx.Done(): log.Infof("API Server: %s", ctx.Err()) - server.terminateRequested.Store(true) - server.shutdown() + a.terminateRequested.Store(true) + a.shutdown() } } -func (server *ArgoCDServer) Initialized() bool { - return server.projInformer.HasSynced() && server.appInformer.HasSynced() +func (a *ArgoCDServer) Initialized() bool { + return a.projInformer.HasSynced() && a.appInformer.HasSynced() } // TerminateRequested returns whether a shutdown was initiated by a signal or context cancel // as opposed to a watch. -func (server *ArgoCDServer) TerminateRequested() bool { - return server.terminateRequested.Load() +func (a *ArgoCDServer) TerminateRequested() bool { + return a.terminateRequested.Load() } // checkServeErr checks the error from a .Serve() call to decide if it was a graceful shutdown -func (server *ArgoCDServer) checkServeErr(name string, err error) { +func (a *ArgoCDServer) checkServeErr(name string, err error) { if err != nil && !errors.Is(err, http.ErrServerClosed) { log.Errorf("Error received from server %s: %v", name, err) } else { @@ -783,81 +772,81 @@ func checkOIDCConfigChange(currentOIDCConfig *settings_util.OIDCConfig, newArgoC // watchSettings watches the configmap and secret for any setting updates that would warrant a // restart of the API server. -func (server *ArgoCDServer) watchSettings() { +func (a *ArgoCDServer) watchSettings() { updateCh := make(chan *settings_util.ArgoCDSettings, 1) - server.settingsMgr.Subscribe(updateCh) + a.settingsMgr.Subscribe(updateCh) - prevURL := server.settings.URL - prevAdditionalURLs := server.settings.AdditionalURLs - prevOIDCConfig := server.settings.OIDCConfig() - prevDexCfgBytes, err := dexutil.GenerateDexConfigYAML(server.settings, server.DexTLSConfig == nil || server.DexTLSConfig.DisableTLS) + prevURL := a.settings.URL + prevAdditionalURLs := a.settings.AdditionalURLs + prevOIDCConfig := a.settings.OIDCConfig() + prevDexCfgBytes, err := dexutil.GenerateDexConfigYAML(a.settings, a.DexTLSConfig == nil || a.DexTLSConfig.DisableTLS) errorsutil.CheckError(err) - prevGitHubSecret := server.settings.WebhookGitHubSecret - prevGitLabSecret := server.settings.WebhookGitLabSecret - prevBitbucketUUID := server.settings.WebhookBitbucketUUID - prevBitbucketServerSecret := server.settings.WebhookBitbucketServerSecret - prevGogsSecret := server.settings.WebhookGogsSecret - prevExtConfig := server.settings.ExtensionConfig + prevGitHubSecret := a.settings.WebhookGitHubSecret + prevGitLabSecret := a.settings.WebhookGitLabSecret + prevBitbucketUUID := a.settings.WebhookBitbucketUUID + prevBitbucketServerSecret := a.settings.WebhookBitbucketServerSecret + prevGogsSecret := a.settings.WebhookGogsSecret + prevExtConfig := a.settings.ExtensionConfig var prevCert, prevCertKey string - if server.settings.Certificate != nil && !server.Insecure { - prevCert, prevCertKey = tlsutil.EncodeX509KeyPairString(*server.settings.Certificate) + if a.settings.Certificate != nil && !a.ArgoCDServerOpts.Insecure { + prevCert, prevCertKey = tlsutil.EncodeX509KeyPairString(*a.settings.Certificate) } for { newSettings := <-updateCh - server.settings = newSettings - newDexCfgBytes, err := dexutil.GenerateDexConfigYAML(server.settings, server.DexTLSConfig == nil || server.DexTLSConfig.DisableTLS) + a.settings = newSettings + newDexCfgBytes, err := dexutil.GenerateDexConfigYAML(a.settings, a.DexTLSConfig == nil || a.DexTLSConfig.DisableTLS) errorsutil.CheckError(err) if string(newDexCfgBytes) != string(prevDexCfgBytes) { log.Infof("dex config modified. restarting") break } - if checkOIDCConfigChange(prevOIDCConfig, server.settings) { + if checkOIDCConfigChange(prevOIDCConfig, a.settings) { log.Infof("oidc config modified. restarting") break } - if prevURL != server.settings.URL { + if prevURL != a.settings.URL { log.Infof("url modified. restarting") break } - if !reflect.DeepEqual(prevAdditionalURLs, server.settings.AdditionalURLs) { + if !reflect.DeepEqual(prevAdditionalURLs, a.settings.AdditionalURLs) { log.Infof("additionalURLs modified. restarting") break } - if prevGitHubSecret != server.settings.WebhookGitHubSecret { + if prevGitHubSecret != a.settings.WebhookGitHubSecret { log.Infof("github secret modified. restarting") break } - if prevGitLabSecret != server.settings.WebhookGitLabSecret { + if prevGitLabSecret != a.settings.WebhookGitLabSecret { log.Infof("gitlab secret modified. restarting") break } - if prevBitbucketUUID != server.settings.WebhookBitbucketUUID { + if prevBitbucketUUID != a.settings.WebhookBitbucketUUID { log.Infof("bitbucket uuid modified. restarting") break } - if prevBitbucketServerSecret != server.settings.WebhookBitbucketServerSecret { + if prevBitbucketServerSecret != a.settings.WebhookBitbucketServerSecret { log.Infof("bitbucket server secret modified. restarting") break } - if prevGogsSecret != server.settings.WebhookGogsSecret { + if prevGogsSecret != a.settings.WebhookGogsSecret { log.Infof("gogs secret modified. restarting") break } - if !reflect.DeepEqual(prevExtConfig, server.settings.ExtensionConfig) { - prevExtConfig = server.settings.ExtensionConfig + if !reflect.DeepEqual(prevExtConfig, a.settings.ExtensionConfig) { + prevExtConfig = a.settings.ExtensionConfig log.Infof("extensions configs modified. Updating proxy registry...") - err := server.extensionManager.UpdateExtensionRegistry(server.settings) + err := a.extensionManager.UpdateExtensionRegistry(a.settings) if err != nil { log.Errorf("error updating extensions configs: %s", err) } else { log.Info("extensions configs updated successfully") } } - if !server.Insecure { + if !a.ArgoCDServerOpts.Insecure { var newCert, newCertKey string - if server.settings.Certificate != nil { - newCert, newCertKey = tlsutil.EncodeX509KeyPairString(*server.settings.Certificate) + if a.settings.Certificate != nil { + newCert, newCertKey = tlsutil.EncodeX509KeyPairString(*a.settings.Certificate) } if newCert != prevCert || newCertKey != prevCertKey { log.Infof("tls certificate modified. reloading certificate") @@ -866,14 +855,14 @@ func (server *ArgoCDServer) watchSettings() { } } log.Info("shutting down settings watch") - server.settingsMgr.Unsubscribe(updateCh) + a.settingsMgr.Unsubscribe(updateCh) close(updateCh) // Triggers server restart - server.stopCh <- GracefulRestartSignal{} + a.stopCh <- GracefulRestartSignal{} } -func (server *ArgoCDServer) rbacPolicyLoader(ctx context.Context) { - err := server.enf.RunPolicyLoader(ctx, func(cm *corev1.ConfigMap) error { +func (a *ArgoCDServer) rbacPolicyLoader(ctx context.Context) { + err := a.enf.RunPolicyLoader(ctx, func(cm *v1.ConfigMap) error { var scopes []string if scopesStr, ok := cm.Data[rbac.ConfigMapScopesKey]; len(scopesStr) > 0 && ok { scopes = make([]string, 0) @@ -883,27 +872,23 @@ func (server *ArgoCDServer) rbacPolicyLoader(ctx context.Context) { } } - server.policyEnforcer.SetScopes(scopes) + a.policyEnforcer.SetScopes(scopes) return nil }) errorsutil.CheckError(err) } -func (server *ArgoCDServer) useTLS() bool { - if server.Insecure || server.settings.Certificate == nil { +func (a *ArgoCDServer) useTLS() bool { + if a.Insecure || a.settings.Certificate == nil { return false } return true } -func (server *ArgoCDServer) newGRPCServer() (*grpc.Server, application.AppResourceTreeFn) { - var serverMetricsOptions []grpc_prometheus.ServerMetricsOption +func (a *ArgoCDServer) newGRPCServer() (*grpc.Server, application.AppResourceTreeFn) { if enableGRPCTimeHistogram { - serverMetricsOptions = append(serverMetricsOptions, grpc_prometheus.WithServerHandlingTimeHistogram()) + grpc_prometheus.EnableHandlingTimeHistogram() } - serverMetrics := grpc_prometheus.NewServerMetrics(serverMetricsOptions...) - reg := prometheus.NewRegistry() - reg.MustRegister(serverMetrics) sOpts := []grpc.ServerOption{ // Set the both send and receive the bytes limit to be 100MB @@ -942,53 +927,53 @@ func (server *ArgoCDServer) newGRPCServer() (*grpc.Server, application.AppResour } // NOTE: notice we do not configure the gRPC server here with TLS (e.g. grpc.Creds(creds)) // This is because TLS handshaking occurs in cmux handling - sOpts = append(sOpts, grpc.ChainStreamInterceptor( + sOpts = append(sOpts, grpc.StreamInterceptor(grpc_middleware.ChainStreamServer( otelgrpc.StreamServerInterceptor(), //nolint:staticcheck // TODO: ignore SA1019 for depreciation: see https://github.com/argoproj/argo-cd/issues/18258 - logging.StreamServerInterceptor(grpc_util.InterceptorLogger(server.log)), - serverMetrics.StreamServerInterceptor(), - grpc_auth.StreamServerInterceptor(server.Authenticate), + grpc_logrus.StreamServerInterceptor(a.log), + grpc_prometheus.StreamServerInterceptor, + grpc_auth.StreamServerInterceptor(a.Authenticate), grpc_util.UserAgentStreamServerInterceptor(common.ArgoCDUserAgentName, clientConstraint), - grpc_util.PayloadStreamServerInterceptor(server.log, true, func(_ context.Context, c interceptors.CallMeta) bool { - return !sensitiveMethods[c.FullMethod()] + grpc_util.PayloadStreamServerInterceptor(a.log, true, func(ctx context.Context, fullMethodName string, servingObject interface{}) bool { + return !sensitiveMethods[fullMethodName] }), grpc_util.ErrorCodeK8sStreamServerInterceptor(), grpc_util.ErrorCodeGitStreamServerInterceptor(), - recovery.StreamServerInterceptor(recovery.WithRecoveryHandler(grpc_util.LoggerRecoveryHandler(server.log))), - )) - sOpts = append(sOpts, grpc.ChainUnaryInterceptor( + grpc_util.PanicLoggerStreamServerInterceptor(a.log), + ))) + sOpts = append(sOpts, grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( bug21955WorkaroundInterceptor, otelgrpc.UnaryServerInterceptor(), //nolint:staticcheck // TODO: ignore SA1019 for depreciation: see https://github.com/argoproj/argo-cd/issues/18258 - logging.UnaryServerInterceptor(grpc_util.InterceptorLogger(server.log)), - serverMetrics.UnaryServerInterceptor(), - grpc_auth.UnaryServerInterceptor(server.Authenticate), + grpc_logrus.UnaryServerInterceptor(a.log), + grpc_prometheus.UnaryServerInterceptor, + grpc_auth.UnaryServerInterceptor(a.Authenticate), grpc_util.UserAgentUnaryServerInterceptor(common.ArgoCDUserAgentName, clientConstraint), - grpc_util.PayloadUnaryServerInterceptor(server.log, true, func(_ context.Context, c interceptors.CallMeta) bool { - return !sensitiveMethods[c.FullMethod()] + grpc_util.PayloadUnaryServerInterceptor(a.log, true, func(ctx context.Context, fullMethodName string, servingObject interface{}) bool { + return !sensitiveMethods[fullMethodName] }), grpc_util.ErrorCodeK8sUnaryServerInterceptor(), grpc_util.ErrorCodeGitUnaryServerInterceptor(), - recovery.UnaryServerInterceptor(recovery.WithRecoveryHandler(grpc_util.LoggerRecoveryHandler(server.log))), - )) + grpc_util.PanicLoggerUnaryServerInterceptor(a.log), + ))) grpcS := grpc.NewServer(sOpts...) - versionpkg.RegisterVersionServiceServer(grpcS, server.serviceSet.VersionService) - clusterpkg.RegisterClusterServiceServer(grpcS, server.serviceSet.ClusterService) - applicationpkg.RegisterApplicationServiceServer(grpcS, server.serviceSet.ApplicationService) - applicationsetpkg.RegisterApplicationSetServiceServer(grpcS, server.serviceSet.ApplicationSetService) - notificationpkg.RegisterNotificationServiceServer(grpcS, server.serviceSet.NotificationService) - repositorypkg.RegisterRepositoryServiceServer(grpcS, server.serviceSet.RepoService) - repocredspkg.RegisterRepoCredsServiceServer(grpcS, server.serviceSet.RepoCredsService) - sessionpkg.RegisterSessionServiceServer(grpcS, server.serviceSet.SessionService) - settingspkg.RegisterSettingsServiceServer(grpcS, server.serviceSet.SettingsService) - projectpkg.RegisterProjectServiceServer(grpcS, server.serviceSet.ProjectService) - accountpkg.RegisterAccountServiceServer(grpcS, server.serviceSet.AccountService) - certificatepkg.RegisterCertificateServiceServer(grpcS, server.serviceSet.CertificateService) - gpgkeypkg.RegisterGPGKeyServiceServer(grpcS, server.serviceSet.GpgkeyService) + versionpkg.RegisterVersionServiceServer(grpcS, a.serviceSet.VersionService) + clusterpkg.RegisterClusterServiceServer(grpcS, a.serviceSet.ClusterService) + applicationpkg.RegisterApplicationServiceServer(grpcS, a.serviceSet.ApplicationService) + applicationsetpkg.RegisterApplicationSetServiceServer(grpcS, a.serviceSet.ApplicationSetService) + notificationpkg.RegisterNotificationServiceServer(grpcS, a.serviceSet.NotificationService) + repositorypkg.RegisterRepositoryServiceServer(grpcS, a.serviceSet.RepoService) + repocredspkg.RegisterRepoCredsServiceServer(grpcS, a.serviceSet.RepoCredsService) + sessionpkg.RegisterSessionServiceServer(grpcS, a.serviceSet.SessionService) + settingspkg.RegisterSettingsServiceServer(grpcS, a.serviceSet.SettingsService) + projectpkg.RegisterProjectServiceServer(grpcS, a.serviceSet.ProjectService) + accountpkg.RegisterAccountServiceServer(grpcS, a.serviceSet.AccountService) + certificatepkg.RegisterCertificateServiceServer(grpcS, a.serviceSet.CertificateService) + gpgkeypkg.RegisterGPGKeyServiceServer(grpcS, a.serviceSet.GpgkeyService) // Register reflection service on gRPC server. reflection.Register(grpcS) - serverMetrics.InitializeMetrics(grpcS) - errorsutil.CheckError(server.serviceSet.ProjectService.NormalizeProjs()) - return grpcS, server.serviceSet.AppResourceTreeFn + grpc_prometheus.Register(grpcS) + errorsutil.CheckError(a.serviceSet.ProjectService.NormalizeProjs()) + return grpcS, a.serviceSet.AppResourceTreeFn } type ArgoCDServiceSet struct { @@ -1013,7 +998,7 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet { clusterService := cluster.NewServer(a.db, a.enf, a.Cache, kubectl) repoService := repository.NewServer(a.RepoClientset, a.db, a.enf, a.Cache, a.appLister, a.projInformer, a.Namespace, a.settingsMgr, a.HydratorEnabled) repoCredsService := repocreds.NewServer(a.RepoClientset, a.db, a.enf, a.settingsMgr) - var loginRateLimiter func() (utilio.Closer, error) + var loginRateLimiter func() (io.Closer, error) if maxConcurrentLoginRequestsCount > 0 { loginRateLimiter = session.NewLoginRateLimiter(maxConcurrentLoginRequestsCount) } @@ -1036,7 +1021,6 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet { a.projInformer, a.ApplicationNamespaces, a.EnableK8sEvent, - a.SyncWithReplaceAllowed, ) applicationSetService := applicationset.NewServer( @@ -1063,7 +1047,7 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet { ) projectService := project.NewServer(a.Namespace, a.KubeClientset, a.AppClientset, a.enf, projectLock, a.sessionMgr, a.policyEnforcer, a.projInformer, a.settingsMgr, a.db, a.EnableK8sEvent) - appsInAnyNamespaceEnabled := len(a.ApplicationNamespaces) > 0 + appsInAnyNamespaceEnabled := len(a.ArgoCDServerOpts.ApplicationNamespaces) > 0 settingsService := settings.NewServer(a.settingsMgr, a.RepoClientset, a, a.DisableAuth, appsInAnyNamespaceEnabled, a.HydratorEnabled) accountService := account.NewServer(a.sessionMgr, a.settingsMgr, a.enf) @@ -1100,27 +1084,27 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet { } // translateGrpcCookieHeader conditionally sets a cookie on the response. -func (server *ArgoCDServer) translateGrpcCookieHeader(ctx context.Context, w http.ResponseWriter, resp golang_proto.Message) error { +func (a *ArgoCDServer) translateGrpcCookieHeader(ctx context.Context, w http.ResponseWriter, resp golang_proto.Message) error { if sessionResp, ok := resp.(*sessionpkg.SessionResponse); ok { token := sessionResp.Token - err := server.setTokenCookie(token, w) + err := a.setTokenCookie(token, w) if err != nil { return fmt.Errorf("error setting token cookie from session response: %w", err) } } else if md, ok := runtime.ServerMetadataFromContext(ctx); ok { renewToken := md.HeaderMD[renewTokenKey] if len(renewToken) > 0 { - return server.setTokenCookie(renewToken[0], w) + return a.setTokenCookie(renewToken[0], w) } } return nil } -func (server *ArgoCDServer) setTokenCookie(token string, w http.ResponseWriter) error { - cookiePath := "path=/" + strings.TrimRight(strings.TrimLeft(server.BaseHRef, "/"), "/") +func (a *ArgoCDServer) setTokenCookie(token string, w http.ResponseWriter) error { + cookiePath := fmt.Sprintf("path=/%s", strings.TrimRight(strings.TrimLeft(a.ArgoCDServerOpts.BaseHRef, "/"), "/")) flags := []string{cookiePath, "SameSite=lax", "httpOnly"} - if !server.Insecure { + if !a.Insecure { flags = append(flags, "Secure") } cookies, err := httputil.MakeCookieMetadata(common.AuthCookieName, token, flags...) @@ -1134,13 +1118,8 @@ func (server *ArgoCDServer) setTokenCookie(token string, w http.ResponseWriter) } func withRootPath(handler http.Handler, a *ArgoCDServer) http.Handler { - // If RootPath is empty, directly return the original handler - if a.RootPath == "" { - return handler - } - // get rid of slashes - root := strings.Trim(a.RootPath, "/") + root := strings.TrimRight(strings.TrimLeft(a.RootPath, "/"), "/") mux := http.NewServeMux() mux.Handle("/"+root+"/", http.StripPrefix("/"+root, handler)) @@ -1163,7 +1142,7 @@ func compressHandler(handler http.Handler) http.Handler { // newHTTPServer returns the HTTP server to serve HTTP/HTTPS requests. This is implemented // using grpc-gateway as a proxy to the gRPC server. -func (server *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandler http.Handler, appResourceTreeFn application.AppResourceTreeFn, conn *grpc.ClientConn, metricsReg HTTPMetricsRegistry) *http.Server { +func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandler http.Handler, appResourceTreeFn application.AppResourceTreeFn, conn *grpc.ClientConn, metricsReg HTTPMetricsRegistry) *http.Server { endpoint := fmt.Sprintf("localhost:%d", port) mux := http.NewServeMux() httpS := http.Server{ @@ -1171,8 +1150,8 @@ func (server *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWeb Handler: &handlerSwitcher{ handler: mux, urlToHandler: map[string]http.Handler{ - "/api/badge": badge.NewHandler(server.AppClientset, server.settingsMgr, server.Namespace, server.ApplicationNamespaces), - common.LogoutEndpoint: logout.NewHandler(server.AppClientset, server.settingsMgr, server.sessionMgr, server.RootPath, server.BaseHRef, server.Namespace), + "/api/badge": badge.NewHandler(a.AppClientset, a.settingsMgr, a.Namespace, a.ApplicationNamespaces), + common.LogoutEndpoint: logout.NewHandler(a.AppClientset, a.settingsMgr, a.sessionMgr, a.ArgoCDServerOpts.RootPath, a.ArgoCDServerOpts.BaseHRef, a.Namespace), }, contentTypeToHandler: map[string]http.Handler{ "application/grpc-web+proto": grpcWebHandler, @@ -1187,60 +1166,60 @@ func (server *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWeb // time.Time, but does not support custom UnmarshalJSON() and MarshalJSON() methods. Therefore // we use our own Marshaler gwMuxOpts := runtime.WithMarshalerOption(runtime.MIMEWildcard, new(grpc_util.JSONMarshaler)) - gwCookieOpts := runtime.WithForwardResponseOption(server.translateGrpcCookieHeader) + gwCookieOpts := runtime.WithForwardResponseOption(a.translateGrpcCookieHeader) gwmux := runtime.NewServeMux(gwMuxOpts, gwCookieOpts) var handler http.Handler = gwmux - if server.EnableGZip { + if a.EnableGZip { handler = compressHandler(handler) } - if len(server.ContentTypes) > 0 { - handler = enforceContentTypes(handler, server.ContentTypes) + if len(a.ContentTypes) > 0 { + handler = enforceContentTypes(handler, a.ContentTypes) } else { log.WithField(common.SecurityField, common.SecurityHigh).Warnf("Content-Type enforcement is disabled, which may make your API vulnerable to CSRF attacks") } mux.Handle("/api/", handler) - terminalOpts := application.TerminalOptions{DisableAuth: server.DisableAuth, Enf: server.enf} + terminalOpts := application.TerminalOptions{DisableAuth: a.ArgoCDServerOpts.DisableAuth, Enf: a.enf} - terminal := application.NewHandler(server.appLister, server.Namespace, server.ApplicationNamespaces, server.db, server.Cache, appResourceTreeFn, server.settings.ExecShells, server.sessionMgr, &terminalOpts). - WithFeatureFlagMiddleware(server.settingsMgr.GetSettings) - th := util_session.WithAuthMiddleware(server.DisableAuth, server.sessionMgr, terminal) + terminal := application.NewHandler(a.appLister, a.Namespace, a.ApplicationNamespaces, a.db, a.Cache, appResourceTreeFn, a.settings.ExecShells, a.sessionMgr, &terminalOpts). + WithFeatureFlagMiddleware(a.settingsMgr.GetSettings) + th := util_session.WithAuthMiddleware(a.DisableAuth, a.sessionMgr, terminal) mux.Handle("/terminal", th) // Proxy extension is currently an alpha feature and is disabled // by default. - if server.EnableProxyExtension { + if a.EnableProxyExtension { // API server won't panic if extensions fail to register. In // this case an error log will be sent and no extension route // will be added in mux. - registerExtensions(mux, server, metricsReg) + registerExtensions(mux, a, metricsReg) } - mustRegisterGWHandler(ctx, versionpkg.RegisterVersionServiceHandler, gwmux, conn) - mustRegisterGWHandler(ctx, clusterpkg.RegisterClusterServiceHandler, gwmux, conn) - mustRegisterGWHandler(ctx, applicationpkg.RegisterApplicationServiceHandler, gwmux, conn) - mustRegisterGWHandler(ctx, applicationsetpkg.RegisterApplicationSetServiceHandler, gwmux, conn) - mustRegisterGWHandler(ctx, notificationpkg.RegisterNotificationServiceHandler, gwmux, conn) - mustRegisterGWHandler(ctx, repositorypkg.RegisterRepositoryServiceHandler, gwmux, conn) - mustRegisterGWHandler(ctx, repocredspkg.RegisterRepoCredsServiceHandler, gwmux, conn) - mustRegisterGWHandler(ctx, sessionpkg.RegisterSessionServiceHandler, gwmux, conn) - mustRegisterGWHandler(ctx, settingspkg.RegisterSettingsServiceHandler, gwmux, conn) - mustRegisterGWHandler(ctx, projectpkg.RegisterProjectServiceHandler, gwmux, conn) - mustRegisterGWHandler(ctx, accountpkg.RegisterAccountServiceHandler, gwmux, conn) - mustRegisterGWHandler(ctx, certificatepkg.RegisterCertificateServiceHandler, gwmux, conn) - mustRegisterGWHandler(ctx, gpgkeypkg.RegisterGPGKeyServiceHandler, gwmux, conn) + mustRegisterGWHandler(versionpkg.RegisterVersionServiceHandler, ctx, gwmux, conn) + mustRegisterGWHandler(clusterpkg.RegisterClusterServiceHandler, ctx, gwmux, conn) + mustRegisterGWHandler(applicationpkg.RegisterApplicationServiceHandler, ctx, gwmux, conn) + mustRegisterGWHandler(applicationsetpkg.RegisterApplicationSetServiceHandler, ctx, gwmux, conn) + mustRegisterGWHandler(notificationpkg.RegisterNotificationServiceHandler, ctx, gwmux, conn) + mustRegisterGWHandler(repositorypkg.RegisterRepositoryServiceHandler, ctx, gwmux, conn) + mustRegisterGWHandler(repocredspkg.RegisterRepoCredsServiceHandler, ctx, gwmux, conn) + mustRegisterGWHandler(sessionpkg.RegisterSessionServiceHandler, ctx, gwmux, conn) + mustRegisterGWHandler(settingspkg.RegisterSettingsServiceHandler, ctx, gwmux, conn) + mustRegisterGWHandler(projectpkg.RegisterProjectServiceHandler, ctx, gwmux, conn) + mustRegisterGWHandler(accountpkg.RegisterAccountServiceHandler, ctx, gwmux, conn) + mustRegisterGWHandler(certificatepkg.RegisterCertificateServiceHandler, ctx, gwmux, conn) + mustRegisterGWHandler(gpgkeypkg.RegisterGPGKeyServiceHandler, ctx, gwmux, conn) // Swagger UI - swagger.ServeSwaggerUI(mux, assets.SwaggerJSON, "/swagger-ui", server.RootPath) - healthz.ServeHealthCheck(mux, server.healthCheck) + swagger.ServeSwaggerUI(mux, assets.SwaggerJSON, "/swagger-ui", a.RootPath) + healthz.ServeHealthCheck(mux, a.healthCheck) // Dex reverse proxy and client app and OAuth2 login/callback - server.registerDexHandlers(mux) + a.registerDexHandlers(mux) // Webhook handler for git events (Note: cache timeouts are hardcoded because API server does not write to cache and not really using them) - argoDB := db.NewDB(server.Namespace, server.settingsMgr, server.KubeClientset) - acdWebhookHandler := webhook.NewHandler(server.Namespace, server.ApplicationNamespaces, server.WebhookParallelism, server.AppClientset, server.settings, server.settingsMgr, server.RepoServerCache, server.Cache, argoDB, server.settingsMgr.GetMaxWebhookPayloadSize()) + argoDB := db.NewDB(a.Namespace, a.settingsMgr, a.KubeClientset) + acdWebhookHandler := webhook.NewHandler(a.Namespace, a.ArgoCDServerOpts.ApplicationNamespaces, a.ArgoCDServerOpts.WebhookParallelism, a.AppClientset, a.settings, a.settingsMgr, a.RepoServerCache, a.Cache, argoDB, a.settingsMgr.GetMaxWebhookPayloadSize()) mux.HandleFunc("/api/webhook", acdWebhookHandler.Handler) @@ -1251,16 +1230,16 @@ func (server *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWeb extensionsSharedPath := "/tmp/extensions/" var extensionsHandler http.Handler = http.HandlerFunc(func(writer http.ResponseWriter, _ *http.Request) { - server.serveExtensions(extensionsSharedPath, writer) + a.serveExtensions(extensionsSharedPath, writer) }) - if server.EnableGZip { + if a.ArgoCDServerOpts.EnableGZip { extensionsHandler = compressHandler(extensionsHandler) } mux.Handle("/extensions.js", extensionsHandler) // Serve UI static assets - var assetsHandler http.Handler = http.HandlerFunc(server.newStaticAssetsHandler()) - if server.EnableGZip { + var assetsHandler http.Handler = http.HandlerFunc(a.newStaticAssetsHandler()) + if a.ArgoCDServerOpts.EnableGZip { assetsHandler = compressHandler(assetsHandler) } mux.Handle("/", assetsHandler) @@ -1289,7 +1268,7 @@ func registerExtensions(mux *http.ServeMux, a *ArgoCDServer, metricsReg HTTPMetr extHandler := http.HandlerFunc(a.extensionManager.CallExtension()) authMiddleware := a.sessionMgr.AuthMiddlewareFunc(a.DisableAuth) // auth middleware ensures that requests to all extensions are authenticated first - mux.Handle(extension.URLPrefix+"/", authMiddleware(extHandler)) + mux.Handle(fmt.Sprintf("%s/", extension.URLPrefix), authMiddleware(extHandler)) a.extensionManager.AddMetricsRegistry(metricsReg) @@ -1301,7 +1280,7 @@ func registerExtensions(mux *http.ServeMux, a *ArgoCDServer, metricsReg HTTPMetr var extensionsPattern = regexp.MustCompile(`^extension(.*)\.js$`) -func (server *ArgoCDServer) serveExtensions(extensionsSharedPath string, w http.ResponseWriter) { +func (a *ArgoCDServer) serveExtensions(extensionsSharedPath string, w http.ResponseWriter) { w.Header().Set("Content-Type", "application/javascript") err := filepath.Walk(extensionsSharedPath, func(filePath string, info os.FileInfo, err error) error { @@ -1310,7 +1289,7 @@ func (server *ArgoCDServer) serveExtensions(extensionsSharedPath string, w http. } if !files.IsSymlink(info) && !info.IsDir() && extensionsPattern.MatchString(info.Name()) { processFile := func() error { - if _, err = fmt.Fprintf(w, "// source: %s/%s \n", filePath, info.Name()); err != nil { + if _, err = w.Write([]byte(fmt.Sprintf("// source: %s/%s \n", filePath, info.Name()))); err != nil { return fmt.Errorf("failed to write to response: %w", err) } @@ -1318,7 +1297,7 @@ func (server *ArgoCDServer) serveExtensions(extensionsSharedPath string, w http. if err != nil { return fmt.Errorf("failed to open file '%s': %w", filePath, err) } - defer utilio.Close(f) + defer io.Close(f) if _, err := goio.Copy(w, f); err != nil { return fmt.Errorf("failed to copy file '%s': %w", filePath, err) @@ -1342,47 +1321,30 @@ func (server *ArgoCDServer) serveExtensions(extensionsSharedPath string, w http. } // registerDexHandlers will register dex HTTP handlers, creating the OAuth client app -func (server *ArgoCDServer) registerDexHandlers(mux *http.ServeMux) { - if !server.settings.IsSSOConfigured() { +func (a *ArgoCDServer) registerDexHandlers(mux *http.ServeMux) { + if !a.settings.IsSSOConfigured() { return } // Run dex OpenID Connect Identity Provider behind a reverse proxy (served at /api/dex) var err error - mux.HandleFunc(common.DexAPIEndpoint+"/", dexutil.NewDexHTTPReverseProxy(server.DexServerAddr, server.BaseHRef, server.DexTLSConfig)) - server.ssoClientApp, err = oidc.NewClientApp(server.settings, server.DexServerAddr, server.DexTLSConfig, server.BaseHRef, cacheutil.NewRedisCache(server.RedisClient, server.settings.UserInfoCacheExpiration(), cacheutil.RedisCompressionNone)) + mux.HandleFunc(common.DexAPIEndpoint+"/", dexutil.NewDexHTTPReverseProxy(a.DexServerAddr, a.BaseHRef, a.DexTLSConfig)) + a.ssoClientApp, err = oidc.NewClientApp(a.settings, a.DexServerAddr, a.DexTLSConfig, a.BaseHRef, cacheutil.NewRedisCache(a.RedisClient, a.settings.UserInfoCacheExpiration(), cacheutil.RedisCompressionNone)) errorsutil.CheckError(err) - mux.HandleFunc(common.LoginEndpoint, server.ssoClientApp.HandleLogin) - mux.HandleFunc(common.CallbackEndpoint, server.ssoClientApp.HandleCallback) + mux.HandleFunc(common.LoginEndpoint, a.ssoClientApp.HandleLogin) + mux.HandleFunc(common.CallbackEndpoint, a.ssoClientApp.HandleCallback) } // newRedirectServer returns an HTTP server which does a 307 redirect to the HTTPS server func newRedirectServer(port int, rootPath string) *http.Server { - var addr string - if rootPath == "" { - addr = fmt.Sprintf("localhost:%d", port) - } else { - addr = fmt.Sprintf("localhost:%d/%s", port, strings.Trim(rootPath, "/")) - } - + addr := fmt.Sprintf("localhost:%d/%s", port, strings.TrimRight(strings.TrimLeft(rootPath, "/"), "/")) return &http.Server{ Addr: addr, Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { target := "https://" + req.Host - if rootPath != "" { - root := strings.Trim(rootPath, "/") - prefix := "/" + root - - // If the request path already starts with rootPath, no need to add rootPath again - if strings.HasPrefix(req.URL.Path, prefix) { - target += req.URL.Path - } else { - target += prefix + req.URL.Path - } - } else { - target += req.URL.Path + target += "/" + strings.TrimRight(strings.TrimLeft(rootPath, "/"), "/") } - + target += req.URL.Path if len(req.URL.RawQuery) > 0 { target += "?" + req.URL.RawQuery } @@ -1404,21 +1366,21 @@ func registerDownloadHandlers(mux *http.ServeMux, base string) { } } -func (server *ArgoCDServer) getIndexData() ([]byte, error) { - server.indexDataInit.Do(func() { +func (s *ArgoCDServer) getIndexData() ([]byte, error) { + s.indexDataInit.Do(func() { data, err := ui.Embedded.ReadFile("dist/app/index.html") if err != nil { - server.indexDataErr = err + s.indexDataErr = err return } - if server.BaseHRef == "/" || server.BaseHRef == "" { - server.indexData = data + if s.BaseHRef == "/" || s.BaseHRef == "" { + s.indexData = data } else { - server.indexData = []byte(replaceBaseHRef(string(data), fmt.Sprintf(``, strings.Trim(server.BaseHRef, "/")))) + s.indexData = []byte(replaceBaseHRef(string(data), fmt.Sprintf(``, strings.Trim(s.BaseHRef, "/")))) } }) - return server.indexData, server.indexDataErr + return s.indexData, s.indexDataErr } func (server *ArgoCDServer) uiAssetExists(filename string) bool { @@ -1426,7 +1388,7 @@ func (server *ArgoCDServer) uiAssetExists(filename string) bool { if err != nil { return false } - defer utilio.Close(f) + defer io.Close(f) stat, err := f.Stat() if err != nil { return false @@ -1472,7 +1434,7 @@ func (server *ArgoCDServer) newStaticAssetsHandler() func(http.ResponseWriter, * if err != nil { modTime = time.Now() } - http.ServeContent(w, r, "index.html", modTime, utilio.NewByteReadSeeker(data)) + http.ServeContent(w, r, "index.html", modTime, io.NewByteReadSeeker(data)) } else { if isMainJsBundle(r.URL) { cacheControl := "public, max-age=31536000, immutable" @@ -1496,7 +1458,7 @@ func isMainJsBundle(url *url.URL) bool { type registerFunc func(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error // mustRegisterGWHandler is a convenience function to register a gateway handler -func mustRegisterGWHandler(ctx context.Context, register registerFunc, mux *runtime.ServeMux, conn *grpc.ClientConn) { +func mustRegisterGWHandler(register registerFunc, ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) { err := register(ctx, mux, conn) if err != nil { panic(err) @@ -1508,14 +1470,14 @@ func replaceBaseHRef(data string, replaceWith string) string { } // Authenticate checks for the presence of a valid token when accessing server-side resources. -func (server *ArgoCDServer) Authenticate(ctx context.Context) (context.Context, error) { - if server.DisableAuth { +func (a *ArgoCDServer) Authenticate(ctx context.Context) (context.Context, error) { + if a.DisableAuth { return ctx, nil } - claims, newToken, claimsErr := server.getClaims(ctx) + claims, newToken, claimsErr := a.getClaims(ctx) if claims != nil { // Add claims to the context to inspect for RBAC - //nolint:staticcheck + // nolint:staticcheck ctx = context.WithValue(ctx, "claims", claims) if newToken != "" { // Session tokens that are expiring soon should be regenerated if user stays active. @@ -1527,26 +1489,27 @@ func (server *ArgoCDServer) Authenticate(ctx context.Context) (context.Context, } } if claimsErr != nil { - //nolint:staticcheck + // nolint:staticcheck ctx = context.WithValue(ctx, util_session.AuthErrorCtxKey, claimsErr) } if claimsErr != nil { - argoCDSettings, err := server.settingsMgr.GetSettings() + argoCDSettings, err := a.settingsMgr.GetSettings() if err != nil { return ctx, status.Errorf(codes.Internal, "unable to load settings: %v", err) } if !argoCDSettings.AnonymousUserEnabled { return ctx, claimsErr + } else { + // nolint:staticcheck + ctx = context.WithValue(ctx, "claims", "") } - //nolint:staticcheck - ctx = context.WithValue(ctx, "claims", "") } return ctx, nil } -func (server *ArgoCDServer) getClaims(ctx context.Context) (jwt.Claims, string, error) { +func (a *ArgoCDServer) getClaims(ctx context.Context) (jwt.Claims, string, error) { md, ok := metadata.FromIncomingContext(ctx) if !ok { return nil, "", ErrNoSession @@ -1555,24 +1518,24 @@ func (server *ArgoCDServer) getClaims(ctx context.Context) (jwt.Claims, string, if tokenString == "" { return nil, "", ErrNoSession } - claims, newToken, err := server.sessionMgr.VerifyToken(tokenString) + claims, newToken, err := a.sessionMgr.VerifyToken(tokenString) if err != nil { return claims, "", status.Errorf(codes.Unauthenticated, "invalid session: %v", err) } - mapClaims, err := jwtutil.MapClaims(claims) - if err != nil { - return claims, "", status.Errorf(codes.Internal, "invalid claims") + // Some SSO implementations (Okta) require a call to + // the OIDC user info path to get attributes like groups + // we assume that everywhere in argocd jwt.MapClaims is used as type for interface jwt.Claims + // otherwise this would cause a panic + var groupClaims jwt.MapClaims + if groupClaims, ok = claims.(jwt.MapClaims); !ok { + if tmpClaims, ok := claims.(*jwt.MapClaims); ok { + groupClaims = *tmpClaims + } } - argoClaims, err := claimsutil.MapClaimsToArgoClaims(mapClaims) - if err != nil { - return claims, "", status.Errorf(codes.Internal, "invalid argo claims") - } - - // Some SSO implementations (Okta) require a call to the OIDC user info path to get attributes like groups - iss := jwtutil.StringField(mapClaims, "iss") - if iss != util_session.SessionManagerClaimsIssuer && server.settings.UserInfoGroupsEnabled() && server.settings.UserInfoPath() != "" { - userInfo, unauthorized, err := server.ssoClientApp.GetUserInfo(mapClaims, server.settings.IssuerURL(), server.settings.UserInfoPath()) + iss := jwtutil.StringField(groupClaims, "iss") + if iss != util_session.SessionManagerClaimsIssuer && a.settings.UserInfoGroupsEnabled() && a.settings.UserInfoPath() != "" { + userInfo, unauthorized, err := a.ssoClientApp.GetUserInfo(groupClaims, a.settings.IssuerURL(), a.settings.UserInfoPath()) if unauthorized { log.Errorf("error while quering userinfo endpoint: %v", err) return claims, "", status.Errorf(codes.Unauthenticated, "invalid session") @@ -1581,17 +1544,13 @@ func (server *ArgoCDServer) getClaims(ctx context.Context) (jwt.Claims, string, log.Errorf("error fetching user info endpoint: %v", err) return claims, "", status.Errorf(codes.Internal, "invalid userinfo response") } - userInfoClaims, err := claimsutil.MapClaimsToArgoClaims(userInfo) - if err != nil { - return claims, "", status.Errorf(codes.Internal, "invalid userinfo claims") - } - if argoClaims.Subject != userInfoClaims.Subject { + if groupClaims["sub"] != userInfo["sub"] { return claims, "", status.Error(codes.Unknown, "subject of claims from user info endpoint didn't match subject of idToken, see https://openid.net/specs/openid-connect-core-1_0.html#UserInfo") } - mapClaims["groups"] = userInfo["groups"] + groupClaims["groups"] = userInfo["groups"] } - return mapClaims, newToken, nil + return groupClaims, newToken, nil } // getToken extracts the token from gRPC metadata or cookie headers @@ -1667,7 +1626,7 @@ func (bf *bug21955Workaround) ServeHTTP(w http.ResponseWriter, r *http.Request) bf.handler.ServeHTTP(w, r) } -func bug21955WorkaroundInterceptor(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) { +func bug21955WorkaroundInterceptor(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { if rq, ok := req.(*repositorypkg.RepoQuery); ok { repo, err := url.QueryUnescape(rq.Repo) if err != nil { @@ -1726,11 +1685,11 @@ func bug21955WorkaroundInterceptor(ctx context.Context, req any, _ *grpc.UnarySe // allowedApplicationNamespacesAsString returns a string containing comma-separated list // of allowed application namespaces -func (server *ArgoCDServer) allowedApplicationNamespacesAsString() string { - ns := server.Namespace - if len(server.ApplicationNamespaces) > 0 { +func (a *ArgoCDServer) allowedApplicationNamespacesAsString() string { + ns := a.Namespace + if len(a.ArgoCDServerOpts.ApplicationNamespaces) > 0 { ns += ", " - ns += strings.Join(server.ApplicationNamespaces, ", ") + ns += strings.Join(a.ArgoCDServerOpts.ApplicationNamespaces, ", ") } return ns } diff --git a/server/server_norace_test.go b/server/server_norace_test.go index ad0dc9356a..cd73a54f12 100644 --- a/server/server_norace_test.go +++ b/server/server_norace_test.go @@ -15,10 +15,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/test" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient" + applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/test" ) func TestUserAgent(t *testing.T) { @@ -34,7 +34,7 @@ func TestUserAgent(t *testing.T) { cancelInformer := test.StartInformer(s.projInformer) defer cancelInformer() - ctx, cancel := context.WithCancel(t.Context()) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() s.Init(ctx) go s.Run(ctx, lns) @@ -50,7 +50,7 @@ func TestUserAgent(t *testing.T) { tests := []testData{ { // Reject out-of-date user-agent - userAgent: common.ArgoCDUserAgentName + "/0.10.0", + userAgent: fmt.Sprintf("%s/0.10.0", common.ArgoCDUserAgentName), errorMsg: "unsatisfied client version constraint", }, { @@ -99,7 +99,7 @@ func Test_StaticHeaders(t *testing.T) { require.NoError(t, err) cancelInformer := test.StartInformer(s.projInformer) defer cancelInformer() - ctx, cancel := context.WithCancel(t.Context()) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() s.Init(ctx) go s.Run(ctx, lns) @@ -128,7 +128,7 @@ func Test_StaticHeaders(t *testing.T) { defer cancelInformer() lns, err := s.Listen() require.NoError(t, err) - ctx, cancel := context.WithCancel(t.Context()) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() s.Init(ctx) go s.Run(ctx, lns) @@ -157,7 +157,7 @@ func Test_StaticHeaders(t *testing.T) { defer cancelInformer() lns, err := s.Listen() require.NoError(t, err) - ctx, cancel := context.WithCancel(t.Context()) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() s.Init(ctx) go s.Run(ctx, lns) diff --git a/server/server_test.go b/server/server_test.go index 312bb13697..cfd4e7d906 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -15,7 +15,7 @@ import ( "testing" "time" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -28,22 +28,23 @@ import ( dynfake "k8s.io/client-go/dynamic/fake" clientfake "sigs.k8s.io/controller-runtime/pkg/client/fake" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - apps "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient/mocks" - servercache "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/server/rbacpolicy" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/assets" - "github.com/argoproj/argo-cd/v3/util/cache" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/oidc" - "github.com/argoproj/argo-cd/v3/util/rbac" - settings_util "github.com/argoproj/argo-cd/v3/util/settings" - testutil "github.com/argoproj/argo-cd/v3/util/test" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + apps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/server/rbacpolicy" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/assets" + "github.com/argoproj/argo-cd/v2/util/cache" + 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/oidc" + "github.com/argoproj/argo-cd/v2/util/rbac" + settings_util "github.com/argoproj/argo-cd/v2/util/settings" + testutil "github.com/argoproj/argo-cd/v2/util/test" ) type FakeArgoCDServer struct { @@ -79,7 +80,7 @@ func fakeServer(t *testing.T) (*FakeArgoCDServer, func()) { ContentSecurityPolicy: "frame-ancestors 'self';", Cache: servercache.NewCache( appstatecache.NewCache( - cache.NewCache(cache.NewInMemoryCache(1*time.Hour)), + cacheutil.NewCache(cacheutil.NewInMemoryCache(1*time.Hour)), 1*time.Minute, ), 1*time.Minute, @@ -92,7 +93,7 @@ func fakeServer(t *testing.T) (*FakeArgoCDServer, func()) { DynamicClientset: dynamicClient, KubeControllerClientset: fakeClient, } - srv := NewServer(t.Context(), argoCDOpts, ApplicationSetOpts{}) + srv := NewServer(context.Background(), argoCDOpts, ApplicationSetOpts{}) fakeSrv := &FakeArgoCDServer{srv, tmpAssetsDir} return fakeSrv, closer } @@ -128,30 +129,30 @@ func TestEnforceProjectToken(t *testing.T) { mockRepoClient := &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}} t.Run("TestEnforceProjectTokenSuccessful", func(t *testing.T) { - s := NewServer(t.Context(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) + s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) cancel := test.StartInformer(s.projInformer) defer cancel() claims := jwt.MapClaims{"sub": defaultSub, "iat": defaultIssuedAt} - assert.True(t, s.enf.Enforce(claims, "projects", "get", existingProj.Name)) + assert.True(t, s.enf.Enforce(claims, "projects", "get", existingProj.ObjectMeta.Name)) assert.True(t, s.enf.Enforce(claims, "applications", "get", defaultTestObject)) }) t.Run("TestEnforceProjectTokenWithDiffCreateAtFailure", func(t *testing.T) { - s := NewServer(t.Context(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) + s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) diffCreateAt := defaultIssuedAt + 1 claims := jwt.MapClaims{"sub": defaultSub, "iat": diffCreateAt} assert.False(t, s.enf.Enforce(claims, "applications", "get", defaultTestObject)) }) t.Run("TestEnforceProjectTokenIncorrectSubFormatFailure", func(t *testing.T) { - s := NewServer(t.Context(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) + s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) invalidSub := "proj:test" claims := jwt.MapClaims{"sub": invalidSub, "iat": defaultIssuedAt} assert.False(t, s.enf.Enforce(claims, "applications", "get", defaultTestObject)) }) t.Run("TestEnforceProjectTokenNoTokenFailure", func(t *testing.T) { - s := NewServer(t.Context(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) + s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) nonExistentToken := "fake-token" invalidSub := fmt.Sprintf(subFormat, projectName, nonExistentToken) claims := jwt.MapClaims{"sub": invalidSub, "iat": defaultIssuedAt} @@ -161,7 +162,7 @@ func TestEnforceProjectToken(t *testing.T) { t.Run("TestEnforceProjectTokenNotJWTTokenFailure", func(t *testing.T) { proj := existingProj.DeepCopy() proj.Spec.Roles[0].JWTTokens = nil - s := NewServer(t.Context(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(proj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) + s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(proj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) claims := jwt.MapClaims{"sub": defaultSub, "iat": defaultIssuedAt} assert.False(t, s.enf.Enforce(claims, "applications", "get", defaultTestObject)) }) @@ -174,7 +175,7 @@ func TestEnforceProjectToken(t *testing.T) { proj := existingProj.DeepCopy() proj.Spec.Roles[0] = role - s := NewServer(t.Context(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(proj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) + s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(proj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) cancel := test.StartInformer(s.projInformer) defer cancel() claims := jwt.MapClaims{"sub": defaultSub, "iat": defaultIssuedAt} @@ -185,16 +186,16 @@ func TestEnforceProjectToken(t *testing.T) { }) t.Run("TestEnforceProjectTokenWithIdSuccessful", func(t *testing.T) { - s := NewServer(t.Context(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) + s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) cancel := test.StartInformer(s.projInformer) defer cancel() claims := jwt.MapClaims{"sub": defaultSub, "jti": defaultId} - assert.True(t, s.enf.Enforce(claims, "projects", "get", existingProj.Name)) + assert.True(t, s.enf.Enforce(claims, "projects", "get", existingProj.ObjectMeta.Name)) assert.True(t, s.enf.Enforce(claims, "applications", "get", defaultTestObject)) }) t.Run("TestEnforceProjectTokenWithInvalidIdFailure", func(t *testing.T) { - s := NewServer(t.Context(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) + s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) invalidId := "invalidId" claims := jwt.MapClaims{"sub": defaultSub, "jti": defaultId} res := s.enf.Enforce(claims, "applications", "get", invalidId) @@ -278,10 +279,10 @@ func TestInitializingExistingDefaultProject(t *testing.T) { RepoClientset: mockRepoClient, } - argocd := NewServer(t.Context(), argoCDOpts, ApplicationSetOpts{}) + argocd := NewServer(context.Background(), argoCDOpts, ApplicationSetOpts{}) assert.NotNil(t, argocd) - proj, err := appClientSet.ArgoprojV1alpha1().AppProjects(test.FakeArgoCDNamespace).Get(t.Context(), v1alpha1.DefaultAppProjectName, metav1.GetOptions{}) + proj, err := appClientSet.ArgoprojV1alpha1().AppProjects(test.FakeArgoCDNamespace).Get(context.Background(), v1alpha1.DefaultAppProjectName, metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, proj) assert.Equal(t, v1alpha1.DefaultAppProjectName, proj.Name) @@ -301,10 +302,10 @@ func TestInitializingNotExistingDefaultProject(t *testing.T) { RepoClientset: mockRepoClient, } - argocd := NewServer(t.Context(), argoCDOpts, ApplicationSetOpts{}) + argocd := NewServer(context.Background(), argoCDOpts, ApplicationSetOpts{}) assert.NotNil(t, argocd) - proj, err := appClientSet.ArgoprojV1alpha1().AppProjects(test.FakeArgoCDNamespace).Get(t.Context(), v1alpha1.DefaultAppProjectName, metav1.GetOptions{}) + proj, err := appClientSet.ArgoprojV1alpha1().AppProjects(test.FakeArgoCDNamespace).Get(context.Background(), v1alpha1.DefaultAppProjectName, metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, proj) assert.Equal(t, v1alpha1.DefaultAppProjectName, proj.Name) @@ -343,14 +344,14 @@ func TestEnforceProjectGroups(t *testing.T) { } mockRepoClient := &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}} kubeclientset := fake.NewClientset(test.NewFakeConfigMap(), test.NewFakeSecret()) - s := NewServer(t.Context(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) + s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) cancel := test.StartInformer(s.projInformer) defer cancel() claims := jwt.MapClaims{ "iat": defaultIssuedAt, "groups": []string{groupName}, } - assert.True(t, s.enf.Enforce(claims, "projects", "get", existingProj.Name)) + assert.True(t, s.enf.Enforce(claims, "projects", "get", existingProj.ObjectMeta.Name)) assert.True(t, s.enf.Enforce(claims, "applications", "get", defaultTestObject)) assert.False(t, s.enf.Enforce(claims, "clusters", "get", "test")) @@ -358,9 +359,9 @@ func TestEnforceProjectGroups(t *testing.T) { log.Println(existingProj.ProjectPoliciesString()) existingProj.Spec.Roles[0].Groups = nil log.Println(existingProj.ProjectPoliciesString()) - _, _ = s.AppClientset.ArgoprojV1alpha1().AppProjects(test.FakeArgoCDNamespace).Update(t.Context(), &existingProj, metav1.UpdateOptions{}) + _, _ = s.AppClientset.ArgoprojV1alpha1().AppProjects(test.FakeArgoCDNamespace).Update(context.Background(), &existingProj, metav1.UpdateOptions{}) time.Sleep(100 * time.Millisecond) // this lets the informer get synced - assert.False(t, s.enf.Enforce(claims, "projects", "get", existingProj.Name)) + assert.False(t, s.enf.Enforce(claims, "projects", "get", existingProj.ObjectMeta.Name)) assert.False(t, s.enf.Enforce(claims, "applications", "get", defaultTestObject)) assert.False(t, s.enf.Enforce(claims, "clusters", "get", "test")) } @@ -405,11 +406,11 @@ func TestRevokedToken(t *testing.T) { }, } - s := NewServer(t.Context(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) + s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) cancel := test.StartInformer(s.projInformer) defer cancel() claims := jwt.MapClaims{"sub": defaultSub, "iat": defaultIssuedAt} - assert.True(t, s.enf.Enforce(claims, "projects", "get", existingProj.Name)) + assert.True(t, s.enf.Enforce(claims, "projects", "get", existingProj.ObjectMeta.Name)) assert.True(t, s.enf.Enforce(claims, "applications", "get", defaultTestObject)) } @@ -428,7 +429,7 @@ func TestGracefulShutdown(t *testing.T) { redis, redisCloser := test.NewInMemoryRedis() defer redisCloser() s := NewServer( - t.Context(), + context.Background(), ArgoCDServerOpts{ ListenPort: port, Namespace: test.FakeArgoCDNamespace, @@ -451,7 +452,7 @@ func TestGracefulShutdown(t *testing.T) { require.NoError(t, err) shutdown := false - runCtx, runCancel := context.WithTimeout(t.Context(), 2*time.Second) + runCtx, runCancel := context.WithTimeout(context.Background(), 2*time.Second) defer runCancel() err = s.healthCheck(&http.Request{URL: &url.URL{Path: "/healthz", RawQuery: "full=true"}}) @@ -526,12 +527,12 @@ func TestAuthenticate(t *testing.T) { AppClientset: appClientSet, RepoClientset: mockRepoClient, } - argocd := NewServer(t.Context(), argoCDOpts, ApplicationSetOpts{}) - ctx := t.Context() + argocd := NewServer(context.Background(), argoCDOpts, ApplicationSetOpts{}) + ctx := context.Background() if testData.user != "" { token, err := argocd.sessionMgr.Create(testData.user, 0, "abc") require.NoError(t, err) - ctx = metadata.NewIncomingContext(t.Context(), metadata.Pairs(apiclient.MetaDataTokenKey, token)) + ctx = metadata.NewIncomingContext(context.Background(), metadata.Pairs(apiclient.MetaDataTokenKey, token)) } _, err := argocd.Authenticate(ctx) @@ -616,7 +617,7 @@ func getTestServer(t *testing.T, anonymousEnabled bool, withFakeSSO bool, useDex if anonymousEnabled { cm.Data["users.anonymous.enabled"] = "true" } - ts := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Start with a placeholder. We need the server URL before setting up the real handler. })) ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -665,7 +666,7 @@ connectors: if withFakeSSO && useDexForSSO { argoCDOpts.DexServerAddr = ts.URL } - argocd = NewServer(t.Context(), argoCDOpts, ApplicationSetOpts{}) + argocd = NewServer(context.Background(), argoCDOpts, ApplicationSetOpts{}) var err error argocd.ssoClientApp, err = oidc.NewClientApp(argocd.settings, argocd.DexServerAddr, argocd.DexTLSConfig, argocd.BaseHRef, cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) @@ -733,7 +734,7 @@ func TestGetClaims(t *testing.T) { t.Parallel() // Must be declared here to avoid race. - ctx := t.Context() //nolint:ineffassign,staticcheck + ctx := context.Background() //nolint:ineffassign,staticcheck argocd, oidcURL := getTestServer(t, false, true, false, testDataCopy.additionalOIDCConfig) @@ -745,7 +746,7 @@ func TestGetClaims(t *testing.T) { require.NoError(t, err) tokenString, err := token.SignedString(key) require.NoError(t, err) - ctx = metadata.NewIncomingContext(t.Context(), metadata.Pairs(apiclient.MetaDataTokenKey, tokenString)) + ctx = metadata.NewIncomingContext(context.Background(), metadata.Pairs(apiclient.MetaDataTokenKey, tokenString)) gotClaims, newToken, err := argocd.getClaims(ctx) @@ -777,7 +778,7 @@ func TestAuthenticate_3rd_party_JWTs(t *testing.T) { anonymousEnabled bool claims jwt.RegisteredClaims expectedErrorContains string - expectedClaims any + expectedClaims interface{} useDex bool } tests := []testData{ @@ -815,7 +816,7 @@ func TestAuthenticate_3rd_party_JWTs(t *testing.T) { anonymousEnabled: false, claims: jwt.RegisteredClaims{Audience: jwt.ClaimStrings{common.ArgoCDClientAppID}, Subject: "admin", ExpiresAt: jwt.NewNumericDate(time.Now())}, expectedErrorContains: common.TokenVerificationError, - expectedClaims: jwt.MapClaims{"iss": "sso"}, + expectedClaims: jwt.RegisteredClaims{Issuer: "sso"}, }, { test: "anonymous enabled, expired token, admin claim", @@ -870,7 +871,7 @@ func TestAuthenticate_3rd_party_JWTs(t *testing.T) { claims: jwt.RegisteredClaims{Audience: jwt.ClaimStrings{common.ArgoCDClientAppID}, Subject: "admin", ExpiresAt: jwt.NewNumericDate(time.Now())}, useDex: true, expectedErrorContains: common.TokenVerificationError, - expectedClaims: jwt.MapClaims{"iss": "sso"}, + expectedClaims: jwt.RegisteredClaims{Issuer: "sso"}, }, { test: "external OIDC: anonymous enabled, expired token, admin claim", @@ -897,19 +898,19 @@ func TestAuthenticate_3rd_party_JWTs(t *testing.T) { t.Parallel() // Must be declared here to avoid race. - ctx := t.Context() //nolint:staticcheck + ctx := context.Background() //nolint:ineffassign,staticcheck argocd, oidcURL := getTestServer(t, testDataCopy.anonymousEnabled, true, testDataCopy.useDex, settings_util.OIDCConfig{}) if testDataCopy.useDex { - testDataCopy.claims.Issuer = oidcURL + "/api/dex" + testDataCopy.claims.Issuer = fmt.Sprintf("%s/api/dex", oidcURL) } else { testDataCopy.claims.Issuer = oidcURL } token := jwt.NewWithClaims(jwt.SigningMethodHS256, testDataCopy.claims) tokenString, err := token.SignedString([]byte("key")) require.NoError(t, err) - ctx = metadata.NewIncomingContext(t.Context(), metadata.Pairs(apiclient.MetaDataTokenKey, tokenString)) + ctx = metadata.NewIncomingContext(context.Background(), metadata.Pairs(apiclient.MetaDataTokenKey, tokenString)) ctx, err = argocd.Authenticate(ctx) claims := ctx.Value("claims") @@ -932,7 +933,7 @@ func TestAuthenticate_no_request_metadata(t *testing.T) { test string anonymousEnabled bool expectedErrorContains string - expectedClaims any + expectedClaims interface{} } tests := []testData{ { @@ -956,7 +957,7 @@ func TestAuthenticate_no_request_metadata(t *testing.T) { t.Parallel() argocd, _ := getTestServer(t, testDataCopy.anonymousEnabled, true, true, settings_util.OIDCConfig{}) - ctx := t.Context() + ctx := context.Background() ctx, err := argocd.Authenticate(ctx) claims := ctx.Value("claims") @@ -975,7 +976,7 @@ func TestAuthenticate_no_SSO(t *testing.T) { test string anonymousEnabled bool expectedErrorMessage string - expectedClaims any + expectedClaims interface{} } tests := []testData{ { @@ -999,13 +1000,13 @@ func TestAuthenticate_no_SSO(t *testing.T) { t.Parallel() // Must be declared here to avoid race. - ctx := t.Context() //nolint:ineffassign,staticcheck + ctx := context.Background() //nolint:ineffassign,staticcheck argocd, dexURL := getTestServer(t, testDataCopy.anonymousEnabled, false, true, settings_util.OIDCConfig{}) - token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{Issuer: dexURL + "/api/dex"}) + token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{Issuer: fmt.Sprintf("%s/api/dex", dexURL)}) tokenString, err := token.SignedString([]byte("key")) require.NoError(t, err) - ctx = metadata.NewIncomingContext(t.Context(), metadata.Pairs(apiclient.MetaDataTokenKey, tokenString)) + ctx = metadata.NewIncomingContext(context.Background(), metadata.Pairs(apiclient.MetaDataTokenKey, tokenString)) ctx, err = argocd.Authenticate(ctx) claims := ctx.Value("claims") @@ -1025,7 +1026,7 @@ func TestAuthenticate_bad_request_metadata(t *testing.T) { anonymousEnabled bool metadata metadata.MD expectedErrorMessage string - expectedClaims any + expectedClaims interface{} } tests := []testData{ { @@ -1107,10 +1108,10 @@ func TestAuthenticate_bad_request_metadata(t *testing.T) { t.Parallel() // Must be declared here to avoid race. - ctx := t.Context() //nolint:ineffassign,staticcheck + ctx := context.Background() //nolint:ineffassign,staticcheck argocd, _ := getTestServer(t, testDataCopy.anonymousEnabled, true, true, settings_util.OIDCConfig{}) - ctx = metadata.NewIncomingContext(t.Context(), testDataCopy.metadata) + ctx = metadata.NewIncomingContext(context.Background(), testDataCopy.metadata) ctx, err := argocd.Authenticate(ctx) claims := ctx.Value("claims") @@ -1149,11 +1150,11 @@ func TestTranslateGrpcCookieHeader(t *testing.T) { AppClientset: apps.NewSimpleClientset(), RepoClientset: &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}}, } - argocd := NewServer(t.Context(), argoCDOpts, ApplicationSetOpts{}) + argocd := NewServer(context.Background(), argoCDOpts, ApplicationSetOpts{}) t.Run("TokenIsNotEmpty", func(t *testing.T) { recorder := httptest.NewRecorder() - err := argocd.translateGrpcCookieHeader(t.Context(), recorder, &session.SessionResponse{ + err := argocd.translateGrpcCookieHeader(context.Background(), recorder, &session.SessionResponse{ Token: "xyz", }) require.NoError(t, err) @@ -1163,7 +1164,7 @@ func TestTranslateGrpcCookieHeader(t *testing.T) { t.Run("TokenIsLongerThan4093", func(t *testing.T) { recorder := httptest.NewRecorder() - err := argocd.translateGrpcCookieHeader(t.Context(), recorder, &session.SessionResponse{ + err := argocd.translateGrpcCookieHeader(context.Background(), recorder, &session.SessionResponse{ Token: "abc.xyz." + strings.Repeat("x", 4093), }) require.NoError(t, err) @@ -1173,11 +1174,11 @@ func TestTranslateGrpcCookieHeader(t *testing.T) { t.Run("TokenIsEmpty", func(t *testing.T) { recorder := httptest.NewRecorder() - err := argocd.translateGrpcCookieHeader(t.Context(), recorder, &session.SessionResponse{ + err := argocd.translateGrpcCookieHeader(context.Background(), recorder, &session.SessionResponse{ Token: "", }) require.NoError(t, err) - assert.Empty(t, recorder.Result().Header.Get("Set-Cookie")) + assert.Equal(t, "", recorder.Result().Header.Get("Set-Cookie")) }) } @@ -1193,7 +1194,7 @@ func TestInitializeDefaultProject_ProjectDoesNotExist(t *testing.T) { require.NoError(t, err) proj, err := argoCDOpts.AppClientset.ArgoprojV1alpha1(). - AppProjects(test.FakeArgoCDNamespace).Get(t.Context(), v1alpha1.DefaultAppProjectName, metav1.GetOptions{}) + AppProjects(test.FakeArgoCDNamespace).Get(context.Background(), v1alpha1.DefaultAppProjectName, metav1.GetOptions{}) require.NoError(t, err) @@ -1227,7 +1228,7 @@ func TestInitializeDefaultProject_ProjectAlreadyInitialized(t *testing.T) { require.NoError(t, err) proj, err := argoCDOpts.AppClientset.ArgoprojV1alpha1(). - AppProjects(test.FakeArgoCDNamespace).Get(t.Context(), v1alpha1.DefaultAppProjectName, metav1.GetOptions{}) + AppProjects(test.FakeArgoCDNamespace).Get(context.Background(), v1alpha1.DefaultAppProjectName, metav1.GetOptions{}) require.NoError(t, err) @@ -1406,8 +1407,8 @@ func TestIsMainJsBundle(t *testing.T) { testCaseCopy := testCase t.Run(testCaseCopy.name, func(t *testing.T) { t.Parallel() - testURL, _ := url.Parse(testCaseCopy.url) - isMainJsBundle := isMainJsBundle(testURL) + testUrl, _ := url.Parse(testCaseCopy.url) + isMainJsBundle := isMainJsBundle(testUrl) assert.Equal(t, testCaseCopy.isMainJsBundle, isMainJsBundle) }) } @@ -1459,7 +1460,7 @@ func TestCacheControlHeaders(t *testing.T) { handler := argocd.newStaticAssetsHandler() rr := httptest.NewRecorder() - req := httptest.NewRequest("", "/"+testCase.filename, nil) + req := httptest.NewRequest("", fmt.Sprintf("/%s", testCase.filename), nil) fp := filepath.Join(argocd.TmpAssetsDir, testCase.filename) @@ -1603,7 +1604,7 @@ 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, _ *http.Request) { + 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(http.StatusOK) }) @@ -1643,40 +1644,3 @@ func Test_enforceContentTypes(t *testing.T) { assert.Equal(t, http.StatusUnsupportedMediaType, resp.StatusCode, "should not have passed, since a disallowed content type was provided") }) } - -func Test_StaticAssetsDir_no_symlink_traversal(t *testing.T) { - tmpDir := t.TempDir() - assetsDir := filepath.Join(tmpDir, "assets") - err := os.MkdirAll(assetsDir, os.ModePerm) - require.NoError(t, err) - - // Create a file in temp dir - filePath := filepath.Join(tmpDir, "test.txt") - err = os.WriteFile(filePath, []byte("test"), 0o644) - require.NoError(t, err) - - argocd, closer := fakeServer(t) - defer closer() - - // Create a symlink to the file - symlinkPath := filepath.Join(argocd.StaticAssetsDir, "link.txt") - err = os.Symlink(filePath, symlinkPath) - require.NoError(t, err) - - // Make a request to get the file from the /assets endpoint - req := httptest.NewRequest(http.MethodGet, "/link.txt", nil) - w := httptest.NewRecorder() - argocd.newStaticAssetsHandler()(w, req) - resp := w.Result() - assert.Equal(t, http.StatusInternalServerError, resp.StatusCode, "should not have been able to access the symlinked file") - - // Make sure a normal file works - normalFilePath := filepath.Join(argocd.StaticAssetsDir, "normal.txt") - err = os.WriteFile(normalFilePath, []byte("normal"), 0o644) - require.NoError(t, err) - req = httptest.NewRequest(http.MethodGet, "/normal.txt", nil) - w = httptest.NewRecorder() - argocd.newStaticAssetsHandler()(w, req) - resp = w.Result() - assert.Equal(t, http.StatusOK, resp.StatusCode, "should have been able to access the normal file") -} diff --git a/server/session/ratelimiter.go b/server/session/ratelimiter.go index 2ffa44a2dc..84967a4072 100644 --- a/server/session/ratelimiter.go +++ b/server/session/ratelimiter.go @@ -1,21 +1,21 @@ package session import ( - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/session" + util "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/session" log "github.com/sirupsen/logrus" "golang.org/x/sync/semaphore" ) -func NewLoginRateLimiter(maxNumber int) func() (utilio.Closer, error) { +func NewLoginRateLimiter(maxNumber int) func() (util.Closer, error) { semaphore := semaphore.NewWeighted(int64(maxNumber)) - return func() (utilio.Closer, error) { + return func() (util.Closer, error) { if !semaphore.TryAcquire(1) { log.Warnf("Exceeded number of concurrent login requests") return nil, session.InvalidLoginErr } - return utilio.NewCloser(func() error { + return util.NewCloser(func() error { defer semaphore.Release(1) return nil }), nil diff --git a/server/session/ratelimiter_test.go b/server/session/ratelimiter_test.go index 0c2a19034c..1642f1b8d4 100644 --- a/server/session/ratelimiter_test.go +++ b/server/session/ratelimiter_test.go @@ -6,12 +6,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/session" + util "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/session" ) func TestRateLimiter(t *testing.T) { - var closers []utilio.Closer + var closers []util.Closer limiter := NewLoginRateLimiter(10) for i := 0; i < 10; i++ { closer, err := limiter() diff --git a/server/session/session.go b/server/session/session.go index 8ba56f042f..780d66c123 100644 --- a/server/session/session.go +++ b/server/session/session.go @@ -4,16 +4,16 @@ import ( "context" "fmt" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/util/settings" "github.com/google/uuid" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" - "github.com/argoproj/argo-cd/v3/server/rbacpolicy" - utilio "github.com/argoproj/argo-cd/v3/util/io" - sessionmgr "github.com/argoproj/argo-cd/v3/util/session" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" + "github.com/argoproj/argo-cd/v2/server/rbacpolicy" + util "github.com/argoproj/argo-cd/v2/util/io" + sessionmgr "github.com/argoproj/argo-cd/v2/util/session" ) // Server provides a Session service @@ -22,7 +22,7 @@ type Server struct { settingsMgr *settings.SettingsManager authenticator Authenticator policyEnf *rbacpolicy.RBACPolicyEnforcer - limitLoginAttempts func() (utilio.Closer, error) + limitLoginAttempts func() (util.Closer, error) } type Authenticator interface { @@ -30,7 +30,7 @@ type Authenticator interface { } // NewServer returns a new instance of the Session service -func NewServer(mgr *sessionmgr.SessionManager, settingsMgr *settings.SettingsManager, authenticator Authenticator, policyEnf *rbacpolicy.RBACPolicyEnforcer, rateLimiter func() (utilio.Closer, error)) *Server { +func NewServer(mgr *sessionmgr.SessionManager, settingsMgr *settings.SettingsManager, authenticator Authenticator, policyEnf *rbacpolicy.RBACPolicyEnforcer, rateLimiter func() (util.Closer, error)) *Server { return &Server{mgr, settingsMgr, authenticator, policyEnf, rateLimiter} } @@ -42,7 +42,7 @@ func (s *Server) Create(_ context.Context, q *session.SessionCreateRequest) (*se if err != nil { return nil, err } - defer utilio.Close(closer) + defer util.Close(closer) } if q.Token != "" { @@ -74,7 +74,7 @@ func (s *Server) Create(_ context.Context, q *session.SessionCreateRequest) (*se } // Delete an authentication cookie from the client. This makes sense only for the Web client. -func (s *Server) Delete(_ context.Context, _ *session.SessionDeleteRequest) (*session.SessionResponse, error) { +func (s *Server) Delete(ctx context.Context, q *session.SessionDeleteRequest) (*session.SessionResponse, error) { return &session.SessionResponse{Token: ""}, nil } @@ -82,13 +82,13 @@ func (s *Server) Delete(_ context.Context, _ *session.SessionDeleteRequest) (*se // Without this function here, ArgoCDServer.authenticate would be invoked and credentials checked. // Since this service is generally invoked when the user has _no_ credentials, that would create a // chicken-and-egg situation if we didn't place this here to allow traffic to pass through. -func (s *Server) AuthFuncOverride(ctx context.Context, _ string) (context.Context, error) { +func (s *Server) AuthFuncOverride(ctx context.Context, fullMethodName string) (context.Context, error) { // this authenticates the user, but ignores any error, so that we have claims populated ctx, _ = s.authenticator.Authenticate(ctx) return ctx, nil } -func (s *Server) GetUserInfo(ctx context.Context, _ *session.GetUserInfoRequest) (*session.GetUserInfoResponse, error) { +func (s *Server) GetUserInfo(ctx context.Context, q *session.GetUserInfoRequest) (*session.GetUserInfoResponse, error) { return &session.GetUserInfoResponse{ LoggedIn: sessionmgr.LoggedIn(ctx), Username: sessionmgr.Username(ctx), diff --git a/server/session/session.proto b/server/session/session.proto index 777711f6dd..d6735bda69 100644 --- a/server/session/session.proto +++ b/server/session/session.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/session"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/session"; // Session Service // diff --git a/server/settings/oidc/claims.pb.go b/server/settings/oidc/claims.pb.go index 521c5a590f..5c2b9ee814 100644 --- a/server/settings/oidc/claims.pb.go +++ b/server/settings/oidc/claims.pb.go @@ -103,8 +103,8 @@ var fileDescriptor_7d353f964edf8c0f = []byte{ 0x58, 0xcb, 0x12, 0x73, 0x4a, 0x53, 0x25, 0x98, 0x14, 0x18, 0x35, 0x38, 0x83, 0x20, 0x1c, 0x21, 0x31, 0x2e, 0x36, 0x30, 0xa3, 0x58, 0x82, 0x59, 0x81, 0x59, 0x83, 0x33, 0x08, 0xca, 0x73, 0x72, 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0xa3, 0x8c, 0x11, - 0x8e, 0xd2, 0x87, 0x39, 0x0a, 0xcc, 0xd0, 0x4d, 0x4e, 0xd1, 0x2f, 0x33, 0xd6, 0xc7, 0xe6, 0xad, - 0x24, 0x36, 0xb0, 0x87, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xec, 0xe7, 0x83, 0x72, 0xf5, + 0x8e, 0xd2, 0x87, 0x39, 0x0a, 0xcc, 0xd0, 0x4d, 0x4e, 0xd1, 0x2f, 0x33, 0xd2, 0xc7, 0xe6, 0xad, + 0x24, 0x36, 0xb0, 0x87, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x04, 0xe3, 0x4e, 0xf5, 0x00, 0x00, 0x00, } diff --git a/server/settings/oidc/claims.proto b/server/settings/oidc/claims.proto index 6d7b98de27..3943fbce8a 100644 --- a/server/settings/oidc/claims.proto +++ b/server/settings/oidc/claims.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/server/settings/oidc"; +option go_package = "github.com/argoproj/argo-cd/v2/server/settings/oidc"; package github.com.argoproj.argo_cd.server.settings.oidc; diff --git a/server/settings/settings.go b/server/settings/settings.go index c2776949d7..919ca89cc3 100644 --- a/server/settings/settings.go +++ b/server/settings/settings.go @@ -7,14 +7,14 @@ import ( "github.com/golang/protobuf/ptypes/empty" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + ioutil "github.com/argoproj/argo-cd/v2/util/io" - sessionmgr "github.com/argoproj/argo-cd/v3/util/session" + sessionmgr "github.com/argoproj/argo-cd/v2/util/session" - settingspkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/settings" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/settings" + settingspkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/settings" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/settings" ) // Server provides a Settings service @@ -37,7 +37,7 @@ func NewServer(mgr *settings.SettingsManager, repoClient apiclient.Clientset, au } // Get returns Argo CD settings -func (s *Server) Get(ctx context.Context, _ *settingspkg.SettingsQuery) (*settingspkg.Settings, error) { +func (s *Server) Get(ctx context.Context, q *settingspkg.SettingsQuery) (*settingspkg.Settings, error) { resourceOverrides, err := s.mgr.GetResourceOverrides() if err != nil { return nil, err @@ -152,7 +152,7 @@ func (s *Server) Get(ctx context.Context, _ *settingspkg.SettingsQuery) (*settin } // GetPlugins returns a list of plugins -func (s *Server) GetPlugins(ctx context.Context, _ *settingspkg.SettingsQuery) (*settingspkg.SettingsPluginsResponse, error) { +func (s *Server) GetPlugins(ctx context.Context, q *settingspkg.SettingsQuery) (*settingspkg.SettingsPluginsResponse, error) { plugins, err := s.plugins(ctx) if err != nil { return nil, err @@ -165,7 +165,7 @@ func (s *Server) plugins(ctx context.Context) ([]*settingspkg.Plugin, error) { if err != nil { return nil, fmt.Errorf("error creating repo server client: %w", err) } - defer utilio.Close(closer) + defer ioutil.Close(closer) pluginList, err := client.ListPlugins(ctx, &empty.Empty{}) if err != nil { diff --git a/server/settings/settings.proto b/server/settings/settings.proto index 3d81eeaee4..c4e8f746d1 100644 --- a/server/settings/settings.proto +++ b/server/settings/settings.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/settings"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/settings"; // Settings Service // @@ -8,8 +8,8 @@ package cluster; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; -import "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1/generated.proto"; -import "github.com/argoproj/argo-cd/v3/server/settings/oidc/claims.proto"; +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; +import "github.com/argoproj/argo-cd/v2/server/settings/oidc/claims.proto"; // SettingsQuery is a query for Argo CD settings message SettingsQuery { @@ -20,16 +20,16 @@ message Settings { DexConfig dexConfig = 2; OIDCConfig oidcConfig = 3 [(gogoproto.customname) = "OIDCConfig"]; string appLabelKey = 4; - map resourceOverrides = 5; + map resourceOverrides = 5; bool statusBadgeEnabled = 6; GoogleAnalyticsConfig googleAnalytics = 7; - github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.KustomizeOptions kustomizeOptions = 8; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.KustomizeOptions kustomizeOptions = 8; // Help settings Help help = 9; repeated Plugin plugins = 10; bool userLoginsDisabled = 11; // Deprecated: use sidecar plugins instead. - repeated github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.ConfigManagementPlugin configManagementPlugins = 12; + repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ConfigManagementPlugin configManagementPlugins = 12; repeated string kustomizeVersions = 13; string uiCssURL = 14; string uiBannerContent = 15; diff --git a/server/version/version.go b/server/version/version.go index 0ec94f03c9..cc4eeb2415 100644 --- a/server/version/version.go +++ b/server/version/version.go @@ -6,12 +6,12 @@ import ( "github.com/golang/protobuf/ptypes/empty" "github.com/google/go-jsonnet" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/version" - "github.com/argoproj/argo-cd/v3/server/settings" - "github.com/argoproj/argo-cd/v3/util/helm" - "github.com/argoproj/argo-cd/v3/util/kustomize" - sessionmgr "github.com/argoproj/argo-cd/v3/util/session" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/version" + "github.com/argoproj/argo-cd/v2/server/settings" + "github.com/argoproj/argo-cd/v2/util/helm" + "github.com/argoproj/argo-cd/v2/util/kustomize" + sessionmgr "github.com/argoproj/argo-cd/v2/util/session" ) type Server struct { @@ -39,7 +39,7 @@ func (s *Server) Version(ctx context.Context, _ *empty.Empty) (*version.VersionM } if s.kustomizeVersion == "" { - kustomizeVersion, err := kustomize.Version() + kustomizeVersion, err := kustomize.Version(true) if err == nil { s.kustomizeVersion = kustomizeVersion } else { @@ -47,7 +47,7 @@ func (s *Server) Version(ctx context.Context, _ *empty.Empty) (*version.VersionM } } if s.helmVersion == "" { - helmVersion, err := helm.Version() + helmVersion, err := helm.Version(true) if err == nil { s.helmVersion = helmVersion } else { @@ -73,7 +73,7 @@ func (s *Server) Version(ctx context.Context, _ *empty.Empty) (*version.VersionM } // AuthFuncOverride allows the version to be returned without auth -func (s *Server) AuthFuncOverride(ctx context.Context, _ string) (context.Context, error) { +func (s *Server) AuthFuncOverride(ctx context.Context, fullMethodName string) (context.Context, error) { if s.authenticator != nil { // this authenticates the user, but ignores any error, so that we have claims populated ctx, _ = s.authenticator.Authenticate(ctx) diff --git a/server/version/version.proto b/server/version/version.proto index 7fb1d63029..f5b887aa29 100644 --- a/server/version/version.proto +++ b/server/version/version.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/pkg/apiclient/version"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/version"; // Version Service // diff --git a/test/container/Dockerfile b/test/container/Dockerfile index c6dcda1144..123fdb073c 100644 --- a/test/container/Dockerfile +++ b/test/container/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/redis:7.4.3@sha256:7df1eeff67eb0ba84f6b9d2940765a6bb1158081426745c185a03b1507de6a09 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,15 +6,15 @@ FROM docker.io/library/redis:7.4.3@sha256:7df1eeff67eb0ba84f6b9d2940765a6bb11580 RUN ln -s /usr/lib/$(uname -m)-linux-gnu /usr/lib/linux-gnu # Please make sure to also check the contained yarn version and update the references below when upgrading this image's version -FROM docker.io/library/node:22.9.0@sha256:69e667a79aa41ec0db50bc452a60e705ca16f35285eaf037ebe627a65a5cdf52 AS node +FROM docker.io/library/node:22.9.0@sha256:69e667a79aa41ec0db50bc452a60e705ca16f35285eaf037ebe627a65a5cdf52 as node -FROM docker.io/library/golang:1.24.2@sha256:30baaea08c5d1e858329c50f29fe381e9b7d7bced11a0f5f1f69a1504cdfbf5e AS golang +FROM docker.io/library/golang:1.24.4@sha256:db5d0afbfb4ab648af2393b92e87eaae9ad5e01132803d80caef91b5752d289c as golang -FROM docker.io/library/registry:3.0@sha256:1fc7de654f2ac1247f0b67e8a459e273b0993be7d2beda1f3f56fbf1001ed3e7 AS registry +FROM docker.io/library/registry:2.8@sha256:ac0192b549007e22998eb74e8d8488dcfe70f1489520c3b144a6047ac5efbe90 as registry -FROM docker.io/bitnami/kubectl:1.32@sha256:493d1b871556d48d6b25d471f192c2427571cd6f78523eebcaf4d263353c7487 AS kubectl +FROM docker.io/bitnami/kubectl:1.31@sha256:4d757d958f7f9c232a9aa4a1c8cc94fa2aa7a7a253869d7dce09b4dc58a3fbd6 as kubectl -FROM docker.io/library/ubuntu:24.04@sha256:1e622c5f073b4f6bfad6632f2616c7f59ef256e96fe78bf6a595d1dc4376ac02 +FROM docker.io/library/ubuntu:24.04@sha256:3f85b7caad41a95462cf5b787d8a04604c8262cdcdf9a472b8c52ef83375fe15 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install --fix-missing -y \ @@ -41,9 +41,9 @@ COPY --from=golang /usr/local/go /usr/local/go COPY --from=kubectl /opt/bitnami/kubectl/bin/kubectl /usr/local/bin/kubectl -ENV PATH=/dist:/go/bin:/usr/local/go/bin:/go/src/github.com/argoproj/argo-cd/dist:$PATH -ENV GOROOT=/usr/local/go -ENV GOPATH=/go +ENV PATH /dist:/go/bin:/usr/local/go/bin:/go/src/github.com/argoproj/argo-cd/dist:$PATH +ENV GOROOT /usr/local/go +ENV GOPATH /go # Install build and test dependencies COPY hack/install.sh hack/tool-versions.sh go.* ./ @@ -54,7 +54,6 @@ RUN ./install.sh helm && \ ./install.sh codegen-tools && \ ./install.sh codegen-go-tools && \ ./install.sh lint-tools && \ - ./install.sh gotestsum && \ go install github.com/mattn/goreman@latest && \ go install github.com/kisielk/godepgraph@latest && \ go install github.com/jstemmer/go-junit-report@latest && \ @@ -81,7 +80,7 @@ RUN mv /usr/lib/linux-gnu/libssl.so.3 /usr/lib/$(uname -m)-linux-gnu/ && \ # Copy registry binaries to the image COPY --from=registry /bin/registry /usr/local/bin/ -COPY --from=registry /etc/distribution/config.yml /etc/docker/registry/config.yml +COPY --from=registry /etc/docker/registry/config.yml /etc/docker/registry/config.yml # Copy node binaries COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules @@ -95,15 +94,12 @@ ARG UID # Prepare user configuration & build environments RUN userdel -r ubuntu && \ - useradd -l -u ${UID} -d /home/user -s /bin/bash user && \ + useradd -l -u ${UID} -d /home/user -s /bin/bash user && \ echo "user ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/user && \ mkdir -p /home/user/.kube && \ mkdir -p /home/user/.cache && \ chown -R user /home/user && \ chgrp -R user /home/user && \ - mkdir -p /go/src/github.com/gogo && \ - mkdir -p /go/src/k8s.io && \ - chown -R user /go && \ HOME=/home/user git config --global user.name "ArgoCD Test User" && \ HOME=/home/user git config --global user.email "noreply@example.com" && \ HOME=/home/user git config --global --add safe.directory '*' && \ diff --git a/test/container/Procfile b/test/container/Procfile index 9aeee211b1..5048fff289 100644 --- a/test/container/Procfile +++ b/test/container/Procfile @@ -9,7 +9,7 @@ reaper: ./test/container/reaper.sh sshd: sudo sh -c "test $ARGOCD_E2E_TEST = true && /usr/sbin/sshd -p 2222 -D -e" fcgiwrap: sudo sh -c "test $ARGOCD_E2E_TEST = true && (fcgiwrap -s unix:/var/run/fcgiwrap.socket & sleep 1 && chmod 777 /var/run/fcgiwrap.socket && wait)" nginx: sudo sh -c "test $ARGOCD_E2E_TEST = true && nginx -g 'daemon off;' -c $(pwd)/test/fixture/testrepos/nginx.conf" -helm-registry: sudo sh -c "OTEL_TRACES_EXPORTER=none REGISTRY_LOG_LEVEL=info registry serve /etc/docker/registry/config.yml" +helm-registry: sudo sh -c "registry serve /etc/docker/registry/config.yml" dev-mounter: test "$ARGOCD_E2E_TEST" != "true" && go run hack/dev-mounter/main.go --configmap argocd-ssh-known-hosts-cm=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} --configmap argocd-tls-certs-cm=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} --configmap argocd-gpg-keys-cm=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} applicationset-controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-applicationset-controller $COMMAND --loglevel debug --metrics-addr localhost:12345 --probe-addr localhost:12346 --argocd-repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}" notification: sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_BINARY_NAME=argocd-notifications go run ./cmd/main.go --loglevel debug" diff --git a/test/e2e/accounts_test.go b/test/e2e/accounts_test.go index b5047b718d..dd56837dac 100644 --- a/test/e2e/accounts_test.go +++ b/test/e2e/accounts_test.go @@ -1,21 +1,22 @@ package e2e import ( + "context" "testing" + "github.com/argoproj/pkg/errors" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/account" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - accountFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/account" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/account" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + accountFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/account" + "github.com/argoproj/argo-cd/v2/util/io" ) func TestCreateAndUseAccount(t *testing.T) { @@ -25,20 +26,49 @@ func TestCreateAndUseAccount(t *testing.T) { When(). Create(). Then(). - And(func(account *account.Account, _ error) { + And(func(account *account.Account, err error) { assert.Equal(t, account.Name, ctx.GetName()) assert.Equal(t, []string{"login"}, account.Capabilities) }). When(). Login(). Then(). - CurrentUser(func(user *session.GetUserInfoResponse, _ error) { + CurrentUser(func(user *session.GetUserInfoResponse, err error) { assert.True(t, user.LoggedIn) assert.Equal(t, user.Username, ctx.GetName()) }) } -func TestCanIGetLogsAllow(t *testing.T) { +func TestCanIGetLogsAllowNoSwitch(t *testing.T) { + ctx := accountFixture.Given(t) + ctx. + Name("test"). + When(). + Create(). + Login(). + CanIGetLogs(). + Then(). + AndCLIOutput(func(output string, err error) { + assert.Contains(t, output, "yes") + }) +} + +func TestCanIGetLogsDenySwitchOn(t *testing.T) { + ctx := accountFixture.Given(t) + ctx. + Name("test"). + When(). + Create(). + Login(). + SetParamInSettingConfigMap("server.rbac.log.enforce.enable", "true"). + CanIGetLogs(). + Then(). + AndCLIOutput(func(output string, err error) { + assert.Contains(t, output, "no") + }) +} + +func TestCanIGetLogsAllowSwitchOn(t *testing.T) { ctx := accountFixture.Given(t) ctx. Name("test"). @@ -58,24 +88,26 @@ func TestCanIGetLogsAllow(t *testing.T) { Scope: ProjectName + "/*", }, }, "log-viewer"). + SetParamInSettingConfigMap("server.rbac.log.enforce.enable", "true"). CanIGetLogs(). Then(). - AndCLIOutput(func(output string, _ error) { + AndCLIOutput(func(output string, err error) { assert.Contains(t, output, "yes") }) } -func TestCanIGetLogsDeny(t *testing.T) { +func TestCanIGetLogsAllowSwitchOff(t *testing.T) { ctx := accountFixture.Given(t) ctx. Name("test"). When(). Create(). Login(). + SetParamInSettingConfigMap("server.rbac.log.enforce.enable", "false"). CanIGetLogs(). Then(). - AndCLIOutput(func(output string, _ error) { - assert.Contains(t, output, "no") + AndCLIOutput(func(output string, err error) { + assert.Contains(t, output, "yes") }) } @@ -107,9 +139,9 @@ test true login, apiKey`, output) testAccountClientset := headless.NewClientOrDie(&clientOpts, &cobra.Command{}) closer, client := testAccountClientset.NewSessionClientOrDie() - defer utilio.Close(closer) + defer io.Close(closer) - info, err := client.GetUserInfo(t.Context(), &session.GetUserInfoRequest{}) + info, err := client.GetUserInfo(context.Background(), &session.GetUserInfoRequest{}) require.NoError(t, err) assert.Equal(t, "test", info.Username) @@ -119,7 +151,7 @@ func TestLoginBadCredentials(t *testing.T) { EnsureCleanState(t) closer, sessionClient := ArgoCDClientset.NewSessionClientOrDie() - defer utilio.Close(closer) + defer io.Close(closer) requests := []session.SessionCreateRequest{{ Username: "user-does-not-exist", Password: "some-password", @@ -128,7 +160,7 @@ func TestLoginBadCredentials(t *testing.T) { }} for _, r := range requests { - _, err := sessionClient.Create(t.Context(), &r) + _, err := sessionClient.Create(context.Background(), &r) require.Error(t, err) errStatus, ok := status.FromError(err) if !assert.True(t, ok) { diff --git a/test/e2e/admin_test.go b/test/e2e/admin_test.go index 6514598ae5..a896888b1b 100644 --- a/test/e2e/admin_test.go +++ b/test/e2e/admin_test.go @@ -1,18 +1,19 @@ package e2e import ( + "context" "testing" "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/admin" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/admin/utils" - appfixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + . "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/admin" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/admin/utils" + appfixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" ) func TestBackupExportImport(t *testing.T) { @@ -68,11 +69,11 @@ func TestBackupExportImport(t *testing.T) { When(). RunImport(exportRawOutput). Then(). - AndCLIOutput(func(_ string, err error) { + AndCLIOutput(func(output string, err error) { require.NoError(t, err, "import finished with error") - _, err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.TestNamespace()).Get(t.Context(), "exported-app1", metav1.GetOptions{}) + _, err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.TestNamespace()).Get(context.Background(), "exported-app1", v1.GetOptions{}) require.NoError(t, err, "failed getting test namespace application after import") - _, err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.AppNamespace()).Get(t.Context(), "exported-app-other-namespace", metav1.GetOptions{}) + _, err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.AppNamespace()).Get(context.Background(), "exported-app-other-namespace", v1.GetOptions{}) require.NoError(t, err, "failed getting app namespace application after import") }) } diff --git a/test/e2e/api_versions_test.go b/test/e2e/api_versions_test.go index c798fac42e..9ef2ba0156 100644 --- a/test/e2e/api_versions_test.go +++ b/test/e2e/api_versions_test.go @@ -3,8 +3,8 @@ package e2e import ( "testing" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" ) func TestAppSyncWrongVersion(t *testing.T) { diff --git a/test/e2e/app_autosync_ns_test.go b/test/e2e/app_autosync_ns_test.go index e030156455..3dbf465df4 100644 --- a/test/e2e/app_autosync_ns_test.go +++ b/test/e2e/app_autosync_ns_test.go @@ -1,17 +1,19 @@ package e2e import ( + "context" "testing" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + . "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/stretchr/testify/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/util/errors" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/util/errors" ) func TestNSAutoSyncSelfHealDisabled(t *testing.T) { @@ -37,8 +39,8 @@ func TestNSAutoSyncSelfHealDisabled(t *testing.T) { // app should not be auto-synced if k8s change detected When(). And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(), - "guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 0}}`), metav1.PatchOptions{})) + errors.FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(context.Background(), + "guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 0}}`), v1.PatchOptions{})) }). Then(). Expect(SyncStatusIs(SyncStatusCodeOutOfSync)) @@ -63,8 +65,8 @@ func TestNSAutoSyncSelfHealEnabled(t *testing.T) { When(). // app should be auto-synced once k8s change detected And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(), - "guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 0}}`), metav1.PatchOptions{})) + errors.FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(context.Background(), + "guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 0}}`), v1.PatchOptions{})) }). Refresh(RefreshTypeNormal). Then(). diff --git a/test/e2e/app_autosync_test.go b/test/e2e/app_autosync_test.go index d0fc29a655..67081fe98a 100644 --- a/test/e2e/app_autosync_test.go +++ b/test/e2e/app_autosync_test.go @@ -1,17 +1,18 @@ package e2e import ( + "context" "testing" . "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/stretchr/testify/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/util/errors" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/util/errors" ) func TestAutoSyncSelfHealDisabled(t *testing.T) { @@ -33,8 +34,8 @@ func TestAutoSyncSelfHealDisabled(t *testing.T) { // app should not be auto-synced if k8s change detected When(). And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(), - "guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 0}}`), metav1.PatchOptions{})) + errors.FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(context.Background(), + "guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 0}}`), v1.PatchOptions{})) }). Refresh(RefreshTypeNormal). Then(). @@ -58,8 +59,8 @@ func TestAutoSyncSelfHealEnabled(t *testing.T) { When(). // app should be auto-synced once k8s change detected And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(), - "guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 0}}`), metav1.PatchOptions{})) + errors.FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(context.Background(), + "guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 0}}`), v1.PatchOptions{})) }). Refresh(RefreshTypeNormal). Then(). diff --git a/test/e2e/app_deletion_test.go b/test/e2e/app_deletion_test.go index e34741745e..c0332eb017 100644 --- a/test/e2e/app_deletion_test.go +++ b/test/e2e/app_deletion_test.go @@ -5,11 +5,11 @@ import ( . "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/util/errors" ) // when a app gets stuck in sync, and we try to delete it, it won't delete, instead we must then terminate it @@ -17,7 +17,7 @@ import ( func TestDeletingAppStuckInSync(t *testing.T) { Given(t). And(func() { - require.NoError(t, SetResourceOverrides(map[string]ResourceOverride{ + errors.CheckError(SetResourceOverrides(map[string]ResourceOverride{ "ConfigMap": { HealthLua: `return { status = obj.annotations and obj.annotations['health'] or 'Progressing' }`, }, @@ -51,14 +51,14 @@ func TestDeletingAppByLabel(t *testing.T) { CreateApp("--label=foo=bar"). Sync(). Then(). - Expect(SyncStatusIs(SyncStatusCodeSynced)). + Expect(SyncStatusIs(SyncStatusCode(SyncStatusCodeSynced))). When(). IgnoreErrors(). DeleteBySelector("foo=baz"). Then(). // delete is unsuccessful since no selector match AndCLIOutput( - func(_ string, err error) { + func(output string, err error) { assert.ErrorContains(t, err, "no apps match selector foo=baz") }, ). diff --git a/test/e2e/app_k8s_events_test.go b/test/e2e/app_k8s_events_test.go index cfa599d740..7438adfe70 100644 --- a/test/e2e/app_k8s_events_test.go +++ b/test/e2e/app_k8s_events_test.go @@ -1,6 +1,7 @@ package e2e import ( + "context" "fmt" "testing" @@ -8,9 +9,9 @@ import ( "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + . "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" ) // resource.includeEventLabelKeys keys set in argocd-cm @@ -28,7 +29,7 @@ func TestLabelsOnAppK8sEvents(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - events, err := KubeClientset.CoreV1().Events(app.Namespace).List(t.Context(), metav1.ListOptions{ + events, err := KubeClientset.CoreV1().Events(app.Namespace).List(context.Background(), metav1.ListOptions{ FieldSelector: fmt.Sprintf("involvedObject.name=%s,involvedObject.kind=Application", app.Name), }) require.NoError(t, err) @@ -53,7 +54,7 @@ func TestNoLabelsOnAppK8sEvents(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - events, err := KubeClientset.CoreV1().Events(app.Namespace).List(t.Context(), metav1.ListOptions{ + events, err := KubeClientset.CoreV1().Events(app.Namespace).List(context.Background(), metav1.ListOptions{ FieldSelector: fmt.Sprintf("involvedObject.name=%s,involvedObject.kind=Application", app.Name), }) require.NoError(t, err) diff --git a/test/e2e/app_management_ns_test.go b/test/e2e/app_management_ns_test.go index 508dcd354a..328d252f66 100644 --- a/test/e2e/app_management_ns_test.go +++ b/test/e2e/app_management_ns_test.go @@ -13,10 +13,11 @@ import ( "github.com/argoproj/gitops-engine/pkg/health" . "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/argoproj/gitops-engine/pkg/utils/kube" + "github.com/argoproj/pkg/errors" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -24,29 +25,30 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/common" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - accountFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/account" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - projectFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/project" - repoFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/repos" - "github.com/argoproj/argo-cd/v3/test/e2e/testdata" + "github.com/argoproj/argo-cd/v2/common" + applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + . "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" + accountFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/account" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + projectFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/project" + repoFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos" + "github.com/argoproj/argo-cd/v2/test/e2e/testdata" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - . "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + . "github.com/argoproj/argo-cd/v2/util/argo" + . "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/settings" ) // This empty test is here only for clarity, to conform to logs rbac tests structure in account. This exact usecase is covered in the TestAppLogs test -func TestNamespacedGetLogsAllow(_ *testing.T) { +func TestNamespacedGetLogsAllowNoSwitch(t *testing.T) { } -func TestNamespacedGetLogsDeny(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") +func TestNamespacedGetLogsDenySwitchOn(t *testing.T) { + SkipOnEnv(t, "OPENSHIFT") accountFixture.Given(t). Name("test"). @@ -77,23 +79,24 @@ func TestNamespacedGetLogsDeny(t *testing.T) { }, "app-creator") ctx := GivenWithSameState(t) - ctx.SetAppNamespace(fixture.ArgoCDAppNamespace) + ctx.SetAppNamespace(ArgoCDAppNamespace) ctx. Path("guestbook-logs"). SetTrackingMethod("annotation"). When(). CreateApp(). Sync(). + SetParamInSettingConfigMap("server.rbac.log.enforce.enable", "true"). Then(). Expect(HealthIs(health.HealthStatusHealthy)). - And(func(_ *Application) { - _, err := fixture.RunCliWithRetry(5, "app", "logs", ctx.AppQualifiedName(), "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") + And(func(app *Application) { + _, err := RunCliWithRetry(5, "app", "logs", ctx.AppQualifiedName(), "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") assert.ErrorContains(t, err, "permission denied") }) } -func TestNamespacedGetLogsAllowNS(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") +func TestNamespacedGetLogsAllowSwitchOnNS(t *testing.T) { + SkipOnEnv(t, "OPENSHIFT") accountFixture.Given(t). Name("test"). @@ -129,35 +132,94 @@ func TestNamespacedGetLogsAllowNS(t *testing.T) { }, "app-creator") ctx := GivenWithSameState(t) - ctx.SetAppNamespace(fixture.AppNamespace()) + ctx.SetAppNamespace(AppNamespace()) ctx. Path("guestbook-logs"). SetTrackingMethod("annotation"). When(). CreateApp(). Sync(). + SetParamInSettingConfigMap("server.rbac.log.enforce.enable", "true"). Then(). Expect(HealthIs(health.HealthStatusHealthy)). - And(func(_ *Application) { - out, err := fixture.RunCliWithRetry(5, "app", "logs", ctx.AppQualifiedName(), "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") + And(func(app *Application) { + out, err := RunCliWithRetry(5, "app", "logs", ctx.AppQualifiedName(), "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") require.NoError(t, err) assert.Contains(t, out, "Hi") }). - And(func(_ *Application) { - out, err := fixture.RunCliWithRetry(5, "app", "logs", ctx.AppQualifiedName(), "--kind", "Pod") + And(func(app *Application) { + out, err := RunCliWithRetry(5, "app", "logs", ctx.AppQualifiedName(), "--kind", "Pod") require.NoError(t, err) assert.Contains(t, out, "Hi") }). - And(func(_ *Application) { - out, err := fixture.RunCliWithRetry(5, "app", "logs", ctx.AppQualifiedName(), "--kind", "Service") + And(func(app *Application) { + out, err := RunCliWithRetry(5, "app", "logs", ctx.AppQualifiedName(), "--kind", "Service") + require.NoError(t, err) + assert.NotContains(t, out, "Hi") + }) +} + +func TestNamespacedGetLogsAllowSwitchOff(t *testing.T) { + SkipOnEnv(t, "OPENSHIFT") + + accountFixture.Given(t). + Name("test"). + When(). + Create(). + Login(). + SetPermissions([]fixture.ACL{ + { + Resource: "applications", + Action: "create", + Scope: "*", + }, + { + Resource: "applications", + Action: "get", + Scope: "*", + }, + { + Resource: "applications", + Action: "sync", + Scope: "*", + }, + { + Resource: "projects", + Action: "get", + Scope: "*", + }, + }, "app-creator") + ctx := GivenWithSameState(t) + ctx.SetAppNamespace(AppNamespace()) + ctx. + Path("guestbook-logs"). + SetTrackingMethod("annotation"). + When(). + CreateApp(). + Sync(). + SetParamInSettingConfigMap("server.rbac.log.enforce.enable", "false"). + Then(). + Expect(HealthIs(health.HealthStatusHealthy)). + And(func(app *Application) { + out, err := RunCliWithRetry(5, "app", "logs", ctx.AppQualifiedName(), "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") + require.NoError(t, err) + assert.Contains(t, out, "Hi") + }). + And(func(app *Application) { + out, err := RunCliWithRetry(5, "app", "logs", ctx.AppQualifiedName(), "--kind", "Pod") + require.NoError(t, err) + assert.Contains(t, out, "Hi") + }). + And(func(app *Application) { + out, err := RunCliWithRetry(5, "app", "logs", ctx.AppQualifiedName(), "--kind", "Service") require.NoError(t, err) assert.NotContains(t, out, "Hi") }) } func TestNamespacedSyncToUnsignedCommit(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") - GivenWithNamespace(t, fixture.AppNamespace()). + SkipOnEnv(t, "GPG") + GivenWithNamespace(t, AppNamespace()). SetTrackingMethod("annotation"). Project("gpg"). Path(guestbookPath). @@ -172,9 +234,9 @@ func TestNamespacedSyncToUnsignedCommit(t *testing.T) { } func TestNamespacedSyncToSignedCommitWKK(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") + SkipOnEnv(t, "GPG") Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Project("gpg"). Path(guestbookPath). @@ -190,9 +252,9 @@ func TestNamespacedSyncToSignedCommitWKK(t *testing.T) { } func TestNamespacedSyncToSignedCommitKWKK(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") + SkipOnEnv(t, "GPG") Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Project("gpg"). Path(guestbookPath). @@ -214,23 +276,23 @@ func TestNamespacedAppCreation(t *testing.T) { ctx. Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Then(). Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). And(func(app *Application) { - assert.Equal(t, fixture.Name(), app.Name) - assert.Equal(t, fixture.AppNamespace(), app.Namespace) - assert.Equal(t, fixture.RepoURL(fixture.RepoURLTypeFile), app.Spec.GetSource().RepoURL) + assert.Equal(t, Name(), app.Name) + assert.Equal(t, AppNamespace(), app.Namespace) + assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.GetSource().RepoURL) assert.Equal(t, guestbookPath, app.Spec.GetSource().Path) - assert.Equal(t, fixture.DeploymentNamespace(), app.Spec.Destination.Namespace) + assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) }). - Expect(NamespacedEvent(fixture.AppNamespace(), EventReasonResourceCreated, "create")). - And(func(_ *Application) { + Expect(NamespacedEvent(AppNamespace(), EventReasonResourceCreated, "create")). + And(func(app *Application) { // app should be listed - output, err := fixture.RunCli("app", "list") + output, err := RunCli("app", "list") require.NoError(t, err) assert.Contains(t, output, ctx.AppQualifiedName()) }). @@ -243,7 +305,7 @@ func TestNamespacedAppCreation(t *testing.T) { When(). // ensure that update replaces spec and merge labels and annotations And(func() { - errors.NewHandler(t).FailOnErr(fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.AppNamespace()).Patch(t.Context(), + FailOnErr(AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).Patch(context.Background(), ctx.GetName(), types.MergePatchType, []byte(`{"metadata": {"labels": { "test": "label" }, "annotations": { "test": "annotation" }}}`), metav1.PatchOptions{})) }). CreateApp("--upsert"). @@ -261,7 +323,7 @@ func TestNamespacedAppCreationWithoutForceUpdate(t *testing.T) { ctx. Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). DestName("in-cluster"). When(). CreateApp(). @@ -269,16 +331,16 @@ func TestNamespacedAppCreationWithoutForceUpdate(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). And(func(app *Application) { assert.Equal(t, ctx.AppName(), app.Name) - assert.Equal(t, fixture.AppNamespace(), app.Namespace) - assert.Equal(t, fixture.RepoURL(fixture.RepoURLTypeFile), app.Spec.GetSource().RepoURL) + assert.Equal(t, AppNamespace(), app.Namespace) + assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.GetSource().RepoURL) assert.Equal(t, guestbookPath, app.Spec.GetSource().Path) - assert.Equal(t, fixture.DeploymentNamespace(), app.Spec.Destination.Namespace) + assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) assert.Equal(t, "in-cluster", app.Spec.Destination.Name) }). - Expect(NamespacedEvent(fixture.AppNamespace(), EventReasonResourceCreated, "create")). + Expect(NamespacedEvent(AppNamespace(), EventReasonResourceCreated, "create")). And(func(_ *Application) { // app should be listed - output, err := fixture.RunCli("app", "list") + output, err := RunCli("app", "list") require.NoError(t, err) assert.Contains(t, output, ctx.AppQualifiedName()) }). @@ -295,7 +357,7 @@ func TestNamespacedDeleteAppResource(t *testing.T) { ctx. Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Sync(). @@ -303,7 +365,7 @@ func TestNamespacedDeleteAppResource(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(_ *Application) { // app should be listed - if _, err := fixture.RunCli("app", "delete-resource", ctx.AppQualifiedName(), "--kind", "Service", "--resource-name", "guestbook-ui"); err != nil { + if _, err := RunCli("app", "delete-resource", ctx.AppQualifiedName(), "--kind", "Service", "--resource-name", "guestbook-ui"); err != nil { require.NoError(t, err) } }). @@ -313,11 +375,11 @@ func TestNamespacedDeleteAppResource(t *testing.T) { // demonstrate that we cannot use a standard sync when an immutable field is changed, we must use "force" func TestNamespacedImmutableChange(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") Given(t). Path("secrets"). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). PatchFile("secrets.yaml", `[{"op": "add", "path": "/data/new-field", "value": "dGVzdA=="}, {"op": "add", "path": "/immutable", "value": true}]`). @@ -338,7 +400,7 @@ func TestNamespacedImmutableChange(t *testing.T) { Expect(ResourceResultMatches(ResourceResult{ Kind: "Secret", Version: "v1", - Namespace: fixture.DeploymentNamespace(), + Namespace: DeploymentNamespace(), Name: "test-secret", SyncPhase: "Sync", Status: "SyncFailed", @@ -360,7 +422,7 @@ func TestNamespacedInvalidAppProject(t *testing.T) { Given(t). SetTrackingMethod("annotation"). Path(guestbookPath). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). Project("does-not-exist"). When(). IgnoreErrors(). @@ -376,7 +438,7 @@ func TestNamespacedAppDeletion(t *testing.T) { ctx. Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Then(). @@ -385,9 +447,9 @@ func TestNamespacedAppDeletion(t *testing.T) { Delete(true). Then(). Expect(DoesNotExist()). - Expect(NamespacedEvent(fixture.AppNamespace(), EventReasonResourceDeleted, "delete")) + Expect(NamespacedEvent(AppNamespace(), EventReasonResourceDeleted, "delete")) - output, err := fixture.RunCli("app", "list") + output, err := RunCli("app", "list") require.NoError(t, err) assert.NotContains(t, output, ctx.AppQualifiedName()) } @@ -397,14 +459,14 @@ func TestNamespacedAppLabels(t *testing.T) { ctx. Path("config-map"). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp("-l", "foo=bar"). Then(). - And(func(_ *Application) { - assert.Contains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list")), ctx.AppQualifiedName()) - assert.Contains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list", "-l", "foo=bar")), ctx.AppQualifiedName()) - assert.NotContains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list", "-l", "foo=rubbish")), ctx.AppQualifiedName()) + And(func(app *Application) { + assert.Contains(t, FailOnErr(RunCli("app", "list")), ctx.AppQualifiedName()) + assert.Contains(t, FailOnErr(RunCli("app", "list", "-l", "foo=bar")), ctx.AppQualifiedName()) + assert.NotContains(t, FailOnErr(RunCli("app", "list", "-l", "foo=rubbish")), ctx.AppQualifiedName()) }). Given(). // remove both name and replace labels means nothing will sync @@ -425,7 +487,7 @@ func TestNamespacedTrackAppStateAndSyncApp(t *testing.T) { Given(t). Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Sync(). @@ -433,9 +495,9 @@ func TestNamespacedTrackAppStateAndSyncApp(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - Expect(Success(fmt.Sprintf("Service %s guestbook-ui Synced ", fixture.DeploymentNamespace()))). - Expect(Success(fmt.Sprintf("apps Deployment %s guestbook-ui Synced", fixture.DeploymentNamespace()))). - Expect(NamespacedEvent(fixture.AppNamespace(), EventReasonResourceUpdated, "sync")). + Expect(Success(fmt.Sprintf("Service %s guestbook-ui Synced ", DeploymentNamespace()))). + Expect(Success(fmt.Sprintf("apps Deployment %s guestbook-ui Synced", DeploymentNamespace()))). + Expect(NamespacedEvent(AppNamespace(), EventReasonResourceUpdated, "sync")). And(func(app *Application) { assert.NotNil(t, app.Status.OperationState.SyncResult) }) @@ -446,7 +508,7 @@ func TestNamespacedAppRollbackSuccessful(t *testing.T) { ctx. Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Sync(). @@ -470,14 +532,14 @@ func TestNamespacedAppRollbackSuccessful(t *testing.T) { }} patch, _, err := diff.CreateTwoWayMergePatch(app, appWithHistory, &Application{}) require.NoError(t, err) - app, err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.AppNamespace()).Patch(t.Context(), app.Name, types.MergePatchType, patch, metav1.PatchOptions{}) + app, err = AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).Patch(context.Background(), app.Name, types.MergePatchType, patch, metav1.PatchOptions{}) require.NoError(t, err) // sync app and make sure it reaches InSync state - _, err = fixture.RunCli("app", "rollback", app.QualifiedName(), "1") + _, err = RunCli("app", "rollback", app.QualifiedName(), "1") require.NoError(t, err) }). - Expect(NamespacedEvent(fixture.AppNamespace(), EventReasonOperationStarted, "rollback")). + Expect(NamespacedEvent(AppNamespace(), EventReasonOperationStarted, "rollback")). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { assert.Equal(t, SyncStatusCodeSynced, app.Status.Sync.Status) @@ -492,7 +554,7 @@ func TestNamespacedComparisonFailsIfClusterNotAdded(t *testing.T) { Given(t). Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). DestServer("https://not-registered-cluster/api"). When(). IgnoreErrors(). @@ -505,7 +567,7 @@ func TestNamespacedCannotSetInvalidPath(t *testing.T) { Given(t). Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). IgnoreErrors(). @@ -519,14 +581,14 @@ func TestNamespacedManipulateApplicationResources(t *testing.T) { ctx. Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - manifests, err := fixture.RunCli("app", "manifests", ctx.AppQualifiedName(), "--source", "live") + manifests, err := RunCli("app", "manifests", ctx.AppQualifiedName(), "--source", "live") require.NoError(t, err) resources, err := kube.SplitYAML([]byte(manifests)) require.NoError(t, err) @@ -542,13 +604,13 @@ func TestNamespacedManipulateApplicationResources(t *testing.T) { deployment := resources[index] - closer, client, err := fixture.ArgoCDClientset.NewApplicationClient() + closer, client, err := ArgoCDClientset.NewApplicationClient() require.NoError(t, err) - defer utilio.Close(closer) + defer io.Close(closer) - _, err = client.DeleteResource(t.Context(), &applicationpkg.ApplicationResourceDeleteRequest{ + _, err = client.DeleteResource(context.Background(), &applicationpkg.ApplicationResourceDeleteRequest{ Name: &app.Name, - AppNamespace: ptr.To(fixture.AppNamespace()), + AppNamespace: ptr.To(AppNamespace()), Group: ptr.To(deployment.GroupVersionKind().Group), Kind: ptr.To(deployment.GroupVersionKind().Kind), Version: ptr.To(deployment.GroupVersionKind().Version), @@ -561,14 +623,14 @@ func TestNamespacedManipulateApplicationResources(t *testing.T) { } func TestNamespacedAppWithSecrets(t *testing.T) { - closer, client, err := fixture.ArgoCDClientset.NewApplicationClient() + closer, client, err := ArgoCDClientset.NewApplicationClient() require.NoError(t, err) - defer utilio.Close(closer) + defer io.Close(closer) ctx := Given(t) ctx. Path("secrets"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). When(). CreateApp(). @@ -576,9 +638,9 @@ func TestNamespacedAppWithSecrets(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - res := errors.NewHandler(t).FailOnErr(client.GetResource(t.Context(), &applicationpkg.ApplicationResourceRequest{ + res := FailOnErr(client.GetResource(context.Background(), &applicationpkg.ApplicationResourceRequest{ Namespace: &app.Spec.Destination.Namespace, - AppNamespace: ptr.To(fixture.AppNamespace()), + AppNamespace: ptr.To(AppNamespace()), Kind: ptr.To(kube.SecretKind), Group: ptr.To(""), Name: &app.Name, @@ -587,29 +649,29 @@ func TestNamespacedAppWithSecrets(t *testing.T) { })).(*applicationpkg.ApplicationResourceResponse) assetSecretDataHidden(t, res.GetManifest()) - manifests, err := client.GetManifests(t.Context(), &applicationpkg.ApplicationManifestQuery{ + manifests, err := client.GetManifests(context.Background(), &applicationpkg.ApplicationManifestQuery{ Name: &app.Name, - AppNamespace: ptr.To(fixture.AppNamespace()), + AppNamespace: ptr.To(AppNamespace()), }) - require.NoError(t, err) + errors.CheckError(err) for _, manifest := range manifests.Manifests { assetSecretDataHidden(t, manifest) } - diffOutput := errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "diff", ctx.AppQualifiedName())).(string) + diffOutput := FailOnErr(RunCli("app", "diff", ctx.AppQualifiedName())).(string) assert.Empty(t, diffOutput) // make sure resource update error does not print secret details - _, err = fixture.RunCli("app", "patch-resource", ctx.AppQualifiedName(), "--resource-name", "test-secret", + _, 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.ErrorContains(t, err, fmt.Sprintf("failed to patch Secret %s/test-secret", fixture.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") // patch secret and make sure app is out of sync and diff detects the change - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Secrets(fixture.DeploymentNamespace()).Patch(t.Context(), + FailOnErr(KubeClientset.CoreV1().Secrets(DeploymentNamespace()).Patch(context.Background(), "test-secret", types.JSONPatchType, []byte(`[ {"op": "remove", "path": "/data/username"}, {"op": "add", "path": "/stringData", "value": {"password": "foo"}} @@ -620,28 +682,28 @@ func TestNamespacedAppWithSecrets(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). And(func(app *Application) { - diffOutput, err := fixture.RunCli("app", "diff", ctx.AppQualifiedName()) + diffOutput, err := RunCli("app", "diff", ctx.AppQualifiedName()) require.Error(t, err) assert.Contains(t, diffOutput, "username: ++++++++") assert.Contains(t, diffOutput, "password: ++++++++++++") // local diff should ignore secrets - diffOutput = errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "diff", ctx.AppQualifiedName(), "--local", "testdata/secrets")).(string) + diffOutput = FailOnErr(RunCli("app", "diff", ctx.AppQualifiedName(), "--local", "testdata/secrets")).(string) assert.Empty(t, diffOutput) // ignore missing field and make sure diff shows no difference app.Spec.IgnoreDifferences = []ResourceIgnoreDifferences{{ Kind: kube.SecretKind, JSONPointers: []string{"/data"}, }} - errors.NewHandler(t).FailOnErr(client.UpdateSpec(t.Context(), &applicationpkg.ApplicationUpdateSpecRequest{Name: &app.Name, AppNamespace: ptr.To(fixture.AppNamespace()), Spec: &app.Spec})) + FailOnErr(client.UpdateSpec(context.Background(), &applicationpkg.ApplicationUpdateSpecRequest{Name: &app.Name, AppNamespace: ptr.To(AppNamespace()), Spec: &app.Spec})) }). When(). Refresh(RefreshTypeNormal). Then(). Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - diffOutput := errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "diff", ctx.AppQualifiedName())).(string) + And(func(app *Application) { + diffOutput := FailOnErr(RunCli("app", "diff", ctx.AppQualifiedName())).(string) assert.Empty(t, diffOutput) }). // verify not committed secret also ignore during diffing @@ -654,8 +716,8 @@ metadata: stringData: username: test-username`). Then(). - And(func(_ *Application) { - diffOutput := errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "diff", ctx.AppQualifiedName(), "--local", "testdata/secrets")).(string) + And(func(app *Application) { + diffOutput := FailOnErr(RunCli("app", "diff", ctx.AppQualifiedName(), "--local", "testdata/secrets")).(string) assert.Empty(t, diffOutput) }) } @@ -665,15 +727,15 @@ func TestNamespacedResourceDiffing(t *testing.T) { ctx. Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { + And(func(app *Application) { // Patch deployment - _, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(), + _, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Patch(context.Background(), "guestbook-ui", types.JSONPatchType, []byte(`[{ "op": "replace", "path": "/spec/template/spec/containers/0/image", "value": "test" }]`), metav1.PatchOptions{}) require.NoError(t, err) }). @@ -681,10 +743,10 @@ func TestNamespacedResourceDiffing(t *testing.T) { Refresh(RefreshTypeNormal). Then(). Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). - And(func(_ *Application) { - diffOutput, err := fixture.RunCli("app", "diff", ctx.AppQualifiedName(), "--local-repo-root", ".", "--local", "testdata/guestbook") + And(func(app *Application) { + diffOutput, err := RunCli("app", "diff", ctx.AppQualifiedName(), "--local-repo-root", ".", "--local", "testdata/guestbook") require.Error(t, err) - assert.Contains(t, diffOutput, fmt.Sprintf("===== apps/Deployment %s/guestbook-ui ======", fixture.DeploymentNamespace())) + assert.Contains(t, diffOutput, fmt.Sprintf("===== apps/Deployment %s/guestbook-ui ======", DeploymentNamespace())) }). Given(). ResourceOverrides(map[string]ResourceOverride{"apps/Deployment": { @@ -694,8 +756,8 @@ func TestNamespacedResourceDiffing(t *testing.T) { Refresh(RefreshTypeNormal). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - diffOutput, err := fixture.RunCli("app", "diff", ctx.AppQualifiedName(), "--local-repo-root", ".", "--local", "testdata/guestbook") + And(func(app *Application) { + diffOutput, err := RunCli("app", "diff", ctx.AppQualifiedName(), "--local-repo-root", ".", "--local", "testdata/guestbook") require.NoError(t, err) assert.Empty(t, diffOutput) }). @@ -713,7 +775,7 @@ func TestNamespacedResourceDiffing(t *testing.T) { }]`). Sync(). And(func() { - output, err := fixture.RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", fixture.DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-") + output, err := RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-") require.NoError(t, err) assert.Contains(t, output, "serverside-applied") }). @@ -740,12 +802,12 @@ func TestNamespacedResourceDiffing(t *testing.T) { "value": { "syncOptions": ["RespectIgnoreDifferences=true"] } }]`). And(func() { - deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + deployment, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, int32(3), *deployment.Spec.RevisionHistoryLimit) }). And(func() { - output, err := fixture.RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", fixture.DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-") + output, err := RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-") require.NoError(t, err) assert.Contains(t, output, "serverside-applied") }). @@ -753,14 +815,14 @@ func TestNamespacedResourceDiffing(t *testing.T) { When().Refresh(RefreshTypeNormal). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + And(func(app *Application) { + deployment, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, int32(1), *deployment.Spec.RevisionHistoryLimit) }). When().Sync().Then().Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + And(func(app *Application) { + deployment, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, int32(1), *deployment.Spec.RevisionHistoryLimit) }) @@ -777,20 +839,20 @@ func TestNamespacedKnownTypesInCRDDiffing(t *testing.T) { ctx. Path("crd-creation"). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When().CreateApp().Sync().Then(). Expect(OperationPhaseIs(OperationSucceeded)).Expect(SyncStatusIs(SyncStatusCodeSynced)). When(). And(func() { - dummyResIf := fixture.DynamicClientset.Resource(dummiesGVR).Namespace(fixture.DeploymentNamespace()) + dummyResIf := DynamicClientset.Resource(dummiesGVR).Namespace(DeploymentNamespace()) patchData := []byte(`{"spec":{"cpu": "2"}}`) - errors.NewHandler(t).FailOnErr(dummyResIf.Patch(t.Context(), "dummy-crd-instance", types.MergePatchType, patchData, metav1.PatchOptions{})) + FailOnErr(dummyResIf.Patch(context.Background(), "dummy-crd-instance", types.MergePatchType, patchData, metav1.PatchOptions{})) }).Refresh(RefreshTypeNormal). Then(). Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). When(). And(func() { - require.NoError(t, fixture.SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "argoproj.io/Dummy": { KnownTypeFields: []KnownTypeField{{ Field: "spec", @@ -819,7 +881,7 @@ func testNSEdgeCasesApplicationResources(t *testing.T, appPath string, statusCod expect := ctx. Path(appPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Sync(). @@ -831,8 +893,8 @@ func testNSEdgeCasesApplicationResources(t *testing.T, appPath string, statusCod } expect. Expect(HealthIs(statusCode)). - And(func(_ *Application) { - diffOutput, err := fixture.RunCli("app", "diff", ctx.AppQualifiedName(), "--local-repo-root", ".", "--local", path.Join("testdata", appPath)) + And(func(app *Application) { + diffOutput, err := RunCli("app", "diff", ctx.AppQualifiedName(), "--local-repo-root", ".", "--local", path.Join("testdata", appPath)) assert.Empty(t, diffOutput) require.NoError(t, err) }) @@ -852,42 +914,42 @@ func TestNamespacedResourceAction(t *testing.T) { ctx. Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). ResourceOverrides(map[string]ResourceOverride{"apps/Deployment": {Actions: actionsConfig}}). When(). CreateApp(). Sync(). Then(). And(func(app *Application) { - closer, client, err := fixture.ArgoCDClientset.NewApplicationClient() + closer, client, err := ArgoCDClientset.NewApplicationClient() require.NoError(t, err) - defer utilio.Close(closer) + defer io.Close(closer) - actions, err := client.ListResourceActions(t.Context(), &applicationpkg.ApplicationResourceRequest{ + actions, err := client.ListResourceActions(context.Background(), &applicationpkg.ApplicationResourceRequest{ Name: &app.Name, - AppNamespace: ptr.To(fixture.AppNamespace()), + AppNamespace: ptr.To(AppNamespace()), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Version: ptr.To("v1"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), ResourceName: ptr.To("guestbook-ui"), }) require.NoError(t, err) assert.Equal(t, []*ResourceAction{{Name: "sample", Disabled: false}}, actions.Actions) - _, err = client.RunResourceAction(t.Context(), &applicationpkg.ResourceActionRunRequest{ + _, err = client.RunResourceAction(context.Background(), &applicationpkg.ResourceActionRunRequest{ Name: &app.Name, Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Version: ptr.To("v1"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), ResourceName: ptr.To("guestbook-ui"), Action: ptr.To("sample"), - AppNamespace: ptr.To(fixture.AppNamespace()), + AppNamespace: ptr.To(AppNamespace()), }) require.NoError(t, err) - deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + deployment, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, "test", deployment.Labels["sample"]) @@ -899,18 +961,18 @@ func TestNamespacedSyncResourceByLabel(t *testing.T) { ctx. Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Sync(). Then(). And(func(app *Application) { - _, _ = fixture.RunCli("app", "sync", ctx.AppQualifiedName(), "--label", "app.kubernetes.io/instance="+app.Name) + _, _ = RunCli("app", "sync", ctx.AppQualifiedName(), "--label", fmt.Sprintf("app.kubernetes.io/instance=%s", app.Name)) }). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - _, err := fixture.RunCli("app", "sync", ctx.AppQualifiedName(), "--label", "this-label=does-not-exist") - assert.ErrorContains(t, err, "\"level\":\"fatal\"") + And(func(app *Application) { + _, err := RunCli("app", "sync", ctx.AppQualifiedName(), "--label", "this-label=does-not-exist") + assert.ErrorContains(t, err, "level=fatal") }) } @@ -919,13 +981,13 @@ func TestNamespacedLocalManifestSync(t *testing.T) { ctx. Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Sync(). Then(). - And(func(_ *Application) { - res, _ := fixture.RunCli("app", "manifests", ctx.AppQualifiedName()) + And(func(app *Application) { + res, _ := RunCli("app", "manifests", ctx.AppQualifiedName()) assert.Contains(t, res, "containerPort: 80") assert.Contains(t, res, "image: quay.io/argoprojlabs/argocd-e2e-container:0.2") }). @@ -935,8 +997,8 @@ func TestNamespacedLocalManifestSync(t *testing.T) { Sync("--local-repo-root", "."). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - res, _ := fixture.RunCli("app", "manifests", ctx.AppQualifiedName()) + And(func(app *Application) { + res, _ := RunCli("app", "manifests", ctx.AppQualifiedName()) assert.Contains(t, res, "containerPort: 81") assert.Contains(t, res, "image: quay.io/argoprojlabs/argocd-e2e-container:0.3") }). @@ -946,8 +1008,8 @@ func TestNamespacedLocalManifestSync(t *testing.T) { Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - res, _ := fixture.RunCli("app", "manifests", ctx.AppQualifiedName()) + And(func(app *Application) { + res, _ := RunCli("app", "manifests", ctx.AppQualifiedName()) assert.Contains(t, res, "containerPort: 80") assert.Contains(t, res, "image: quay.io/argoprojlabs/argocd-e2e-container:0.2") }) @@ -958,12 +1020,12 @@ func TestNamespacedLocalSync(t *testing.T) { // we've got to use Helm as this uses kubeVersion Path("helm"). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Then(). And(func(app *Application) { - errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "sync", app.QualifiedName(), "--local", "testdata/helm")) + FailOnErr(RunCli("app", "sync", app.QualifiedName(), "--local", "testdata/helm")) }) } @@ -971,16 +1033,16 @@ func TestNamespacedNoLocalSyncWithAutosyncEnabled(t *testing.T) { Given(t). Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Sync(). Then(). And(func(app *Application) { - _, err := fixture.RunCli("app", "set", app.QualifiedName(), "--sync-policy", "automated") + _, err := RunCli("app", "set", app.QualifiedName(), "--sync-policy", "automated") require.NoError(t, err) - _, err = fixture.RunCli("app", "sync", app.QualifiedName(), "--local", guestbookPathLocal) + _, err = RunCli("app", "sync", app.QualifiedName(), "--local", guestbookPathLocal) assert.ErrorContains(t, err, "Cannot use local sync") }) } @@ -989,17 +1051,17 @@ func TestNamespacedLocalSyncDryRunWithASEnabled(t *testing.T) { Given(t). Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Sync(). Then(). And(func(app *Application) { - _, err := fixture.RunCli("app", "set", app.QualifiedName(), "--sync-policy", "automated") + _, err := RunCli("app", "set", app.QualifiedName(), "--sync-policy", "automated") require.NoError(t, err) appBefore := app.DeepCopy() - _, err = fixture.RunCli("app", "sync", app.QualifiedName(), "--dry-run", "--local-repo-root", ".", "--local", guestbookPathLocal) + _, err = RunCli("app", "sync", app.QualifiedName(), "--dry-run", "--local-repo-root", ".", "--local", guestbookPathLocal) require.NoError(t, err) appAfter := app.DeepCopy() @@ -1011,7 +1073,7 @@ func TestNamespacedSyncAsync(t *testing.T) { Given(t). Path(guestbookPath). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). Async(true). When(). CreateApp(). @@ -1033,18 +1095,18 @@ func assertNSResourceActions(t *testing.T, appName string, successful bool) { } } - closer, cdClient := fixture.ArgoCDClientset.NewApplicationClientOrDie() - defer utilio.Close(closer) + closer, cdClient := ArgoCDClientset.NewApplicationClientOrDie() + defer io.Close(closer) - deploymentResource, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + deploymentResource, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) require.NoError(t, err) - logs, err := cdClient.PodLogs(t.Context(), &applicationpkg.ApplicationPodLogsQuery{ + logs, err := cdClient.PodLogs(context.Background(), &applicationpkg.ApplicationPodLogsQuery{ Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Name: &appName, - AppNamespace: ptr.To(fixture.AppNamespace()), - Namespace: ptr.To(fixture.DeploymentNamespace()), + AppNamespace: ptr.To(AppNamespace()), + Namespace: ptr.To(DeploymentNamespace()), Container: ptr.To(""), SinceSeconds: ptr.To(int64(0)), TailLines: ptr.To(int64(0)), @@ -1054,33 +1116,33 @@ func assertNSResourceActions(t *testing.T, appName string, successful bool) { _, err = logs.Recv() assertError(err, "EOF") - expectedError := "Deployment apps guestbook-ui not found as part of application " + appName + expectedError := fmt.Sprintf("Deployment apps guestbook-ui not found as part of application %s", appName) - _, err = cdClient.ListResourceEvents(t.Context(), &applicationpkg.ApplicationResourceEventsQuery{ + _, err = cdClient.ListResourceEvents(context.Background(), &applicationpkg.ApplicationResourceEventsQuery{ Name: &appName, - AppNamespace: ptr.To(fixture.AppNamespace()), + AppNamespace: ptr.To(AppNamespace()), ResourceName: ptr.To("guestbook-ui"), - ResourceNamespace: ptr.To(fixture.DeploymentNamespace()), + ResourceNamespace: ptr.To(DeploymentNamespace()), ResourceUID: ptr.To(string(deploymentResource.UID)), }) assertError(err, fmt.Sprintf("%s not found as part of application %s", "guestbook-ui", appName)) - _, err = cdClient.GetResource(t.Context(), &applicationpkg.ApplicationResourceRequest{ + _, err = cdClient.GetResource(context.Background(), &applicationpkg.ApplicationResourceRequest{ Name: &appName, - AppNamespace: ptr.To(fixture.AppNamespace()), + AppNamespace: ptr.To(AppNamespace()), ResourceName: ptr.To("guestbook-ui"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), Version: ptr.To("v1"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), }) assertError(err, expectedError) - _, err = cdClient.RunResourceAction(t.Context(), &applicationpkg.ResourceActionRunRequest{ + _, err = cdClient.RunResourceAction(context.Background(), &applicationpkg.ResourceActionRunRequest{ Name: &appName, - AppNamespace: ptr.To(fixture.AppNamespace()), + AppNamespace: ptr.To(AppNamespace()), ResourceName: ptr.To("guestbook-ui"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), Version: ptr.To("v1"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), @@ -1088,11 +1150,11 @@ func assertNSResourceActions(t *testing.T, appName string, successful bool) { }) assertError(err, expectedError) - _, err = cdClient.DeleteResource(t.Context(), &applicationpkg.ApplicationResourceDeleteRequest{ + _, err = cdClient.DeleteResource(context.Background(), &applicationpkg.ApplicationResourceDeleteRequest{ Name: &appName, - AppNamespace: ptr.To(fixture.AppNamespace()), + AppNamespace: ptr.To(AppNamespace()), ResourceName: ptr.To("guestbook-ui"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), Version: ptr.To("v1"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), @@ -1106,17 +1168,17 @@ func TestNamespacedPermissions(t *testing.T) { projActions := projectFixture. Given(t). Name(projName). - SourceNamespaces([]string{fixture.AppNamespace()}). + SourceNamespaces([]string{AppNamespace()}). When(). Create() - sourceError := fmt.Sprintf("application repo %s is not permitted in project 'argo-project'", fixture.RepoURL(fixture.RepoURLTypeFile)) - destinationError := fmt.Sprintf("application destination server '%s' and namespace '%s' do not match any of the allowed destinations in project 'argo-project'", KubernetesInternalAPIServerAddr, fixture.DeploymentNamespace()) + sourceError := fmt.Sprintf("application repo %s is not permitted in project 'argo-project'", RepoURL(RepoURLTypeFile)) + destinationError := fmt.Sprintf("application destination server '%s' and namespace '%s' do not match any of the allowed destinations in project 'argo-project'", KubernetesInternalAPIServerAddr, DeploymentNamespace()) appCtx. Path("guestbook-logs"). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). Project(projName). When(). IgnoreErrors(). @@ -1153,9 +1215,9 @@ func TestNamespacedPermissions(t *testing.T) { Expect(Condition(ApplicationConditionInvalidSpecError, destinationError)). Expect(Condition(ApplicationConditionInvalidSpecError, sourceError)). And(func(app *Application) { - closer, cdClient := fixture.ArgoCDClientset.NewApplicationClientOrDie() - defer utilio.Close(closer) - tree, err := cdClient.ResourceTree(t.Context(), &applicationpkg.ResourcesQuery{ApplicationName: &app.Name, AppNamespace: &app.Namespace}) + closer, cdClient := ArgoCDClientset.NewApplicationClientOrDie() + defer io.Close(closer) + tree, err := cdClient.ResourceTree(context.Background(), &applicationpkg.ResourcesQuery{ApplicationName: &app.Name, AppNamespace: &app.Namespace}) require.NoError(t, err) assert.Empty(t, tree.Nodes) assert.Empty(t, tree.OrphanedNodes) @@ -1184,23 +1246,23 @@ func TestNamespacedPermissionWithScopedRepo(t *testing.T) { projectFixture. Given(t). Name(projName). - SourceNamespaces([]string{fixture.AppNamespace()}). + SourceNamespaces([]string{AppNamespace()}). Destination("*,*"). When(). Create() repoFixture.GivenWithSameState(t). When(). - Path(fixture.RepoURL(fixture.RepoURLTypeFile)). + Path(RepoURL(RepoURLTypeFile)). Project(projName). Create() GivenWithSameState(t). Project(projName). - RepoURLType(fixture.RepoURLTypeFile). + RepoURLType(RepoURLTypeFile). Path("two-nice-pods"). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). PatchFile("pod-1.yaml", `[{"op": "add", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/sync-options": "Prune=false"}}]`). CreateApp(). @@ -1225,20 +1287,20 @@ func TestNamespacedPermissionDeniedWithScopedRepo(t *testing.T) { Given(t). Name(projName). Destination("*,*"). - SourceNamespaces([]string{fixture.AppNamespace()}). + SourceNamespaces([]string{AppNamespace()}). When(). Create() repoFixture.GivenWithSameState(t). When(). - Path(fixture.RepoURL(fixture.RepoURLTypeFile)). + Path(RepoURL(RepoURLTypeFile)). Create() GivenWithSameState(t). Project(projName). - RepoURLType(fixture.RepoURLTypeFile). + RepoURLType(RepoURLTypeFile). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). Path("two-nice-pods"). When(). PatchFile("pod-1.yaml", `[{"op": "add", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/sync-options": "Prune=false"}}]`). @@ -1253,7 +1315,7 @@ func TestNamespacedSyncOptionPruneFalse(t *testing.T) { Given(t). Path("two-nice-pods"). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). PatchFile("pod-1.yaml", `[{"op": "add", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/sync-options": "Prune=false"}}]`). CreateApp(). @@ -1277,7 +1339,7 @@ func TestNamespacedSyncOptionValidateFalse(t *testing.T) { Given(t). Path("crd-validation"). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Then(). @@ -1301,7 +1363,7 @@ func TestNamespacedCompareOptionIgnoreExtraneous(t *testing.T) { Given(t). Prune(false). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). Path("two-nice-pods"). When(). PatchFile("pod-1.yaml", `[{"op": "add", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/compare-options": "IgnoreExtraneous"}}]`). @@ -1335,21 +1397,21 @@ func TestNamespacedSelfManagedApps(t *testing.T) { Given(t). Path("self-managed-app"). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). - PatchFile("resources.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/spec/source/repoURL", "value": "%s"}]`, fixture.RepoURL(fixture.RepoURLTypeFile))). + PatchFile("resources.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/spec/source/repoURL", "value": "%s"}]`, RepoURL(RepoURLTypeFile))). CreateApp(). Sync(). Then(). Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(a *Application) { - ctx, cancel := context.WithTimeout(t.Context(), time.Second*3) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() reconciledCount := 0 var lastReconciledAt *metav1.Time - for event := range fixture.ArgoCDClientset.WatchApplicationWithRetry(ctx, a.QualifiedName(), a.ResourceVersion) { + for event := range ArgoCDClientset.WatchApplicationWithRetry(ctx, a.QualifiedName(), a.ResourceVersion) { reconciledAt := event.Application.Status.ReconciledAt if reconciledAt == nil { reconciledAt = &metav1.Time{} @@ -1368,7 +1430,7 @@ func TestNamespacedExcludedResource(t *testing.T) { Given(t). ResourceOverrides(map[string]ResourceOverride{"apps/Deployment": {Actions: actionsConfig}}). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). Path(guestbookPath). ResourceFilter(settings.ResourcesFilter{ ResourceExclusions: []settings.FilteredResource{{Kinds: []string{kube.DeploymentKind}}}, @@ -1385,7 +1447,7 @@ func TestNamespacedRevisionHistoryLimit(t *testing.T) { Given(t). Path("config-map"). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). When(). CreateApp(). Sync(). @@ -1407,16 +1469,16 @@ func TestNamespacedRevisionHistoryLimit(t *testing.T) { } func TestNamespacedOrphanedResource(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") Given(t). ProjectSpec(AppProjectSpec{ SourceRepos: []string{"*"}, Destinations: []ApplicationDestination{{Namespace: "*", Server: "*"}}, OrphanedResources: &OrphanedResourcesMonitorSettings{Warn: ptr.To(true)}, - SourceNamespaces: []string{fixture.AppNamespace()}, + SourceNamespaces: []string{AppNamespace()}, }). SetTrackingMethod("annotation"). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). Path(guestbookPath). When(). CreateApp(). @@ -1426,7 +1488,7 @@ func TestNamespacedOrphanedResource(t *testing.T) { Expect(NoConditions()). When(). And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{ + FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "orphaned-configmap", }, @@ -1436,7 +1498,7 @@ func TestNamespacedOrphanedResource(t *testing.T) { Then(). Expect(Condition(ApplicationConditionOrphanedResourceWarning, "Application has 1 orphaned resources")). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.QualifiedName()) + output, err := RunCli("app", "resources", app.QualifiedName()) require.NoError(t, err) assert.Contains(t, output, "orphaned-configmap") }). @@ -1445,14 +1507,14 @@ func TestNamespacedOrphanedResource(t *testing.T) { SourceRepos: []string{"*"}, Destinations: []ApplicationDestination{{Namespace: "*", Server: "*"}}, OrphanedResources: &OrphanedResourcesMonitorSettings{Warn: ptr.To(true), Ignore: []OrphanedResourceKey{{Group: "Test", Kind: "ConfigMap"}}}, - SourceNamespaces: []string{fixture.AppNamespace()}, + SourceNamespaces: []string{AppNamespace()}, }). When(). Refresh(RefreshTypeNormal). Then(). Expect(Condition(ApplicationConditionOrphanedResourceWarning, "Application has 1 orphaned resources")). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.QualifiedName()) + output, err := RunCli("app", "resources", app.QualifiedName()) require.NoError(t, err) assert.Contains(t, output, "orphaned-configmap") }). @@ -1461,7 +1523,7 @@ func TestNamespacedOrphanedResource(t *testing.T) { SourceRepos: []string{"*"}, Destinations: []ApplicationDestination{{Namespace: "*", Server: "*"}}, OrphanedResources: &OrphanedResourcesMonitorSettings{Warn: ptr.To(true), Ignore: []OrphanedResourceKey{{Kind: "ConfigMap"}}}, - SourceNamespaces: []string{fixture.AppNamespace()}, + SourceNamespaces: []string{AppNamespace()}, }). When(). Refresh(RefreshTypeNormal). @@ -1469,7 +1531,7 @@ func TestNamespacedOrphanedResource(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(NoConditions()). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.QualifiedName()) + output, err := RunCli("app", "resources", app.QualifiedName()) require.NoError(t, err) assert.NotContains(t, output, "orphaned-configmap") }). @@ -1478,7 +1540,7 @@ func TestNamespacedOrphanedResource(t *testing.T) { SourceRepos: []string{"*"}, Destinations: []ApplicationDestination{{Namespace: "*", Server: "*"}}, OrphanedResources: &OrphanedResourcesMonitorSettings{Warn: ptr.To(true), Ignore: []OrphanedResourceKey{{Kind: "ConfigMap", Name: "orphaned-configmap"}}}, - SourceNamespaces: []string{fixture.AppNamespace()}, + SourceNamespaces: []string{AppNamespace()}, }). When(). Refresh(RefreshTypeNormal). @@ -1486,7 +1548,7 @@ func TestNamespacedOrphanedResource(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(NoConditions()). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.QualifiedName()) + output, err := RunCli("app", "resources", app.QualifiedName()) require.NoError(t, err) assert.NotContains(t, output, "orphaned-configmap") }). @@ -1495,7 +1557,7 @@ func TestNamespacedOrphanedResource(t *testing.T) { SourceRepos: []string{"*"}, Destinations: []ApplicationDestination{{Namespace: "*", Server: "*"}}, OrphanedResources: nil, - SourceNamespaces: []string{fixture.AppNamespace()}, + SourceNamespaces: []string{AppNamespace()}, }). When(). Refresh(RefreshTypeNormal). @@ -1506,13 +1568,13 @@ func TestNamespacedOrphanedResource(t *testing.T) { func TestNamespacedNotPermittedResources(t *testing.T) { ctx := Given(t) - ctx.SetAppNamespace(fixture.AppNamespace()) + ctx.SetAppNamespace(AppNamespace()) pathType := networkingv1.PathTypePrefix ingress := &networkingv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "sample-ingress", Annotations: map[string]string{ - common.AnnotationKeyAppInstance: fmt.Sprintf("%s_%s:networking/Ingress:%s/sample-ingress", fixture.AppNamespace(), ctx.AppName(), fixture.DeploymentNamespace()), + common.AnnotationKeyAppInstance: fmt.Sprintf("%s_%s:networking/Ingress:%s/sample-ingress", AppNamespace(), ctx.AppName(), DeploymentNamespace()), }, }, Spec: networkingv1.IngressSpec{ @@ -1535,19 +1597,19 @@ func TestNamespacedNotPermittedResources(t *testing.T) { }, } defer func() { - log.Infof("Ingress 'sample-ingress' deleted from %s", fixture.TestNamespace()) - require.NoError(t, fixture.KubeClientset.NetworkingV1().Ingresses(fixture.TestNamespace()).Delete(t.Context(), "sample-ingress", metav1.DeleteOptions{})) + log.Infof("Ingress 'sample-ingress' deleted from %s", TestNamespace()) + CheckError(KubeClientset.NetworkingV1().Ingresses(TestNamespace()).Delete(context.Background(), "sample-ingress", metav1.DeleteOptions{})) }() - svc := &corev1.Service{ + svc := &v1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: "guestbook-ui", Annotations: map[string]string{ - common.AnnotationKeyAppInstance: fmt.Sprintf("%s_%s:Service:%s/guesbook-ui", fixture.TestNamespace(), ctx.AppQualifiedName(), fixture.DeploymentNamespace()), + common.AnnotationKeyAppInstance: fmt.Sprintf("%s_%s:Service:%s/guesbook-ui", TestNamespace(), ctx.AppQualifiedName(), DeploymentNamespace()), }, }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{{ + Spec: v1.ServiceSpec{ + Ports: []v1.ServicePort{{ Port: 80, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: 80}, }}, @@ -1559,15 +1621,15 @@ func TestNamespacedNotPermittedResources(t *testing.T) { ctx.ProjectSpec(AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []ApplicationDestination{{Namespace: fixture.DeploymentNamespace(), Server: "*"}}, - SourceNamespaces: []string{fixture.AppNamespace()}, + Destinations: []ApplicationDestination{{Namespace: DeploymentNamespace(), Server: "*"}}, + SourceNamespaces: []string{AppNamespace()}, NamespaceResourceBlacklist: []metav1.GroupKind{ {Group: "", Kind: "Service"}, }, }). And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.NetworkingV1().Ingresses(fixture.TestNamespace()).Create(t.Context(), ingress, metav1.CreateOptions{})) - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Services(fixture.DeploymentNamespace()).Create(t.Context(), svc, metav1.CreateOptions{})) + FailOnErr(KubeClientset.NetworkingV1().Ingresses(TestNamespace()).Create(context.Background(), ingress, metav1.CreateOptions{})) + FailOnErr(KubeClientset.CoreV1().Services(DeploymentNamespace()).Create(context.Background(), svc, metav1.CreateOptions{})) }). Path(guestbookPath). When(). @@ -1592,8 +1654,8 @@ func TestNamespacedNotPermittedResources(t *testing.T) { Expect(DoesNotExist()) // Make sure prohibited resources are not deleted during application deletion - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.NetworkingV1().Ingresses(fixture.TestNamespace()).Get(t.Context(), "sample-ingress", metav1.GetOptions{})) - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Services(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})) + FailOnErr(KubeClientset.NetworkingV1().Ingresses(TestNamespace()).Get(context.Background(), "sample-ingress", metav1.GetOptions{})) + FailOnErr(KubeClientset.CoreV1().Services(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{})) } func TestNamespacedSyncWithInfos(t *testing.T) { @@ -1602,14 +1664,14 @@ func TestNamespacedSyncWithInfos(t *testing.T) { expectedInfo[1] = &Info{Name: "name2", Value: "val2"} Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Path(guestbookPath). When(). CreateApp(). Then(). And(func(app *Application) { - _, err := fixture.RunCli("app", "sync", app.QualifiedName(), + _, err := RunCli("app", "sync", app.QualifiedName(), "--info", fmt.Sprintf("%s=%s", expectedInfo[0].Name, expectedInfo[0].Value), "--info", fmt.Sprintf("%s=%s", expectedInfo[1].Name, expectedInfo[1].Value)) require.NoError(t, err) @@ -1627,14 +1689,14 @@ func TestNamespacedSyncWithInfos(t *testing.T) { // Expect: no app.Status.Conditions func TestNamespacedCreateAppWithNoNameSpaceForGlobalResource(t *testing.T) { Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Path(globalWithNoNameSpace). When(). CreateWithNoNameSpace(). Then(). And(func(app *Application) { - app, err := fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.AppNamespace()).Get(t.Context(), app.Name, metav1.GetOptions{}) + app, err := AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).Get(context.Background(), app.Name, metav1.GetOptions{}) require.NoError(t, err) assert.Empty(t, app.Status.Conditions) }) @@ -1648,7 +1710,7 @@ func TestNamespacedCreateAppWithNoNameSpaceForGlobalResource(t *testing.T) { // Expect: app.Status.Conditions for deployment ans service which does not have namespace in manifest func TestNamespacedCreateAppWithNoNameSpaceWhenRequired(t *testing.T) { Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Path(guestbookPath). When(). @@ -1656,7 +1718,7 @@ func TestNamespacedCreateAppWithNoNameSpaceWhenRequired(t *testing.T) { Refresh(RefreshTypeNormal). Then(). And(func(app *Application) { - updatedApp, err := fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.AppNamespace()).Get(t.Context(), app.Name, metav1.GetOptions{}) + updatedApp, err := AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).Get(context.Background(), app.Name, metav1.GetOptions{}) require.NoError(t, err) assert.Len(t, updatedApp.Status.Conditions, 2) @@ -1674,7 +1736,7 @@ func TestNamespacedCreateAppWithNoNameSpaceWhenRequired(t *testing.T) { // Expect: app.Status.Conditions for deployment and service which does not have namespace in manifest func TestNamespacedCreateAppWithNoNameSpaceWhenRequired2(t *testing.T) { Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Path(guestbookWithNamespace). When(). @@ -1682,7 +1744,7 @@ func TestNamespacedCreateAppWithNoNameSpaceWhenRequired2(t *testing.T) { Refresh(RefreshTypeNormal). Then(). And(func(app *Application) { - updatedApp, err := fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.AppNamespace()).Get(t.Context(), app.Name, metav1.GetOptions{}) + updatedApp, err := AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).Get(context.Background(), app.Name, metav1.GetOptions{}) require.NoError(t, err) assert.Len(t, updatedApp.Status.Conditions, 2) @@ -1692,15 +1754,15 @@ func TestNamespacedCreateAppWithNoNameSpaceWhenRequired2(t *testing.T) { } func TestNamespacedListResource(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). ProjectSpec(AppProjectSpec{ SourceRepos: []string{"*"}, Destinations: []ApplicationDestination{{Namespace: "*", Server: "*"}}, OrphanedResources: &OrphanedResourcesMonitorSettings{Warn: ptr.To(true)}, - SourceNamespaces: []string{fixture.AppNamespace()}, + SourceNamespaces: []string{AppNamespace()}, }). Path(guestbookPath). When(). @@ -1711,7 +1773,7 @@ func TestNamespacedListResource(t *testing.T) { Expect(NoConditions()). When(). And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{ + FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "orphaned-configmap", }, @@ -1721,19 +1783,19 @@ func TestNamespacedListResource(t *testing.T) { Then(). Expect(Condition(ApplicationConditionOrphanedResourceWarning, "Application has 1 orphaned resources")). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.QualifiedName()) + output, err := RunCli("app", "resources", app.QualifiedName()) require.NoError(t, err) assert.Contains(t, output, "orphaned-configmap") assert.Contains(t, output, "guestbook-ui") }). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.QualifiedName(), "--orphaned=true") + output, err := RunCli("app", "resources", app.QualifiedName(), "--orphaned=true") require.NoError(t, err) assert.Contains(t, output, "orphaned-configmap") assert.NotContains(t, output, "guestbook-ui") }). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.QualifiedName(), "--orphaned=false") + output, err := RunCli("app", "resources", app.QualifiedName(), "--orphaned=false") require.NoError(t, err) assert.NotContains(t, output, "orphaned-configmap") assert.Contains(t, output, "guestbook-ui") @@ -1743,7 +1805,7 @@ func TestNamespacedListResource(t *testing.T) { SourceRepos: []string{"*"}, Destinations: []ApplicationDestination{{Namespace: "*", Server: "*"}}, OrphanedResources: nil, - SourceNamespaces: []string{fixture.AppNamespace()}, + SourceNamespaces: []string{AppNamespace()}, }). When(). Refresh(RefreshTypeNormal). @@ -1761,16 +1823,16 @@ func TestNamespacedListResource(t *testing.T) { // application sync successful // when application is deleted, --dest-namespace is not deleted func TestNamespacedNamespaceAutoCreation(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") updatedNamespace := getNewNamespace(t) defer func() { if !t.Skipped() { - _, err := fixture.Run("", "kubectl", "delete", "namespace", updatedNamespace) + _, err := Run("", "kubectl", "delete", "namespace", updatedNamespace) require.NoError(t, err) } }() Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Timeout(30). Path("guestbook"). @@ -1791,9 +1853,9 @@ func TestNamespacedNamespaceAutoCreation(t *testing.T) { Delete(true). Then(). Expect(Success("")). - And(func(_ *Application) { + And(func(app *Application) { // Verify delete app does not delete the namespace auto created - output, err := fixture.Run("", "kubectl", "get", "namespace", updatedNamespace) + output, err := Run("", "kubectl", "get", "namespace", updatedNamespace) require.NoError(t, err) assert.Contains(t, output, updatedNamespace) }) @@ -1805,17 +1867,17 @@ func TestNamespacedNamespaceAutoCreation(t *testing.T) { // // Verify application --dest-namespace is created with managedNamespaceMetadata func TestNamespacedNamespaceAutoCreationWithMetadata(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") updatedNamespace := getNewNamespace(t) defer func() { if !t.Skipped() { - _, err := fixture.Run("", "kubectl", "delete", "namespace", updatedNamespace) + _, err := Run("", "kubectl", "delete", "namespace", updatedNamespace) require.NoError(t, err) } }() ctx := Given(t) ctx. - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Timeout(30). Path("guestbook"). @@ -1836,7 +1898,7 @@ func TestNamespacedNamespaceAutoCreationWithMetadata(t *testing.T) { Sync(). Then(). Expect(Success("")). - Expect(Namespace(updatedNamespace, func(app *Application, ns *corev1.Namespace) { + Expect(Namespace(updatedNamespace, func(app *Application, ns *v1.Namespace) { assert.Empty(t, app.Status.Conditions) delete(ns.Labels, "kubernetes.io/metadata.name") @@ -1854,13 +1916,13 @@ func TestNamespacedNamespaceAutoCreationWithMetadata(t *testing.T) { Expect(ResourceSyncStatusWithNamespaceIs("Deployment", "guestbook-ui", updatedNamespace, SyncStatusCodeSynced)). When(). And(func() { - errors.NewHandler(t).FailOnErr(fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.AppNamespace()).Patch(t.Context(), + FailOnErr(AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).Patch(context.Background(), ctx.GetName(), types.JSONPatchType, []byte(`[{ "op": "replace", "path": "/spec/syncPolicy/managedNamespaceMetadata/labels", "value": {"new":"label"} }]`), metav1.PatchOptions{})) }). Sync(). Then(). Expect(Success("")). - Expect(Namespace(updatedNamespace, func(app *Application, ns *corev1.Namespace) { + Expect(Namespace(updatedNamespace, func(app *Application, ns *v1.Namespace) { delete(ns.Labels, "kubernetes.io/metadata.name") delete(ns.Labels, "argocd.argoproj.io/tracking-id") delete(ns.Annotations, "kubectl.kubernetes.io/last-applied-configuration") @@ -1873,13 +1935,13 @@ func TestNamespacedNamespaceAutoCreationWithMetadata(t *testing.T) { })). When(). And(func() { - errors.NewHandler(t).FailOnErr(fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.AppNamespace()).Patch(t.Context(), + FailOnErr(AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).Patch(context.Background(), ctx.GetName(), types.JSONPatchType, []byte(`[{ "op": "replace", "path": "/spec/syncPolicy/managedNamespaceMetadata/annotations", "value": {"new":"custom-annotation"} }]`), metav1.PatchOptions{})) }). Sync(). Then(). Expect(Success("")). - Expect(Namespace(updatedNamespace, func(app *Application, ns *corev1.Namespace) { + Expect(Namespace(updatedNamespace, func(app *Application, ns *v1.Namespace) { delete(ns.Labels, "kubernetes.io/metadata.name") delete(ns.Labels, "argocd.argoproj.io/tracking-id") delete(ns.Annotations, "argocd.argoproj.io/tracking-id") @@ -1898,18 +1960,18 @@ func TestNamespacedNamespaceAutoCreationWithMetadata(t *testing.T) { // // Verify application namespace manifest takes precedence over managedNamespaceMetadata func TestNamespacedNamespaceAutoCreationWithMetadataAndNsManifest(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") namespace := "guestbook-ui-with-namespace-manifest" defer func() { if !t.Skipped() { - _, err := fixture.Run("", "kubectl", "delete", "namespace", namespace) + _, err := Run("", "kubectl", "delete", "namespace", namespace) require.NoError(t, err) } }() ctx := Given(t) ctx. - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Timeout(30). Path("guestbook-with-namespace-manifest"). @@ -1930,7 +1992,7 @@ func TestNamespacedNamespaceAutoCreationWithMetadataAndNsManifest(t *testing.T) Sync(). Then(). Expect(Success("")). - Expect(Namespace(namespace, func(_ *Application, ns *corev1.Namespace) { + Expect(Namespace(namespace, func(app *Application, ns *v1.Namespace) { delete(ns.Labels, "kubernetes.io/metadata.name") delete(ns.Labels, "argocd.argoproj.io/tracking-id") delete(ns.Labels, "kubectl.kubernetes.io/last-applied-configuration") @@ -1952,11 +2014,11 @@ func TestNamespacedNamespaceAutoCreationWithMetadataAndNsManifest(t *testing.T) // // Verify application --dest-namespace is updated with managedNamespaceMetadata labels and annotations func TestNamespacedNamespaceAutoCreationWithPreexistingNs(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") updatedNamespace := getNewNamespace(t) defer func() { if !t.Skipped() { - _, err := fixture.Run("", "kubectl", "delete", "namespace", updatedNamespace) + _, err := Run("", "kubectl", "delete", "namespace", updatedNamespace) require.NoError(t, err) } }() @@ -1973,17 +2035,17 @@ metadata: ` s := fmt.Sprintf(existingNs, updatedNamespace) - tmpFile, err := os.CreateTemp(t.TempDir(), "") - require.NoError(t, err) + tmpFile, err := os.CreateTemp("", "") + errors.CheckError(err) _, err = tmpFile.Write([]byte(s)) - require.NoError(t, err) + errors.CheckError(err) - _, err = fixture.Run("", "kubectl", "apply", "-f", tmpFile.Name()) + _, err = Run("", "kubectl", "apply", "-f", tmpFile.Name()) require.NoError(t, err) ctx := Given(t) ctx. - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Timeout(30). Path("guestbook"). @@ -1998,7 +2060,7 @@ metadata: } }). Then(). - Expect(Namespace(updatedNamespace, func(app *Application, ns *corev1.Namespace) { + Expect(Namespace(updatedNamespace, func(app *Application, ns *v1.Namespace) { assert.Empty(t, app.Status.Conditions) delete(ns.Labels, "kubernetes.io/metadata.name") @@ -2012,7 +2074,7 @@ metadata: Sync(). Then(). Expect(Success("")). - Expect(Namespace(updatedNamespace, func(app *Application, ns *corev1.Namespace) { + Expect(Namespace(updatedNamespace, func(app *Application, ns *v1.Namespace) { assert.Empty(t, app.Status.Conditions) delete(ns.Labels, "kubernetes.io/metadata.name") @@ -2025,13 +2087,13 @@ metadata: })). When(). And(func() { - errors.NewHandler(t).FailOnErr(fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.AppNamespace()).Patch(t.Context(), + FailOnErr(AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).Patch(context.Background(), ctx.GetName(), types.JSONPatchType, []byte(`[{ "op": "add", "path": "/spec/syncPolicy/managedNamespaceMetadata/annotations/something", "value": "hmm" }]`), metav1.PatchOptions{})) }). Sync(). Then(). Expect(Success("")). - Expect(Namespace(updatedNamespace, func(app *Application, ns *corev1.Namespace) { + Expect(Namespace(updatedNamespace, func(app *Application, ns *v1.Namespace) { assert.Empty(t, app.Status.Conditions) delete(ns.Labels, "kubernetes.io/metadata.name") @@ -2045,13 +2107,13 @@ metadata: })). When(). And(func() { - errors.NewHandler(t).FailOnErr(fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.AppNamespace()).Patch(t.Context(), + FailOnErr(AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).Patch(context.Background(), ctx.GetName(), types.JSONPatchType, []byte(`[{ "op": "remove", "path": "/spec/syncPolicy/managedNamespaceMetadata/annotations/something" }]`), metav1.PatchOptions{})) }). Sync(). Then(). Expect(Success("")). - Expect(Namespace(updatedNamespace, func(app *Application, ns *corev1.Namespace) { + Expect(Namespace(updatedNamespace, func(app *Application, ns *v1.Namespace) { assert.Empty(t, app.Status.Conditions) delete(ns.Labels, "kubernetes.io/metadata.name") @@ -2070,7 +2132,7 @@ metadata: func TestNamespacedFailedSyncWithRetry(t *testing.T) { Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Path("hook"). When(). @@ -2087,15 +2149,15 @@ func TestNamespacedFailedSyncWithRetry(t *testing.T) { func TestNamespacedCreateDisableValidation(t *testing.T) { Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Path("baddir"). When(). CreateApp("--validate=false"). Then(). And(func(app *Application) { - _, err := fixture.RunCli("app", "create", app.QualifiedName(), "--upsert", "--validate=false", "--repo", fixture.RepoURL(fixture.RepoURLTypeFile), - "--path", "baddir2", "--project", app.Spec.Project, "--dest-server", KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace()) + _, err := RunCli("app", "create", app.QualifiedName(), "--upsert", "--validate=false", "--repo", RepoURL(RepoURLTypeFile), + "--path", "baddir2", "--project", app.Spec.Project, "--dest-server", KubernetesInternalAPIServerAddr, "--dest-namespace", DeploymentNamespace()) require.NoError(t, err) }). When(). @@ -2119,7 +2181,7 @@ spec: path := "helm-values" Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). When(). // app should be auto-synced once created @@ -2129,9 +2191,9 @@ spec: Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(NoConditions()). And(func(app *Application) { - assert.Equal(t, map[string]string{"labels.local/from-file": "file", "labels.local/from-args": "args"}, app.Labels) - assert.Equal(t, map[string]string{"annotations.local/from-file": "file"}, app.Annotations) - assert.Equal(t, []string{"resources-finalizer.argocd.argoproj.io"}, app.Finalizers) + assert.Equal(t, map[string]string{"labels.local/from-file": "file", "labels.local/from-args": "args"}, app.ObjectMeta.Labels) + assert.Equal(t, map[string]string{"annotations.local/from-file": "file"}, app.ObjectMeta.Annotations) + assert.Equal(t, []string{"resources-finalizer.argocd.argoproj.io"}, app.ObjectMeta.Finalizers) assert.Equal(t, path, app.Spec.GetSource().Path) assert.Equal(t, []HelmParameter{{Name: "foo", Value: "foo"}}, app.Spec.GetSource().Helm.Parameters) }) @@ -2166,11 +2228,11 @@ definitions: return obj ` Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Path("crd-subresource"). And(func() { - require.NoError(t, fixture.SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "argoproj.io/StatusSubResource": { Actions: actions, }, @@ -2186,49 +2248,49 @@ definitions: Then(). // tests resource actions on a CRD using status subresource And(func(app *Application) { - _, err := fixture.RunCli("app", "actions", "run", app.QualifiedName(), "--kind", "StatusSubResource", "update-both") + _, err := RunCli("app", "actions", "run", app.QualifiedName(), "--kind", "StatusSubResource", "update-both") require.NoError(t, err) - text := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.spec.foo}")).(string) + text := FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.spec.foo}")).(string) assert.Equal(t, "update-both", text) - text = errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.status.bar}")).(string) + text = FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.status.bar}")).(string) assert.Equal(t, "update-both", text) - _, err = fixture.RunCli("app", "actions", "run", app.QualifiedName(), "--kind", "StatusSubResource", "update-spec") + _, err = RunCli("app", "actions", "run", app.QualifiedName(), "--kind", "StatusSubResource", "update-spec") require.NoError(t, err) - text = errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.spec.foo}")).(string) + text = FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.spec.foo}")).(string) assert.Equal(t, "update-spec", text) - _, err = fixture.RunCli("app", "actions", "run", app.QualifiedName(), "--kind", "StatusSubResource", "update-status") + _, err = RunCli("app", "actions", "run", app.QualifiedName(), "--kind", "StatusSubResource", "update-status") require.NoError(t, err) - text = errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.status.bar}")).(string) + text = FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.status.bar}")).(string) assert.Equal(t, "update-status", text) }). // tests resource actions on a CRD *not* using status subresource And(func(app *Application) { - _, err := fixture.RunCli("app", "actions", "run", app.QualifiedName(), "--kind", "NonStatusSubResource", "update-both") + _, err := RunCli("app", "actions", "run", app.QualifiedName(), "--kind", "NonStatusSubResource", "update-both") require.NoError(t, err) - text := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.spec.foo}")).(string) + text := FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.spec.foo}")).(string) assert.Equal(t, "update-both", text) - text = errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.status.bar}")).(string) + text = FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.status.bar}")).(string) assert.Equal(t, "update-both", text) - _, err = fixture.RunCli("app", "actions", "run", app.QualifiedName(), "--kind", "NonStatusSubResource", "update-spec") + _, err = RunCli("app", "actions", "run", app.QualifiedName(), "--kind", "NonStatusSubResource", "update-spec") require.NoError(t, err) - text = errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.spec.foo}")).(string) + text = FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.spec.foo}")).(string) assert.Equal(t, "update-spec", text) - _, err = fixture.RunCli("app", "actions", "run", app.QualifiedName(), "--kind", "NonStatusSubResource", "update-status") + _, err = RunCli("app", "actions", "run", app.QualifiedName(), "--kind", "NonStatusSubResource", "update-status") require.NoError(t, err) - text = errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.status.bar}")).(string) + text = FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.status.bar}")).(string) assert.Equal(t, "update-status", text) }) } func TestNamespacedAppLogs(t *testing.T) { t.SkipNow() // Too flaky. https://github.com/argoproj/argo-cd/issues/13834 - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Path("guestbook-logs"). When(). @@ -2237,17 +2299,17 @@ func TestNamespacedAppLogs(t *testing.T) { Then(). Expect(HealthIs(health.HealthStatusHealthy)). And(func(app *Application) { - out, err := fixture.RunCliWithRetry(5, "app", "logs", app.QualifiedName(), "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") + out, err := RunCliWithRetry(5, "app", "logs", app.QualifiedName(), "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") require.NoError(t, err) assert.Contains(t, out, "Hi") }). And(func(app *Application) { - out, err := fixture.RunCliWithRetry(5, "app", "logs", app.QualifiedName(), "--kind", "Pod") + out, err := RunCliWithRetry(5, "app", "logs", app.QualifiedName(), "--kind", "Pod") require.NoError(t, err) assert.Contains(t, out, "Hi") }). And(func(app *Application) { - out, err := fixture.RunCliWithRetry(5, "app", "logs", app.QualifiedName(), "--kind", "Service") + out, err := RunCliWithRetry(5, "app", "logs", app.QualifiedName(), "--kind", "Service") require.NoError(t, err) assert.NotContains(t, out, "Hi") }) @@ -2255,10 +2317,10 @@ func TestNamespacedAppLogs(t *testing.T) { func TestNamespacedAppWaitOperationInProgress(t *testing.T) { Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). And(func() { - require.NoError(t, fixture.SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "batch/Job": { HealthLua: `return { status = 'Running' }`, }, @@ -2278,14 +2340,14 @@ func TestNamespacedAppWaitOperationInProgress(t *testing.T) { When(). Then(). And(func(app *Application) { - _, err := fixture.RunCli("app", "wait", app.QualifiedName(), "--suspended") - require.NoError(t, err) + _, err := RunCli("app", "wait", app.QualifiedName(), "--suspended") + errors.CheckError(err) }) } func TestNamespacedSyncOptionReplace(t *testing.T) { Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Path("config-map"). When(). @@ -2308,7 +2370,7 @@ func TestNamespacedSyncOptionReplace(t *testing.T) { func TestNamespacedSyncOptionReplaceFromCLI(t *testing.T) { Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Path("config-map"). Replace(). @@ -2332,7 +2394,7 @@ func TestNamespacedSyncOptionReplaceFromCLI(t *testing.T) { func TestNamespacedDiscoverNewCommit(t *testing.T) { var sha string Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Path("config-map"). When(). @@ -2364,7 +2426,7 @@ func TestNamespacedDiscoverNewCommit(t *testing.T) { func TestNamespacedDisableManifestGeneration(t *testing.T) { Given(t). - SetAppNamespace(fixture.AppNamespace()). + SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). Path("guestbook"). When(). @@ -2376,13 +2438,13 @@ func TestNamespacedDisableManifestGeneration(t *testing.T) { }). When(). And(func() { - require.NoError(t, fixture.SetEnableManifestGeneration(map[ApplicationSourceType]bool{ + CheckError(SetEnableManifestGeneration(map[ApplicationSourceType]bool{ ApplicationSourceTypeKustomize: false, })) }). Refresh(RefreshTypeHard). Then(). - And(func(_ *Application) { + And(func(app *Application) { // Wait for refresh to complete time.Sleep(1 * time.Second) }). diff --git a/test/e2e/app_management_test.go b/test/e2e/app_management_test.go index 766084f54d..9a6cfeee56 100644 --- a/test/e2e/app_management_test.go +++ b/test/e2e/app_management_test.go @@ -11,10 +11,11 @@ import ( "github.com/argoproj/gitops-engine/pkg/health" . "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/argoproj/gitops-engine/pkg/utils/kube" + "github.com/argoproj/pkg/errors" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -25,22 +26,23 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/common" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - accountFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/account" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - clusterFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/cluster" - projectFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/project" - repoFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/repos" - "github.com/argoproj/argo-cd/v3/test/e2e/testdata" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + . "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" + accountFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/account" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + projectFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/project" + repoFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos" + "github.com/argoproj/argo-cd/v2/test/e2e/testdata" + "github.com/argoproj/argo-cd/v2/util/argo" + . "github.com/argoproj/argo-cd/v2/util/argo" + . "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/settings" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) const ( @@ -53,11 +55,11 @@ const ( ) // This empty test is here only for clarity, to conform to logs rbac tests structure in account. This exact usecase is covered in the TestAppLogs test -func TestGetLogsAllowNoSwitch(_ *testing.T) { +func TestGetLogsAllowNoSwitch(t *testing.T) { } -func TestGetLogsDeny(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") +func TestGetLogsDenySwitchOn(t *testing.T) { + SkipOnEnv(t, "OPENSHIFT") accountFixture.Given(t). Name("test"). @@ -92,16 +94,17 @@ func TestGetLogsDeny(t *testing.T) { When(). CreateApp(). Sync(). + SetParamInSettingConfigMap("server.rbac.log.enforce.enable", "true"). Then(). Expect(HealthIs(health.HealthStatusHealthy)). And(func(app *Application) { - _, err := fixture.RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") + _, err := RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") assert.ErrorContains(t, err, "permission denied") }) } -func TestGetLogsAllow(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") +func TestGetLogsAllowSwitchOn(t *testing.T) { + SkipOnEnv(t, "OPENSHIFT") accountFixture.Given(t). Name("test"). @@ -141,27 +144,84 @@ func TestGetLogsAllow(t *testing.T) { When(). CreateApp(). Sync(). + SetParamInSettingConfigMap("server.rbac.log.enforce.enable", "true"). Then(). Expect(HealthIs(health.HealthStatusHealthy)). And(func(app *Application) { - out, err := fixture.RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") + out, err := RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") require.NoError(t, err) assert.Contains(t, out, "Hi") }). And(func(app *Application) { - out, err := fixture.RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Pod") + out, err := RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Pod") require.NoError(t, err) assert.Contains(t, out, "Hi") }). And(func(app *Application) { - out, err := fixture.RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Service") + out, err := RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Service") + require.NoError(t, err) + assert.NotContains(t, out, "Hi") + }) +} + +func TestGetLogsAllowSwitchOff(t *testing.T) { + SkipOnEnv(t, "OPENSHIFT") + + accountFixture.Given(t). + Name("test"). + When(). + Create(). + Login(). + SetPermissions([]fixture.ACL{ + { + Resource: "applications", + Action: "create", + Scope: "*", + }, + { + Resource: "applications", + Action: "get", + Scope: "*", + }, + { + Resource: "applications", + Action: "sync", + Scope: "*", + }, + { + Resource: "projects", + Action: "get", + Scope: "*", + }, + }, "app-creator") + + GivenWithSameState(t). + Path("guestbook-logs"). + When(). + CreateApp(). + Sync(). + SetParamInSettingConfigMap("server.rbac.log.enforce.enable", "false"). + Then(). + Expect(HealthIs(health.HealthStatusHealthy)). + And(func(app *Application) { + out, err := RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") + require.NoError(t, err) + assert.Contains(t, out, "Hi") + }). + And(func(app *Application) { + out, err := RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Pod") + require.NoError(t, err) + assert.Contains(t, out, "Hi") + }). + And(func(app *Application) { + out, err := RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Service") require.NoError(t, err) assert.NotContains(t, out, "Hi") }) } func TestSyncToUnsignedCommit(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") + SkipOnEnv(t, "GPG") Given(t). Project("gpg"). Path(guestbookPath). @@ -176,7 +236,7 @@ func TestSyncToUnsignedCommit(t *testing.T) { } func TestSyncToSignedCommitWithoutKnownKey(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") + SkipOnEnv(t, "GPG") Given(t). Project("gpg"). Path(guestbookPath). @@ -192,7 +252,7 @@ func TestSyncToSignedCommitWithoutKnownKey(t *testing.T) { } func TestSyncToSignedCommitWithKnownKey(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") + SkipOnEnv(t, "GPG") Given(t). Project("gpg"). Path(guestbookPath). @@ -210,7 +270,7 @@ func TestSyncToSignedCommitWithKnownKey(t *testing.T) { } func TestSyncToSignedBranchWithKnownKey(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") + SkipOnEnv(t, "GPG") Given(t). Project("gpg"). Path(guestbookPath). @@ -229,7 +289,7 @@ func TestSyncToSignedBranchWithKnownKey(t *testing.T) { } func TestSyncToSignedBranchWithUnknownKey(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") + SkipOnEnv(t, "GPG") Given(t). Project("gpg"). Path(guestbookPath). @@ -247,7 +307,7 @@ func TestSyncToSignedBranchWithUnknownKey(t *testing.T) { } func TestSyncToUnsignedBranch(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") + SkipOnEnv(t, "GPG") Given(t). Project("gpg"). Revision("master"). @@ -265,7 +325,7 @@ func TestSyncToUnsignedBranch(t *testing.T) { } func TestSyncToSignedTagWithKnownKey(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") + SkipOnEnv(t, "GPG") Given(t). Project("gpg"). Revision("signed-tag"). @@ -284,7 +344,7 @@ func TestSyncToSignedTagWithKnownKey(t *testing.T) { } func TestSyncToSignedTagWithUnknownKey(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") + SkipOnEnv(t, "GPG") Given(t). Project("gpg"). Revision("signed-tag"). @@ -302,7 +362,7 @@ func TestSyncToSignedTagWithUnknownKey(t *testing.T) { } func TestSyncToUnsignedTag(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") + SkipOnEnv(t, "GPG") Given(t). Project("gpg"). Revision("unsigned-tag"). @@ -329,18 +389,18 @@ func TestAppCreation(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). And(func(app *Application) { - assert.Equal(t, fixture.Name(), app.Name) - assert.Equal(t, fixture.RepoURL(fixture.RepoURLTypeFile), app.Spec.GetSource().RepoURL) + assert.Equal(t, Name(), app.Name) + assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.GetSource().RepoURL) assert.Equal(t, guestbookPath, app.Spec.GetSource().Path) - assert.Equal(t, fixture.DeploymentNamespace(), app.Spec.Destination.Namespace) + assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) }). - Expect(Event(argo.EventReasonResourceCreated, "create")). + Expect(Event(EventReasonResourceCreated, "create")). And(func(_ *Application) { // app should be listed - output, err := fixture.RunCli("app", "list") + output, err := RunCli("app", "list") require.NoError(t, err) - assert.Contains(t, output, fixture.Name()) + assert.Contains(t, output, Name()) }). When(). // ensure that create is idempotent @@ -351,7 +411,7 @@ func TestAppCreation(t *testing.T) { When(). // ensure that update replaces spec and merge labels and annotations And(func() { - errors.NewHandler(t).FailOnErr(fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.TestNamespace()).Patch(t.Context(), + FailOnErr(AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).Patch(context.Background(), ctx.GetName(), types.MergePatchType, []byte(`{"metadata": {"labels": { "test": "label" }, "annotations": { "test": "annotation" }}}`), metav1.PatchOptions{})) }). CreateApp("--upsert"). @@ -375,17 +435,17 @@ func TestAppCreationWithoutForceUpdate(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). And(func(app *Application) { assert.Equal(t, ctx.AppName(), app.Name) - assert.Equal(t, fixture.RepoURL(fixture.RepoURLTypeFile), app.Spec.GetSource().RepoURL) + assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.GetSource().RepoURL) assert.Equal(t, guestbookPath, app.Spec.GetSource().Path) - assert.Equal(t, fixture.DeploymentNamespace(), app.Spec.Destination.Namespace) + assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) assert.Equal(t, "in-cluster", app.Spec.Destination.Name) }). - Expect(Event(argo.EventReasonResourceCreated, "create")). + Expect(Event(EventReasonResourceCreated, "create")). And(func(_ *Application) { // app should be listed - output, err := fixture.RunCli("app", "list") + output, err := RunCli("app", "list") require.NoError(t, err) - assert.Contains(t, output, fixture.Name()) + assert.Contains(t, output, Name()) }). When(). IgnoreErrors(). @@ -445,7 +505,7 @@ func TestDeleteAppResource(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(_ *Application) { // app should be listed - if _, err := fixture.RunCli("app", "delete-resource", fixture.Name(), "--kind", "Service", "--resource-name", "guestbook-ui"); err != nil { + if _, err := RunCli("app", "delete-resource", Name(), "--kind", "Service", "--resource-name", "guestbook-ui"); err != nil { require.NoError(t, err) } }). @@ -472,7 +532,7 @@ func TestPatchHttp(t *testing.T) { // demonstrate that we cannot use a standard sync when an immutable field is changed, we must use "force" func TestImmutableChange(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") Given(t). Path("secrets"). When(). @@ -495,7 +555,7 @@ func TestImmutableChange(t *testing.T) { Expect(ResourceResultMatches(ResourceResult{ Kind: "Secret", Version: "v1", - Namespace: fixture.DeploymentNamespace(), + Namespace: DeploymentNamespace(), Name: "test-secret", SyncPhase: "Sync", Status: "SyncFailed", @@ -537,11 +597,11 @@ func TestAppDeletion(t *testing.T) { Delete(true). Then(). Expect(DoesNotExist()). - Expect(Event(argo.EventReasonResourceDeleted, "delete")) + Expect(Event(EventReasonResourceDeleted, "delete")) - output, err := fixture.RunCli("app", "list") + output, err := RunCli("app", "list") require.NoError(t, err) - assert.NotContains(t, output, fixture.Name()) + assert.NotContains(t, output, Name()) } func TestAppLabels(t *testing.T) { @@ -550,10 +610,10 @@ func TestAppLabels(t *testing.T) { When(). CreateApp("-l", "foo=bar"). Then(). - And(func(_ *Application) { - assert.Contains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list")), fixture.Name()) - assert.Contains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list", "-l", "foo=bar")), fixture.Name()) - assert.NotContains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list", "-l", "foo=rubbish")), fixture.Name()) + And(func(app *Application) { + assert.Contains(t, FailOnErr(RunCli("app", "list")), Name()) + assert.Contains(t, FailOnErr(RunCli("app", "list", "-l", "foo=bar")), Name()) + assert.NotContains(t, FailOnErr(RunCli("app", "list", "-l", "foo=rubbish")), Name()) }). Given(). // remove both name and replace labels means nothing will sync @@ -580,9 +640,9 @@ func TestTrackAppStateAndSyncApp(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - Expect(Success(fmt.Sprintf("Service %s guestbook-ui Synced ", fixture.DeploymentNamespace()))). - Expect(Success(fmt.Sprintf("apps Deployment %s guestbook-ui Synced", fixture.DeploymentNamespace()))). - Expect(Event(argo.EventReasonResourceUpdated, "sync")). + Expect(Success(fmt.Sprintf("Service %s guestbook-ui Synced ", DeploymentNamespace()))). + Expect(Success(fmt.Sprintf("apps Deployment %s guestbook-ui Synced", DeploymentNamespace()))). + Expect(Event(EventReasonResourceUpdated, "sync")). And(func(app *Application) { assert.NotNil(t, app.Status.OperationState.SyncResult) }) @@ -614,14 +674,14 @@ func TestAppRollbackSuccessful(t *testing.T) { }} patch, _, err := diff.CreateTwoWayMergePatch(app, appWithHistory, &Application{}) require.NoError(t, err) - app, err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.TestNamespace()).Patch(t.Context(), app.Name, types.MergePatchType, patch, metav1.PatchOptions{}) + app, err = AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).Patch(context.Background(), app.Name, types.MergePatchType, patch, metav1.PatchOptions{}) require.NoError(t, err) // sync app and make sure it reaches InSync state - _, err = fixture.RunCli("app", "rollback", app.Name, "1") + _, err = RunCli("app", "rollback", app.Name, "1") require.NoError(t, err) }). - Expect(Event(argo.EventReasonOperationStarted, "rollback")). + Expect(Event(EventReasonOperationStarted, "rollback")). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { assert.Equal(t, SyncStatusCodeSynced, app.Status.Sync.Status) @@ -643,58 +703,6 @@ func TestComparisonFailsIfClusterNotAdded(t *testing.T) { Expect(DoesNotExist()) } -func TestComparisonFailsIfDestinationClusterIsInvalid(t *testing.T) { - clusterActions := clusterFixture.Given(t). - Name("temp-cluster"). - Server(KubernetesInternalAPIServerAddr). - When(). - Create() - - GivenWithSameState(t). - Path(guestbookPath). - DestName("temp-cluster"). - When(). - CreateApp(). - Refresh(RefreshTypeNormal). - Sync(). - Then(). - Expect(Success("")). - Expect(HealthIs(health.HealthStatusHealthy)). - Expect(SyncStatusIs(SyncStatusCodeSynced)). - When(). - And(func() { - clusterActions.DeleteByName() - }). - Refresh(RefreshTypeNormal). - Then(). - Expect(Success("")). - Expect(HealthIs(health.HealthStatusUnknown)). - Expect(SyncStatusIs(SyncStatusCodeUnknown)). - Expect(Condition(ApplicationConditionInvalidSpecError, "there are no clusters with this name")) -} - -func TestComparisonFailsIfInClusterDisabled(t *testing.T) { - Given(t). - Path(guestbookPath). - DestServer(KubernetesInternalAPIServerAddr). - When(). - CreateApp(). - Refresh(RefreshTypeNormal). - Sync(). - Then(). - Expect(Success("")). - Expect(HealthIs(health.HealthStatusHealthy)). - Expect(SyncStatusIs(SyncStatusCodeSynced)). - When(). - SetParamInSettingConfigMap("cluster.inClusterEnabled", "false"). - Refresh(RefreshTypeNormal). - Then(). - Expect(Success("")). - Expect(HealthIs(health.HealthStatusUnknown)). - Expect(SyncStatusIs(SyncStatusCodeUnknown)). - Expect(Condition(ApplicationConditionInvalidSpecError, fmt.Sprintf("cluster %q is disabled", KubernetesInternalAPIServerAddr))) -} - func TestCannotSetInvalidPath(t *testing.T) { Given(t). Path(guestbookPath). @@ -715,7 +723,7 @@ func TestManipulateApplicationResources(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - manifests, err := fixture.RunCli("app", "manifests", app.Name, "--source", "live") + manifests, err := RunCli("app", "manifests", app.Name, "--source", "live") require.NoError(t, err) resources, err := kube.SplitYAML([]byte(manifests)) require.NoError(t, err) @@ -731,11 +739,11 @@ func TestManipulateApplicationResources(t *testing.T) { deployment := resources[index] - closer, client, err := fixture.ArgoCDClientset.NewApplicationClient() + closer, client, err := ArgoCDClientset.NewApplicationClient() require.NoError(t, err) - defer utilio.Close(closer) + defer io.Close(closer) - _, err = client.DeleteResource(t.Context(), &applicationpkg.ApplicationResourceDeleteRequest{ + _, err = client.DeleteResource(context.Background(), &applicationpkg.ApplicationResourceDeleteRequest{ Name: &app.Name, Group: ptr.To(deployment.GroupVersionKind().Group), Kind: ptr.To(deployment.GroupVersionKind().Kind), @@ -766,7 +774,7 @@ func assetSecretDataHidden(t *testing.T, manifest string) { var lastAppliedConfigAnnotation string annotations := secret.GetAnnotations() if annotations != nil { - lastAppliedConfigAnnotation = annotations[corev1.LastAppliedConfigAnnotation] + lastAppliedConfigAnnotation = annotations[v1.LastAppliedConfigAnnotation] } if lastAppliedConfigAnnotation != "" { assetSecretDataHidden(t, lastAppliedConfigAnnotation) @@ -774,9 +782,9 @@ func assetSecretDataHidden(t *testing.T, manifest string) { } func TestAppWithSecrets(t *testing.T) { - closer, client, err := fixture.ArgoCDClientset.NewApplicationClient() + closer, client, err := ArgoCDClientset.NewApplicationClient() require.NoError(t, err) - defer utilio.Close(closer) + defer io.Close(closer) Given(t). Path("secrets"). @@ -786,7 +794,7 @@ func TestAppWithSecrets(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - res := errors.NewHandler(t).FailOnErr(client.GetResource(t.Context(), &applicationpkg.ApplicationResourceRequest{ + res := FailOnErr(client.GetResource(context.Background(), &applicationpkg.ApplicationResourceRequest{ Namespace: &app.Spec.Destination.Namespace, Kind: ptr.To(kube.SecretKind), Group: ptr.To(""), @@ -796,26 +804,26 @@ func TestAppWithSecrets(t *testing.T) { })).(*applicationpkg.ApplicationResourceResponse) assetSecretDataHidden(t, res.GetManifest()) - manifests, err := client.GetManifests(t.Context(), &applicationpkg.ApplicationManifestQuery{Name: &app.Name}) - require.NoError(t, err) + manifests, err := client.GetManifests(context.Background(), &applicationpkg.ApplicationManifestQuery{Name: &app.Name}) + errors.CheckError(err) for _, manifest := range manifests.Manifests { assetSecretDataHidden(t, manifest) } - diffOutput := errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "diff", app.Name)).(string) + diffOutput := FailOnErr(RunCli("app", "diff", app.Name)).(string) assert.Empty(t, diffOutput) // make sure resource update error does not print secret details - _, err = fixture.RunCli("app", "patch-resource", "test-app-with-secrets", "--resource-name", "test-secret", + _, 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.ErrorContains(t, err, fmt.Sprintf("failed to patch Secret %s/test-secret", fixture.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") // patch secret and make sure app is out of sync and diff detects the change - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Secrets(fixture.DeploymentNamespace()).Patch(t.Context(), + FailOnErr(KubeClientset.CoreV1().Secrets(DeploymentNamespace()).Patch(context.Background(), "test-secret", types.JSONPatchType, []byte(`[ {"op": "remove", "path": "/data/username"}, {"op": "add", "path": "/stringData", "value": {"password": "foo"}} @@ -826,20 +834,20 @@ func TestAppWithSecrets(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). And(func(app *Application) { - diffOutput, err := fixture.RunCli("app", "diff", app.Name) + diffOutput, err := RunCli("app", "diff", app.Name) require.Error(t, err) assert.Contains(t, diffOutput, "username: ++++++++") assert.Contains(t, diffOutput, "password: ++++++++++++") // local diff should ignore secrets - diffOutput = errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "diff", app.Name, "--local", "testdata", "--server-side-generate")).(string) + diffOutput = FailOnErr(RunCli("app", "diff", app.Name, "--local", "testdata", "--server-side-generate")).(string) assert.Empty(t, diffOutput) // ignore missing field and make sure diff shows no difference app.Spec.IgnoreDifferences = []ResourceIgnoreDifferences{{ Kind: kube.SecretKind, JSONPointers: []string{"/data"}, }} - errors.NewHandler(t).FailOnErr(client.UpdateSpec(t.Context(), &applicationpkg.ApplicationUpdateSpecRequest{Name: &app.Name, Spec: &app.Spec})) + FailOnErr(client.UpdateSpec(context.Background(), &applicationpkg.ApplicationUpdateSpecRequest{Name: &app.Name, Spec: &app.Spec})) }). When(). Refresh(RefreshTypeNormal). @@ -847,7 +855,7 @@ func TestAppWithSecrets(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - diffOutput := errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "diff", app.Name)).(string) + diffOutput := FailOnErr(RunCli("app", "diff", app.Name)).(string) assert.Empty(t, diffOutput) }). // verify not committed secret also ignore during diffing @@ -861,7 +869,7 @@ stringData: username: test-username`). Then(). And(func(app *Application) { - diffOutput := errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "diff", app.Name, "--local", "testdata", "--server-side-generate")).(string) + diffOutput := FailOnErr(RunCli("app", "diff", app.Name, "--local", "testdata", "--server-side-generate")).(string) assert.Empty(t, diffOutput) }) } @@ -874,9 +882,9 @@ func TestResourceDiffing(t *testing.T) { Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { + And(func(app *Application) { // Patch deployment - _, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(), + _, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Patch(context.Background(), "guestbook-ui", types.JSONPatchType, []byte(`[{ "op": "replace", "path": "/spec/template/spec/containers/0/image", "value": "test" }]`), metav1.PatchOptions{}) require.NoError(t, err) }). @@ -885,9 +893,9 @@ func TestResourceDiffing(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). And(func(app *Application) { - diffOutput, err := fixture.RunCli("app", "diff", app.Name, "--local", "testdata", "--server-side-generate") + diffOutput, err := RunCli("app", "diff", app.Name, "--local", "testdata", "--server-side-generate") require.Error(t, err) - assert.Contains(t, diffOutput, fmt.Sprintf("===== apps/Deployment %s/guestbook-ui ======", fixture.DeploymentNamespace())) + assert.Contains(t, diffOutput, fmt.Sprintf("===== apps/Deployment %s/guestbook-ui ======", DeploymentNamespace())) }). Given(). ResourceOverrides(map[string]ResourceOverride{"apps/Deployment": { @@ -898,7 +906,7 @@ func TestResourceDiffing(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - diffOutput, err := fixture.RunCli("app", "diff", app.Name, "--local", "testdata", "--server-side-generate") + diffOutput, err := RunCli("app", "diff", app.Name, "--local", "testdata", "--server-side-generate") require.NoError(t, err) assert.Empty(t, diffOutput) }). @@ -916,7 +924,7 @@ func TestResourceDiffing(t *testing.T) { }]`). Sync(). And(func() { - output, err := fixture.RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", fixture.DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-") + output, err := RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-") require.NoError(t, err) assert.Contains(t, output, "serverside-applied") }). @@ -943,12 +951,12 @@ func TestResourceDiffing(t *testing.T) { "value": { "syncOptions": ["RespectIgnoreDifferences=true"] } }]`). And(func() { - deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + deployment, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, int32(3), *deployment.Spec.RevisionHistoryLimit) }). And(func() { - output, err := fixture.RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", fixture.DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-") + output, err := RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-") require.NoError(t, err) assert.Contains(t, output, "serverside-applied") }). @@ -956,14 +964,14 @@ func TestResourceDiffing(t *testing.T) { When().Refresh(RefreshTypeNormal). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + And(func(app *Application) { + deployment, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, int32(1), *deployment.Spec.RevisionHistoryLimit) }). When().Sync().Then().Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + And(func(app *Application) { + deployment, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, int32(1), *deployment.Spec.RevisionHistoryLimit) }) @@ -982,15 +990,15 @@ func TestKnownTypesInCRDDiffing(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)).Expect(SyncStatusIs(SyncStatusCodeSynced)). When(). And(func() { - dummyResIf := fixture.DynamicClientset.Resource(dummiesGVR).Namespace(fixture.DeploymentNamespace()) + dummyResIf := DynamicClientset.Resource(dummiesGVR).Namespace(DeploymentNamespace()) patchData := []byte(`{"spec":{"cpu": "2"}}`) - errors.NewHandler(t).FailOnErr(dummyResIf.Patch(t.Context(), "dummy-crd-instance", types.MergePatchType, patchData, metav1.PatchOptions{})) + FailOnErr(dummyResIf.Patch(context.Background(), "dummy-crd-instance", types.MergePatchType, patchData, metav1.PatchOptions{})) }).Refresh(RefreshTypeNormal). Then(). Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). When(). And(func() { - require.NoError(t, fixture.SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "argoproj.io/Dummy": { KnownTypeFields: []KnownTypeField{{ Field: "spec", @@ -1004,27 +1012,6 @@ func TestKnownTypesInCRDDiffing(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)) } -func TestDuplicatedClusterResourcesAnnotationTracking(t *testing.T) { - // This test will fail if the controller fails to fix the tracking annotation for malformed cluster resources - // (i.e. resources where metadata.namespace is set). Before the bugfix, this test would fail with a diff in the - // tracking annotation. - Given(t). - SetTrackingMethod(string(TrackingMethodAnnotation)). - Path("duplicated-resources"). - When(). - CreateApp(). - Sync(). - Then(). - Expect(OperationPhaseIs(OperationSucceeded)). - Expect(SyncStatusIs(SyncStatusCodeSynced)). - Expect(HealthIs(health.HealthStatusHealthy)). - And(func(app *Application) { - diffOutput, err := fixture.RunCli("app", "diff", app.Name, "--local", "testdata", "--server-side-generate") - assert.Empty(t, diffOutput) - require.NoError(t, err) - }) -} - func TestDuplicatedResources(t *testing.T) { testEdgeCasesApplicationResources(t, "duplicated-resources", health.HealthStatusHealthy) } @@ -1049,7 +1036,7 @@ func testEdgeCasesApplicationResources(t *testing.T, appPath string, statusCode expect. Expect(HealthIs(statusCode)). And(func(app *Application) { - diffOutput, err := fixture.RunCli("app", "diff", app.Name, "--local", "testdata", "--server-side-generate") + diffOutput, err := RunCli("app", "diff", app.Name, "--local", "testdata", "--server-side-generate") assert.Empty(t, diffOutput) require.NoError(t, err) }) @@ -1071,33 +1058,33 @@ func TestOldStyleResourceAction(t *testing.T) { Sync(). Then(). And(func(app *Application) { - closer, client, err := fixture.ArgoCDClientset.NewApplicationClient() + closer, client, err := ArgoCDClientset.NewApplicationClient() require.NoError(t, err) - defer utilio.Close(closer) + defer io.Close(closer) - actions, err := client.ListResourceActions(t.Context(), &applicationpkg.ApplicationResourceRequest{ + actions, err := client.ListResourceActions(context.Background(), &applicationpkg.ApplicationResourceRequest{ Name: &app.Name, Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Version: ptr.To("v1"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), ResourceName: ptr.To("guestbook-ui"), }) require.NoError(t, err) assert.Equal(t, []*ResourceAction{{Name: "sample", Disabled: false}}, actions.Actions) - _, err = client.RunResourceAction(t.Context(), &applicationpkg.ResourceActionRunRequest{ + _, err = client.RunResourceAction(context.Background(), &applicationpkg.ResourceActionRunRequest{ Name: &app.Name, Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Version: ptr.To("v1"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), ResourceName: ptr.To("guestbook-ui"), Action: ptr.To("sample"), }) require.NoError(t, err) - deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + deployment, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, "test", deployment.Labels["sample"]) @@ -1177,33 +1164,33 @@ func TestNewStyleResourceActionPermitted(t *testing.T) { Sync(). Then(). And(func(app *Application) { - closer, client, err := fixture.ArgoCDClientset.NewApplicationClient() + closer, client, err := ArgoCDClientset.NewApplicationClient() require.NoError(t, err) - defer utilio.Close(closer) + defer io.Close(closer) - actions, err := client.ListResourceActions(t.Context(), &applicationpkg.ApplicationResourceRequest{ + actions, err := client.ListResourceActions(context.Background(), &applicationpkg.ApplicationResourceRequest{ Name: &app.Name, Group: ptr.To("batch"), Kind: ptr.To("CronJob"), Version: ptr.To("v1"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), ResourceName: ptr.To("hello"), }) require.NoError(t, err) assert.Equal(t, []*ResourceAction{{Name: "sample", Disabled: false}}, actions.Actions) - _, err = client.RunResourceAction(t.Context(), &applicationpkg.ResourceActionRunRequest{ + _, err = client.RunResourceAction(context.Background(), &applicationpkg.ResourceActionRunRequest{ Name: &app.Name, Group: ptr.To("batch"), Kind: ptr.To("CronJob"), Version: ptr.To("v1"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), ResourceName: ptr.To("hello"), Action: ptr.To("sample"), }) require.NoError(t, err) - _, err = fixture.KubeClientset.BatchV1().Jobs(fixture.DeploymentNamespace()).Get(t.Context(), "hello-123", metav1.GetOptions{}) + _, err = KubeClientset.BatchV1().Jobs(DeploymentNamespace()).Get(context.Background(), "hello-123", metav1.GetOptions{}) require.NoError(t, err) }) } @@ -1262,7 +1249,6 @@ definitions: result = {} result[1] = impactedResource1 - obj.metadata.labels = {} obj.metadata.labels["aKey"] = 'aValue' impactedResource2 = {} impactedResource2.operation = "patch" @@ -1289,37 +1275,37 @@ func TestNewStyleResourceActionMixedOk(t *testing.T) { Sync(). Then(). And(func(app *Application) { - closer, client, err := fixture.ArgoCDClientset.NewApplicationClient() + closer, client, err := ArgoCDClientset.NewApplicationClient() require.NoError(t, err) - defer utilio.Close(closer) + defer io.Close(closer) - actions, err := client.ListResourceActions(t.Context(), &applicationpkg.ApplicationResourceRequest{ + actions, err := client.ListResourceActions(context.Background(), &applicationpkg.ApplicationResourceRequest{ Name: &app.Name, Group: ptr.To("batch"), Kind: ptr.To("CronJob"), Version: ptr.To("v1"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), ResourceName: ptr.To("hello"), }) require.NoError(t, err) assert.Equal(t, []*ResourceAction{{Name: "sample", Disabled: false}}, actions.Actions) - _, err = client.RunResourceAction(t.Context(), &applicationpkg.ResourceActionRunRequest{ + _, err = client.RunResourceAction(context.Background(), &applicationpkg.ResourceActionRunRequest{ Name: &app.Name, Group: ptr.To("batch"), Kind: ptr.To("CronJob"), Version: ptr.To("v1"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), ResourceName: ptr.To("hello"), Action: ptr.To("sample"), }) require.NoError(t, err) // Assert new Job was created - _, err = fixture.KubeClientset.BatchV1().Jobs(fixture.DeploymentNamespace()).Get(t.Context(), "hello-123", metav1.GetOptions{}) + _, err = KubeClientset.BatchV1().Jobs(DeploymentNamespace()).Get(context.Background(), "hello-123", metav1.GetOptions{}) require.NoError(t, err) // Assert the original CronJob was patched - cronJob, err := fixture.KubeClientset.BatchV1().CronJobs(fixture.DeploymentNamespace()).Get(t.Context(), "hello", metav1.GetOptions{}) + cronJob, err := KubeClientset.BatchV1().CronJobs(DeploymentNamespace()).Get(context.Background(), "hello", metav1.GetOptions{}) assert.Equal(t, "aValue", cronJob.Labels["aKey"]) require.NoError(t, err) }) @@ -1333,12 +1319,12 @@ func TestSyncResourceByLabel(t *testing.T) { Sync(). Then(). And(func(app *Application) { - _, _ = fixture.RunCli("app", "sync", app.Name, "--label", "app.kubernetes.io/instance="+app.Name) + _, _ = RunCli("app", "sync", app.Name, "--label", fmt.Sprintf("app.kubernetes.io/instance=%s", app.Name)) }). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - _, err := fixture.RunCli("app", "sync", app.Name, "--label", "this-label=does-not-exist") - assert.ErrorContains(t, err, "\"level\":\"fatal\"") + _, err := RunCli("app", "sync", app.Name, "--label", "this-label=does-not-exist") + assert.ErrorContains(t, err, "level=fatal") }) } @@ -1350,12 +1336,12 @@ func TestSyncResourceByProject(t *testing.T) { Sync(). Then(). And(func(app *Application) { - _, _ = fixture.RunCli("app", "sync", app.Name, "--project", app.Spec.Project) + _, _ = RunCli("app", "sync", app.Name, "--project", app.Spec.Project) }). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - _, err := fixture.RunCli("app", "sync", app.Name, "--project", "this-project-does-not-exist") - assert.ErrorContains(t, err, "\"level\":\"fatal\"") + _, err := RunCli("app", "sync", app.Name, "--project", "this-project-does-not-exist") + assert.ErrorContains(t, err, "level=fatal") }) } @@ -1367,7 +1353,7 @@ func TestLocalManifestSync(t *testing.T) { Sync(). Then(). And(func(app *Application) { - res, _ := fixture.RunCli("app", "manifests", app.Name) + res, _ := RunCli("app", "manifests", app.Name) assert.Contains(t, res, "containerPort: 80") assert.Contains(t, res, "image: quay.io/argoprojlabs/argocd-e2e-container:0.2") }). @@ -1378,7 +1364,7 @@ func TestLocalManifestSync(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - res, _ := fixture.RunCli("app", "manifests", app.Name) + res, _ := RunCli("app", "manifests", app.Name) assert.Contains(t, res, "containerPort: 81") assert.Contains(t, res, "image: quay.io/argoprojlabs/argocd-e2e-container:0.3") }). @@ -1389,7 +1375,7 @@ func TestLocalManifestSync(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - res, _ := fixture.RunCli("app", "manifests", app.Name) + res, _ := RunCli("app", "manifests", app.Name) assert.Contains(t, res, "containerPort: 80") assert.Contains(t, res, "image: quay.io/argoprojlabs/argocd-e2e-container:0.2") }) @@ -1403,7 +1389,7 @@ func TestLocalSync(t *testing.T) { CreateApp(). Then(). And(func(app *Application) { - errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "sync", app.Name, "--local", "testdata/helm")) + FailOnErr(RunCli("app", "sync", app.Name, "--local", "testdata/helm")) }) } @@ -1415,10 +1401,10 @@ func TestNoLocalSyncWithAutosyncEnabled(t *testing.T) { Sync(). Then(). And(func(app *Application) { - _, err := fixture.RunCli("app", "set", app.Name, "--sync-policy", "automated") + _, err := RunCli("app", "set", app.Name, "--sync-policy", "automated") require.NoError(t, err) - _, err = fixture.RunCli("app", "sync", app.Name, "--local", guestbookPathLocal) + _, err = RunCli("app", "sync", app.Name, "--local", guestbookPathLocal) require.Error(t, err) }) } @@ -1431,11 +1417,11 @@ func TestLocalSyncDryRunWithAutosyncEnabled(t *testing.T) { Sync(). Then(). And(func(app *Application) { - _, err := fixture.RunCli("app", "set", app.Name, "--sync-policy", "automated") + _, err := RunCli("app", "set", app.Name, "--sync-policy", "automated") require.NoError(t, err) appBefore := app.DeepCopy() - _, err = fixture.RunCli("app", "sync", app.Name, "--dry-run", "--local-repo-root", ".", "--local", guestbookPathLocal) + _, err = RunCli("app", "sync", app.Name, "--dry-run", "--local-repo-root", ".", "--local", guestbookPathLocal) require.NoError(t, err) appAfter := app.DeepCopy() @@ -1467,17 +1453,17 @@ func assertResourceActions(t *testing.T, appName string, successful bool) { } } - closer, cdClient := fixture.ArgoCDClientset.NewApplicationClientOrDie() - defer utilio.Close(closer) + closer, cdClient := ArgoCDClientset.NewApplicationClientOrDie() + defer io.Close(closer) - deploymentResource, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + deploymentResource, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) require.NoError(t, err) - logs, err := cdClient.PodLogs(t.Context(), &applicationpkg.ApplicationPodLogsQuery{ + logs, err := cdClient.PodLogs(context.Background(), &applicationpkg.ApplicationPodLogsQuery{ Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Name: &appName, - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), Container: ptr.To(""), SinceSeconds: ptr.To(int64(0)), TailLines: ptr.To(int64(0)), @@ -1487,30 +1473,30 @@ func assertResourceActions(t *testing.T, appName string, successful bool) { _, err = logs.Recv() assertError(err, "EOF") - expectedError := "Deployment apps guestbook-ui not found as part of application " + appName + expectedError := fmt.Sprintf("Deployment apps guestbook-ui not found as part of application %s", appName) - _, err = cdClient.ListResourceEvents(t.Context(), &applicationpkg.ApplicationResourceEventsQuery{ + _, err = cdClient.ListResourceEvents(context.Background(), &applicationpkg.ApplicationResourceEventsQuery{ Name: &appName, ResourceName: ptr.To("guestbook-ui"), - ResourceNamespace: ptr.To(fixture.DeploymentNamespace()), + ResourceNamespace: ptr.To(DeploymentNamespace()), ResourceUID: ptr.To(string(deploymentResource.UID)), }) assertError(err, fmt.Sprintf("%s not found as part of application %s", "guestbook-ui", appName)) - _, err = cdClient.GetResource(t.Context(), &applicationpkg.ApplicationResourceRequest{ + _, err = cdClient.GetResource(context.Background(), &applicationpkg.ApplicationResourceRequest{ Name: &appName, ResourceName: ptr.To("guestbook-ui"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), Version: ptr.To("v1"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), }) assertError(err, expectedError) - _, err = cdClient.RunResourceAction(t.Context(), &applicationpkg.ResourceActionRunRequest{ + _, err = cdClient.RunResourceAction(context.Background(), &applicationpkg.ResourceActionRunRequest{ Name: &appName, ResourceName: ptr.To("guestbook-ui"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), Version: ptr.To("v1"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), @@ -1518,10 +1504,10 @@ func assertResourceActions(t *testing.T, appName string, successful bool) { }) assertError(err, expectedError) - _, err = cdClient.DeleteResource(t.Context(), &applicationpkg.ApplicationResourceDeleteRequest{ + _, err = cdClient.DeleteResource(context.Background(), &applicationpkg.ApplicationResourceDeleteRequest{ Name: &appName, ResourceName: ptr.To("guestbook-ui"), - Namespace: ptr.To(fixture.DeploymentNamespace()), + Namespace: ptr.To(DeploymentNamespace()), Version: ptr.To("v1"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), @@ -1538,8 +1524,8 @@ func TestPermissions(t *testing.T) { When(). Create() - sourceError := fmt.Sprintf("application repo %s is not permitted in project 'argo-project'", fixture.RepoURL(fixture.RepoURLTypeFile)) - destinationError := fmt.Sprintf("application destination server '%s' and namespace '%s' do not match any of the allowed destinations in project 'argo-project'", KubernetesInternalAPIServerAddr, fixture.DeploymentNamespace()) + sourceError := fmt.Sprintf("application repo %s is not permitted in project 'argo-project'", RepoURL(RepoURLTypeFile)) + destinationError := fmt.Sprintf("application destination server '%s' and namespace '%s' do not match any of the allowed destinations in project 'argo-project'", KubernetesInternalAPIServerAddr, DeploymentNamespace()) appCtx. Path("guestbook-logs"). @@ -1579,11 +1565,11 @@ func TestPermissions(t *testing.T) { Expect(Condition(ApplicationConditionInvalidSpecError, destinationError)). Expect(Condition(ApplicationConditionInvalidSpecError, sourceError)). And(func(app *Application) { - closer, cdClient := fixture.ArgoCDClientset.NewApplicationClientOrDie() - defer utilio.Close(closer) + closer, cdClient := ArgoCDClientset.NewApplicationClientOrDie() + defer io.Close(closer) appName, appNs := argo.ParseFromQualifiedName(app.Name, "") fmt.Printf("APP NAME: %s\n", appName) - tree, err := cdClient.ResourceTree(t.Context(), &applicationpkg.ResourcesQuery{ApplicationName: &appName, AppNamespace: &appNs}) + tree, err := cdClient.ResourceTree(context.Background(), &applicationpkg.ResourcesQuery{ApplicationName: &appName, AppNamespace: &appNs}) require.NoError(t, err) assert.Empty(t, tree.Nodes) assert.Empty(t, tree.OrphanedNodes) @@ -1601,7 +1587,7 @@ func TestPermissions(t *testing.T) { Refresh(RefreshTypeNormal). Then(). // make sure application resource actiions are failing - And(func(_ *Application) { + And(func(app *Application) { assertResourceActions(t, "test-permissions", false) }) } @@ -1619,13 +1605,13 @@ func TestPermissionWithScopedRepo(t *testing.T) { repoFixture.GivenWithSameState(t). When(). - Path(fixture.RepoURL(fixture.RepoURLTypeFile)). + Path(RepoURL(RepoURLTypeFile)). Project(projName). Create() GivenWithSameState(t). Project(projName). - RepoURLType(fixture.RepoURLTypeFile). + RepoURLType(RepoURLTypeFile). Path("two-nice-pods"). When(). PatchFile("pod-1.yaml", `[{"op": "add", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/sync-options": "Prune=false"}}]`). @@ -1656,12 +1642,12 @@ func TestPermissionDeniedWithScopedRepo(t *testing.T) { repoFixture.GivenWithSameState(t). When(). - Path(fixture.RepoURL(fixture.RepoURLTypeFile)). + Path(RepoURL(RepoURLTypeFile)). Create() GivenWithSameState(t). Project(projName). - RepoURLType(fixture.RepoURLTypeFile). + RepoURLType(RepoURLTypeFile). Path("two-nice-pods"). When(). PatchFile("pod-1.yaml", `[{"op": "add", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/sync-options": "Prune=false"}}]`). @@ -1682,13 +1668,13 @@ func TestPermissionDeniedWithNegatedNamespace(t *testing.T) { repoFixture.GivenWithSameState(t). When(). - Path(fixture.RepoURL(fixture.RepoURLTypeFile)). + Path(RepoURL(RepoURLTypeFile)). Project(projName). Create() GivenWithSameState(t). Project(projName). - RepoURLType(fixture.RepoURLTypeFile). + RepoURLType(RepoURLTypeFile). Path("two-nice-pods"). When(). PatchFile("pod-1.yaml", `[{"op": "add", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/sync-options": "Prune=false"}}]`). @@ -1709,13 +1695,13 @@ func TestPermissionDeniedWithNegatedServer(t *testing.T) { repoFixture.GivenWithSameState(t). When(). - Path(fixture.RepoURL(fixture.RepoURLTypeFile)). + Path(RepoURL(RepoURLTypeFile)). Project(projName). Create() GivenWithSameState(t). Project(projName). - RepoURLType(fixture.RepoURLTypeFile). + RepoURLType(RepoURLTypeFile). Path("two-nice-pods"). When(). PatchFile("pod-1.yaml", `[{"op": "add", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/sync-options": "Prune=false"}}]`). @@ -1807,7 +1793,7 @@ func TestSourceNamespaceCanBeMigratedToManagedNamespaceWithoutBeingPrunedOrOutOf Prune(true). Path("guestbook-with-plain-namespace-manifest"). When(). - PatchFile("guestbook-ui-namespace.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/metadata/name", "value": "%s"}]`, fixture.DeploymentNamespace())). + PatchFile("guestbook-ui-namespace.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/metadata/name", "value": "%s"}]`, DeploymentNamespace())). CreateApp(). Sync(). Then(). @@ -1840,19 +1826,19 @@ func TestSelfManagedApps(t *testing.T) { Given(t). Path("self-managed-app"). When(). - PatchFile("resources.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/spec/source/repoURL", "value": "%s"}]`, fixture.RepoURL(fixture.RepoURLTypeFile))). + PatchFile("resources.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/spec/source/repoURL", "value": "%s"}]`, RepoURL(RepoURLTypeFile))). CreateApp(). Sync(). Then(). Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(a *Application) { - ctx, cancel := context.WithTimeout(t.Context(), time.Second*3) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() reconciledCount := 0 var lastReconciledAt *metav1.Time - for event := range fixture.ArgoCDClientset.WatchApplicationWithRetry(ctx, a.Name, a.ResourceVersion) { + for event := range ArgoCDClientset.WatchApplicationWithRetry(ctx, a.Name, a.ResourceVersion) { reconciledAt := event.Application.Status.ReconciledAt if reconciledAt == nil { reconciledAt = &metav1.Time{} @@ -1906,7 +1892,7 @@ func TestRevisionHistoryLimit(t *testing.T) { } func TestOrphanedResource(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") Given(t). ProjectSpec(AppProjectSpec{ SourceRepos: []string{"*"}, @@ -1922,7 +1908,7 @@ func TestOrphanedResource(t *testing.T) { Expect(NoConditions()). When(). And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{ + FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "orphaned-configmap", }, @@ -1932,7 +1918,7 @@ func TestOrphanedResource(t *testing.T) { Then(). Expect(Condition(ApplicationConditionOrphanedResourceWarning, "Application has 1 orphaned resources")). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.Name) + output, err := RunCli("app", "resources", app.Name) require.NoError(t, err) assert.Contains(t, output, "orphaned-configmap") }). @@ -1947,7 +1933,7 @@ func TestOrphanedResource(t *testing.T) { Then(). Expect(Condition(ApplicationConditionOrphanedResourceWarning, "Application has 1 orphaned resources")). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.Name) + output, err := RunCli("app", "resources", app.Name) require.NoError(t, err) assert.Contains(t, output, "orphaned-configmap") }). @@ -1963,7 +1949,7 @@ func TestOrphanedResource(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(NoConditions()). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.Name) + output, err := RunCli("app", "resources", app.Name) require.NoError(t, err) assert.NotContains(t, output, "orphaned-configmap") }). @@ -1979,7 +1965,7 @@ func TestOrphanedResource(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(NoConditions()). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.Name) + output, err := RunCli("app", "resources", app.Name) require.NoError(t, err) assert.NotContains(t, output, "orphaned-configmap") }). @@ -2027,19 +2013,19 @@ func TestNotPermittedResources(t *testing.T) { }, } defer func() { - log.Infof("Ingress 'sample-ingress' deleted from %s", fixture.TestNamespace()) - require.NoError(t, fixture.KubeClientset.NetworkingV1().Ingresses(fixture.TestNamespace()).Delete(t.Context(), "sample-ingress", metav1.DeleteOptions{})) + log.Infof("Ingress 'sample-ingress' deleted from %s", TestNamespace()) + CheckError(KubeClientset.NetworkingV1().Ingresses(TestNamespace()).Delete(context.Background(), "sample-ingress", metav1.DeleteOptions{})) }() - svc := &corev1.Service{ + svc := &v1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: "guestbook-ui", Labels: map[string]string{ common.LabelKeyAppInstance: ctx.GetName(), }, }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{{ + Spec: v1.ServiceSpec{ + Ports: []v1.ServicePort{{ Port: 80, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: 80}, }}, @@ -2051,14 +2037,14 @@ func TestNotPermittedResources(t *testing.T) { ctx.ProjectSpec(AppProjectSpec{ SourceRepos: []string{"*"}, - Destinations: []ApplicationDestination{{Namespace: fixture.DeploymentNamespace(), Server: "*"}}, + Destinations: []ApplicationDestination{{Namespace: DeploymentNamespace(), Server: "*"}}, NamespaceResourceBlacklist: []metav1.GroupKind{ {Group: "", Kind: "Service"}, }, }). And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.NetworkingV1().Ingresses(fixture.TestNamespace()).Create(t.Context(), ingress, metav1.CreateOptions{})) - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Services(fixture.DeploymentNamespace()).Create(t.Context(), svc, metav1.CreateOptions{})) + FailOnErr(KubeClientset.NetworkingV1().Ingresses(TestNamespace()).Create(context.Background(), ingress, metav1.CreateOptions{})) + FailOnErr(KubeClientset.CoreV1().Services(DeploymentNamespace()).Create(context.Background(), svc, metav1.CreateOptions{})) }). Path(guestbookPath). When(). @@ -2083,8 +2069,8 @@ func TestNotPermittedResources(t *testing.T) { Expect(DoesNotExist()) // Make sure prohibited resources are not deleted during application deletion - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.NetworkingV1().Ingresses(fixture.TestNamespace()).Get(t.Context(), "sample-ingress", metav1.GetOptions{})) - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Services(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})) + FailOnErr(KubeClientset.NetworkingV1().Ingresses(TestNamespace()).Get(context.Background(), "sample-ingress", metav1.GetOptions{})) + FailOnErr(KubeClientset.CoreV1().Services(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{})) } func TestSyncWithInfos(t *testing.T) { @@ -2098,7 +2084,7 @@ func TestSyncWithInfos(t *testing.T) { CreateApp(). Then(). And(func(app *Application) { - _, err := fixture.RunCli("app", "sync", app.Name, + _, err := RunCli("app", "sync", app.Name, "--info", fmt.Sprintf("%s=%s", expectedInfo[0].Name, expectedInfo[0].Value), "--info", fmt.Sprintf("%s=%s", expectedInfo[1].Name, expectedInfo[1].Value)) require.NoError(t, err) @@ -2121,7 +2107,7 @@ func TestCreateAppWithNoNameSpaceForGlobalResource(t *testing.T) { CreateWithNoNameSpace(). Then(). And(func(app *Application) { - app, err := fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.TestNamespace()).Get(t.Context(), app.Name, metav1.GetOptions{}) + app, err := AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).Get(context.Background(), app.Name, metav1.GetOptions{}) require.NoError(t, err) assert.Empty(t, app.Status.Conditions) }) @@ -2141,7 +2127,7 @@ func TestCreateAppWithNoNameSpaceWhenRequired(t *testing.T) { Refresh(RefreshTypeNormal). Then(). And(func(app *Application) { - updatedApp, err := fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.TestNamespace()).Get(t.Context(), app.Name, metav1.GetOptions{}) + updatedApp, err := AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).Get(context.Background(), app.Name, metav1.GetOptions{}) require.NoError(t, err) assert.Len(t, updatedApp.Status.Conditions, 2) @@ -2165,7 +2151,7 @@ func TestCreateAppWithNoNameSpaceWhenRequired2(t *testing.T) { Refresh(RefreshTypeNormal). Then(). And(func(app *Application) { - updatedApp, err := fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.TestNamespace()).Get(t.Context(), app.Name, metav1.GetOptions{}) + updatedApp, err := AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).Get(context.Background(), app.Name, metav1.GetOptions{}) require.NoError(t, err) assert.Len(t, updatedApp.Status.Conditions, 2) @@ -2174,21 +2160,8 @@ func TestCreateAppWithNoNameSpaceWhenRequired2(t *testing.T) { }) } -func TestCreateAppWithInClusterDisabled(t *testing.T) { - Given(t). - Path(guestbookPath). - DestServer(KubernetesInternalAPIServerAddr). - When(). - SetParamInSettingConfigMap("cluster.inClusterEnabled", "false"). - IgnoreErrors(). - CreateApp(). - Then(). - // RPC error messages are quoted: time="2024-12-18T04:13:58Z" level=fatal msg="" - Expect(Error("", fmt.Sprintf(`cluster \"%s\" is disabled`, KubernetesInternalAPIServerAddr))) -} - func TestListResource(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") Given(t). ProjectSpec(AppProjectSpec{ SourceRepos: []string{"*"}, @@ -2204,7 +2177,7 @@ func TestListResource(t *testing.T) { Expect(NoConditions()). When(). And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{ + FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "orphaned-configmap", }, @@ -2214,19 +2187,19 @@ func TestListResource(t *testing.T) { Then(). Expect(Condition(ApplicationConditionOrphanedResourceWarning, "Application has 1 orphaned resources")). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.Name) + output, err := RunCli("app", "resources", app.Name) require.NoError(t, err) assert.Contains(t, output, "orphaned-configmap") assert.Contains(t, output, "guestbook-ui") }). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.Name, "--orphaned=true") + output, err := RunCli("app", "resources", app.Name, "--orphaned=true") require.NoError(t, err) assert.Contains(t, output, "orphaned-configmap") assert.NotContains(t, output, "guestbook-ui") }). And(func(app *Application) { - output, err := fixture.RunCli("app", "resources", app.Name, "--orphaned=false") + output, err := RunCli("app", "resources", app.Name, "--orphaned=false") require.NoError(t, err) assert.NotContains(t, output, "orphaned-configmap") assert.Contains(t, output, "guestbook-ui") @@ -2253,11 +2226,11 @@ func TestListResource(t *testing.T) { // application sync successful // when application is deleted, --dest-namespace is not deleted func TestNamespaceAutoCreation(t *testing.T) { - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") updatedNamespace := getNewNamespace(t) defer func() { if !t.Skipped() { - _, err := fixture.Run("", "kubectl", "delete", "namespace", updatedNamespace) + _, err := Run("", "kubectl", "delete", "namespace", updatedNamespace) require.NoError(t, err) } }() @@ -2267,9 +2240,9 @@ func TestNamespaceAutoCreation(t *testing.T) { When(). CreateApp("--sync-option", "CreateNamespace=true"). Then(). - And(func(_ *Application) { + And(func(app *Application) { // Make sure the namespace we are about to update to does not exist - _, err := fixture.Run("", "kubectl", "get", "namespace", updatedNamespace) + _, err := Run("", "kubectl", "get", "namespace", updatedNamespace) assert.ErrorContains(t, err, "not found") }). When(). @@ -2285,9 +2258,9 @@ func TestNamespaceAutoCreation(t *testing.T) { Delete(true). Then(). Expect(Success("")). - And(func(_ *Application) { + And(func(app *Application) { // Verify delete app does not delete the namespace auto created - output, err := fixture.Run("", "kubectl", "get", "namespace", updatedNamespace) + output, err := Run("", "kubectl", "get", "namespace", updatedNamespace) require.NoError(t, err) assert.Contains(t, output, updatedNamespace) }) @@ -2315,8 +2288,8 @@ func TestCreateDisableValidation(t *testing.T) { CreateApp("--validate=false"). Then(). And(func(app *Application) { - _, err := fixture.RunCli("app", "create", app.Name, "--upsert", "--validate=false", "--repo", fixture.RepoURL(fixture.RepoURLTypeFile), - "--path", "baddir2", "--project", app.Spec.Project, "--dest-server", KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace()) + _, err := RunCli("app", "create", app.Name, "--upsert", "--validate=false", "--repo", RepoURL(RepoURLTypeFile), + "--path", "baddir2", "--project", app.Spec.Project, "--dest-server", KubernetesInternalAPIServerAddr, "--dest-namespace", DeploymentNamespace()) require.NoError(t, err) }). When(). @@ -2348,9 +2321,9 @@ spec: Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(NoConditions()). And(func(app *Application) { - assert.Equal(t, map[string]string{"labels.local/from-file": "file", "labels.local/from-args": "args"}, app.Labels) - assert.Equal(t, map[string]string{"annotations.local/from-file": "file"}, app.Annotations) - assert.Equal(t, []string{"resources-finalizer.argocd.argoproj.io"}, app.Finalizers) + assert.Equal(t, map[string]string{"labels.local/from-file": "file", "labels.local/from-args": "args"}, app.ObjectMeta.Labels) + assert.Equal(t, map[string]string{"annotations.local/from-file": "file"}, app.ObjectMeta.Annotations) + assert.Equal(t, []string{"resources-finalizer.argocd.argoproj.io"}, app.ObjectMeta.Finalizers) assert.Equal(t, path, app.Spec.GetSource().Path) assert.Equal(t, []HelmParameter{{Name: "foo", Value: "foo"}}, app.Spec.GetSource().Helm.Parameters) }) @@ -2387,7 +2360,7 @@ definitions: Given(t). Path("crd-subresource"). And(func() { - require.NoError(t, fixture.SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "argoproj.io/StatusSubResource": { Actions: actions, }, @@ -2403,47 +2376,47 @@ definitions: Then(). // tests resource actions on a CRD using status subresource And(func(app *Application) { - _, err := fixture.RunCli("app", "actions", "run", app.Name, "--kind", "StatusSubResource", "update-both") + _, err := RunCli("app", "actions", "run", app.Name, "--kind", "StatusSubResource", "update-both") require.NoError(t, err) - text := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.spec.foo}")).(string) + text := FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.spec.foo}")).(string) assert.Equal(t, "update-both", text) - text = errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.status.bar}")).(string) + text = FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.status.bar}")).(string) assert.Equal(t, "update-both", text) - _, err = fixture.RunCli("app", "actions", "run", app.Name, "--kind", "StatusSubResource", "update-spec") + _, err = RunCli("app", "actions", "run", app.Name, "--kind", "StatusSubResource", "update-spec") require.NoError(t, err) - text = errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.spec.foo}")).(string) + text = FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.spec.foo}")).(string) assert.Equal(t, "update-spec", text) - _, err = fixture.RunCli("app", "actions", "run", app.Name, "--kind", "StatusSubResource", "update-status") + _, err = RunCli("app", "actions", "run", app.Name, "--kind", "StatusSubResource", "update-status") require.NoError(t, err) - text = errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.status.bar}")).(string) + text = FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "statussubresources", "status-subresource", "-o", "jsonpath={.status.bar}")).(string) assert.Equal(t, "update-status", text) }). // tests resource actions on a CRD *not* using status subresource And(func(app *Application) { - _, err := fixture.RunCli("app", "actions", "run", app.Name, "--kind", "NonStatusSubResource", "update-both") + _, err := RunCli("app", "actions", "run", app.Name, "--kind", "NonStatusSubResource", "update-both") require.NoError(t, err) - text := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.spec.foo}")).(string) + text := FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.spec.foo}")).(string) assert.Equal(t, "update-both", text) - text = errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.status.bar}")).(string) + text = FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.status.bar}")).(string) assert.Equal(t, "update-both", text) - _, err = fixture.RunCli("app", "actions", "run", app.Name, "--kind", "NonStatusSubResource", "update-spec") + _, err = RunCli("app", "actions", "run", app.Name, "--kind", "NonStatusSubResource", "update-spec") require.NoError(t, err) - text = errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.spec.foo}")).(string) + text = FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.spec.foo}")).(string) assert.Equal(t, "update-spec", text) - _, err = fixture.RunCli("app", "actions", "run", app.Name, "--kind", "NonStatusSubResource", "update-status") + _, err = RunCli("app", "actions", "run", app.Name, "--kind", "NonStatusSubResource", "update-status") require.NoError(t, err) - text = errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.status.bar}")).(string) + text = FailOnErr(Run(".", "kubectl", "-n", app.Spec.Destination.Namespace, "get", "nonstatussubresources", "non-status-subresource", "-o", "jsonpath={.status.bar}")).(string) assert.Equal(t, "update-status", text) }) } func TestAppLogs(t *testing.T) { t.SkipNow() // Too flaky. https://github.com/argoproj/argo-cd/issues/13834 - fixture.SkipOnEnv(t, "OPENSHIFT") + SkipOnEnv(t, "OPENSHIFT") Given(t). Path("guestbook-logs"). When(). @@ -2452,17 +2425,17 @@ func TestAppLogs(t *testing.T) { Then(). Expect(HealthIs(health.HealthStatusHealthy)). And(func(app *Application) { - out, err := fixture.RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") + out, err := RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") require.NoError(t, err) assert.Contains(t, out, "Hi") }). And(func(app *Application) { - out, err := fixture.RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Pod") + out, err := RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Pod") require.NoError(t, err) assert.Contains(t, out, "Hi") }). And(func(app *Application) { - out, err := fixture.RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Service") + out, err := RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Service") require.NoError(t, err) assert.NotContains(t, out, "Hi") }) @@ -2472,7 +2445,7 @@ func TestAppWaitOperationInProgress(t *testing.T) { ctx := Given(t) ctx. And(func() { - require.NoError(t, fixture.SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "batch/Job": { HealthLua: `return { status = 'Running' }`, }, @@ -2491,8 +2464,8 @@ func TestAppWaitOperationInProgress(t *testing.T) { Expect(OperationPhaseIs(OperationRunning)). When(). And(func() { - _, err := fixture.RunCli("app", "wait", ctx.AppName(), "--suspended") - require.NoError(t, err) + _, err := RunCli("app", "wait", ctx.AppName(), "--suspended") + errors.CheckError(err) }) } @@ -2581,13 +2554,13 @@ func TestDisableManifestGeneration(t *testing.T) { }). When(). And(func() { - require.NoError(t, fixture.SetEnableManifestGeneration(map[ApplicationSourceType]bool{ + CheckError(SetEnableManifestGeneration(map[ApplicationSourceType]bool{ ApplicationSourceTypeKustomize: false, })) }). Refresh(RefreshTypeHard). Then(). - And(func(_ *Application) { + And(func(app *Application) { // Wait for refresh to complete time.Sleep(1 * time.Second) }). @@ -2600,7 +2573,7 @@ func TestSwitchTrackingMethod(t *testing.T) { ctx := Given(t) ctx. - SetTrackingMethod(string(TrackingMethodAnnotation)). + SetTrackingMethod(string(argo.TrackingMethodAnnotation)). Path("deployment"). When(). CreateApp(). @@ -2614,11 +2587,11 @@ func TestSwitchTrackingMethod(t *testing.T) { And(func() { // Add resource with tracking annotation. This should put the // application OutOfSync. - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{ + FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "other-configmap", Annotations: map[string]string{ - common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", fixture.Name(), fixture.DeploymentNamespace()), + common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", Name(), DeploymentNamespace()), }, }, }, metav1.CreateOptions{})) @@ -2630,14 +2603,14 @@ func TestSwitchTrackingMethod(t *testing.T) { When(). And(func() { // Delete resource to bring application back in sync - errors.NewHandler(t).FailOnErr(nil, fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Delete(t.Context(), "other-configmap", metav1.DeleteOptions{})) + FailOnErr(nil, KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Delete(context.Background(), "other-configmap", metav1.DeleteOptions{})) }). Then(). Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). When(). - SetTrackingMethod(string(TrackingMethodLabel)). + SetTrackingMethod(string(argo.TrackingMethodLabel)). Sync(). Then(). Expect(OperationPhaseIs(OperationSucceeded)). @@ -2648,11 +2621,11 @@ func TestSwitchTrackingMethod(t *testing.T) { // Add a resource with a tracking annotation. This should not // affect the application, because we now use the tracking method // "label". - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{ + FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "other-configmap", Annotations: map[string]string{ - common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", fixture.Name(), fixture.DeploymentNamespace()), + common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", Name(), DeploymentNamespace()), }, }, }, metav1.CreateOptions{})) @@ -2665,11 +2638,11 @@ func TestSwitchTrackingMethod(t *testing.T) { And(func() { // Add a resource with the tracking label. The app should become // OutOfSync. - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{ + FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "extra-configmap", Labels: map[string]string{ - common.LabelKeyAppInstance: fixture.Name(), + common.LabelKeyAppInstance: Name(), }, }, }, metav1.CreateOptions{})) @@ -2681,7 +2654,7 @@ func TestSwitchTrackingMethod(t *testing.T) { When(). And(func() { // Delete resource to bring application back in sync - errors.NewHandler(t).FailOnErr(nil, fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Delete(t.Context(), "extra-configmap", metav1.DeleteOptions{})) + FailOnErr(nil, KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Delete(context.Background(), "extra-configmap", metav1.DeleteOptions{})) }). Then(). Expect(OperationPhaseIs(OperationSucceeded)). @@ -2692,7 +2665,6 @@ func TestSwitchTrackingMethod(t *testing.T) { func TestSwitchTrackingLabel(t *testing.T) { ctx := Given(t) - require.NoError(t, fixture.SetTrackingMethod(string(TrackingMethodLabel))) ctx. Path("deployment"). When(). @@ -2707,11 +2679,11 @@ func TestSwitchTrackingLabel(t *testing.T) { And(func() { // Add extra resource that carries the default tracking label // We expect the app to go out of sync. - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{ + FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "other-configmap", Labels: map[string]string{ - common.LabelKeyAppInstance: fixture.Name(), + common.LabelKeyAppInstance: Name(), }, }, }, metav1.CreateOptions{})) @@ -2723,7 +2695,7 @@ func TestSwitchTrackingLabel(t *testing.T) { When(). And(func() { // Delete resource to bring application back in sync - errors.NewHandler(t).FailOnErr(nil, fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Delete(t.Context(), "other-configmap", metav1.DeleteOptions{})) + FailOnErr(nil, KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Delete(context.Background(), "other-configmap", metav1.DeleteOptions{})) }). Then(). Expect(OperationPhaseIs(OperationSucceeded)). @@ -2741,11 +2713,11 @@ func TestSwitchTrackingLabel(t *testing.T) { And(func() { // Create resource with the new tracking label, the application // is expected to go out of sync - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{ + FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "other-configmap", Labels: map[string]string{ - "argocd.tracking": fixture.Name(), + "argocd.tracking": Name(), }, }, }, metav1.CreateOptions{})) @@ -2757,7 +2729,7 @@ func TestSwitchTrackingLabel(t *testing.T) { When(). And(func() { // Delete resource to bring application back in sync - errors.NewHandler(t).FailOnErr(nil, fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Delete(t.Context(), "other-configmap", metav1.DeleteOptions{})) + FailOnErr(nil, KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Delete(context.Background(), "other-configmap", metav1.DeleteOptions{})) }). Then(). Expect(OperationPhaseIs(OperationSucceeded)). @@ -2768,11 +2740,11 @@ func TestSwitchTrackingLabel(t *testing.T) { // Add extra resource that carries the default tracking label // We expect the app to stay in sync, because the configured // label is different. - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{ + FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "other-configmap", Labels: map[string]string{ - common.LabelKeyAppInstance: fixture.Name(), + common.LabelKeyAppInstance: Name(), }, }, }, metav1.CreateOptions{})) @@ -2786,7 +2758,7 @@ func TestSwitchTrackingLabel(t *testing.T) { func TestAnnotationTrackingExtraResources(t *testing.T) { ctx := Given(t) - require.NoError(t, fixture.SetTrackingMethod(string(TrackingMethodAnnotation))) + CheckError(SetTrackingMethod(string(argo.TrackingMethodAnnotation))) ctx. Path("deployment"). When(). @@ -2801,11 +2773,11 @@ func TestAnnotationTrackingExtraResources(t *testing.T) { And(func() { // Add a resource with an annotation that is not referencing the // resource. - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{ + FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "extra-configmap", Annotations: map[string]string{ - common.AnnotationKeyAppInstance: fmt.Sprintf("%s:apps/Deployment:%s/guestbook-cm", fixture.Name(), fixture.DeploymentNamespace()), + common.AnnotationKeyAppInstance: fmt.Sprintf("%s:apps/Deployment:%s/guestbook-cm", Name(), DeploymentNamespace()), }, }, }, metav1.CreateOptions{})) @@ -2819,18 +2791,18 @@ func TestAnnotationTrackingExtraResources(t *testing.T) { Sync("--prune"). And(func() { // The extra configmap must not be pruned, because it's not tracked - cm, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Get(t.Context(), "extra-configmap", metav1.GetOptions{}) + cm, err := KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Get(context.Background(), "extra-configmap", metav1.GetOptions{}) require.NoError(t, err) require.Equal(t, "extra-configmap", cm.Name) }). And(func() { // Add a resource with an annotation that is self-referencing the // resource. - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{ + FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "other-configmap", Annotations: map[string]string{ - common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", fixture.Name(), fixture.DeploymentNamespace()), + common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", Name(), DeploymentNamespace()), }, }, }, metav1.CreateOptions{})) @@ -2844,9 +2816,9 @@ func TestAnnotationTrackingExtraResources(t *testing.T) { Sync("--prune"). And(func() { // The extra configmap must be pruned now, because it's tracked - cm, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Get(t.Context(), "other-configmap", metav1.GetOptions{}) + cm, err := KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Get(context.Background(), "other-configmap", metav1.GetOptions{}) require.Error(t, err) - require.Empty(t, cm.Name) + require.Equal(t, "", cm.Name) }). Then(). Expect(OperationPhaseIs(OperationSucceeded)). @@ -2855,11 +2827,11 @@ func TestAnnotationTrackingExtraResources(t *testing.T) { When(). And(func() { // Add a cluster-scoped resource that is not referencing itself - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.RbacV1().ClusterRoles().Create(t.Context(), &rbacv1.ClusterRole{ + FailOnErr(KubeClientset.RbacV1().ClusterRoles().Create(context.Background(), &rbacv1.ClusterRole{ ObjectMeta: metav1.ObjectMeta{ Name: "e2e-test-clusterrole", Annotations: map[string]string{ - common.AnnotationKeyAppInstance: fmt.Sprintf("%s:rbac.authorization.k8s.io/ClusterRole:%s/e2e-other-clusterrole", fixture.Name(), fixture.DeploymentNamespace()), + common.AnnotationKeyAppInstance: fmt.Sprintf("%s:rbac.authorization.k8s.io/ClusterRole:%s/e2e-other-clusterrole", Name(), DeploymentNamespace()), }, Labels: map[string]string{ fixture.TestingLabel: "true", @@ -2875,11 +2847,11 @@ func TestAnnotationTrackingExtraResources(t *testing.T) { When(). And(func() { // Add a cluster-scoped resource that is referencing itself - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.RbacV1().ClusterRoles().Create(t.Context(), &rbacv1.ClusterRole{ + FailOnErr(KubeClientset.RbacV1().ClusterRoles().Create(context.Background(), &rbacv1.ClusterRole{ ObjectMeta: metav1.ObjectMeta{ Name: "e2e-other-clusterrole", Annotations: map[string]string{ - common.AnnotationKeyAppInstance: fmt.Sprintf("%s:rbac.authorization.k8s.io/ClusterRole:%s/e2e-other-clusterrole", fixture.Name(), fixture.DeploymentNamespace()), + common.AnnotationKeyAppInstance: fmt.Sprintf("%s:rbac.authorization.k8s.io/ClusterRole:%s/e2e-other-clusterrole", Name(), DeploymentNamespace()), }, Labels: map[string]string{ fixture.TestingLabel: "true", @@ -2896,9 +2868,9 @@ func TestAnnotationTrackingExtraResources(t *testing.T) { Sync("--prune"). And(func() { // The extra configmap must be pruned now, because it's tracked and does not exist in git - cr, err := fixture.KubeClientset.RbacV1().ClusterRoles().Get(t.Context(), "e2e-other-clusterrole", metav1.GetOptions{}) + cr, err := KubeClientset.RbacV1().ClusterRoles().Get(context.Background(), "e2e-other-clusterrole", metav1.GetOptions{}) require.Error(t, err) - require.Empty(t, cr.Name) + require.Equal(t, "", cr.Name) }). Then(). Expect(OperationPhaseIs(OperationSucceeded)). @@ -2914,7 +2886,7 @@ func TestCreateConfigMapsAndWaitForUpdate(t *testing.T) { Sync(). Then(). And(func(app *Application) { - _, err := fixture.RunCli("app", "set", app.Name, "--sync-policy", "automated") + _, err := RunCli("app", "set", app.Name, "--sync-policy", "automated") require.NoError(t, err) }). When(). @@ -2943,23 +2915,23 @@ data: Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - Expect(ResourceHealthWithNamespaceIs("ConfigMap", "other-map", fixture.DeploymentNamespace(), health.HealthStatusHealthy)). - Expect(ResourceSyncStatusWithNamespaceIs("ConfigMap", "other-map", fixture.DeploymentNamespace(), SyncStatusCodeSynced)). - Expect(ResourceHealthWithNamespaceIs("ConfigMap", "yet-another-map", fixture.DeploymentNamespace(), health.HealthStatusHealthy)). - Expect(ResourceSyncStatusWithNamespaceIs("ConfigMap", "yet-another-map", fixture.DeploymentNamespace(), SyncStatusCodeSynced)) + Expect(ResourceHealthWithNamespaceIs("ConfigMap", "other-map", DeploymentNamespace(), health.HealthStatusHealthy)). + Expect(ResourceSyncStatusWithNamespaceIs("ConfigMap", "other-map", DeploymentNamespace(), SyncStatusCodeSynced)). + 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(TrackingMethodAnnotation)). + SetTrackingMethod(string(argo.TrackingMethodAnnotation)). And(func() { - _, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create( - t.Context(), &corev1.ConfigMap{ + _, 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(), fixture.DeploymentNamespace()), + common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/test-configmap", ctx.AppName(), DeploymentNamespace()), }, }, }, metav1.CreateOptions{}) @@ -2985,11 +2957,11 @@ func TestInstallationID(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { require.Len(t, app.Status.Resources, 2) - svc, err := fixture.KubeClientset.CoreV1().Services(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + 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(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + 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]) }) @@ -2999,8 +2971,8 @@ func TestDeletionConfirmation(t *testing.T) { ctx := Given(t) ctx. And(func() { - _, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create( - t.Context(), &corev1.ConfigMap{ + _, err := fixture.KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create( + context.Background(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "test-configmap", Labels: map[string]string{ diff --git a/test/e2e/app_multiple_sources_test.go b/test/e2e/app_multiple_sources_test.go index 75d82e25a7..9ed4848fca 100644 --- a/test/e2e/app_multiple_sources_test.go +++ b/test/e2e/app_multiple_sources_test.go @@ -7,10 +7,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - . "github.com/argoproj/argo-cd/v3/util/argo" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + . "github.com/argoproj/argo-cd/v2/util/argo" ) func TestMultiSourceAppCreation(t *testing.T) { @@ -199,7 +199,7 @@ func TestMultiSourceAppWithSourceName(t *testing.T) { assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) }). Expect(Event(EventReasonResourceCreated, "create")). - And(func(_ *Application) { + And(func(app *Application) { // we remove the first source output, err := RunCli("app", "remove-source", Name(), "--source-name", sources[0].Name) require.NoError(t, err) @@ -261,7 +261,7 @@ func TestMultiSourceAppSetWithSourceName(t *testing.T) { assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) }). Expect(Event(EventReasonResourceCreated, "create")). - And(func(_ *Application) { + And(func(app *Application) { _, err := RunCli("app", "set", Name(), "--source-name", sources[1].Name, "--path", "deployment") require.NoError(t, err) }). @@ -288,12 +288,14 @@ func TestMultiSourceApptErrorWhenSourceNameAndSourcePosition(t *testing.T) { CreateMultiSourceAppFromFile(). Then(). Expect(Event(EventReasonResourceCreated, "create")). - And(func(_ *Application) { + And(func(app *Application) { _, err := RunCli("app", "get", Name(), "--source-name", sources[1].Name, "--source-position", "1") - assert.ErrorContains(t, err, "Only one of source-position and source-name can be specified.") + require.Error(t, err) + assert.Contains(t, err.Error(), "Only one of source-position and source-name can be specified.") }). - And(func(_ *Application) { + And(func(app *Application) { _, err := RunCli("app", "manifests", Name(), "--revisions", "0.0.2", "--source-names", sources[0].Name, "--revisions", "0.0.2", "--source-positions", "1") - assert.ErrorContains(t, err, "Only one of source-positions and source-names can be specified.") + require.Error(t, err) + assert.Contains(t, err.Error(), "Only one of source-positions and source-names can be specified.") }) } diff --git a/test/e2e/app_namespaces_test.go b/test/e2e/app_namespaces_test.go index d54eabbbdb..d8195850f7 100644 --- a/test/e2e/app_namespaces_test.go +++ b/test/e2e/app_namespaces_test.go @@ -1,6 +1,7 @@ package e2e import ( + "context" "testing" . "github.com/argoproj/gitops-engine/pkg/sync/common" @@ -9,11 +10,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - . "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/errors" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + . "github.com/argoproj/argo-cd/v2/util/argo" + . "github.com/argoproj/argo-cd/v2/util/errors" ) func TestAppCreationInOtherNamespace(t *testing.T) { @@ -49,7 +50,7 @@ func TestAppCreationInOtherNamespace(t *testing.T) { When(). // ensure that update replaces spec and merge labels and annotations And(func() { - errors.NewHandler(t).FailOnErr(AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).Patch(t.Context(), + FailOnErr(AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).Patch(context.Background(), ctx.AppName(), types.MergePatchType, []byte(`{"metadata": {"labels": { "test": "label" }, "annotations": { "test": "annotation" }}}`), metav1.PatchOptions{})) }). CreateApp("--upsert"). @@ -76,7 +77,7 @@ func TestForbiddenNamespace(t *testing.T) { func TestDeletingNamespacedAppStuckInSync(t *testing.T) { ctx := Given(t) ctx.And(func() { - require.NoError(t, SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "ConfigMap": { HealthLua: `return { status = obj.annotations and obj.annotations['health'] or 'Progressing' }`, }, diff --git a/test/e2e/app_skipreconcile_test.go b/test/e2e/app_skipreconcile_test.go index da6a5243b9..2ea2881275 100644 --- a/test/e2e/app_skipreconcile_test.go +++ b/test/e2e/app_skipreconcile_test.go @@ -3,9 +3,9 @@ package e2e import ( "testing" - "github.com/argoproj/argo-cd/v3/common" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/common" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" ) func TestAppSkipReconcileTrue(t *testing.T) { diff --git a/test/e2e/app_sync_options_test.go b/test/e2e/app_sync_options_test.go index d1c8a620d0..7d0a0ffeab 100644 --- a/test/e2e/app_sync_options_test.go +++ b/test/e2e/app_sync_options_test.go @@ -6,11 +6,11 @@ import ( "github.com/argoproj/gitops-engine/pkg/health" . "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + . "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" ) // Given application is set with --sync-option CreateNamespace=true and --sync-option ServerSideApply=true @@ -48,7 +48,7 @@ func TestNamespaceCreationWithSSA(t *testing.T) { Sync(). Then(). Expect(Success("")). - Expect(Namespace(namespace, func(_ *Application, ns *corev1.Namespace) { + Expect(Namespace(namespace, func(app *Application, ns *v1.Namespace) { assert.NotContains(t, ns.Annotations, "kubectl.kubernetes.io/last-applied-configuration") })). Expect(SyncStatusIs(SyncStatusCodeSynced)). diff --git a/test/e2e/applicationset_git_generator_test.go b/test/e2e/applicationset_git_generator_test.go deleted file mode 100644 index ce10d2d175..0000000000 --- a/test/e2e/applicationset_git_generator_test.go +++ /dev/null @@ -1,1545 +0,0 @@ -package e2e - -import ( - "crypto/rand" - "encoding/hex" - "strings" - "testing" - "time" - - "github.com/redis/go-redis/v9" - "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets/utils" -) - -func randStr(t *testing.T) string { - t.Helper() - bytes := make([]byte, 16) - if _, err := rand.Read(bytes); err != nil { - require.NoError(t, err) - return "" - } - return hex.EncodeToString(bytes) -} - -func TestSimpleGitDirectoryGenerator(t *testing.T) { - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: name, - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: name, - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("kustomize-guestbook"), - generateExpectedApp("helm-guestbook"), - } - - var expectedAppsNewNamespace []v1alpha1.Application - var expectedAppsNewMetadata []v1alpha1.Application - - Given(t). - When(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "{{path}}", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "{{path.basename}}", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - Directories: []v1alpha1.GitDirectoryGeneratorItem{ - { - Path: "*guestbook*", - }, - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsExist(expectedApps)). - - // Update the ApplicationSet template namespace, and verify it updates the Applications - When(). - And(func() { - for _, expectedApp := range expectedApps { - newExpectedApp := expectedApp.DeepCopy() - newExpectedApp.Spec.Destination.Namespace = "guestbook2" - expectedAppsNewNamespace = append(expectedAppsNewNamespace, *newExpectedApp) - } - }). - Update(func(appset *v1alpha1.ApplicationSet) { - appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist(expectedAppsNewNamespace)). - - // Update the metadata fields in the appset template, and make sure it propagates to the apps - When(). - And(func() { - for _, expectedApp := range expectedAppsNewNamespace { - expectedAppNewMetadata := expectedApp.DeepCopy() - expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"} - expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"} - expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata) - } - }). - Update(func(appset *v1alpha1.ApplicationSet) { - appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} - appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} - }).Then().Expect(ApplicationsExist(expectedAppsNewMetadata)). - - // verify the ApplicationSet status conditions were set correctly - Expect(ApplicationSetHasConditions("simple-git-generator", ExpectedConditions)). - - // Delete the ApplicationSet, and verify it deletes the Applications - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) -} - -func TestSimpleGitDirectoryGeneratorGoTemplate(t *testing.T) { - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: name, - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: name, - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("kustomize-guestbook"), - generateExpectedApp("helm-guestbook"), - } - - var expectedAppsNewNamespace []v1alpha1.Application - var expectedAppsNewMetadata []v1alpha1.Application - - Given(t). - When(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator", - }, - Spec: v1alpha1.ApplicationSetSpec{ - GoTemplate: true, - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "{{.path.path}}", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "{{.path.basename}}", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - Directories: []v1alpha1.GitDirectoryGeneratorItem{ - { - Path: "*guestbook*", - }, - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsExist(expectedApps)). - - // Update the ApplicationSet template namespace, and verify it updates the Applications - When(). - And(func() { - for _, expectedApp := range expectedApps { - newExpectedApp := expectedApp.DeepCopy() - newExpectedApp.Spec.Destination.Namespace = "guestbook2" - expectedAppsNewNamespace = append(expectedAppsNewNamespace, *newExpectedApp) - } - }). - Update(func(appset *v1alpha1.ApplicationSet) { - appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist(expectedAppsNewNamespace)). - - // Update the metadata fields in the appset template, and make sure it propagates to the apps - When(). - And(func() { - for _, expectedApp := range expectedAppsNewNamespace { - expectedAppNewMetadata := expectedApp.DeepCopy() - expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"} - expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"} - expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata) - } - }). - Update(func(appset *v1alpha1.ApplicationSet) { - appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} - appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} - }).Then().Expect(ApplicationsExist(expectedAppsNewMetadata)). - - // verify the ApplicationSet status conditions were set correctly - Expect(ApplicationSetHasConditions("simple-git-generator", ExpectedConditions)). - - // Delete the ApplicationSet, and verify it deletes the Applications - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) -} - -func TestSimpleGitDirectoryGeneratorGPGEnabledUnsignedCommits(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") - expectedErrorMessage := `error generating params from git: error getting directories from repo: error retrieving Git Directories: rpc error: code = Unknown desc = permission denied` - expectedConditionsParamsError := []v1alpha1.ApplicationSetCondition{ - { - Type: v1alpha1.ApplicationSetConditionErrorOccurred, - Status: v1alpha1.ApplicationSetConditionStatusTrue, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, - }, - { - Type: v1alpha1.ApplicationSetConditionParametersGenerated, - Status: v1alpha1.ApplicationSetConditionStatusFalse, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonErrorOccurred, - }, - { - Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, - Status: v1alpha1.ApplicationSetConditionStatusFalse, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, - }, - } - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: name, - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: name, - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("guestbook"), - } - project := "gpg" - - Given(t). - Project(project). - When(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ - Project: project, - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "{{path}}", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "{{path.basename}}", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - Directories: []v1alpha1.GitDirectoryGeneratorItem{ - { - Path: guestbookPath, - }, - }, - }, - }, - }, - }, - }). - Then().Expect(ApplicationsDoNotExist(expectedApps)). - // verify the ApplicationSet error status conditions were set correctly - Expect(ApplicationSetHasConditions("simple-git-generator", expectedConditionsParamsError)). - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedApps)) -} - -func TestSimpleGitDirectoryGeneratorGPGEnabledWithoutKnownKeys(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") - expectedErrorMessage := `error generating params from git: error getting directories from repo: error retrieving Git Directories: rpc error: code = Unknown desc = permission denied` - expectedConditionsParamsError := []v1alpha1.ApplicationSetCondition{ - { - Type: v1alpha1.ApplicationSetConditionErrorOccurred, - Status: v1alpha1.ApplicationSetConditionStatusTrue, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, - }, - { - Type: v1alpha1.ApplicationSetConditionParametersGenerated, - Status: v1alpha1.ApplicationSetConditionStatusFalse, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonErrorOccurred, - }, - { - Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, - Status: v1alpha1.ApplicationSetConditionStatusFalse, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, - }, - } - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: name, - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: name, - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("guestbook"), - } - - project := "gpg" - - Given(t). - Project(project). - Path(guestbookPath). - When(). - AddSignedFile("test.yaml", randStr(t)).IgnoreErrors(). - IgnoreErrors(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ - Project: project, - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "{{path}}", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "{{path.basename}}", - }, - // Automatically create resources - SyncPolicy: &v1alpha1.SyncPolicy{ - Automated: &v1alpha1.SyncPolicyAutomated{}, - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - Directories: []v1alpha1.GitDirectoryGeneratorItem{ - { - Path: guestbookPath, - }, - }, - }, - }, - }, - }, - }).Then(). - // verify the ApplicationSet error status conditions were set correctly - Expect(ApplicationSetHasConditions("simple-git-generator", expectedConditionsParamsError)). - Expect(ApplicationsDoNotExist(expectedApps)). - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedApps)) -} - -func TestSimpleGitFilesGenerator(t *testing.T) { - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "guestbook", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "guestbook", - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("engineering-dev-guestbook"), - generateExpectedApp("engineering-prod-guestbook"), - } - - var expectedAppsNewNamespace []v1alpha1.Application - var expectedAppsNewMetadata []v1alpha1.Application - - Given(t). - When(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "guestbook", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "guestbook", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: "https://github.com/argoproj/applicationset.git", - Files: []v1alpha1.GitFileGeneratorItem{ - { - Path: "examples/git-generator-files-discovery/cluster-config/**/config.json", - }, - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsExist(expectedApps)). - - // Update the ApplicationSet template namespace, and verify it updates the Applications - When(). - And(func() { - for _, expectedApp := range expectedApps { - newExpectedApp := expectedApp.DeepCopy() - newExpectedApp.Spec.Destination.Namespace = "guestbook2" - expectedAppsNewNamespace = append(expectedAppsNewNamespace, *newExpectedApp) - } - }). - Update(func(appset *v1alpha1.ApplicationSet) { - appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist(expectedAppsNewNamespace)). - - // Update the metadata fields in the appset template, and make sure it propagates to the apps - When(). - And(func() { - for _, expectedApp := range expectedAppsNewNamespace { - expectedAppNewMetadata := expectedApp.DeepCopy() - expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"} - expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"} - expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata) - } - }). - Update(func(appset *v1alpha1.ApplicationSet) { - appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} - appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} - }).Then().Expect(ApplicationsExist(expectedAppsNewMetadata)). - - // verify the ApplicationSet status conditions were set correctly - Expect(ApplicationSetHasConditions("simple-git-generator", ExpectedConditions)). - - // Delete the ApplicationSet, and verify it deletes the Applications - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) -} - -func TestSimpleGitFilesGeneratorGPGEnabledUnsignedCommits(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") - expectedErrorMessage := `error generating params from git: error retrieving Git files: rpc error: code = Unknown desc = permission denied` - expectedConditionsParamsError := []v1alpha1.ApplicationSetCondition{ - { - Type: v1alpha1.ApplicationSetConditionErrorOccurred, - Status: v1alpha1.ApplicationSetConditionStatusTrue, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, - }, - { - Type: v1alpha1.ApplicationSetConditionParametersGenerated, - Status: v1alpha1.ApplicationSetConditionStatusFalse, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonErrorOccurred, - }, - { - Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, - Status: v1alpha1.ApplicationSetConditionStatusFalse, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, - }, - } - project := "gpg" - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: project, - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "guestbook", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "guestbook", - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("engineering-dev-guestbook"), - generateExpectedApp("engineering-prod-guestbook"), - } - - Given(t). - Project(project). - When(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ - Project: project, - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "guestbook", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "guestbook", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: "https://github.com/argoproj/applicationset.git", - Files: []v1alpha1.GitFileGeneratorItem{ - { - Path: "examples/git-generator-files-discovery/cluster-config/**/config.json", - }, - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsDoNotExist(expectedApps)). - // verify the ApplicationSet error status conditions were set correctly - Expect(ApplicationSetHasConditions("simple-git-generator", expectedConditionsParamsError)). - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedApps)) -} - -func TestSimpleGitFilesGeneratorGPGEnabledWithoutKnownKeys(t *testing.T) { - fixture.SkipOnEnv(t, "GPG") - expectedErrorMessage := `error generating params from git: error retrieving Git files: rpc error: code = Unknown desc = permission denied` - expectedConditionsParamsError := []v1alpha1.ApplicationSetCondition{ - { - Type: v1alpha1.ApplicationSetConditionErrorOccurred, - Status: v1alpha1.ApplicationSetConditionStatusTrue, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, - }, - { - Type: v1alpha1.ApplicationSetConditionParametersGenerated, - Status: v1alpha1.ApplicationSetConditionStatusFalse, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonErrorOccurred, - }, - { - Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, - Status: v1alpha1.ApplicationSetConditionStatusFalse, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, - }, - } - project := "gpg" - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: project, - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "guestbook", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "guestbook", - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("engineering-dev-guestbook"), - generateExpectedApp("engineering-prod-guestbook"), - } - - Given(t). - Project(project). - Path(guestbookPath). - When(). - AddSignedFile("test.yaml", randStr(t)).IgnoreErrors(). - IgnoreErrors(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ - Project: project, - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "guestbook", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "guestbook", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: "https://github.com/argoproj/applicationset.git", - Files: []v1alpha1.GitFileGeneratorItem{ - { - Path: "examples/git-generator-files-discovery/cluster-config/**/config.json", - }, - }, - }, - }, - }, - }, - }).Then(). - // verify the ApplicationSet error status conditions were set correctly - Expect(ApplicationSetHasConditions("simple-git-generator", expectedConditionsParamsError)). - Expect(ApplicationsDoNotExist(expectedApps)). - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedApps)) -} - -func TestSimpleGitFilesGeneratorGoTemplate(t *testing.T) { - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "guestbook", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "guestbook", - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("engineering-dev-guestbook"), - generateExpectedApp("engineering-prod-guestbook"), - } - - var expectedAppsNewNamespace []v1alpha1.Application - var expectedAppsNewMetadata []v1alpha1.Application - - Given(t). - When(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator", - }, - Spec: v1alpha1.ApplicationSetSpec{ - GoTemplate: true, - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster.name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "guestbook", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "guestbook", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: "https://github.com/argoproj/applicationset.git", - Files: []v1alpha1.GitFileGeneratorItem{ - { - Path: "examples/git-generator-files-discovery/cluster-config/**/config.json", - }, - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsExist(expectedApps)). - - // Update the ApplicationSet template namespace, and verify it updates the Applications - When(). - And(func() { - for _, expectedApp := range expectedApps { - newExpectedApp := expectedApp.DeepCopy() - newExpectedApp.Spec.Destination.Namespace = "guestbook2" - expectedAppsNewNamespace = append(expectedAppsNewNamespace, *newExpectedApp) - } - }). - Update(func(appset *v1alpha1.ApplicationSet) { - appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist(expectedAppsNewNamespace)). - - // Update the metadata fields in the appset template, and make sure it propagates to the apps - When(). - And(func() { - for _, expectedApp := range expectedAppsNewNamespace { - expectedAppNewMetadata := expectedApp.DeepCopy() - expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"} - expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"} - expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata) - } - }). - Update(func(appset *v1alpha1.ApplicationSet) { - appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} - appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} - }).Then().Expect(ApplicationsExist(expectedAppsNewMetadata)). - - // verify the ApplicationSet status conditions were set correctly - Expect(ApplicationSetHasConditions("simple-git-generator", ExpectedConditions)). - - // Delete the ApplicationSet, and verify it deletes the Applications - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) -} - -func TestSimpleGitFilesPreserveResourcesOnDeletion(t *testing.T) { - Given(t). - When(). - CreateNamespace(utils.ApplicationsResourcesNamespace). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "guestbook", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: utils.ApplicationsResourcesNamespace, - }, - - // Automatically create resources - SyncPolicy: &v1alpha1.SyncPolicy{ - Automated: &v1alpha1.SyncPolicyAutomated{}, - }, - }, - }, - SyncPolicy: &v1alpha1.ApplicationSetSyncPolicy{ - PreserveResourcesOnDeletion: true, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: "https://github.com/argoproj/applicationset.git", - Files: []v1alpha1.GitFileGeneratorItem{ - { - Path: "examples/git-generator-files-discovery/cluster-config/**/config.json", - }, - }, - }, - }, - }, - }, - // We use an extra-long duration here, as we might need to wait for image pull. - }).Then().ExpectWithDuration(Pod(t, func(p corev1.Pod) bool { return strings.Contains(p.Name, "guestbook-ui") }), 6*time.Minute). - When(). - Delete(). - And(func() { - t.Log("Waiting 15 seconds to give the cluster a chance to delete the pods.") - // Wait 15 seconds to give the cluster a chance to deletes the pods, if it is going to do so. - // It should NOT delete the pods; to do so would be an ApplicationSet bug, and - // that is what we are testing here. - time.Sleep(15 * time.Second) - // The pod should continue to exist after 15 seconds. - }).Then().Expect(Pod(t, func(p corev1.Pod) bool { return strings.Contains(p.Name, "guestbook-ui") })) -} - -func TestSimpleGitFilesPreserveResourcesOnDeletionGoTemplate(t *testing.T) { - Given(t). - When(). - CreateNamespace(utils.ApplicationsResourcesNamespace). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator", - }, - Spec: v1alpha1.ApplicationSetSpec{ - GoTemplate: true, - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster.name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://github.com/argoproj/argocd-example-apps.git", - TargetRevision: "HEAD", - Path: "guestbook", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: utils.ApplicationsResourcesNamespace, - }, - - // Automatically create resources - SyncPolicy: &v1alpha1.SyncPolicy{ - Automated: &v1alpha1.SyncPolicyAutomated{}, - }, - }, - }, - SyncPolicy: &v1alpha1.ApplicationSetSyncPolicy{ - PreserveResourcesOnDeletion: true, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: "https://github.com/argoproj/applicationset.git", - Files: []v1alpha1.GitFileGeneratorItem{ - { - Path: "examples/git-generator-files-discovery/cluster-config/**/config.json", - }, - }, - }, - }, - }, - }, - // We use an extra-long duration here, as we might need to wait for image pull. - }).Then().ExpectWithDuration(Pod(t, func(p corev1.Pod) bool { return strings.Contains(p.Name, "guestbook-ui") }), 6*time.Minute). - When(). - Delete(). - And(func() { - t.Log("Waiting 15 seconds to give the cluster a chance to delete the pods.") - // Wait 15 seconds to give the cluster a chance to deletes the pods, if it is going to do so. - // It should NOT delete the pods; to do so would be an ApplicationSet bug, and - // that is what we are testing here. - time.Sleep(15 * time.Second) - // The pod should continue to exist after 15 seconds. - }).Then().Expect(Pod(t, func(p corev1.Pod) bool { return strings.Contains(p.Name, "guestbook-ui") })) -} - -func TestGitGeneratorPrivateRepo(t *testing.T) { - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: name, - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: name, - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("https-kustomize-base"), - } - - var expectedAppsNewNamespace []v1alpha1.Application - - Given(t). - HTTPSInsecureRepoURLAdded(""). - When(). - // Create a GitGenerator-based ApplicationSet - - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator-private", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: "{{path}}", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "{{path.basename}}", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - Directories: []v1alpha1.GitDirectoryGeneratorItem{ - { - Path: "*kustomize*", - }, - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsExist(expectedApps)). - // Delete the ApplicationSet, and verify it deletes the Applications - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) -} - -func TestGitGeneratorPrivateRepoGoTemplate(t *testing.T) { - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: name, - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: name, - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("https-kustomize-base"), - } - - var expectedAppsNewNamespace []v1alpha1.Application - - Given(t). - HTTPSInsecureRepoURLAdded(""). - When(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator-private", - }, - Spec: v1alpha1.ApplicationSetSpec{ - GoTemplate: true, - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: "{{.path.path}}", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "{{.path.basename}}", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - Directories: []v1alpha1.GitDirectoryGeneratorItem{ - { - Path: "*kustomize*", - }, - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsExist(expectedApps)). - // Delete the ApplicationSet, and verify it deletes the Applications - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) -} - -func TestSimpleGitGeneratorPrivateRepoWithNoRepo(t *testing.T) { - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: name, - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: name, - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("https-kustomize-base"), - } - - var expectedAppsNewNamespace []v1alpha1.Application - - Given(t). - When(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator-private", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: "{{path}}", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "{{path.basename}}", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - Directories: []v1alpha1.GitDirectoryGeneratorItem{ - { - Path: "*kustomize*", - }, - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsDoNotExist(expectedApps)). - // Delete the ApplicationSet, and verify it deletes the Applications - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) -} - -func TestSimpleGitGeneratorPrivateRepoWithMatchingProject(t *testing.T) { - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: name, - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: name, - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("https-kustomize-base"), - } - - var expectedAppsNewNamespace []v1alpha1.Application - - Given(t). - HTTPSInsecureRepoURLAdded("default"). - When(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator-private", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: "{{path}}", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "{{path.basename}}", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - Directories: []v1alpha1.GitDirectoryGeneratorItem{ - { - Path: "*kustomize*", - }, - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsExist(expectedApps)). - // Delete the ApplicationSet, and verify it deletes the Applications - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) -} - -func TestSimpleGitGeneratorPrivateRepoWithMismatchingProject(t *testing.T) { - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: name, - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: name, - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("https-kustomize-base"), - } - - var expectedAppsNewNamespace []v1alpha1.Application - - Given(t). - HTTPSInsecureRepoURLAdded("some-other-project"). - When(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator-private", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: "{{path}}", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "{{path.basename}}", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - Directories: []v1alpha1.GitDirectoryGeneratorItem{ - { - Path: "*kustomize*", - }, - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsDoNotExist(expectedApps)). - // Delete the ApplicationSet, and verify it deletes the Applications - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) -} - -func TestGitGeneratorPrivateRepoWithTemplatedProject(t *testing.T) { - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: name, - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: name, - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("https-kustomize-base"), - } - - var expectedAppsNewNamespace []v1alpha1.Application - - Given(t). - HTTPSInsecureRepoURLAdded(""). - When(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator-private", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "{{values.project}}", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: "{{path}}", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "{{path.basename}}", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - Directories: []v1alpha1.GitDirectoryGeneratorItem{ - { - Path: "*kustomize*", - }, - }, - Values: map[string]string{ - "project": "default", - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsExist(expectedApps)). - // Delete the ApplicationSet, and verify it deletes the Applications - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) -} - -func TestGitGeneratorPrivateRepoWithTemplatedProjectAndProjectScopedRepo(t *testing.T) { - // Flush repo-server cache. Why? We want to ensure that the previous test has not already populated the repo-server - // cache. - r := redis.NewClient(&redis.Options{ - Addr: "localhost:6379", - }) - all := r.FlushAll(t.Context()) - require.NoError(t, all.Err()) - - generateExpectedApp := func(name string) v1alpha1.Application { - return v1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: fixture.TestNamespace(), - Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, - }, - Spec: v1alpha1.ApplicationSpec{ - Project: "default", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: name, - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: name, - }, - }, - } - } - - expectedApps := []v1alpha1.Application{ - generateExpectedApp("https-kustomize-base"), - } - - var expectedAppsNewNamespace []v1alpha1.Application - - Given(t). - HTTPSInsecureRepoURLAdded("default"). - When(). - // Create a GitGenerator-based ApplicationSet - Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-git-generator-private", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ - Project: "{{values.project}}", - Source: &v1alpha1.ApplicationSource{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - TargetRevision: "HEAD", - Path: "{{path}}", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "{{path.basename}}", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - Git: &v1alpha1.GitGenerator{ - RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), - Directories: []v1alpha1.GitDirectoryGeneratorItem{ - { - Path: "*kustomize*", - }, - }, - Values: map[string]string{ - "project": "default", - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsDoNotExist(expectedApps)). - // Delete the ApplicationSet, and verify it deletes the Applications - When(). - Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) -} diff --git a/test/e2e/applicationset_test.go b/test/e2e/applicationset_test.go index f9d3aace48..8289f7dd47 100644 --- a/test/e2e/applicationset_test.go +++ b/test/e2e/applicationset_test.go @@ -1,12 +1,15 @@ package e2e import ( + "context" "fmt" "io" "net" "net/http" "net/http/httptest" + "strings" "testing" + "time" "github.com/google/uuid" @@ -15,17 +18,21 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "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" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets/utils" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" + . "github.com/argoproj/argo-cd/v2/util/errors" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) var ExpectedConditions = []v1alpha1.ApplicationSetCondition{ @@ -52,7 +59,7 @@ var ExpectedConditions = []v1alpha1.ApplicationSetCondition{ func TestSimpleListGeneratorExternalNamespace(t *testing.T) { externalNamespace := string(utils.ArgoCDExternalNamespace) - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", APIVersion: "argoproj.io/v1alpha1", @@ -62,21 +69,21 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) { Namespace: externalNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, }, } - var expectedAppNewNamespace *v1alpha1.Application - var expectedAppNewMetadata *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application Given(t). // Create a ListGenerator-based ApplicationSet @@ -91,14 +98,14 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) { GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{.url}}", Namespace: "guestbook", }, @@ -114,7 +121,7 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). @@ -124,7 +131,7 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the metadata fields in the appset template, and make sure it propagates to the apps When(). @@ -140,21 +147,21 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) { appset.Spec.Template.Labels = map[string]string{ "label-key": "label-value", } - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). // verify the ApplicationSet status conditions were set correctly Expect(ApplicationSetHasConditions("simple-list-generator-external", ExpectedConditions)). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewMetadata})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewMetadata})) } func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) { externalNamespace := string(utils.ArgoCDExternalNamespace) externalNamespace2 := string(utils.ArgoCDExternalNamespace2) - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", APIVersion: "argoproj.io/v1alpha1", @@ -164,21 +171,21 @@ func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) { Namespace: externalNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, }, } - expectedAppExternalNamespace2 := v1alpha1.Application{ + expectedAppExternalNamespace2 := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", APIVersion: "argoproj.io/v1alpha1", @@ -188,22 +195,22 @@ func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) { Namespace: externalNamespace2, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, }, } - var expectedAppNewNamespace *v1alpha1.Application - var expectedAppNewMetadata *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application Given(t). // Create a ListGenerator-based ApplicationSet @@ -218,14 +225,14 @@ func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) { GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{.url}}", Namespace: "guestbook", }, @@ -241,7 +248,7 @@ func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppExternalNamespace2})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). When(). SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). CreateNamespace(externalNamespace).Create(v1alpha1.ApplicationSet{ @@ -253,14 +260,14 @@ func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) { GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{.url}}", Namespace: "guestbook", }, @@ -276,11 +283,11 @@ func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). When(). SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). Then(). - Expect(ApplicationsExist([]v1alpha1.Application{expectedAppExternalNamespace2})). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). When(). SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). Then(). @@ -292,11 +299,11 @@ func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). When(). SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). Then(). - Expect(ApplicationsExist([]v1alpha1.Application{expectedAppExternalNamespace2})). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). When(). SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). Then(). @@ -314,30 +321,30 @@ func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) { appset.Spec.Template.Labels = map[string]string{ "label-key": "label-value", } - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). // verify the ApplicationSet status conditions were set correctly Expect(ApplicationSetHasConditions("simple-list-generator-external", ExpectedConditions)). When(). SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). Then(). - Expect(ApplicationsExist([]v1alpha1.Application{expectedAppExternalNamespace2})). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). When(). SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). Then(). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewMetadata})). + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewMetadata})). When(). SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). Then(). - Expect(ApplicationsExist([]v1alpha1.Application{expectedAppExternalNamespace2})). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppExternalNamespace2})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppExternalNamespace2})) } func TestSimpleListGenerator(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -347,21 +354,21 @@ func TestSimpleListGenerator(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, }, } - var expectedAppNewNamespace *v1alpha1.Application - var expectedAppNewMetadata *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application Given(t). // Create a ListGenerator-based ApplicationSet @@ -372,14 +379,14 @@ func TestSimpleListGenerator(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{url}}", Namespace: "guestbook", }, @@ -395,7 +402,7 @@ func TestSimpleListGenerator(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). @@ -405,7 +412,7 @@ func TestSimpleListGenerator(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the metadata fields in the appset template, and make sure it propagates to the apps When(). @@ -417,18 +424,18 @@ func TestSimpleListGenerator(t *testing.T) { Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). // verify the ApplicationSet status conditions were set correctly Expect(ApplicationSetHasConditions("simple-list-generator", ExpectedConditions)). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewMetadata})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewMetadata})) } func TestSimpleListGeneratorGoTemplate(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -438,21 +445,21 @@ func TestSimpleListGeneratorGoTemplate(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, }, } - var expectedAppNewNamespace *v1alpha1.Application - var expectedAppNewMetadata *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application Given(t). // Create a ListGenerator-based ApplicationSet @@ -464,14 +471,14 @@ func TestSimpleListGeneratorGoTemplate(t *testing.T) { GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{.url}}", Namespace: "guestbook", }, @@ -487,7 +494,7 @@ func TestSimpleListGeneratorGoTemplate(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). @@ -497,7 +504,7 @@ func TestSimpleListGeneratorGoTemplate(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the metadata fields in the appset template, and make sure it propagates to the apps When(). @@ -509,18 +516,18 @@ func TestSimpleListGeneratorGoTemplate(t *testing.T) { Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). // verify the ApplicationSet status conditions were set correctly Expect(ApplicationSetHasConditions("simple-list-generator", ExpectedConditions)). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewMetadata})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewMetadata})) } func TestRenderHelmValuesObject(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -530,20 +537,20 @@ func TestRenderHelmValuesObject(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "helm-guestbook", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argov1alpha1.ApplicationSourceHelm{ ValuesObject: &runtime.RawExtension{ // This will always be converted as yaml Raw: []byte(`{"some":{"string":"Hello world"}}`), }, }, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -560,19 +567,19 @@ func TestRenderHelmValuesObject(t *testing.T) { GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "helm-guestbook", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argov1alpha1.ApplicationSourceHelm{ ValuesObject: &runtime.RawExtension{ Raw: []byte(`{"some":{"string":"{{.test}}"}}`), }, }, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{.url}}", Namespace: "guestbook", }, @@ -588,14 +595,14 @@ func TestRenderHelmValuesObject(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedApp})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedApp})) } func TestTemplatePatch(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -608,19 +615,19 @@ func TestTemplatePatch(t *testing.T) { "annotation-some-key": "annotation-some-value", }, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, - SyncPolicy: &v1alpha1.SyncPolicy{ - SyncOptions: v1alpha1.SyncOptions{"CreateNamespace=true"}, + SyncPolicy: &argov1alpha1.SyncPolicy{ + SyncOptions: argov1alpha1.SyncOptions{"CreateNamespace=true"}, }, }, } @@ -645,8 +652,8 @@ func TestTemplatePatch(t *testing.T) { } ` - var expectedAppNewNamespace *v1alpha1.Application - var expectedAppNewMetadata *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application Given(t). // Create a ListGenerator-based ApplicationSet @@ -658,14 +665,14 @@ func TestTemplatePatch(t *testing.T) { GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{.url}}", Namespace: "guestbook", }, @@ -689,7 +696,7 @@ func TestTemplatePatch(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). @@ -699,7 +706,7 @@ func TestTemplatePatch(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the metadata fields in the appset template, and make sure it propagates to the apps When(). @@ -711,18 +718,18 @@ func TestTemplatePatch(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). // verify the ApplicationSet status conditions were set correctly Expect(ApplicationSetHasConditions("patch-template", ExpectedConditions)). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewMetadata})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewMetadata})) } func TestUpdateHelmValuesObject(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -732,20 +739,20 @@ func TestUpdateHelmValuesObject(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "helm-guestbook", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argov1alpha1.ApplicationSourceHelm{ ValuesObject: &runtime.RawExtension{ // This will always be converted as yaml Raw: []byte(`{"some":{"foo":"bar"}}`), }, }, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -762,19 +769,19 @@ func TestUpdateHelmValuesObject(t *testing.T) { GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "helm-guestbook", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argov1alpha1.ApplicationSourceHelm{ ValuesObject: &runtime.RawExtension{ Raw: []byte(`{"some":{"string":"{{.test}}"}}`), }, }, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{.url}}", Namespace: "guestbook", }, @@ -794,20 +801,20 @@ func TestUpdateHelmValuesObject(t *testing.T) { Expect(ApplicationSetHasConditions("test-values-object-patch", ExpectedConditions)). When(). // Update the app spec with some knew ValuesObject to force a merge - Update(func(as *v1alpha1.ApplicationSet) { + Update(func(as *argov1alpha1.ApplicationSet) { as.Spec.Template.Spec.Source.Helm.ValuesObject = &runtime.RawExtension{ Raw: []byte(`{"some":{"foo":"bar"}}`), } }). Then(). - Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). When(). // Delete the ApplicationSet, and verify it deletes the Applications - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedApp})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedApp})) } func TestSyncPolicyCreateUpdate(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", APIVersion: "argoproj.io/v1alpha1", @@ -817,21 +824,21 @@ func TestSyncPolicyCreateUpdate(t *testing.T) { Namespace: utils.ArgoCDNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, }, } - var expectedAppNewNamespace *v1alpha1.Application - var expectedAppNewMetadata *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application Given(t). // Create a ListGenerator-based ApplicationSet @@ -846,14 +853,14 @@ func TestSyncPolicyCreateUpdate(t *testing.T) { Name: "{{.cluster}}-guestbook-sync-policy-create-update", Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{.url}}", Namespace: "guestbook", }, @@ -869,7 +876,7 @@ func TestSyncPolicyCreateUpdate(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). @@ -879,7 +886,7 @@ func TestSyncPolicyCreateUpdate(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the metadata fields in the appset template // Update as well the policy @@ -897,18 +904,18 @@ func TestSyncPolicyCreateUpdate(t *testing.T) { appset.Spec.Template.Labels = map[string]string{ "label-key": "label-value", } - applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicyCreateUpdate - appset.Spec.SyncPolicy = &v1alpha1.ApplicationSetSyncPolicy{ + applicationsSyncPolicy := argov1alpha1.ApplicationsSyncPolicyCreateUpdate + appset.Spec.SyncPolicy = &argov1alpha1.ApplicationSetSyncPolicy{ ApplicationsSync: &applicationsSyncPolicy, } - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). // Update the list and remove element // As policy is create-update, app deletion must not be reflected When(). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Generators = []v1alpha1.ApplicationSetGenerator{} - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). // verify the ApplicationSet status conditions were set correctly Expect(ApplicationSetHasConditions("sync-policy-create-update", ExpectedConditions)). @@ -917,11 +924,11 @@ func TestSyncPolicyCreateUpdate(t *testing.T) { // As policy is create-update, AppSet controller will remove all generated applications's ownerReferences on delete AppSet // So AppSet deletion will be reflected, but all the applications it generates will still exist When(). - Delete().Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})) + Delete().Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})) } func TestSyncPolicyCreateDelete(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", APIVersion: "argoproj.io/v1alpha1", @@ -931,20 +938,20 @@ func TestSyncPolicyCreateDelete(t *testing.T) { Namespace: utils.ArgoCDNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, }, } - var expectedAppNewNamespace *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application Given(t). // Create a ListGenerator-based ApplicationSet @@ -956,14 +963,14 @@ func TestSyncPolicyCreateDelete(t *testing.T) { GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook-sync-policy-create-delete"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{.url}}", Namespace: "guestbook", }, @@ -979,7 +986,7 @@ func TestSyncPolicyCreateDelete(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). @@ -989,7 +996,7 @@ func TestSyncPolicyCreateDelete(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the metadata fields in the appset template // Update as well the policy @@ -998,29 +1005,29 @@ func TestSyncPolicyCreateDelete(t *testing.T) { Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} - applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicyCreateDelete - appset.Spec.SyncPolicy = &v1alpha1.ApplicationSetSyncPolicy{ + applicationsSyncPolicy := argov1alpha1.ApplicationsSyncPolicyCreateDelete + appset.Spec.SyncPolicy = &argov1alpha1.ApplicationSetSyncPolicy{ ApplicationsSync: &applicationsSyncPolicy, } - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the list and remove element // As policy is create-delete, app deletion must be reflected When(). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Generators = []v1alpha1.ApplicationSetGenerator{} - }).Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // verify the ApplicationSet status conditions were set correctly Expect(ApplicationSetHasConditions("sync-policy-create-delete", ExpectedConditions)). // Delete the ApplicationSet When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewNamespace})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewNamespace})) } func TestSyncPolicyCreateOnly(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", APIVersion: "argoproj.io/v1alpha1", @@ -1030,20 +1037,20 @@ func TestSyncPolicyCreateOnly(t *testing.T) { Namespace: utils.ArgoCDNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, }, } - var expectedAppNewNamespace *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application Given(t). // Create a ListGenerator-based ApplicationSet @@ -1058,14 +1065,14 @@ func TestSyncPolicyCreateOnly(t *testing.T) { Name: "{{.cluster}}-guestbook-sync-policy-create-only", Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{.url}}", Namespace: "guestbook", }, @@ -1081,7 +1088,7 @@ func TestSyncPolicyCreateOnly(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). @@ -1091,7 +1098,7 @@ func TestSyncPolicyCreateOnly(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the metadata fields in the appset template // Update as well the policy @@ -1100,18 +1107,18 @@ func TestSyncPolicyCreateOnly(t *testing.T) { Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} - applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicyCreateOnly - appset.Spec.SyncPolicy = &v1alpha1.ApplicationSetSyncPolicy{ + applicationsSyncPolicy := argov1alpha1.ApplicationsSyncPolicyCreateOnly + appset.Spec.SyncPolicy = &argov1alpha1.ApplicationSetSyncPolicy{ ApplicationsSync: &applicationsSyncPolicy, } - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the list and remove element // As policy is create-only, app deletion must not be reflected When(). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Generators = []v1alpha1.ApplicationSetGenerator{} - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // verify the ApplicationSet status conditions were set correctly Expect(ApplicationSetHasConditions("sync-policy-create-only", ExpectedConditions)). @@ -1120,7 +1127,978 @@ func TestSyncPolicyCreateOnly(t *testing.T) { // As policy is create-update, AppSet controller will remove all generated applications's ownerReferences on delete AppSet // So AppSet deletion will be reflected, but all the applications it generates will still exist When(). - Delete().Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})) + Delete().Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})) +} + +func TestSimpleGitDirectoryGenerator(t *testing.T) { + generateExpectedApp := func(name string) argov1alpha1.Application { + return argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + 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: name, + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: name, + }, + }, + } + } + + expectedApps := []argov1alpha1.Application{ + generateExpectedApp("kustomize-guestbook"), + generateExpectedApp("helm-guestbook"), + } + + var expectedAppsNewNamespace []argov1alpha1.Application + var expectedAppsNewMetadata []argov1alpha1.Application + + Given(t). + When(). + // Create a GitGenerator-based ApplicationSet + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-git-generator", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "{{path}}", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "{{path.basename}}", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Git: &v1alpha1.GitGenerator{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + Directories: []v1alpha1.GitDirectoryGeneratorItem{ + { + Path: "*guestbook*", + }, + }, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist(expectedApps)). + + // Update the ApplicationSet template namespace, and verify it updates the Applications + When(). + And(func() { + for _, expectedApp := range expectedApps { + newExpectedApp := expectedApp.DeepCopy() + newExpectedApp.Spec.Destination.Namespace = "guestbook2" + expectedAppsNewNamespace = append(expectedAppsNewNamespace, *newExpectedApp) + } + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" + }).Then().Expect(ApplicationsExist(expectedAppsNewNamespace)). + + // Update the metadata fields in the appset template, and make sure it propagates to the apps + When(). + And(func() { + for _, expectedApp := range expectedAppsNewNamespace { + expectedAppNewMetadata := expectedApp.DeepCopy() + expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"} + expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"} + expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata) + } + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} + appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} + }).Then().Expect(ApplicationsExist(expectedAppsNewMetadata)). + + // verify the ApplicationSet status conditions were set correctly + Expect(ApplicationSetHasConditions("simple-git-generator", ExpectedConditions)). + + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) +} + +func TestSimpleGitDirectoryGeneratorGoTemplate(t *testing.T) { + generateExpectedApp := func(name string) argov1alpha1.Application { + return argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + 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: name, + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: name, + }, + }, + } + } + + expectedApps := []argov1alpha1.Application{ + generateExpectedApp("kustomize-guestbook"), + generateExpectedApp("helm-guestbook"), + } + + var expectedAppsNewNamespace []argov1alpha1.Application + var expectedAppsNewMetadata []argov1alpha1.Application + + Given(t). + When(). + // Create a GitGenerator-based ApplicationSet + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-git-generator", + }, + Spec: v1alpha1.ApplicationSetSpec{ + GoTemplate: true, + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.path.basename}}"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "{{.path.path}}", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "{{.path.basename}}", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Git: &v1alpha1.GitGenerator{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + Directories: []v1alpha1.GitDirectoryGeneratorItem{ + { + Path: "*guestbook*", + }, + }, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist(expectedApps)). + + // Update the ApplicationSet template namespace, and verify it updates the Applications + When(). + And(func() { + for _, expectedApp := range expectedApps { + newExpectedApp := expectedApp.DeepCopy() + newExpectedApp.Spec.Destination.Namespace = "guestbook2" + expectedAppsNewNamespace = append(expectedAppsNewNamespace, *newExpectedApp) + } + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" + }).Then().Expect(ApplicationsExist(expectedAppsNewNamespace)). + + // Update the metadata fields in the appset template, and make sure it propagates to the apps + When(). + And(func() { + for _, expectedApp := range expectedAppsNewNamespace { + expectedAppNewMetadata := expectedApp.DeepCopy() + expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"} + expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"} + expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata) + } + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} + appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} + }).Then().Expect(ApplicationsExist(expectedAppsNewMetadata)). + + // verify the ApplicationSet status conditions were set correctly + Expect(ApplicationSetHasConditions("simple-git-generator", ExpectedConditions)). + + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) +} + +func TestSimpleGitDirectoryGeneratorGPGEnabledUnsignedCommits(t *testing.T) { + fixture.SkipOnEnv(t, "GPG") + expectedErrorMessage := `error generating params from git: error getting directories from repo: error retrieving Git Directories: rpc error: code = Unknown desc = permission denied` + expectedConditionsParamsError := []v1alpha1.ApplicationSetCondition{ + { + Type: v1alpha1.ApplicationSetConditionErrorOccurred, + Status: v1alpha1.ApplicationSetConditionStatusTrue, + Message: expectedErrorMessage, + Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, + }, + { + Type: v1alpha1.ApplicationSetConditionParametersGenerated, + Status: v1alpha1.ApplicationSetConditionStatusFalse, + Message: expectedErrorMessage, + Reason: v1alpha1.ApplicationSetReasonErrorOccurred, + }, + { + Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, + Status: v1alpha1.ApplicationSetConditionStatusFalse, + Message: expectedErrorMessage, + Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, + }, + } + generateExpectedApp := func(name string) argov1alpha1.Application { + return argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + 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: name, + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: name, + }, + }, + } + } + + expectedApps := []argov1alpha1.Application{ + generateExpectedApp("guestbook"), + } + project := "gpg" + + Given(t). + Project(project). + When(). + // Create a GitGenerator-based ApplicationSet + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-git-generator", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: project, + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "{{path}}", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "{{path.basename}}", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Git: &v1alpha1.GitGenerator{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + Directories: []v1alpha1.GitDirectoryGeneratorItem{ + { + Path: guestbookPath, + }, + }, + }, + }, + }, + }, + }). + Then().Expect(ApplicationsDoNotExist(expectedApps)). + // verify the ApplicationSet error status conditions were set correctly + Expect(ApplicationSetHasConditions("simple-git-generator", expectedConditionsParamsError)). + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedApps)) +} + +func TestSimpleGitDirectoryGeneratorGPGEnabledWithoutKnownKeys(t *testing.T) { + fixture.SkipOnEnv(t, "GPG") + expectedErrorMessage := `error generating params from git: error getting directories from repo: error retrieving Git Directories: rpc error: code = Unknown desc = permission denied` + expectedConditionsParamsError := []v1alpha1.ApplicationSetCondition{ + { + Type: v1alpha1.ApplicationSetConditionErrorOccurred, + Status: v1alpha1.ApplicationSetConditionStatusTrue, + Message: expectedErrorMessage, + Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, + }, + { + Type: v1alpha1.ApplicationSetConditionParametersGenerated, + Status: v1alpha1.ApplicationSetConditionStatusFalse, + Message: expectedErrorMessage, + Reason: v1alpha1.ApplicationSetReasonErrorOccurred, + }, + { + Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, + Status: v1alpha1.ApplicationSetConditionStatusFalse, + Message: expectedErrorMessage, + Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, + }, + } + generateExpectedApp := func(name string) argov1alpha1.Application { + return argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + 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: name, + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: name, + }, + }, + } + } + + expectedApps := []argov1alpha1.Application{ + generateExpectedApp("guestbook"), + } + + project := "gpg" + + str, _ := rand.RandString(1) + + Given(t). + Project(project). + Path(guestbookPath). + When(). + AddSignedFile("test.yaml", str).IgnoreErrors(). + IgnoreErrors(). + // Create a GitGenerator-based ApplicationSet + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-git-generator", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: project, + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "{{path}}", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "{{path.basename}}", + }, + // Automatically create resources + SyncPolicy: &argov1alpha1.SyncPolicy{ + Automated: &argov1alpha1.SyncPolicyAutomated{}, + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Git: &v1alpha1.GitGenerator{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + Directories: []v1alpha1.GitDirectoryGeneratorItem{ + { + Path: guestbookPath, + }, + }, + }, + }, + }, + }, + }).Then(). + // verify the ApplicationSet error status conditions were set correctly + Expect(ApplicationSetHasConditions("simple-git-generator", expectedConditionsParamsError)). + Expect(ApplicationsDoNotExist(expectedApps)). + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedApps)) +} + +func TestSimpleGitFilesGenerator(t *testing.T) { + generateExpectedApp := func(name string) argov1alpha1.Application { + return argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + 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: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + } + } + + expectedApps := []argov1alpha1.Application{ + generateExpectedApp("engineering-dev-guestbook"), + generateExpectedApp("engineering-prod-guestbook"), + } + + var expectedAppsNewNamespace []argov1alpha1.Application + var expectedAppsNewMetadata []argov1alpha1.Application + + Given(t). + When(). + // Create a GitGenerator-based ApplicationSet + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-git-generator", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Git: &v1alpha1.GitGenerator{ + RepoURL: "https://github.com/argoproj/applicationset.git", + Files: []v1alpha1.GitFileGeneratorItem{ + { + Path: "examples/git-generator-files-discovery/cluster-config/**/config.json", + }, + }, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist(expectedApps)). + + // Update the ApplicationSet template namespace, and verify it updates the Applications + When(). + And(func() { + for _, expectedApp := range expectedApps { + newExpectedApp := expectedApp.DeepCopy() + newExpectedApp.Spec.Destination.Namespace = "guestbook2" + expectedAppsNewNamespace = append(expectedAppsNewNamespace, *newExpectedApp) + } + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" + }).Then().Expect(ApplicationsExist(expectedAppsNewNamespace)). + + // Update the metadata fields in the appset template, and make sure it propagates to the apps + When(). + And(func() { + for _, expectedApp := range expectedAppsNewNamespace { + expectedAppNewMetadata := expectedApp.DeepCopy() + expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"} + expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"} + expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata) + } + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} + appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} + }).Then().Expect(ApplicationsExist(expectedAppsNewMetadata)). + + // verify the ApplicationSet status conditions were set correctly + Expect(ApplicationSetHasConditions("simple-git-generator", ExpectedConditions)). + + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) +} + +func TestSimpleGitFilesGeneratorGPGEnabledUnsignedCommits(t *testing.T) { + fixture.SkipOnEnv(t, "GPG") + expectedErrorMessage := `error generating params from git: error retrieving Git files: rpc error: code = Unknown desc = permission denied` + expectedConditionsParamsError := []v1alpha1.ApplicationSetCondition{ + { + Type: v1alpha1.ApplicationSetConditionErrorOccurred, + Status: v1alpha1.ApplicationSetConditionStatusTrue, + Message: expectedErrorMessage, + Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, + }, + { + Type: v1alpha1.ApplicationSetConditionParametersGenerated, + Status: v1alpha1.ApplicationSetConditionStatusFalse, + Message: expectedErrorMessage, + Reason: v1alpha1.ApplicationSetReasonErrorOccurred, + }, + { + Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, + Status: v1alpha1.ApplicationSetConditionStatusFalse, + Message: expectedErrorMessage, + Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, + }, + } + project := "gpg" + generateExpectedApp := func(name string) argov1alpha1.Application { + return argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: fixture.TestNamespace(), + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: project, + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + } + } + + expectedApps := []argov1alpha1.Application{ + generateExpectedApp("engineering-dev-guestbook"), + generateExpectedApp("engineering-prod-guestbook"), + } + + Given(t). + Project(project). + When(). + // Create a GitGenerator-based ApplicationSet + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-git-generator", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: project, + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Git: &v1alpha1.GitGenerator{ + RepoURL: "https://github.com/argoproj/applicationset.git", + Files: []v1alpha1.GitFileGeneratorItem{ + { + Path: "examples/git-generator-files-discovery/cluster-config/**/config.json", + }, + }, + }, + }, + }, + }, + }).Then().Expect(ApplicationsDoNotExist(expectedApps)). + // verify the ApplicationSet error status conditions were set correctly + Expect(ApplicationSetHasConditions("simple-git-generator", expectedConditionsParamsError)). + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedApps)) +} + +func TestSimpleGitFilesGeneratorGPGEnabledWithoutKnownKeys(t *testing.T) { + fixture.SkipOnEnv(t, "GPG") + expectedErrorMessage := `error generating params from git: error retrieving Git files: rpc error: code = Unknown desc = permission denied` + expectedConditionsParamsError := []v1alpha1.ApplicationSetCondition{ + { + Type: v1alpha1.ApplicationSetConditionErrorOccurred, + Status: v1alpha1.ApplicationSetConditionStatusTrue, + Message: expectedErrorMessage, + Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, + }, + { + Type: v1alpha1.ApplicationSetConditionParametersGenerated, + Status: v1alpha1.ApplicationSetConditionStatusFalse, + Message: expectedErrorMessage, + Reason: v1alpha1.ApplicationSetReasonErrorOccurred, + }, + { + Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, + Status: v1alpha1.ApplicationSetConditionStatusFalse, + Message: expectedErrorMessage, + Reason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, + }, + } + project := "gpg" + generateExpectedApp := func(name string) argov1alpha1.Application { + return argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: fixture.TestNamespace(), + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: project, + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + } + } + + str, _ := rand.RandString(1) + + expectedApps := []argov1alpha1.Application{ + generateExpectedApp("engineering-dev-guestbook"), + generateExpectedApp("engineering-prod-guestbook"), + } + + Given(t). + Project(project). + Path(guestbookPath). + When(). + AddSignedFile("test.yaml", str).IgnoreErrors(). + IgnoreErrors(). + // Create a GitGenerator-based ApplicationSet + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-git-generator", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: project, + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Git: &v1alpha1.GitGenerator{ + RepoURL: "https://github.com/argoproj/applicationset.git", + Files: []v1alpha1.GitFileGeneratorItem{ + { + Path: "examples/git-generator-files-discovery/cluster-config/**/config.json", + }, + }, + }, + }, + }, + }, + }).Then(). + // verify the ApplicationSet error status conditions were set correctly + Expect(ApplicationSetHasConditions("simple-git-generator", expectedConditionsParamsError)). + Expect(ApplicationsDoNotExist(expectedApps)). + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedApps)) +} + +func TestSimpleGitFilesGeneratorGoTemplate(t *testing.T) { + generateExpectedApp := func(name string) argov1alpha1.Application { + return argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + 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: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + } + } + + expectedApps := []argov1alpha1.Application{ + generateExpectedApp("engineering-dev-guestbook"), + generateExpectedApp("engineering-prod-guestbook"), + } + + var expectedAppsNewNamespace []argov1alpha1.Application + var expectedAppsNewMetadata []argov1alpha1.Application + + Given(t). + When(). + // Create a GitGenerator-based ApplicationSet + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-git-generator", + }, + Spec: v1alpha1.ApplicationSetSpec{ + GoTemplate: true, + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster.name}}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Git: &v1alpha1.GitGenerator{ + RepoURL: "https://github.com/argoproj/applicationset.git", + Files: []v1alpha1.GitFileGeneratorItem{ + { + Path: "examples/git-generator-files-discovery/cluster-config/**/config.json", + }, + }, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist(expectedApps)). + + // Update the ApplicationSet template namespace, and verify it updates the Applications + When(). + And(func() { + for _, expectedApp := range expectedApps { + newExpectedApp := expectedApp.DeepCopy() + newExpectedApp.Spec.Destination.Namespace = "guestbook2" + expectedAppsNewNamespace = append(expectedAppsNewNamespace, *newExpectedApp) + } + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" + }).Then().Expect(ApplicationsExist(expectedAppsNewNamespace)). + + // Update the metadata fields in the appset template, and make sure it propagates to the apps + When(). + And(func() { + for _, expectedApp := range expectedAppsNewNamespace { + expectedAppNewMetadata := expectedApp.DeepCopy() + expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"} + expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"} + expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata) + } + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} + appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} + }).Then().Expect(ApplicationsExist(expectedAppsNewMetadata)). + + // verify the ApplicationSet status conditions were set correctly + Expect(ApplicationSetHasConditions("simple-git-generator", ExpectedConditions)). + + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) +} + +func TestSimpleGitFilesPreserveResourcesOnDeletion(t *testing.T) { + Given(t). + When(). + CreateNamespace(utils.ApplicationsResourcesNamespace). + // Create a GitGenerator-based ApplicationSet + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-git-generator", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: utils.ApplicationsResourcesNamespace, + }, + + // Automatically create resources + SyncPolicy: &argov1alpha1.SyncPolicy{ + Automated: &argov1alpha1.SyncPolicyAutomated{}, + }, + }, + }, + SyncPolicy: &v1alpha1.ApplicationSetSyncPolicy{ + PreserveResourcesOnDeletion: true, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Git: &v1alpha1.GitGenerator{ + RepoURL: "https://github.com/argoproj/applicationset.git", + Files: []v1alpha1.GitFileGeneratorItem{ + { + Path: "examples/git-generator-files-discovery/cluster-config/**/config.json", + }, + }, + }, + }, + }, + }, + // We use an extra-long duration here, as we might need to wait for image pull. + }).Then().ExpectWithDuration(Pod(func(p corev1.Pod) bool { return strings.Contains(p.Name, "guestbook-ui") }), 6*time.Minute). + When(). + Delete(). + And(func() { + t.Log("Waiting 15 seconds to give the cluster a chance to delete the pods.") + // Wait 15 seconds to give the cluster a chance to deletes the pods, if it is going to do so. + // It should NOT delete the pods; to do so would be an ApplicationSet bug, and + // that is what we are testing here. + time.Sleep(15 * time.Second) + // The pod should continue to exist after 15 seconds. + }).Then().Expect(Pod(func(p corev1.Pod) bool { return strings.Contains(p.Name, "guestbook-ui") })) +} + +func TestSimpleGitFilesPreserveResourcesOnDeletionGoTemplate(t *testing.T) { + Given(t). + When(). + CreateNamespace(utils.ApplicationsResourcesNamespace). + // Create a GitGenerator-based ApplicationSet + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-git-generator", + }, + Spec: v1alpha1.ApplicationSetSpec{ + GoTemplate: true, + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster.name}}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: utils.ApplicationsResourcesNamespace, + }, + + // Automatically create resources + SyncPolicy: &argov1alpha1.SyncPolicy{ + Automated: &argov1alpha1.SyncPolicyAutomated{}, + }, + }, + }, + SyncPolicy: &v1alpha1.ApplicationSetSyncPolicy{ + PreserveResourcesOnDeletion: true, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Git: &v1alpha1.GitGenerator{ + RepoURL: "https://github.com/argoproj/applicationset.git", + Files: []v1alpha1.GitFileGeneratorItem{ + { + Path: "examples/git-generator-files-discovery/cluster-config/**/config.json", + }, + }, + }, + }, + }, + }, + // We use an extra-long duration here, as we might need to wait for image pull. + }).Then().ExpectWithDuration(Pod(func(p corev1.Pod) bool { return strings.Contains(p.Name, "guestbook-ui") }), 6*time.Minute). + When(). + Delete(). + And(func() { + t.Log("Waiting 15 seconds to give the cluster a chance to delete the pods.") + // Wait 15 seconds to give the cluster a chance to deletes the pods, if it is going to do so. + // It should NOT delete the pods; to do so would be an ApplicationSet bug, and + // that is what we are testing here. + time.Sleep(15 * time.Second) + // The pod should continue to exist after 15 seconds. + }).Then().Expect(Pod(func(p corev1.Pod) bool { return strings.Contains(p.Name, "guestbook-ui") })) } func githubSCMMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { @@ -1334,7 +2312,7 @@ func TestSimpleSCMProviderGenerator(t *testing.T) { ts.Start() defer ts.Close() - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -1344,14 +2322,14 @@ func TestSimpleSCMProviderGenerator(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:argoproj/argo-cd.git", TargetRevision: "master", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -1370,14 +2348,14 @@ func TestSimpleSCMProviderGenerator(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{ repository }}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "{{ url }}", TargetRevision: "{{ branch }}", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -1399,7 +2377,7 @@ func TestSimpleSCMProviderGenerator(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})) + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})) } func TestSimpleSCMProviderGeneratorGoTemplate(t *testing.T) { @@ -1409,7 +2387,7 @@ func TestSimpleSCMProviderGeneratorGoTemplate(t *testing.T) { ts.Start() defer ts.Close() - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -1419,14 +2397,14 @@ func TestSimpleSCMProviderGeneratorGoTemplate(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:argoproj/argo-cd.git", TargetRevision: "master", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -1446,14 +2424,14 @@ func TestSimpleSCMProviderGeneratorGoTemplate(t *testing.T) { GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{ .repository }}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "{{ .url }}", TargetRevision: "{{ .branch }}", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -1475,11 +2453,11 @@ func TestSimpleSCMProviderGeneratorGoTemplate(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})) + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})) } func TestSCMProviderGeneratorSCMProviderNotAllowed(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -1489,14 +2467,14 @@ func TestSCMProviderGeneratorSCMProviderNotAllowed(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:argoproj/argo-cd.git", TargetRevision: "master", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -1516,14 +2494,14 @@ func TestSCMProviderGeneratorSCMProviderNotAllowed(t *testing.T) { GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{ .repository }}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "{{ .url }}", TargetRevision: "{{ .branch }}", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -1545,7 +2523,7 @@ func TestSCMProviderGeneratorSCMProviderNotAllowed(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedApp})). And(func() { // app should be listed output, err := fixture.RunCli("appset", "get", "scm-provider-generator-scm-provider-not-allowed") @@ -1555,7 +2533,7 @@ func TestSCMProviderGeneratorSCMProviderNotAllowed(t *testing.T) { } func TestCustomApplicationFinalizers(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -1565,14 +2543,14 @@ func TestCustomApplicationFinalizers(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io/background"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -1591,14 +2569,14 @@ func TestCustomApplicationFinalizers(t *testing.T) { Name: "{{cluster}}-guestbook", Finalizers: []string{"resources-finalizer.argocd.argoproj.io/background"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{url}}", Namespace: "guestbook", }, @@ -1614,15 +2592,15 @@ func TestCustomApplicationFinalizers(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedApp})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedApp})) } func TestCustomApplicationFinalizersGoTemplate(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -1632,14 +2610,14 @@ func TestCustomApplicationFinalizersGoTemplate(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io/background"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -1659,14 +2637,14 @@ func TestCustomApplicationFinalizersGoTemplate(t *testing.T) { Name: "{{.cluster}}-guestbook", Finalizers: []string{"resources-finalizer.argocd.argoproj.io/background"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "{{.url}}", Namespace: "guestbook", }, @@ -1682,11 +2660,11 @@ func TestCustomApplicationFinalizersGoTemplate(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedApp})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedApp})) } func githubPullMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { @@ -1736,7 +2714,7 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictOk(t *testing.T) { ts.Start() defer ts.Close() - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -1746,14 +2724,14 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictOk(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:argoproj/argo-cd.git", TargetRevision: "master", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -1765,7 +2743,7 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictOk(t *testing.T) { Given(t). And(func() { - _, err := utils.GetE2EFixtureK8sClient(t).KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Create(t.Context(), &corev1.Secret{ + _, err := utils.GetE2EFixtureK8sClient().KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Create(context.Background(), &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Namespace: fixture.TestNamespace(), Name: secretName, @@ -1788,14 +2766,14 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictOk(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{ repository }}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "{{ url }}", TargetRevision: "{{ branch }}", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -1807,7 +2785,7 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictOk(t *testing.T) { Github: &v1alpha1.SCMProviderGeneratorGithub{ Organization: "argoproj", API: ts.URL, - TokenRef: &v1alpha1.SecretRef{ + TokenRef: &argov1alpha1.SecretRef{ SecretName: secretName, Key: "hello", }, @@ -1821,9 +2799,9 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictOk(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). When().And(func() { - err := utils.GetE2EFixtureK8sClient(t).KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Delete(t.Context(), secretName, metav1.DeleteOptions{}) + err := utils.GetE2EFixtureK8sClient().KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Delete(context.Background(), secretName, metav1.DeleteOptions{}) assert.NoError(t, err) }) } @@ -1838,7 +2816,7 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictKo(t *testing.T) { ts.Start() defer ts.Close() - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -1851,14 +2829,14 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictKo(t *testing.T) { common.LabelKeyAppInstance: "simple-scm-provider-generator-strict-ko", }, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:argoproj/argo-cd.git", TargetRevision: "master", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -1870,7 +2848,7 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictKo(t *testing.T) { Given(t). And(func() { - _, err := utils.GetE2EFixtureK8sClient(t).KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Create(t.Context(), &corev1.Secret{ + _, err := utils.GetE2EFixtureK8sClient().KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Create(context.Background(), &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Namespace: fixture.TestNamespace(), Name: secretName, @@ -1894,14 +2872,14 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictKo(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{ repository }}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "{{ url }}", TargetRevision: "{{ branch }}", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, @@ -1913,7 +2891,7 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictKo(t *testing.T) { Github: &v1alpha1.SCMProviderGeneratorGithub{ Organization: "argoproj", API: ts.URL, - TokenRef: &v1alpha1.SecretRef{ + TokenRef: &argov1alpha1.SecretRef{ SecretName: secretName, Key: "hello", }, @@ -1927,14 +2905,14 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictKo(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedApp})). + }).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(t).KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Delete(t.Context(), secretName, metav1.DeleteOptions{}) + err2 := utils.GetE2EFixtureK8sClient().KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Delete(context.Background(), secretName, metav1.DeleteOptions{}) assert.NoError(t, err2) }) } @@ -1947,7 +2925,7 @@ func TestSimplePullRequestGenerator(t *testing.T) { ts.Start() defer ts.Close() - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -1957,17 +2935,17 @@ func TestSimplePullRequestGenerator(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:applicationset-test-org/argocd-example-apps.git", TargetRevision: "824a5c987fdfb2b0629e9dbf5f31636c69ba4772", Path: "kustomize-guestbook", - Kustomize: &v1alpha1.ApplicationSourceKustomize{ + Kustomize: &argov1alpha1.ApplicationSourceKustomize{ NamePrefix: "guestbook-1", }, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook-pull-request", }, @@ -1983,17 +2961,17 @@ func TestSimplePullRequestGenerator(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "guestbook-{{ number }}"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:applicationset-test-org/argocd-example-apps.git", TargetRevision: "{{ head_sha }}", Path: "kustomize-guestbook", - Kustomize: &v1alpha1.ApplicationSourceKustomize{ + Kustomize: &argov1alpha1.ApplicationSourceKustomize{ NamePrefix: "guestbook-{{ number }}", }, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook-{{ branch }}", }, @@ -2014,7 +2992,7 @@ func TestSimplePullRequestGenerator(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})) + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})) } func TestSimplePullRequestGeneratorGoTemplate(t *testing.T) { @@ -2025,7 +3003,7 @@ func TestSimplePullRequestGeneratorGoTemplate(t *testing.T) { ts.Start() defer ts.Close() - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -2036,17 +3014,17 @@ func TestSimplePullRequestGeneratorGoTemplate(t *testing.T) { Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, Labels: map[string]string{"app": "preview"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:applicationset-test-org/argocd-example-apps.git", TargetRevision: "824a5c987fdfb2b0629e9dbf5f31636c69ba4772", Path: "kustomize-guestbook", - Kustomize: &v1alpha1.ApplicationSourceKustomize{ + Kustomize: &argov1alpha1.ApplicationSourceKustomize{ NamePrefix: "guestbook-1", }, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook-pull-request", }, @@ -2066,17 +3044,17 @@ func TestSimplePullRequestGeneratorGoTemplate(t *testing.T) { Name: "guestbook-{{ .number }}", Labels: map[string]string{"app": "{{index .labels 0}}"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:applicationset-test-org/argocd-example-apps.git", TargetRevision: "{{ .head_sha }}", Path: "kustomize-guestbook", - Kustomize: &v1alpha1.ApplicationSourceKustomize{ + Kustomize: &argov1alpha1.ApplicationSourceKustomize{ NamePrefix: "guestbook-{{ .number }}", }, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook-{{ .branch }}", }, @@ -2097,11 +3075,11 @@ func TestSimplePullRequestGeneratorGoTemplate(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})) + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})) } func TestPullRequestGeneratorNotAllowedSCMProvider(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -2114,17 +3092,17 @@ func TestPullRequestGeneratorNotAllowedSCMProvider(t *testing.T) { "app": "preview", }, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:applicationset-test-org/argocd-example-apps.git", TargetRevision: "824a5c987fdfb2b0629e9dbf5f31636c69ba4772", Path: "kustomize-guestbook", - Kustomize: &v1alpha1.ApplicationSourceKustomize{ + Kustomize: &argov1alpha1.ApplicationSourceKustomize{ NamePrefix: "guestbook-1", }, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook-pull-request", }, @@ -2144,17 +3122,17 @@ func TestPullRequestGeneratorNotAllowedSCMProvider(t *testing.T) { Name: "guestbook-{{ .number }}", Labels: map[string]string{"app": "{{index .labels 0}}"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:applicationset-test-org/argocd-example-apps.git", TargetRevision: "{{ .head_sha }}", Path: "kustomize-guestbook", - Kustomize: &v1alpha1.ApplicationSourceKustomize{ + Kustomize: &argov1alpha1.ApplicationSourceKustomize{ NamePrefix: "guestbook-{{ .number }}", }, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook-{{ .branch }}", }, @@ -2175,7 +3153,7 @@ func TestPullRequestGeneratorNotAllowedSCMProvider(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedApp})). And(func() { // app should be listed output, err := fixture.RunCli("appset", "get", "pull-request-generator-not-allowed-scm") @@ -2183,3 +3161,156 @@ func TestPullRequestGeneratorNotAllowedSCMProvider(t *testing.T) { assert.Contains(t, output, "scm provider not allowed") }) } + +func TestGitGeneratorPrivateRepo(t *testing.T) { + FailOnErr(fixture.RunCli("repo", "add", fixture.RepoURL(fixture.RepoURLTypeHTTPS), "--username", fixture.GitUsername, "--password", fixture.GitPassword, "--insecure-skip-server-verification")) + generateExpectedApp := func(name string) argov1alpha1.Application { + return argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: fixture.TestNamespace(), + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), + TargetRevision: "HEAD", + Path: name, + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: name, + }, + }, + } + } + + expectedApps := []argov1alpha1.Application{ + generateExpectedApp("https-kustomize-base"), + } + + var expectedAppsNewNamespace []argov1alpha1.Application + + Given(t). + When(). + // Create a GitGenerator-based ApplicationSet + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-git-generator-private", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), + TargetRevision: "HEAD", + Path: "{{path}}", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "{{path.basename}}", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Git: &v1alpha1.GitGenerator{ + RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), + Directories: []v1alpha1.GitDirectoryGeneratorItem{ + { + Path: "*kustomize*", + }, + }, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist(expectedApps)). + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) +} + +func TestGitGeneratorPrivateRepoGoTemplate(t *testing.T) { + FailOnErr(fixture.RunCli("repo", "add", fixture.RepoURL(fixture.RepoURLTypeHTTPS), "--username", fixture.GitUsername, "--password", fixture.GitPassword, "--insecure-skip-server-verification")) + generateExpectedApp := func(name string) argov1alpha1.Application { + return argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: fixture.TestNamespace(), + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), + TargetRevision: "HEAD", + Path: name, + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: name, + }, + }, + } + } + + expectedApps := []argov1alpha1.Application{ + generateExpectedApp("https-kustomize-base"), + } + + var expectedAppsNewNamespace []argov1alpha1.Application + + Given(t). + When(). + // Create a GitGenerator-based ApplicationSet + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-git-generator-private", + }, + Spec: v1alpha1.ApplicationSetSpec{ + GoTemplate: true, + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.path.basename}}"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), + TargetRevision: "HEAD", + Path: "{{.path.path}}", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "{{.path.basename}}", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Git: &v1alpha1.GitGenerator{ + RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), + Directories: []v1alpha1.GitDirectoryGeneratorItem{ + { + Path: "*kustomize*", + }, + }, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist(expectedApps)). + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace)) +} diff --git a/test/e2e/cli_test.go b/test/e2e/cli_test.go index 54098517c2..1472116be7 100644 --- a/test/e2e/cli_test.go +++ b/test/e2e/cli_test.go @@ -1,8 +1,6 @@ package e2e import ( - "os" - "path/filepath" "testing" "github.com/argoproj/gitops-engine/pkg/health" @@ -10,30 +8,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + . "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" ) -// createTestPlugin creates a temporary Argo CD CLI plugin script for testing purposes. -// The script is written to a temporary directory with executable permissions. -func createTestPlugin(t *testing.T, name, content string) string { - t.Helper() - - tmpDir := t.TempDir() - pluginPath := filepath.Join(tmpDir, "argocd-"+name) - - require.NoError(t, os.WriteFile(pluginPath, []byte(content), 0o755)) - - // Ensure the plugin is cleaned up properly - t.Cleanup(func() { - _ = os.Remove(pluginPath) - }) - - return pluginPath -} - -// TestCliAppCommand verifies the basic Argo CD CLI commands for app synchronization and listing. func TestCliAppCommand(t *testing.T) { Given(t). Path("hook"). @@ -42,9 +21,9 @@ func TestCliAppCommand(t *testing.T) { And(func() { output, err := RunCli("app", "sync", Name(), "--timeout", "90") require.NoError(t, err) - vars := map[string]any{"Name": Name(), "Namespace": DeploymentNamespace()} - assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} pod Synced Progressing pod/pod created`, vars)) - assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} hook Succeeded Sync pod/hook created`, vars)) + vars := map[string]interface{}{"Name": Name(), "Namespace": DeploymentNamespace()} + assert.Contains(t, NormalizeOutput(output), Tmpl(`Pod {{.Namespace}} pod Synced Progressing pod/pod created`, vars)) + assert.Contains(t, NormalizeOutput(output), Tmpl(`Pod {{.Namespace}} hook Succeeded Sync pod/hook created`, vars)) }). Then(). Expect(OperationPhaseIs(OperationSucceeded)). @@ -53,215 +32,8 @@ func TestCliAppCommand(t *testing.T) { output, err := RunCli("app", "list") require.NoError(t, err) expected := Tmpl( - t, `{{.Name}} https://kubernetes.default.svc {{.Namespace}} default Synced Healthy Manual `, - map[string]any{"Name": Name(), "Namespace": DeploymentNamespace()}) + map[string]interface{}{"Name": Name(), "Namespace": DeploymentNamespace()}) assert.Contains(t, NormalizeOutput(output), expected) }) } - -// TestNormalArgoCDCommandsExecuteOverPluginsWithSameName verifies that normal Argo CD CLI commands -// take precedence over plugins with the same name when both exist in the path. -func TestNormalArgoCDCommandsExecuteOverPluginsWithSameName(t *testing.T) { - pluginScript := `#!/bin/bash - echo "I am a plugin, not Argo CD!" - exit 0` - - pluginPath := createTestPlugin(t, "app", pluginScript) - - origPath := os.Getenv("PATH") - t.Cleanup(func() { - t.Setenv("PATH", origPath) - }) - t.Setenv("PATH", filepath.Dir(pluginPath)+":"+origPath) - - Given(t). - Path("hook"). - When(). - CreateApp(). - And(func() { - output, err := RunCli("app", "sync", Name(), "--timeout", "90") - require.NoError(t, err) - - assert.NotContains(t, NormalizeOutput(output), "I am a plugin, not Argo CD!") - - vars := map[string]any{"Name": Name(), "Namespace": DeploymentNamespace()} - assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} pod Synced Progressing pod/pod created`, vars)) - assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} hook Succeeded Sync pod/hook created`, vars)) - }). - Then(). - Expect(OperationPhaseIs(OperationSucceeded)). - Expect(HealthIs(health.HealthStatusHealthy)). - And(func(_ *Application) { - output, err := RunCli("app", "list") - require.NoError(t, err) - - assert.NotContains(t, NormalizeOutput(output), "I am a plugin, not Argo CD!") - - expected := Tmpl( - t, - `{{.Name}} https://kubernetes.default.svc {{.Namespace}} default Synced Healthy Manual `, - map[string]any{"Name": Name(), "Namespace": DeploymentNamespace()}) - assert.Contains(t, NormalizeOutput(output), expected) - }) -} - -// TestCliPluginExecution tests the execution of a valid Argo CD CLI plugin. -func TestCliPluginExecution(t *testing.T) { - pluginScript := `#!/bin/bash - echo "Hello from myplugin" - exit 0` - pluginPath := createTestPlugin(t, "myplugin", pluginScript) - - origPath := os.Getenv("PATH") - t.Cleanup(func() { - t.Setenv("PATH", origPath) - }) - t.Setenv("PATH", filepath.Dir(pluginPath)+":"+origPath) - - output, err := RunPluginCli("", "myplugin") - require.NoError(t, err) - assert.Contains(t, NormalizeOutput(output), "Hello from myplugin") -} - -// TestCliPluginExecutionConditions tests for plugin execution conditions -func TestCliPluginExecutionConditions(t *testing.T) { - createValidPlugin := func(t *testing.T, name string, executable bool) string { - t.Helper() - - script := `#!/bin/bash - echo "Hello from $0" - exit 0 -` - - pluginPath := createTestPlugin(t, name, script) - - if executable { - require.NoError(t, os.Chmod(pluginPath, 0o755)) - } else { - require.NoError(t, os.Chmod(pluginPath, 0o644)) - } - - return pluginPath - } - - createInvalidPlugin := func(t *testing.T, name string) string { - t.Helper() - - script := `#!/bin/bash - echo "Hello from $0" - exit 0 -` - - tmpDir := t.TempDir() - pluginPath := filepath.Join(tmpDir, "argocd_"+name) // this is an invalid plugin name format - require.NoError(t, os.WriteFile(pluginPath, []byte(script), 0o755)) - - return pluginPath - } - - // 'argocd-valid-plugin' is a valid plugin name - validPlugin := createValidPlugin(t, "valid-plugin", true) - // 'argocd_invalid-plugin' is an invalid plugin name - invalidPlugin := createInvalidPlugin(t, "invalid-plugin") - // 'argocd-nonexec-plugin' is a valid plugin name but lacks executable permissions - noExecPlugin := createValidPlugin(t, "noexec-plugin", false) - - origPath := os.Getenv("PATH") - defer func() { - t.Setenv("PATH", origPath) - }() - t.Setenv("PATH", filepath.Dir(validPlugin)+":"+filepath.Dir(invalidPlugin)+":"+filepath.Dir(noExecPlugin)+":"+origPath) - - output, err := RunPluginCli("", "valid-plugin") - require.NoError(t, err) - assert.Contains(t, NormalizeOutput(output), "Hello from") - - _, err = RunPluginCli("", "invalid-plugin") - require.Error(t, err) - - _, err = RunPluginCli("", "noexec-plugin") - // expects error since plugin lacks executable permissions - require.Error(t, err) -} - -// TestCliPluginStatusCodes verifies that a plugin returns the correct exit codes based on its execution. -func TestCliPluginStatusCodes(t *testing.T) { - pluginScript := `#!/bin/bash - case "$1" in - "success") exit 0 ;; - "error1") exit 1 ;; - "error2") exit 2 ;; - *) echo "Unknown argument: $1"; exit 3 ;; - esac` - - pluginPath := createTestPlugin(t, "error-plugin", pluginScript) - - origPath := os.Getenv("PATH") - t.Cleanup(func() { - t.Setenv("PATH", origPath) - }) - t.Setenv("PATH", filepath.Dir(pluginPath)+":"+origPath) - - output, err := RunPluginCli("", "error-plugin", "success") - require.NoError(t, err) - assert.Contains(t, NormalizeOutput(output), "") - - _, err = RunPluginCli("", "error-plugin", "error1") - require.Error(t, err) - assert.Contains(t, err.Error(), "exit status 1") - - _, err = RunPluginCli("", "error-plugin", "error2") - require.Error(t, err) - assert.Contains(t, err.Error(), "exit status 2") - - _, err = RunPluginCli("", "error-plugin", "unknown") - require.Error(t, err) - assert.Contains(t, err.Error(), "exit status 3") -} - -// TestCliPluginStdinHandling verifies that a CLI plugin correctly handles input from stdin. -func TestCliPluginStdinHandling(t *testing.T) { - pluginScript := `#!/bin/bash - input=$(cat) - echo "Received: $input" - exit 0` - - pluginPath := createTestPlugin(t, "stdin-plugin", pluginScript) - - origPath := os.Getenv("PATH") - t.Cleanup(func() { - t.Setenv("PATH", origPath) - }) - t.Setenv("PATH", filepath.Dir(pluginPath)+":"+origPath) - - testCases := []struct { - name string - stdin string - expected string - }{ - { - "Single line input", - "Hello, ArgoCD!", - "Received: Hello, ArgoCD!", - }, - { - "Multiline input", - "Line1\nLine2\nLine3", - "Received: Line1\nLine2\nLine3", - }, - { - "Empty input", - "", - "Received:", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - output, err := RunPluginCli(tc.stdin, "stdin-plugin") - require.NoError(t, err) - assert.Contains(t, NormalizeOutput(output), tc.expected) - }) - } -} diff --git a/test/e2e/cluster_generator_test.go b/test/e2e/cluster_generator_test.go index e1dc84b203..558d5c9c84 100644 --- a/test/e2e/cluster_generator_test.go +++ b/test/e2e/cluster_generator_test.go @@ -4,19 +4,22 @@ import ( "testing" "time" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets/utils" + "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/applicationsets" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) { externalNamespace := string(utils.ArgoCDExternalNamespace) - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", APIVersion: "argoproj.io/v1alpha1", @@ -26,22 +29,22 @@ func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) { Namespace: externalNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "cluster1", Namespace: "guestbook", }, }, } - var expectedAppNewNamespace *v1alpha1.Application - var expectedAppNewMetadata *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application Given(t). // Create a ClusterGenerator-based ApplicationSet @@ -56,14 +59,14 @@ func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{name}}", // Server: "{{server}}", Namespace: "guestbook", @@ -82,7 +85,7 @@ func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). @@ -92,7 +95,7 @@ func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the metadata fields in the appset template, and make sure it propagates to the apps When(). @@ -108,15 +111,15 @@ func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) { appset.Spec.Template.Labels = map[string]string{ "label-key": "label-value", } - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewNamespace})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewNamespace})) } func TestSimpleClusterGenerator(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -126,22 +129,22 @@ func TestSimpleClusterGenerator(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "cluster1", Namespace: "guestbook", }, }, } - var expectedAppNewNamespace *v1alpha1.Application - var expectedAppNewMetadata *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application Given(t). // Create a ClusterGenerator-based ApplicationSet @@ -154,14 +157,14 @@ func TestSimpleClusterGenerator(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{name}}", // Server: "{{server}}", Namespace: "guestbook", @@ -180,7 +183,7 @@ func TestSimpleClusterGenerator(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). @@ -190,7 +193,7 @@ func TestSimpleClusterGenerator(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the metadata fields in the appset template, and make sure it propagates to the apps When(). @@ -202,15 +205,15 @@ func TestSimpleClusterGenerator(t *testing.T) { Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewNamespace})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewNamespace})) } func TestClusterGeneratorWithLocalCluster(t *testing.T) { - expectedAppTemplate := v1alpha1.Application{ + expectedAppTemplate := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -220,9 +223,9 @@ func TestClusterGeneratorWithLocalCluster(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -233,27 +236,27 @@ func TestClusterGeneratorWithLocalCluster(t *testing.T) { tests := []struct { name string - appsetDestination v1alpha1.ApplicationDestination - appDestination v1alpha1.ApplicationDestination + appsetDestination argov1alpha1.ApplicationDestination + appDestination argov1alpha1.ApplicationDestination }{ { name: "specify local cluster by server field", - appDestination: v1alpha1.ApplicationDestination{ + appDestination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "guestbook", }, - appsetDestination: v1alpha1.ApplicationDestination{ + appsetDestination: argov1alpha1.ApplicationDestination{ Server: "{{server}}", Namespace: "guestbook", }, }, { name: "specify local cluster by name field", - appDestination: v1alpha1.ApplicationDestination{ + appDestination: argov1alpha1.ApplicationDestination{ Name: "in-cluster", Namespace: "guestbook", }, - appsetDestination: v1alpha1.ApplicationDestination{ + appsetDestination: argov1alpha1.ApplicationDestination{ Name: "{{name}}", Namespace: "guestbook", }, @@ -262,8 +265,8 @@ func TestClusterGeneratorWithLocalCluster(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - var expectedAppNewNamespace *v1alpha1.Application - var expectedAppNewMetadata *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application // Create the expected application from the template, and copy in the destination from the test case expectedApp := *expectedAppTemplate.DeepCopy() @@ -279,9 +282,9 @@ func TestClusterGeneratorWithLocalCluster(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -295,7 +298,7 @@ func TestClusterGeneratorWithLocalCluster(t *testing.T) { }, }, }, - }).Then().ExpectWithDuration(ApplicationsExist([]v1alpha1.Application{expectedApp}), 8*time.Minute). + }).Then().ExpectWithDuration(ApplicationsExist([]argov1alpha1.Application{expectedApp}), 8*time.Minute). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). @@ -305,7 +308,7 @@ func TestClusterGeneratorWithLocalCluster(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the metadata fields in the appset template, and make sure it propagates to the apps When(). @@ -317,17 +320,17 @@ func TestClusterGeneratorWithLocalCluster(t *testing.T) { Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewNamespace})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewNamespace})) }) } } func TestSimpleClusterGeneratorAddingCluster(t *testing.T) { - expectedAppTemplate := v1alpha1.Application{ + expectedAppTemplate := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -337,14 +340,14 @@ func TestSimpleClusterGeneratorAddingCluster(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{name}}", Namespace: "guestbook", }, @@ -353,11 +356,11 @@ func TestSimpleClusterGeneratorAddingCluster(t *testing.T) { expectedAppCluster1 := *expectedAppTemplate.DeepCopy() expectedAppCluster1.Spec.Destination.Name = "cluster1" - expectedAppCluster1.Name = "cluster1-guestbook" + expectedAppCluster1.ObjectMeta.Name = "cluster1-guestbook" expectedAppCluster2 := *expectedAppTemplate.DeepCopy() expectedAppCluster2.Spec.Destination.Name = "cluster2" - expectedAppCluster2.Name = "cluster2-guestbook" + expectedAppCluster2.ObjectMeta.Name = "cluster2-guestbook" Given(t). // Create a ClusterGenerator-based ApplicationSet @@ -370,14 +373,14 @@ func TestSimpleClusterGeneratorAddingCluster(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{name}}", // Server: "{{server}}", Namespace: "guestbook", @@ -396,20 +399,20 @@ func TestSimpleClusterGeneratorAddingCluster(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1})). + }).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([]v1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). + Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster1, expectedAppCluster2})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})) } func TestSimpleClusterGeneratorDeletingCluster(t *testing.T) { - expectedAppTemplate := v1alpha1.Application{ + expectedAppTemplate := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -419,14 +422,14 @@ func TestSimpleClusterGeneratorDeletingCluster(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{name}}", Namespace: "guestbook", }, @@ -435,11 +438,11 @@ func TestSimpleClusterGeneratorDeletingCluster(t *testing.T) { expectedAppCluster1 := *expectedAppTemplate.DeepCopy() expectedAppCluster1.Spec.Destination.Name = "cluster1" - expectedAppCluster1.Name = "cluster1-guestbook" + expectedAppCluster1.ObjectMeta.Name = "cluster1-guestbook" expectedAppCluster2 := *expectedAppTemplate.DeepCopy() expectedAppCluster2.Spec.Destination.Name = "cluster2" - expectedAppCluster2.Name = "cluster2-guestbook" + expectedAppCluster2.ObjectMeta.Name = "cluster2-guestbook" Given(t). // Create a ClusterGenerator-based ApplicationSet @@ -453,14 +456,14 @@ func TestSimpleClusterGeneratorDeletingCluster(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{name}}", // Server: "{{server}}", Namespace: "guestbook", @@ -479,21 +482,21 @@ func TestSimpleClusterGeneratorDeletingCluster(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). DeleteClusterSecret("my-secret2"). - Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1})). - Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster2})). + Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1})). + Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster2})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster1})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster1})) } func TestClusterGeneratorWithFlatListMode(t *testing.T) { - expectedAppTemplate := v1alpha1.Application{ + expectedAppTemplate := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -503,32 +506,32 @@ func TestClusterGeneratorWithFlatListMode(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "helm-guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "cluster1", Namespace: fixture.TestNamespace(), }, - SyncPolicy: &v1alpha1.SyncPolicy{ - Automated: &v1alpha1.SyncPolicyAutomated{}, + SyncPolicy: &argov1alpha1.SyncPolicy{ + Automated: &argov1alpha1.SyncPolicyAutomated{}, }, }, } expectedAppCluster1 := *expectedAppTemplate.DeepCopy() - expectedAppCluster1.Spec.Source.Helm = &v1alpha1.ApplicationSourceHelm{ + expectedAppCluster1.Spec.Source.Helm = &argov1alpha1.ApplicationSourceHelm{ Values: `clusters: - name: cluster1 `, } expectedAppCluster2 := *expectedAppTemplate.DeepCopy() - expectedAppCluster2.Spec.Source.Helm = &v1alpha1.ApplicationSourceHelm{ + expectedAppCluster2.Spec.Source.Helm = &argov1alpha1.ApplicationSourceHelm{ Values: `clusters: - name: cluster1 - name: cluster2 @@ -547,13 +550,13 @@ func TestClusterGeneratorWithFlatListMode(t *testing.T) { GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "flat-clusters"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "helm-guestbook", - Helm: &v1alpha1.ApplicationSourceHelm{ + Helm: &argov1alpha1.ApplicationSourceHelm{ Values: `clusters: {{- range .clusters }} - name: {{ .name }} @@ -561,12 +564,12 @@ func TestClusterGeneratorWithFlatListMode(t *testing.T) { `, }, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "cluster1", Namespace: fixture.TestNamespace(), }, - SyncPolicy: &v1alpha1.SyncPolicy{ - Automated: &v1alpha1.SyncPolicyAutomated{}, + SyncPolicy: &argov1alpha1.SyncPolicy{ + Automated: &argov1alpha1.SyncPolicyAutomated{}, }, }, }, @@ -583,15 +586,15 @@ func TestClusterGeneratorWithFlatListMode(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1})). + }).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([]v1alpha1.Application{expectedAppCluster2})). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster2})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster2})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster2})) } diff --git a/test/e2e/cluster_objects_test.go b/test/e2e/cluster_objects_test.go index 7907836098..59ee43d397 100644 --- a/test/e2e/cluster_objects_test.go +++ b/test/e2e/cluster_objects_test.go @@ -8,9 +8,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/util/argo" ) func TestClusterRoleBinding(t *testing.T) { @@ -29,7 +30,7 @@ func TestClusterRoleBinding(t *testing.T) { assert.Empty(t, diffOutput) }). When(). - SetTrackingMethod(string(TrackingMethodAnnotation)). + SetTrackingMethod(string(argo.TrackingMethodAnnotation)). Sync(). Then(). Expect(OperationPhaseIs(OperationSucceeded)). diff --git a/test/e2e/cluster_test.go b/test/e2e/cluster_test.go index 53cb6a5bf1..eab0d49f6a 100644 --- a/test/e2e/cluster_test.go +++ b/test/e2e/cluster_test.go @@ -9,25 +9,26 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - accountFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/account" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - clusterFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/cluster" - "github.com/argoproj/argo-cd/v3/util/errors" + . "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" + accountFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/account" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + clusterFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/cluster" + . "github.com/argoproj/argo-cd/v2/util/errors" ) func TestClusterList(t *testing.T) { - fixture.SkipIfAlreadyRun(t) - defer fixture.RecordTestRun(t) + SkipIfAlreadyRun(t) + defer RecordTestRun(t) last := "" expected := fmt.Sprintf(`SERVER NAME VERSION STATUS MESSAGE PROJECT -https://kubernetes.default.svc in-cluster %v Successful `, fixture.GetVersions(t).ServerVersion) +https://kubernetes.default.svc in-cluster %v Successful `, GetVersions().ServerVersion) clusterFixture. Given(t). - Project(fixture.ProjectName) + Project(ProjectName) // We need an application targeting the cluster, otherwise the test will // fail if run isolated. @@ -37,12 +38,12 @@ https://kubernetes.default.svc in-cluster %v Successful `, fixtu CreateApp() tries := 25 - for i := 0; i <= tries; i++ { + for i := 0; i <= tries; i += 1 { clusterFixture.GivenWithSameState(t). When(). List(). Then(). - AndCLIOutput(func(output string, _ error) { + AndCLIOutput(func(output string, err error) { last = output }) if expected == last { @@ -58,16 +59,16 @@ https://kubernetes.default.svc in-cluster %v Successful `, fixtu func TestClusterAdd(t *testing.T) { clusterFixture. Given(t). - Project(fixture.ProjectName). + Project(ProjectName). Upsert(true). Server(KubernetesInternalAPIServerAddr). When(). Create(). List(). Then(). - AndCLIOutput(func(output string, _ error) { + AndCLIOutput(func(output string, err error) { assert.Equal(t, fmt.Sprintf(`SERVER NAME VERSION STATUS MESSAGE PROJECT -https://kubernetes.default.svc test-cluster-add %v Successful %s`, fixture.GetVersions(t).ServerVersion, fixture.ProjectName), output) +https://kubernetes.default.svc test-cluster-add %v Successful %s`, GetVersions().ServerVersion, ProjectName), output) }) } @@ -81,14 +82,14 @@ func TestClusterAddPermissionDenied(t *testing.T) { clusterFixture. GivenWithSameState(t). - Project(fixture.ProjectName). + Project(ProjectName). Upsert(true). Server(KubernetesInternalAPIServerAddr). When(). IgnoreErrors(). Create(). Then(). - AndCLIOutput(func(_ string, err error) { + AndCLIOutput(func(output string, err error) { assert.ErrorContains(t, err, "PermissionDenied desc = permission denied") }) } @@ -103,27 +104,27 @@ func TestClusterAddAllowed(t *testing.T) { { Resource: "clusters", Action: "create", - Scope: fixture.ProjectName + "/*", + Scope: ProjectName + "/*", }, { Resource: "clusters", Action: "get", - Scope: fixture.ProjectName + "/*", + Scope: ProjectName + "/*", }, }, "org-admin") clusterFixture. GivenWithSameState(t). - Project(fixture.ProjectName). + Project(ProjectName). Upsert(true). Server(KubernetesInternalAPIServerAddr). When(). Create(). List(). Then(). - AndCLIOutput(func(output string, _ error) { + AndCLIOutput(func(output string, err error) { assert.Equal(t, fmt.Sprintf(`SERVER NAME VERSION STATUS MESSAGE PROJECT -https://kubernetes.default.svc test-cluster-add-allowed %v Successful argo-project`, fixture.GetVersions(t).ServerVersion), output) +https://kubernetes.default.svc test-cluster-add-allowed %v Successful argo-project`, GetVersions().ServerVersion), output) }) } @@ -137,30 +138,30 @@ func TestClusterListDenied(t *testing.T) { { Resource: "clusters", Action: "create", - Scope: fixture.ProjectName + "/*", + Scope: ProjectName + "/*", }, }, "org-admin") clusterFixture. GivenWithSameState(t). - Project(fixture.ProjectName). + Project(ProjectName). Upsert(true). Server(KubernetesInternalAPIServerAddr). When(). Create(). List(). Then(). - AndCLIOutput(func(output string, _ error) { + AndCLIOutput(func(output string, err error) { assert.Equal(t, "SERVER NAME VERSION STATUS MESSAGE PROJECT", output) }) } func TestClusterSet(t *testing.T) { - fixture.EnsureCleanState(t) - defer fixture.RecordTestRun(t) + EnsureCleanState(t) + defer RecordTestRun(t) clusterFixture. GivenWithSameState(t). - Project(fixture.ProjectName). + Project(ProjectName). Name("in-cluster"). Namespaces([]string{"namespace-edit-1", "namespace-edit-2"}). Server(KubernetesInternalAPIServerAddr). @@ -168,21 +169,21 @@ func TestClusterSet(t *testing.T) { SetNamespaces(). GetByName("in-cluster"). Then(). - AndCLIOutput(func(output string, _ error) { + AndCLIOutput(func(output string, err error) { assert.Contains(t, output, "namespace-edit-1") assert.Contains(t, output, "namespace-edit-2") }) } func TestClusterGet(t *testing.T) { - fixture.SkipIfAlreadyRun(t) - fixture.EnsureCleanState(t) - defer fixture.RecordTestRun(t) - output := errors.NewHandler(t).FailOnErr(fixture.RunCli("cluster", "get", "https://kubernetes.default.svc")).(string) + SkipIfAlreadyRun(t) + EnsureCleanState(t) + defer RecordTestRun(t) + output := FailOnErr(RunCli("cluster", "get", "https://kubernetes.default.svc")).(string) assert.Contains(t, output, "name: in-cluster") assert.Contains(t, output, "server: https://kubernetes.default.svc") - assert.Contains(t, output, fmt.Sprintf(`serverVersion: "%v"`, fixture.GetVersions(t).ServerVersion)) + assert.Contains(t, output, fmt.Sprintf(`serverVersion: "%v"`, GetVersions().ServerVersion)) assert.Contains(t, output, `config: tlsClientConfig: insecure: false`) @@ -191,34 +192,34 @@ func TestClusterGet(t *testing.T) { } func TestClusterNameInRestAPI(t *testing.T) { - fixture.EnsureCleanState(t) + EnsureCleanState(t) var cluster Cluster - err := fixture.DoHttpJsonRequest("GET", "/api/v1/clusters/in-cluster?id.type=name", &cluster) + err := DoHttpJsonRequest("GET", "/api/v1/clusters/in-cluster?id.type=name", &cluster) require.NoError(t, err) assert.Equal(t, "in-cluster", cluster.Name) assert.Contains(t, cluster.Server, "https://kubernetes.default.svc") - err = fixture.DoHttpJsonRequest("PUT", + err = DoHttpJsonRequest("PUT", "/api/v1/clusters/in-cluster?id.type=name&updatedFields=labels", &cluster, []byte(`{"labels":{"test": "val"}}`)...) require.NoError(t, err) assert.Equal(t, map[string]string{"test": "val"}, cluster.Labels) } func TestClusterURLInRestAPI(t *testing.T) { - fixture.EnsureCleanState(t) + EnsureCleanState(t) clusterURL := url.QueryEscape(KubernetesInternalAPIServerAddr) var cluster Cluster - err := fixture.DoHttpJsonRequest("GET", "/api/v1/clusters/"+clusterURL, &cluster) + err := DoHttpJsonRequest("GET", fmt.Sprintf("/api/v1/clusters/%s", clusterURL), &cluster) require.NoError(t, err) assert.Equal(t, "in-cluster", cluster.Name) assert.Contains(t, cluster.Server, "https://kubernetes.default.svc") - err = fixture.DoHttpJsonRequest("PUT", + err = DoHttpJsonRequest("PUT", fmt.Sprintf("/api/v1/clusters/%s?&updatedFields=labels", clusterURL), &cluster, []byte(`{"labels":{"test": "val"}}`)...) require.NoError(t, err) assert.Equal(t, map[string]string{"test": "val"}, cluster.Labels) @@ -234,40 +235,40 @@ func TestClusterDeleteDenied(t *testing.T) { { Resource: "clusters", Action: "create", - Scope: fixture.ProjectName + "/*", + Scope: ProjectName + "/*", }, { Resource: "clusters", Action: "get", - Scope: fixture.ProjectName + "/*", + Scope: ProjectName + "/*", }, }, "org-admin") // Attempt to remove cluster creds by name clusterFixture. GivenWithSameState(t). - Project(fixture.ProjectName). + Project(ProjectName). Upsert(true). Server(KubernetesInternalAPIServerAddr). When(). Create(). DeleteByName(). Then(). - AndCLIOutput(func(_ string, err error) { + AndCLIOutput(func(output string, err error) { assert.ErrorContains(t, err, "PermissionDenied desc = permission denied") }) // Attempt to remove cluster creds by server clusterFixture. GivenWithSameState(t). - Project(fixture.ProjectName). + Project(ProjectName). Upsert(true). Server(KubernetesInternalAPIServerAddr). When(). Create(). DeleteByServer(). Then(). - AndCLIOutput(func(_ string, err error) { + AndCLIOutput(func(output string, err error) { assert.ErrorContains(t, err, "PermissionDenied desc = permission denied") }) } @@ -282,24 +283,24 @@ func TestClusterDelete(t *testing.T) { { Resource: "clusters", Action: "create", - Scope: fixture.ProjectName + "/*", + Scope: ProjectName + "/*", }, { Resource: "clusters", Action: "get", - Scope: fixture.ProjectName + "/*", + Scope: ProjectName + "/*", }, { Resource: "clusters", Action: "delete", - Scope: fixture.ProjectName + "/*", + Scope: ProjectName + "/*", }, }, "org-admin") clstAction := clusterFixture. GivenWithSameState(t). Name("default"). - Project(fixture.ProjectName). + Project(ProjectName). Upsert(true). Server(KubernetesInternalAPIServerAddr). When(). @@ -317,7 +318,7 @@ func TestClusterDelete(t *testing.T) { clstAction.DeleteByName(). Then(). - AndCLIOutput(func(output string, _ error) { + AndCLIOutput(func(output string, err error) { assert.Equal(t, "Cluster 'default' removed", output) }) diff --git a/test/e2e/clusterdecisiongenerator_e2e_test.go b/test/e2e/clusterdecisiongenerator_e2e_test.go index db7951ac46..3ee4a30509 100644 --- a/test/e2e/clusterdecisiongenerator_e2e_test.go +++ b/test/e2e/clusterdecisiongenerator_e2e_test.go @@ -3,15 +3,16 @@ package e2e import ( "testing" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets/utils" + "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/applicationsets" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) var tenSec = int64(10) @@ -19,7 +20,7 @@ var tenSec = int64(10) func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { externalNamespace := string(utils.ArgoCDExternalNamespace) - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", APIVersion: "argoproj.io/v1alpha1", @@ -29,25 +30,25 @@ func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { Namespace: externalNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "cluster1", Namespace: "guestbook", }, }, } - var expectedAppNewNamespace *v1alpha1.Application - var expectedAppNewMetadata *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application - clusterList := []any{ - map[string]any{ + clusterList := []interface{}{ + map[string]interface{}{ "clusterName": "cluster1", "reason": "argotest", }, @@ -70,14 +71,14 @@ func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{clusterName}}", // Server: "{{server}}", Namespace: "guestbook", @@ -93,7 +94,7 @@ func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). @@ -103,7 +104,7 @@ func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the metadata fields in the appset template, and make sure it propagates to the apps When(). @@ -119,15 +120,15 @@ func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { appset.Spec.Template.Labels = map[string]string{ "label-key": "label-value", } - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewNamespace})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewNamespace})) } func TestSimpleClusterDecisionResourceGenerator(t *testing.T) { - expectedApp := v1alpha1.Application{ + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -137,25 +138,25 @@ func TestSimpleClusterDecisionResourceGenerator(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "cluster1", Namespace: "guestbook", }, }, } - var expectedAppNewNamespace *v1alpha1.Application - var expectedAppNewMetadata *v1alpha1.Application + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application - clusterList := []any{ - map[string]any{ + clusterList := []interface{}{ + map[string]interface{}{ "clusterName": "cluster1", "reason": "argotest", }, @@ -176,14 +177,14 @@ func TestSimpleClusterDecisionResourceGenerator(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{clusterName}}", // Server: "{{server}}", Namespace: "guestbook", @@ -199,7 +200,7 @@ func TestSimpleClusterDecisionResourceGenerator(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). @@ -209,7 +210,7 @@ func TestSimpleClusterDecisionResourceGenerator(t *testing.T) { }). Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). // Update the metadata fields in the appset template, and make sure it propagates to the apps When(). @@ -221,15 +222,15 @@ func TestSimpleClusterDecisionResourceGenerator(t *testing.T) { Update(func(appset *v1alpha1.ApplicationSet) { appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewNamespace})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewNamespace})) } func TestSimpleClusterDecisionResourceGeneratorAddingCluster(t *testing.T) { - expectedAppTemplate := v1alpha1.Application{ + expectedAppTemplate := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -239,14 +240,14 @@ func TestSimpleClusterDecisionResourceGeneratorAddingCluster(t *testing.T) { Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{clusterName}}", Namespace: "guestbook", }, @@ -255,18 +256,18 @@ func TestSimpleClusterDecisionResourceGeneratorAddingCluster(t *testing.T) { expectedAppCluster1 := *expectedAppTemplate.DeepCopy() expectedAppCluster1.Spec.Destination.Name = "cluster1" - expectedAppCluster1.Name = "cluster1-guestbook" + expectedAppCluster1.ObjectMeta.Name = "cluster1-guestbook" expectedAppCluster2 := *expectedAppTemplate.DeepCopy() expectedAppCluster2.Spec.Destination.Name = "cluster2" - expectedAppCluster2.Name = "cluster2-guestbook" + expectedAppCluster2.ObjectMeta.Name = "cluster2-guestbook" - clusterList := []any{ - map[string]any{ + clusterList := []interface{}{ + map[string]interface{}{ "clusterName": "cluster1", "reason": "argotest", }, - map[string]any{ + map[string]interface{}{ "clusterName": "cluster2", "reason": "argotest", }, @@ -287,14 +288,14 @@ func TestSimpleClusterDecisionResourceGeneratorAddingCluster(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{clusterName}}", // Server: "{{server}}", Namespace: "guestbook", @@ -311,20 +312,20 @@ func TestSimpleClusterDecisionResourceGeneratorAddingCluster(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1})). + }).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([]v1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). + Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster1, expectedAppCluster2})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})) } func TestSimpleClusterDecisionResourceGeneratorDeletingClusterSecret(t *testing.T) { - expectedAppTemplate := v1alpha1.Application{ + expectedAppTemplate := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -334,14 +335,14 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterSecret(t *testing. Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{name}}", Namespace: "guestbook", }, @@ -350,18 +351,18 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterSecret(t *testing. expectedAppCluster1 := *expectedAppTemplate.DeepCopy() expectedAppCluster1.Spec.Destination.Name = "cluster1" - expectedAppCluster1.Name = "cluster1-guestbook" + expectedAppCluster1.ObjectMeta.Name = "cluster1-guestbook" expectedAppCluster2 := *expectedAppTemplate.DeepCopy() expectedAppCluster2.Spec.Destination.Name = "cluster2" - expectedAppCluster2.Name = "cluster2-guestbook" + expectedAppCluster2.ObjectMeta.Name = "cluster2-guestbook" - clusterList := []any{ - map[string]any{ + clusterList := []interface{}{ + map[string]interface{}{ "clusterName": "cluster1", "reason": "argotest", }, - map[string]any{ + map[string]interface{}{ "clusterName": "cluster2", "reason": "argotest", }, @@ -383,14 +384,14 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterSecret(t *testing. Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{clusterName}}", // Server: "{{server}}", Namespace: "guestbook", @@ -407,21 +408,21 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterSecret(t *testing. }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). DeleteClusterSecret("my-secret2"). - Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1})). - Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster2})). + Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1})). + Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster2})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster1})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster1})) } func TestSimpleClusterDecisionResourceGeneratorDeletingClusterFromResource(t *testing.T) { - expectedAppTemplate := v1alpha1.Application{ + expectedAppTemplate := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -431,14 +432,14 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterFromResource(t *te Namespace: fixture.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{name}}", Namespace: "guestbook", }, @@ -447,25 +448,25 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterFromResource(t *te expectedAppCluster1 := *expectedAppTemplate.DeepCopy() expectedAppCluster1.Spec.Destination.Name = "cluster1" - expectedAppCluster1.Name = "cluster1-guestbook" + expectedAppCluster1.ObjectMeta.Name = "cluster1-guestbook" expectedAppCluster2 := *expectedAppTemplate.DeepCopy() expectedAppCluster2.Spec.Destination.Name = "cluster2" - expectedAppCluster2.Name = "cluster2-guestbook" + expectedAppCluster2.ObjectMeta.Name = "cluster2-guestbook" - clusterList := []any{ - map[string]any{ + clusterList := []interface{}{ + map[string]interface{}{ "clusterName": "cluster1", "reason": "argotest", }, - map[string]any{ + map[string]interface{}{ "clusterName": "cluster2", "reason": "argotest", }, } - clusterListSmall := []any{ - map[string]any{ + clusterListSmall := []interface{}{ + map[string]interface{}{ "clusterName": "cluster1", "reason": "argotest", }, @@ -487,14 +488,14 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterFromResource(t *te Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{clusterName}}", // Server: "{{server}}", Namespace: "guestbook", @@ -511,15 +512,15 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterFromResource(t *te }, }, }, - }).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). // Update the ApplicationSet template namespace, and verify it updates the Applications When(). StatusUpdatePlacementDecision("my-placementdecision", clusterListSmall). - Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1})). - Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster2})). + Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1})). + Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster2})). // Delete the ApplicationSet, and verify it deletes the Applications When(). - Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster1})) + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster1})) } diff --git a/test/e2e/custom_tool_test.go b/test/e2e/custom_tool_test.go index f80dbaa328..f9bfc014bb 100644 --- a/test/e2e/custom_tool_test.go +++ b/test/e2e/custom_tool_test.go @@ -13,10 +13,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/util/errors" + . "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" ) // make sure we can echo back the Git creds @@ -31,7 +32,7 @@ func TestCustomToolWithGitCreds(t *testing.T) { CustomCACertAdded(). // add the private repo with credentials HTTPSRepoURLAdded(true). - RepoURLType(fixture.RepoURLTypeHTTPS). + RepoURLType(RepoURLTypeHTTPS). Path("cmp-gitcreds"). When(). CreateApp(). @@ -40,8 +41,8 @@ func TestCustomToolWithGitCreds(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - And(func(_ *Application) { - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitAskpass}") + 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) }) @@ -61,7 +62,7 @@ func TestCustomToolWithGitCredsTemplate(t *testing.T) { HTTPSCredentialsUserPassAdded(). // add the private repo without credentials HTTPSRepoURLAdded(false). - RepoURLType(fixture.RepoURLTypeHTTPS). + RepoURLType(RepoURLTypeHTTPS). Path("cmp-gitcredstemplate"). When(). CreateApp(). @@ -70,18 +71,18 @@ func TestCustomToolWithGitCredsTemplate(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - And(func(_ *Application) { - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitAskpass}") + 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(_ *Application) { - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitUsername}") + And(func(app *Application) { + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitUsername}") require.NoError(t, err) assert.Empty(t, output) }). - And(func(_ *Application) { - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitPassword}") + And(func(app *Application) { + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitPassword}") require.NoError(t, err) assert.Empty(t, output) }) @@ -110,13 +111,13 @@ func TestCustomToolWithSSHGitCreds(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - And(func(_ *Application) { - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", fixture.Name(), "-o", "jsonpath={.metadata.annotations.GitSSHCommand}") + 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(_ *Application) { - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", fixture.Name(), "-o", "jsonpath={.metadata.annotations.GitSSHCredsFileSHA}") + 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") }) @@ -135,7 +136,7 @@ func TestCustomToolWithSSHGitCredsDisabled(t *testing.T) { // add the private repo with ssh credentials CustomSSHKnownHostsAdded(). SSHRepoURLAdded(true). - RepoURLType(fixture.RepoURLTypeSSH). + RepoURLType(RepoURLTypeSSH). Path("cmp-gitsshcreds"). When(). IgnoreErrors(). @@ -163,9 +164,6 @@ func TestCustomToolWithEnv(t *testing.T) { Env: Env{{ Name: "FOO", Value: "bar", - }, { - Name: "EMPTY", - Value: "", }}, } }). @@ -174,33 +172,33 @@ func TestCustomToolWithEnv(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - And(func(_ *Application) { - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Bar}") + And(func(app *Application) { + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Bar}") require.NoError(t, err) assert.Equal(t, "baz", output) }). - And(func(_ *Application) { - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Foo}") + And(func(app *Application) { + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Foo}") require.NoError(t, err) assert.Equal(t, "bar", output) }). - And(func(_ *Application) { - expectedKubeVersion := fixture.GetVersions(t).ServerVersion.Format("%s.%s") - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeVersion}") + And(func(app *Application) { + expectedKubeVersion := GetVersions().ServerVersion.Format("%s.%s") + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeVersion}") require.NoError(t, err) assert.Equal(t, expectedKubeVersion, output) }). - And(func(_ *Application) { - expectedAPIVersion := fixture.GetApiResources(t) - expectedAPIVersionSlice := strings.Split(expectedAPIVersion, ",") - sort.Strings(expectedAPIVersionSlice) + And(func(app *Application) { + expectedApiVersion := GetApiResources() + expectedApiVersionSlice := strings.Split(expectedApiVersion, ",") + sort.Strings(expectedApiVersionSlice) - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeApiVersion}") + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeApiVersion}") require.NoError(t, err) outputSlice := strings.Split(output, ",") sort.Strings(outputSlice) - assert.Equal(t, expectedAPIVersionSlice, outputSlice) + assert.EqualValues(t, expectedApiVersionSlice, outputSlice) }) } @@ -225,17 +223,17 @@ func TestCustomToolSyncAndDiffLocal(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - And(func(_ *Application) { - errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "sync", ctx.AppName(), "--local", appPath, "--local-repo-root", testdataPath)) + And(func(app *Application) { + FailOnErr(RunCli("app", "sync", ctx.AppName(), "--local", appPath, "--local-repo-root", testdataPath)) }). - And(func(_ *Application) { - errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "diff", ctx.AppName(), "--local", appPath, "--local-repo-root", testdataPath)) + And(func(app *Application) { + FailOnErr(RunCli("app", "diff", ctx.AppName(), "--local", appPath, "--local-repo-root", testdataPath)) }) } func startCMPServer(t *testing.T, configFile string) { t.Helper() - pluginSockFilePath := fixture.TmpDir + fixture.PluginSockFilePath + 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 t.Setenv("ARGOCD_PLUGINSOCKFILEPATH", pluginSockFilePath) @@ -244,7 +242,7 @@ func startCMPServer(t *testing.T, configFile string) { err := os.Mkdir(pluginSockFilePath, 0o700) require.NoError(t, err) } - errors.NewHandler(t).FailOnErr(fixture.RunWithStdin("", "", "../../dist/argocd", "--config-dir-path", configFile)) + FailOnErr(RunWithStdin("", "", "../../dist/argocd", "--config-dir-path", configFile)) } // Discover by fileName @@ -323,28 +321,28 @@ func TestCMPDiscoverWithFindCommandWithEnv(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - And(func(_ *Application) { - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Bar}") + And(func(app *Application) { + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Bar}") require.NoError(t, err) assert.Equal(t, "baz", output) }). - And(func(_ *Application) { - expectedKubeVersion := fixture.GetVersions(t).ServerVersion.Format("%s.%s") - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeVersion}") + And(func(app *Application) { + expectedKubeVersion := GetVersions().ServerVersion.Format("%s.%s") + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeVersion}") require.NoError(t, err) assert.Equal(t, expectedKubeVersion, output) }). - And(func(_ *Application) { - expectedAPIVersion := fixture.GetApiResources(t) - expectedAPIVersionSlice := strings.Split(expectedAPIVersion, ",") - sort.Strings(expectedAPIVersionSlice) + And(func(app *Application) { + expectedApiVersion := GetApiResources() + expectedApiVersionSlice := strings.Split(expectedApiVersion, ",") + sort.Strings(expectedApiVersionSlice) - output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeApiVersion}") + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeApiVersion}") require.NoError(t, err) outputSlice := strings.Split(output, ",") sort.Strings(outputSlice) - assert.Equal(t, expectedAPIVersionSlice, outputSlice) + assert.EqualValues(t, expectedApiVersionSlice, outputSlice) }) } @@ -366,7 +364,7 @@ func TestPruneResourceFromCMP(t *testing.T) { Then(). Expect(DoesNotExist()). AndAction(func() { - _, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "deployment", "guestbook-ui") + _, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "deployment", "guestbook-ui") require.Error(t, err) }) } @@ -392,7 +390,7 @@ func TestPreserveFileModeForCMP(t *testing.T) { } func TestCMPWithSymlinkPartialFiles(t *testing.T) { - Given(t, fixture.WithTestData("testdata2")). + Given(t, WithTestData("testdata2")). And(func() { go startCMPServer(t, "./testdata2/cmp-symlink") time.Sleep(100 * time.Millisecond) @@ -409,7 +407,7 @@ func TestCMPWithSymlinkPartialFiles(t *testing.T) { } func TestCMPWithSymlinkFiles(t *testing.T) { - Given(t, fixture.WithTestData("testdata2")). + Given(t, WithTestData("testdata2")). And(func() { go startCMPServer(t, "./testdata2/cmp-symlink") time.Sleep(100 * time.Millisecond) @@ -426,7 +424,7 @@ func TestCMPWithSymlinkFiles(t *testing.T) { } func TestCMPWithSymlinkFolder(t *testing.T) { - Given(t, fixture.WithTestData("testdata2")). + Given(t, WithTestData("testdata2")). And(func() { go startCMPServer(t, "./testdata2/cmp-symlink") time.Sleep(100 * time.Millisecond) diff --git a/test/e2e/declarative_test.go b/test/e2e/declarative_test.go index 25d279c3ca..0b1649b527 100644 --- a/test/e2e/declarative_test.go +++ b/test/e2e/declarative_test.go @@ -6,8 +6,8 @@ import ( "github.com/argoproj/gitops-engine/pkg/health" . "github.com/argoproj/gitops-engine/pkg/sync/common" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" ) func TestDeclarativeHappyApp(t *testing.T) { diff --git a/test/e2e/deployment_test.go b/test/e2e/deployment_test.go index 2bfbf228fb..49ae9ad402 100644 --- a/test/e2e/deployment_test.go +++ b/test/e2e/deployment_test.go @@ -3,7 +3,6 @@ package e2e import ( "context" "encoding/json" - stderrors "errors" "fmt" "os" "testing" @@ -17,15 +16,17 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/tools/clientcmd" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/clusterauth" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/clusterauth" + "github.com/argoproj/argo-cd/v2/util/errors" "github.com/argoproj/gitops-engine/pkg/health" . "github.com/argoproj/gitops-engine/pkg/sync/common" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + . "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" ) // when we have a config map generator, AND the ignore annotation, it is ignored in the app's sync status @@ -53,7 +54,7 @@ func TestDeployment(t *testing.T) { func TestDeploymentWithAnnotationTrackingMode(t *testing.T) { ctx := Given(t) - require.NoError(t, SetTrackingMethod(string(TrackingMethodAnnotation))) + errors.CheckError(SetTrackingMethod(string(argo.TrackingMethodAnnotation))) ctx. Path("deployment"). When(). @@ -65,7 +66,7 @@ func TestDeploymentWithAnnotationTrackingMode(t *testing.T) { Expect(HealthIs(health.HealthStatusHealthy)). When(). Then(). - And(func(_ *Application) { + And(func(app *Application) { out, err := RunCli("app", "manifests", ctx.AppName()) require.NoError(t, err) assert.Contains(t, out, fmt.Sprintf(`annotations: @@ -76,7 +77,7 @@ func TestDeploymentWithAnnotationTrackingMode(t *testing.T) { func TestDeploymentWithLabelTrackingMode(t *testing.T) { ctx := Given(t) - require.NoError(t, SetTrackingMethod(string(TrackingMethodLabel))) + errors.CheckError(SetTrackingMethod(string(argo.TrackingMethodLabel))) ctx. Path("deployment"). When(). @@ -88,7 +89,7 @@ func TestDeploymentWithLabelTrackingMode(t *testing.T) { Expect(HealthIs(health.HealthStatusHealthy)). When(). Then(). - And(func(_ *Application) { + And(func(app *Application) { out, err := RunCli("app", "manifests", ctx.AppName()) require.NoError(t, err) assert.Contains(t, out, fmt.Sprintf(`labels: @@ -111,12 +112,13 @@ func TestDeploymentWithoutTrackingMode(t *testing.T) { Expect(HealthIs(health.HealthStatusHealthy)). When(). Then(). - And(func(_ *Application) { + And(func(app *Application) { out, err := RunCli("app", "manifests", ctx.AppName()) require.NoError(t, err) - assert.Contains(t, out, fmt.Sprintf(`annotations: - argocd.argoproj.io/tracking-id: %s:apps/Deployment:%s/nginx-deployment -`, ctx.AppName(), DeploymentNamespace())) + assert.Contains(t, out, fmt.Sprintf(`labels: + app: nginx + app.kubernetes.io/instance: %s +`, ctx.AppName())) }) } @@ -266,7 +268,7 @@ func createNamespaceScopedUser(t *testing.T, username string, clusterScopedSecre Name: username, }, } - _, err := KubeClientset.CoreV1().Namespaces().Create(t.Context(), &ns, metav1.CreateOptions{}) + _, err := KubeClientset.CoreV1().Namespaces().Create(context.Background(), &ns, metav1.CreateOptions{}) require.NoError(t, err) // Create a ServiceAccount in that Namespace, which will be used for the Argo CD Cluster SEcret @@ -286,7 +288,7 @@ func createNamespaceScopedUser(t *testing.T, username string, clusterScopedSecre APIGroups: []string{"*"}, }}, } - _, err = KubeClientset.RbacV1().Roles(role.Namespace).Create(t.Context(), &role, metav1.CreateOptions{}) + _, err = KubeClientset.RbacV1().Roles(role.Namespace).Create(context.Background(), &role, metav1.CreateOptions{}) require.NoError(t, err) // Bind the Role with the ServiceAccount in the Namespace @@ -306,14 +308,14 @@ func createNamespaceScopedUser(t *testing.T, username string, clusterScopedSecre Name: role.Name, }, } - _, err = KubeClientset.RbacV1().RoleBindings(roleBinding.Namespace).Create(t.Context(), &roleBinding, metav1.CreateOptions{}) + _, err = KubeClientset.RbacV1().RoleBindings(roleBinding.Namespace).Create(context.Background(), &roleBinding, metav1.CreateOptions{}) require.NoError(t, err) var token string // Attempting to patch the ServiceAccount can intermittently fail with 'failed to patch serviceaccount "(...)" with bearer token secret: Operation cannot be fulfilled on serviceaccounts "(...)": the object has been modified; please apply your changes to the latest version and try again' // We thus keep trying for up to 20 seconds. - waitErr := wait.PollUntilContextTimeout(t.Context(), 1*time.Second, 20*time.Second, true, func(context.Context) (done bool, err error) { + waitErr := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 20*time.Second, true, func(context.Context) (done bool, err error) { // Retrieve the bearer token from the ServiceAccount token, err = clusterauth.GetServiceAccountBearerToken(KubeClientset, ns.Name, serviceAccountName, time.Second*60) @@ -327,10 +329,10 @@ func createNamespaceScopedUser(t *testing.T, username string, clusterScopedSecre if clusterScopedSecrets { clusterRole, clusterRoleBinding := generateReadOnlyClusterRoleandBindingForServiceAccount(username, username) - _, err := KubeClientset.RbacV1().ClusterRoles().Create(t.Context(), &clusterRole, metav1.CreateOptions{}) + _, err := KubeClientset.RbacV1().ClusterRoles().Create(context.Background(), &clusterRole, metav1.CreateOptions{}) require.NoError(t, err) - _, err = KubeClientset.RbacV1().ClusterRoleBindings().Create(t.Context(), &clusterRoleBinding, metav1.CreateOptions{}) + _, err = KubeClientset.RbacV1().ClusterRoleBindings().Create(context.Background(), &clusterRoleBinding, metav1.CreateOptions{}) require.NoError(t, err) } @@ -363,7 +365,7 @@ func createNamespaceScopedUser(t *testing.T, username string, clusterScopedSecre string(jsonStringBytes), clusterResourcesField, namespacesField) // Finally, create the Cluster secret in the Argo CD E2E namespace - _, err = KubeClientset.CoreV1().Secrets(secret.Namespace).Create(t.Context(), &secret, metav1.CreateOptions{}) + _, err = KubeClientset.CoreV1().Secrets(secret.Namespace).Create(context.Background(), &secret, metav1.CreateOptions{}) require.NoError(t, err) } @@ -382,12 +384,12 @@ func extractKubeConfigValues() (string, string, error) { context, ok := config.Contexts[config.CurrentContext] if !ok || context == nil { - return "", "", stderrors.New("no context") + return "", "", fmt.Errorf("no context") } cluster, ok := config.Clusters[context.Cluster] if !ok || cluster == nil { - return "", "", stderrors.New("no cluster") + return "", "", fmt.Errorf("no cluster") } var kubeConfigDefault string @@ -405,7 +407,7 @@ func extractKubeConfigValues() (string, string, error) { } if kubeConfigDefault == "" { - return "", "", stderrors.New("unable to retrieve kube config path") + return "", "", fmt.Errorf("unable to retrieve kube config path") } } diff --git a/test/e2e/diff_test.go b/test/e2e/diff_test.go index a7e65175a7..feb295d9c0 100644 --- a/test/e2e/diff_test.go +++ b/test/e2e/diff_test.go @@ -5,9 +5,9 @@ import ( . "github.com/argoproj/gitops-engine/pkg/sync/common" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/test/fixture/test" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/test/fixture/test" ) func TestPatch(t *testing.T) { diff --git a/test/e2e/fixture/account/actions.go b/test/e2e/fixture/account/actions.go index 209d824254..41b6b2a63b 100644 --- a/test/e2e/fixture/account/actions.go +++ b/test/e2e/fixture/account/actions.go @@ -1,11 +1,8 @@ package project import ( - "time" - - "github.com/stretchr/testify/require" - - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/errors" ) // this implements the "when" part of given/when/then @@ -50,8 +47,7 @@ func (a *Actions) prepareSetPasswordArgs(account string) []string { } func (a *Actions) Create() *Actions { - a.context.t.Helper() - require.NoError(a.context.t, fixture.SetAccounts(map[string][]string{ + errors.CheckError(fixture.SetAccounts(map[string][]string{ a.context.name: {"login"}, })) _, _ = fixture.RunCli(a.prepareSetPasswordArgs(a.context.name)...) @@ -59,20 +55,17 @@ func (a *Actions) Create() *Actions { } func (a *Actions) SetPermissions(permissions []fixture.ACL, roleName string) *Actions { - a.context.t.Helper() - require.NoError(a.context.t, fixture.SetPermissions(permissions, a.context.name, roleName)) + errors.CheckError(fixture.SetPermissions(permissions, a.context.name, roleName)) return a } func (a *Actions) SetParamInSettingConfigMap(key, value string) *Actions { - a.context.t.Helper() - require.NoError(a.context.t, fixture.SetParamInSettingConfigMap(key, value)) + errors.CheckError(fixture.SetParamInSettingConfigMap(key, value)) return a } func (a *Actions) Login() *Actions { - a.context.t.Helper() - require.NoError(a.context.t, fixture.LoginAs(a.context.name)) + errors.CheckError(fixture.LoginAs(a.context.name)) return a } @@ -83,6 +76,5 @@ func (a *Actions) runCli(args ...string) { func (a *Actions) Then() *Consequences { a.context.t.Helper() - time.Sleep(fixture.WhenThenSleepInterval) return &Consequences{a.context, a} } diff --git a/test/e2e/fixture/account/consequences.go b/test/e2e/fixture/account/consequences.go index ea98242b2a..dee78bd39c 100644 --- a/test/e2e/fixture/account/consequences.go +++ b/test/e2e/fixture/account/consequences.go @@ -3,15 +3,13 @@ package project import ( "context" "errors" - "time" - "github.com/stretchr/testify/require" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" - - "github.com/argoproj/argo-cd/v3/pkg/apiclient/account" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/account" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/io" ) // this implements the "then" part of given/when/then @@ -53,10 +51,9 @@ func (c *Consequences) get() (*account.Account, error) { } func (c *Consequences) getCurrentUser() (*session.GetUserInfoResponse, error) { - c.context.t.Helper() closer, client, err := fixture.ArgoCDClientset.NewSessionClient() - require.NoError(c.context.t, err) - defer utilio.Close(closer) + CheckError(err) + defer io.Close(closer) return client.GetUserInfo(context.Background(), &session.GetUserInfoRequest{}) } @@ -65,6 +62,5 @@ func (c *Consequences) Given() *Context { } func (c *Consequences) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return c.actions } diff --git a/test/e2e/fixture/account/context.go b/test/e2e/fixture/account/context.go index 2f9af3b47a..8013030a95 100644 --- a/test/e2e/fixture/account/context.go +++ b/test/e2e/fixture/account/context.go @@ -2,10 +2,9 @@ package project import ( "testing" - "time" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/env" ) // this implements the "given" part of given/when/then @@ -46,6 +45,5 @@ func (c *Context) And(block func()) *Context { } func (c *Context) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return &Actions{context: c} } diff --git a/test/e2e/fixture/admin/actions.go b/test/e2e/fixture/admin/actions.go index 1c534df0f9..4519d228f9 100644 --- a/test/e2e/fixture/admin/actions.go +++ b/test/e2e/fixture/admin/actions.go @@ -1,9 +1,7 @@ package admin import ( - "time" - - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" ) // this implements the "when" part of given/when/then @@ -65,6 +63,5 @@ func (a *Actions) runCliWithStdin(stdin string, args ...string) { func (a *Actions) Then() *Consequences { a.context.t.Helper() - time.Sleep(fixture.WhenThenSleepInterval) return &Consequences{a.context, a} } diff --git a/test/e2e/fixture/admin/consequences.go b/test/e2e/fixture/admin/consequences.go index 3216d71236..bc65f3a532 100644 --- a/test/e2e/fixture/admin/consequences.go +++ b/test/e2e/fixture/admin/consequences.go @@ -1,10 +1,7 @@ package admin import ( - "time" - - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/admin/utils" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/admin/utils" ) // this implements the "then" part of given/when/then @@ -26,8 +23,8 @@ func (c *Consequences) AndCLIOutput(block func(output string, err error)) *Conse } // For use after running export with the exported resources desirialized -func (c *Consequences) AndExportedResources(block func(resources *utils.ExportedResources, err error)) { - result, err := utils.GetExportedResourcesFromOutput(c.actions.lastOutput) +func (c *Consequences) AndExportedResources(block func(resources *ExportedResources, err error)) { + result, err := GetExportedResourcesFromOutput(c.actions.lastOutput) block(&result, err) } @@ -36,6 +33,5 @@ func (c *Consequences) Given() *Context { } func (c *Consequences) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return c.actions } diff --git a/test/e2e/fixture/admin/context.go b/test/e2e/fixture/admin/context.go index 8b8b44bef4..017407f0c9 100644 --- a/test/e2e/fixture/admin/context.go +++ b/test/e2e/fixture/admin/context.go @@ -2,10 +2,9 @@ package admin import ( "testing" - "time" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/env" ) // this implements the "given" part of given/when/then @@ -40,6 +39,5 @@ func (c *Context) And(block func()) *Context { } func (c *Context) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return &Actions{context: c} } diff --git a/test/e2e/fixture/admin/fixture.go b/test/e2e/fixture/admin/fixture.go index 08cdf69abe..92216c58d4 100644 --- a/test/e2e/fixture/admin/fixture.go +++ b/test/e2e/fixture/admin/fixture.go @@ -1,7 +1,7 @@ package admin import ( - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" ) // For admin CLI with kubernetes context diff --git a/test/e2e/fixture/admin/utils/backup.go b/test/e2e/fixture/admin/utils/backup.go index f68a5ff2b2..79bd890518 100644 --- a/test/e2e/fixture/admin/utils/backup.go +++ b/test/e2e/fixture/admin/utils/backup.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "github.com/argoproj/gitops-engine/pkg/utils/kube" + kube "github.com/argoproj/gitops-engine/pkg/utils/kube" yaml "gopkg.in/yaml.v3" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -13,7 +13,7 @@ type ExportedResources []unstructured.Unstructured func GetExportedResourcesFromOutput(output string) (ExportedResources, error) { var resources []unstructured.Unstructured - docs := strings.Split(output, "\n---\n") + docs := strings.Split(output, "---") for _, doc := range docs { doc = strings.TrimSpace(doc) @@ -21,7 +21,7 @@ func GetExportedResourcesFromOutput(output string) (ExportedResources, error) { continue } - var resourceData map[string]any + var resourceData map[string]interface{} if err := yaml.Unmarshal([]byte(doc), &resourceData); err != nil { return nil, fmt.Errorf("error unmarshaling YAML: %w", err) diff --git a/test/e2e/fixture/app/actions.go b/test/e2e/fixture/app/actions.go index 4a7ee3a0ce..83b097eb09 100644 --- a/test/e2e/fixture/app/actions.go +++ b/test/e2e/fixture/app/actions.go @@ -7,16 +7,14 @@ import ( "slices" "strconv" - rbacv1 "k8s.io/api/rbac/v1" - log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - client "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/util/grpc" + client "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + . "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/util/errors" + "github.com/argoproj/argo-cd/v2/util/grpc" ) // this implements the "when" part of given/when/then @@ -42,43 +40,43 @@ func (a *Actions) DoNotIgnoreErrors() *Actions { func (a *Actions) PatchFile(file string, jsonPath string) *Actions { a.context.t.Helper() - fixture.Patch(a.context.t, a.context.path+"/"+file, jsonPath) + fixture.Patch(a.context.path+"/"+file, jsonPath) return a } func (a *Actions) DeleteFile(file string) *Actions { a.context.t.Helper() - fixture.Delete(a.context.t, a.context.path+"/"+file) + fixture.Delete(a.context.path + "/" + file) return a } func (a *Actions) WriteFile(fileName, fileContents string) *Actions { a.context.t.Helper() - fixture.WriteFile(a.context.t, a.context.path+"/"+fileName, fileContents) + fixture.WriteFile(a.context.path+"/"+fileName, fileContents) return a } func (a *Actions) AddFile(fileName, fileContents string) *Actions { a.context.t.Helper() - fixture.AddFile(a.context.t, a.context.path+"/"+fileName, fileContents) + fixture.AddFile(a.context.path+"/"+fileName, fileContents) return a } func (a *Actions) AddSignedFile(fileName, fileContents string) *Actions { a.context.t.Helper() - fixture.AddSignedFile(a.context.t, a.context.path+"/"+fileName, fileContents) + fixture.AddSignedFile(a.context.path+"/"+fileName, fileContents) return a } func (a *Actions) AddSignedTag(name string) *Actions { a.context.t.Helper() - fixture.AddSignedTag(a.context.t, name) + fixture.AddSignedTag(name) return a } func (a *Actions) AddTag(name string) *Actions { a.context.t.Helper() - fixture.AddTag(a.context.t, name) + fixture.AddTag(name) return a } @@ -96,16 +94,16 @@ func (a *Actions) AddTagWithForce(name string) *Actions { func (a *Actions) RemoveSubmodule() *Actions { a.context.t.Helper() - fixture.RemoveSubmodule(a.context.t) + fixture.RemoveSubmodule() return a } func (a *Actions) CreateFromPartialFile(data string, flags ...string) *Actions { a.context.t.Helper() tmpFile, err := os.CreateTemp("", "") - require.NoError(a.context.t, err) + errors.CheckError(err) _, err = tmpFile.Write([]byte(data)) - require.NoError(a.context.t, err) + errors.CheckError(err) args := append([]string{ "app", "create", @@ -123,20 +121,20 @@ func (a *Actions) CreateFromPartialFile(data string, flags ...string) *Actions { return a } -func (a *Actions) CreateFromFile(handler func(app *v1alpha1.Application), flags ...string) *Actions { +func (a *Actions) CreateFromFile(handler func(app *Application), flags ...string) *Actions { a.context.t.Helper() - app := &v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{ + app := &Application{ + ObjectMeta: v1.ObjectMeta{ Name: a.context.AppName(), Namespace: a.context.AppNamespace(), }, - Spec: v1alpha1.ApplicationSpec{ + Spec: ApplicationSpec{ Project: a.context.project, - Source: &v1alpha1.ApplicationSource{ + Source: &ApplicationSource{ RepoURL: fixture.RepoURL(a.context.repoURLType), Path: a.context.path, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: ApplicationDestination{ Server: a.context.destServer, Namespace: fixture.DeploymentNamespace(), }, @@ -144,32 +142,32 @@ func (a *Actions) CreateFromFile(handler func(app *v1alpha1.Application), flags } source := app.Spec.GetSource() if a.context.namePrefix != "" || a.context.nameSuffix != "" { - source.Kustomize = &v1alpha1.ApplicationSourceKustomize{ + source.Kustomize = &ApplicationSourceKustomize{ NamePrefix: a.context.namePrefix, NameSuffix: a.context.nameSuffix, } } if a.context.configManagementPlugin != "" { - source.Plugin = &v1alpha1.ApplicationSourcePlugin{ + source.Plugin = &ApplicationSourcePlugin{ Name: a.context.configManagementPlugin, } } if len(a.context.parameters) > 0 { - log.Fatal("v1alpha1.Application parameters or json tlas are not supported") + log.Fatal("Application parameters or json tlas are not supported") } if a.context.directoryRecurse { - source.Directory = &v1alpha1.ApplicationSourceDirectory{Recurse: true} + source.Directory = &ApplicationSourceDirectory{Recurse: true} } app.Spec.Source = &source handler(app) data := grpc.MustMarshal(app) tmpFile, err := os.CreateTemp("", "") - require.NoError(a.context.t, err) + errors.CheckError(err) _, err = tmpFile.Write(data) - require.NoError(a.context.t, err) + errors.CheckError(err) args := append([]string{ "app", "create", @@ -182,20 +180,20 @@ func (a *Actions) CreateFromFile(handler func(app *v1alpha1.Application), flags func (a *Actions) CreateMultiSourceAppFromFile(flags ...string) *Actions { a.context.t.Helper() - app := &v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{ + app := &Application{ + ObjectMeta: v1.ObjectMeta{ Name: a.context.AppName(), Namespace: a.context.AppNamespace(), }, - Spec: v1alpha1.ApplicationSpec{ + Spec: ApplicationSpec{ Project: a.context.project, Sources: a.context.sources, - Destination: v1alpha1.ApplicationDestination{ + Destination: ApplicationDestination{ Server: a.context.destServer, Namespace: fixture.DeploymentNamespace(), }, - SyncPolicy: &v1alpha1.SyncPolicy{ - Automated: &v1alpha1.SyncPolicyAutomated{ + SyncPolicy: &SyncPolicy{ + Automated: &SyncPolicyAutomated{ SelfHeal: true, }, }, @@ -204,9 +202,9 @@ func (a *Actions) CreateMultiSourceAppFromFile(flags ...string) *Actions { data := grpc.MustMarshal(app) tmpFile, err := os.CreateTemp("", "") - require.NoError(a.context.t, err) + errors.CheckError(err) _, err = tmpFile.Write(data) - require.NoError(a.context.t, err) + errors.CheckError(err) args := append([]string{ "app", "create", @@ -326,7 +324,7 @@ func (a *Actions) Declarative(filename string) *Actions { func (a *Actions) DeclarativeWithCustomRepo(filename string, repoURL string) *Actions { a.context.t.Helper() - values := map[string]any{ + values := map[string]interface{}{ "ArgoCDNamespace": fixture.TestNamespace(), "DeploymentNamespace": fixture.DeploymentNamespace(), "Name": a.context.AppName(), @@ -334,7 +332,7 @@ func (a *Actions) DeclarativeWithCustomRepo(filename string, repoURL string) *Ac "Project": a.context.project, "RepoURL": repoURL, } - a.lastOutput, a.lastError = fixture.Declarative(a.context.t, filename, values) + a.lastOutput, a.lastError = fixture.Declarative(filename, values) a.verifyAction() return a } @@ -345,9 +343,9 @@ func (a *Actions) PatchApp(patch string) *Actions { return a } -func (a *Actions) PatchAppHttp(patch string) *Actions { //nolint:revive //FIXME(var-naming) +func (a *Actions) PatchAppHttp(patch string) *Actions { a.context.t.Helper() - var application v1alpha1.Application + var application Application patchType := "merge" appName := a.context.AppQualifiedName() appNamespace := a.context.AppNamespace() @@ -358,12 +356,12 @@ func (a *Actions) PatchAppHttp(patch string) *Actions { //nolint:revive //FIXME( AppNamespace: &appNamespace, } jsonBytes, err := json.MarshalIndent(patchRequest, "", " ") - require.NoError(a.context.t, err) + errors.CheckError(err) err = fixture.DoHttpJsonRequest("PATCH", fmt.Sprintf("/api/v1/applications/%v", appName), &application, jsonBytes...) - require.NoError(a.context.t, err) + errors.CheckError(err) return a } @@ -443,11 +441,11 @@ func (a *Actions) TerminateOp() *Actions { return a } -func (a *Actions) Refresh(refreshType v1alpha1.RefreshType) *Actions { +func (a *Actions) Refresh(refreshType RefreshType) *Actions { a.context.t.Helper() - flag := map[v1alpha1.RefreshType]string{ - v1alpha1.RefreshTypeNormal: "--refresh", - v1alpha1.RefreshTypeHard: "--hard-refresh", + flag := map[RefreshType]string{ + RefreshTypeNormal: "--refresh", + RefreshTypeHard: "--hard-refresh", }[refreshType] a.runCli("app", "get", a.context.AppQualifiedName(), flag) @@ -469,13 +467,13 @@ func (a *Actions) Delete(cascade bool) *Actions { func (a *Actions) DeleteBySelector(selector string) *Actions { a.context.t.Helper() - a.runCli("app", "delete", "--selector="+selector, "--yes") + a.runCli("app", "delete", fmt.Sprintf("--selector=%s", selector), "--yes") return a } func (a *Actions) DeleteBySelectorWithWait(selector string) *Actions { a.context.t.Helper() - a.runCli("app", "delete", "--selector="+selector, "--yes", "--wait") + a.runCli("app", "delete", fmt.Sprintf("--selector=%s", selector), "--yes", "--wait") return a } @@ -491,8 +489,7 @@ func (a *Actions) Wait(args ...string) *Actions { } func (a *Actions) SetParamInSettingConfigMap(key, value string) *Actions { - a.context.t.Helper() - require.NoError(a.context.t, fixture.SetParamInSettingConfigMap(key, value)) + errors.CheckError(fixture.SetParamInSettingConfigMap(key, value)) return a } @@ -521,35 +518,16 @@ func (a *Actions) verifyAction() { } func (a *Actions) SetTrackingMethod(trackingMethod string) *Actions { - a.context.t.Helper() - require.NoError(a.context.t, fixture.SetTrackingMethod(trackingMethod)) + errors.CheckError(fixture.SetTrackingMethod(trackingMethod)) return a } func (a *Actions) SetInstallationID(installationID string) *Actions { - a.context.t.Helper() - require.NoError(a.context.t, fixture.SetInstallationID(installationID)) + errors.CheckError(fixture.SetInstallationID(installationID)) return a } func (a *Actions) SetTrackingLabel(trackingLabel string) *Actions { - a.context.t.Helper() - require.NoError(a.context.t, fixture.SetTrackingLabel(trackingLabel)) - return a -} - -func (a *Actions) WithImpersonationEnabled(serviceAccountName string, policyRules []rbacv1.PolicyRule) *Actions { - a.context.t.Helper() - require.NoError(a.context.t, fixture.SetImpersonationEnabled("true")) - if serviceAccountName == "" || policyRules == nil { - return a - } - require.NoError(a.context.t, fixture.CreateRBACResourcesForImpersonation(serviceAccountName, policyRules)) - return a -} - -func (a *Actions) WithImpersonationDisabled() *Actions { - a.context.t.Helper() - require.NoError(a.context.t, fixture.SetImpersonationEnabled("false")) + errors.CheckError(fixture.SetTrackingLabel(trackingLabel)) return a } diff --git a/test/e2e/fixture/app/consequences.go b/test/e2e/fixture/app/consequences.go index 985e5a8126..0aaed85008 100644 --- a/test/e2e/fixture/app/consequences.go +++ b/test/e2e/fixture/app/consequences.go @@ -6,14 +6,11 @@ import ( "github.com/argoproj/gitops-engine/pkg/health" log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/utils/ptr" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - utilio "github.com/argoproj/argo-cd/v3/util/io" + . "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/util/errors" ) // this implements the "then" part of given/when/then @@ -84,7 +81,7 @@ func (c *Consequences) ExpectConsistently(e Expectation, waitDuration time.Durat return c } -func (c *Consequences) And(block func(app *v1alpha1.Application)) *Consequences { +func (c *Consequences) And(block func(app *Application)) *Consequences { c.context.t.Helper() block(c.app()) return c @@ -101,39 +98,27 @@ func (c *Consequences) Given() *Context { } func (c *Consequences) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return c.actions } -func (c *Consequences) app() *v1alpha1.Application { - c.context.t.Helper() +func (c *Consequences) app() *Application { app, err := c.get() - require.NoError(c.context.t, err) + errors.CheckError(err) return app } -func (c *Consequences) get() (*v1alpha1.Application, error) { - return fixture.AppClientset.ArgoprojV1alpha1().Applications(c.context.AppNamespace()).Get(context.Background(), c.context.AppName(), metav1.GetOptions{}) +func (c *Consequences) get() (*Application, error) { + return fixture.AppClientset.ArgoprojV1alpha1().Applications(c.context.AppNamespace()).Get(context.Background(), c.context.AppName(), v1.GetOptions{}) } -func (c *Consequences) resource(kind, name, namespace string) v1alpha1.ResourceStatus { - c.context.t.Helper() - closer, client, err := fixture.ArgoCDClientset.NewApplicationClient() - require.NoError(c.context.t, err) - defer utilio.Close(closer) - app, err := client.Get(context.Background(), &applicationpkg.ApplicationQuery{ - Name: ptr.To(c.context.AppName()), - Projects: []string{c.context.project}, - AppNamespace: ptr.To(c.context.appNamespace), - }) - require.NoError(c.context.t, err) - for _, r := range app.Status.Resources { +func (c *Consequences) resource(kind, name, namespace string) ResourceStatus { + for _, r := range c.app().Status.Resources { if r.Kind == kind && r.Name == name && (namespace == "" || namespace == r.Namespace) { return r } } - return v1alpha1.ResourceStatus{ - Health: &v1alpha1.HealthStatus{ + return ResourceStatus{ + Health: &HealthStatus{ Status: health.HealthStatusMissing, Message: "not found", }, diff --git a/test/e2e/fixture/app/context.go b/test/e2e/fixture/app/context.go index f3343e7d17..b013f7fbd4 100644 --- a/test/e2e/fixture/app/context.go +++ b/test/e2e/fixture/app/context.go @@ -4,15 +4,15 @@ import ( "testing" "time" - "github.com/stretchr/testify/require" - - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/certs" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/gpgkeys" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/repos" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/settings" + "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/certs" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/gpgkeys" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/settings" ) // Context implements the "given" part of given/when/then @@ -87,7 +87,7 @@ func GivenWithSameState(t *testing.T) *Context { timeout: timeout, project: "default", prune: true, - trackingMethod: v1alpha1.TrackingMethodLabel, + trackingMethod: argo.TrackingMethodLabel, } } @@ -98,15 +98,17 @@ func (c *Context) AppName() string { func (c *Context) AppQualifiedName() string { if c.appNamespace != "" { return c.appNamespace + "/" + c.AppName() + } else { + return c.AppName() } - return c.AppName() } func (c *Context) AppNamespace() string { if c.appNamespace != "" { return c.appNamespace + } else { + return fixture.TestNamespace() } - return fixture.TestNamespace() } func (c *Context) SetAppNamespace(namespace string) *Context { @@ -116,110 +118,109 @@ func (c *Context) SetAppNamespace(namespace string) *Context { } func (c *Context) GPGPublicKeyAdded() *Context { - gpgkeys.AddGPGPublicKey(c.t) + gpgkeys.AddGPGPublicKey() return c } func (c *Context) GPGPublicKeyRemoved() *Context { - gpgkeys.DeleteGPGPublicKey(c.t) + gpgkeys.DeleteGPGPublicKey() return c } func (c *Context) CustomCACertAdded() *Context { - certs.AddCustomCACert(c.t) + certs.AddCustomCACert() return c } func (c *Context) CustomSSHKnownHostsAdded() *Context { - certs.AddCustomSSHKnownHostsKeys(c.t) + certs.AddCustomSSHKnownHostsKeys() return c } func (c *Context) HTTPSRepoURLAdded(withCreds bool) *Context { - repos.AddHTTPSRepo(c.t, false, withCreds, "", fixture.RepoURLTypeHTTPS) + repos.AddHTTPSRepo(false, withCreds, fixture.RepoURLTypeHTTPS) return c } func (c *Context) HTTPSInsecureRepoURLAdded(withCreds bool) *Context { - repos.AddHTTPSRepo(c.t, true, withCreds, "", fixture.RepoURLTypeHTTPS) + repos.AddHTTPSRepo(true, withCreds, fixture.RepoURLTypeHTTPS) return c } func (c *Context) HTTPSInsecureRepoURLWithClientCertAdded() *Context { - repos.AddHTTPSRepoClientCert(c.t, true) + repos.AddHTTPSRepoClientCert(true) return c } func (c *Context) HTTPSRepoURLWithClientCertAdded() *Context { - repos.AddHTTPSRepoClientCert(c.t, false) + repos.AddHTTPSRepoClientCert(false) return c } func (c *Context) SubmoduleHTTPSRepoURLAdded(withCreds bool) *Context { - fixture.CreateSubmoduleRepos(c.t, "https") - repos.AddHTTPSRepo(c.t, false, withCreds, "", fixture.RepoURLTypeHTTPSSubmoduleParent) + fixture.CreateSubmoduleRepos("https") + repos.AddHTTPSRepo(false, withCreds, fixture.RepoURLTypeHTTPSSubmoduleParent) return c } func (c *Context) SSHRepoURLAdded(withCreds bool) *Context { - repos.AddSSHRepo(c.t, false, withCreds, fixture.RepoURLTypeSSH) + repos.AddSSHRepo(false, withCreds, fixture.RepoURLTypeSSH) return c } func (c *Context) SSHInsecureRepoURLAdded(withCreds bool) *Context { - repos.AddSSHRepo(c.t, true, withCreds, fixture.RepoURLTypeSSH) + repos.AddSSHRepo(true, withCreds, fixture.RepoURLTypeSSH) return c } func (c *Context) SubmoduleSSHRepoURLAdded(withCreds bool) *Context { - fixture.CreateSubmoduleRepos(c.t, "ssh") - repos.AddSSHRepo(c.t, false, withCreds, fixture.RepoURLTypeSSHSubmoduleParent) + fixture.CreateSubmoduleRepos("ssh") + repos.AddSSHRepo(false, withCreds, fixture.RepoURLTypeSSHSubmoduleParent) return c } func (c *Context) HelmRepoAdded(name string) *Context { - repos.AddHelmRepo(c.t, name) + repos.AddHelmRepo(name) return c } func (c *Context) HelmOCIRepoAdded(name string) *Context { - repos.AddHelmOCIRepo(c.t, name) + repos.AddHelmOCIRepo(name) return c } func (c *Context) PushChartToOCIRegistry(chartPathName, chartName, chartVersion string) *Context { - repos.PushChartToOCIRegistry(c.t, chartPathName, chartName, chartVersion) + repos.PushChartToOCIRegistry(chartPathName, chartName, chartVersion) return c } func (c *Context) HTTPSCredentialsUserPassAdded() *Context { - repos.AddHTTPSCredentialsUserPass(c.t) + repos.AddHTTPSCredentialsUserPass() return c } func (c *Context) HelmHTTPSCredentialsUserPassAdded() *Context { - repos.AddHelmHTTPSCredentialsTLSClientCert(c.t) + repos.AddHelmHTTPSCredentialsTLSClientCert() return c } func (c *Context) HelmoOCICredentialsWithoutUserPassAdded() *Context { - repos.AddHelmoOCICredentialsWithoutUserPass(c.t) + repos.AddHelmoOCICredentialsWithoutUserPass() return c } func (c *Context) HTTPSCredentialsTLSClientCertAdded() *Context { - repos.AddHTTPSCredentialsTLSClientCert(c.t) + repos.AddHTTPSCredentialsTLSClientCert() return c } func (c *Context) SSHCredentialsAdded() *Context { - repos.AddSSHCredentials(c.t) + repos.AddSSHCredentials() return c } func (c *Context) ProjectSpec(spec v1alpha1.AppProjectSpec) *Context { - c.t.Helper() - require.NoError(c.t, fixture.SetProjectSpec(c.project, spec)) + errors.CheckError(fixture.SetProjectSpec(c.project, spec)) return c } @@ -331,14 +332,12 @@ func (c *Context) NameSuffix(nameSuffix string) *Context { } func (c *Context) ResourceOverrides(overrides map[string]v1alpha1.ResourceOverride) *Context { - c.t.Helper() - require.NoError(c.t, fixture.SetResourceOverrides(overrides)) + errors.CheckError(fixture.SetResourceOverrides(overrides)) return c } func (c *Context) ResourceFilter(filter settings.ResourcesFilter) *Context { - c.t.Helper() - require.NoError(c.t, fixture.SetResourceFilter(filter)) + errors.CheckError(fixture.SetResourceFilter(filter)) return c } @@ -348,7 +347,6 @@ func (c *Context) And(block func()) *Context { } func (c *Context) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return &Actions{context: c} } @@ -408,14 +406,12 @@ func (c *Context) HelmSkipTests() *Context { } func (c *Context) SetTrackingMethod(trackingMethod string) *Context { - c.t.Helper() - require.NoError(c.t, fixture.SetTrackingMethod(trackingMethod)) + errors.CheckError(fixture.SetTrackingMethod(trackingMethod)) return c } func (c *Context) SetInstallationID(installationID string) *Context { - c.t.Helper() - require.NoError(c.t, fixture.SetInstallationID(installationID)) + errors.CheckError(fixture.SetInstallationID(installationID)) return c } diff --git a/test/e2e/fixture/app/expectation.go b/test/e2e/fixture/app/expectation.go index 5c952553bd..b5e83a6640 100644 --- a/test/e2e/fixture/app/expectation.go +++ b/test/e2e/fixture/app/expectation.go @@ -8,14 +8,14 @@ import ( "strings" "github.com/argoproj/gitops-engine/pkg/health" - "github.com/argoproj/gitops-engine/pkg/sync/common" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + . "github.com/argoproj/gitops-engine/pkg/sync/common" + v1 "k8s.io/api/core/v1" + apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" ) type state = string @@ -28,10 +28,10 @@ const ( type Expectation func(c *Consequences) (state state, message string) -func OperationPhaseIs(expected common.OperationPhase) Expectation { +func OperationPhaseIs(expected OperationPhase) Expectation { return func(c *Consequences) (state, string) { operationState := c.app().Status.OperationState - actual := common.OperationRunning + actual := OperationRunning if operationState != nil { actual = operationState.Phase } @@ -53,18 +53,19 @@ func OperationMessageContains(text string) Expectation { func simple(success bool, message string) (state, string) { if success { return succeeded, message + } else { + return pending, message } - return pending, message } -func SyncStatusIs(expected v1alpha1.SyncStatusCode) Expectation { +func SyncStatusIs(expected SyncStatusCode) Expectation { return func(c *Consequences) (state, string) { actual := c.app().Status.Sync.Status return simple(actual == expected, fmt.Sprintf("sync status to be %s, is %s", expected, actual)) } } -func Condition(conditionType v1alpha1.ApplicationConditionType, conditionMessage string) Expectation { +func Condition(conditionType ApplicationConditionType, conditionMessage string) Expectation { return func(c *Consequences) (state, string) { got := c.app().Status.Conditions message := fmt.Sprintf("condition {%s %s} in %v", conditionType, conditionMessage, got) @@ -107,11 +108,11 @@ func StatusExists() Expectation { } } -func Namespace(name string, block func(app *v1alpha1.Application, ns *corev1.Namespace)) Expectation { +func Namespace(name string, block func(app *Application, ns *v1.Namespace)) Expectation { return func(c *Consequences) (state, string) { ns, err := namespace(name) if err != nil { - return failed, "namespace not found " + err.Error() + return failed, fmt.Sprintf("namespace not found %s", err.Error()) } block(c.app(), ns) @@ -126,14 +127,14 @@ func HealthIs(expected health.HealthStatusCode) Expectation { } } -func ResourceSyncStatusIs(kind, resource string, expected v1alpha1.SyncStatusCode) Expectation { +func ResourceSyncStatusIs(kind, resource string, expected SyncStatusCode) Expectation { return func(c *Consequences) (state, string) { actual := c.resource(kind, resource, "").Status return simple(actual == expected, fmt.Sprintf("resource '%s/%s' sync status should be %s, is %s", kind, resource, expected, actual)) } } -func ResourceSyncStatusWithNamespaceIs(kind, resource, namespace string, expected v1alpha1.SyncStatusCode) Expectation { +func ResourceSyncStatusWithNamespaceIs(kind, resource, namespace string, expected SyncStatusCode) Expectation { return func(c *Consequences) (state, string) { actual := c.resource(kind, resource, namespace).Status return simple(actual == expected, fmt.Sprintf("resource '%s/%s' sync status should be %s, is %s", kind, resource, expected, actual)) @@ -175,12 +176,13 @@ func ResourceResultNumbering(num int) Expectation { return pending, fmt.Sprintf("not enough results yet, want %d, got %d", num, actualNum) } else if actualNum == num { return succeeded, fmt.Sprintf("right number of results, want %d, got %d", num, actualNum) + } else { + return failed, fmt.Sprintf("too many results, want %d, got %d", num, actualNum) } - return failed, fmt.Sprintf("too many results, want %d, got %d", num, actualNum) } } -func ResourceResultIs(result v1alpha1.ResourceResult) Expectation { +func ResourceResultIs(result ResourceResult) Expectation { return func(c *Consequences) (state, string) { results := c.app().Status.OperationState.SyncResult.Resources for _, res := range results { @@ -192,7 +194,7 @@ func ResourceResultIs(result v1alpha1.ResourceResult) Expectation { } } -func sameResourceResult(res1, res2 v1alpha1.ResourceResult) bool { +func sameResourceResult(res1, res2 ResourceResult) bool { return res1.Kind == res2.Kind && res1.Group == res2.Group && res1.Namespace == res2.Namespace && @@ -202,7 +204,7 @@ func sameResourceResult(res1, res2 v1alpha1.ResourceResult) bool { res1.HookPhase == res2.HookPhase } -func ResourceResultMatches(result v1alpha1.ResourceResult) Expectation { +func ResourceResultMatches(result ResourceResult) Expectation { return func(c *Consequences) (state, string) { results := c.app().Status.OperationState.SyncResult.Resources for _, res := range results { @@ -221,7 +223,7 @@ func DoesNotExist() Expectation { return func(c *Consequences) (state, string) { _, err := c.get() if err != nil { - if apierrors.IsNotFound(err) { + if apierr.IsNotFound(err) { return succeeded, "app does not exist" } return failed, err.Error() @@ -234,7 +236,7 @@ func DoesNotExistNow() Expectation { return func(c *Consequences) (state, string) { _, err := c.get() if err != nil { - if apierrors.IsNotFound(err) { + if apierr.IsNotFound(err) { return succeeded, "app does not exist" } return failed, err.Error() @@ -243,8 +245,8 @@ func DoesNotExistNow() Expectation { } } -func Pod(predicate func(p corev1.Pod) bool) Expectation { - return func(_ *Consequences) (state, string) { +func Pod(predicate func(p v1.Pod) bool) Expectation { + return func(c *Consequences) (state, string) { pods, err := pods() if err != nil { return failed, err.Error() @@ -258,8 +260,8 @@ func Pod(predicate func(p corev1.Pod) bool) Expectation { } } -func NotPod(predicate func(p corev1.Pod) bool) Expectation { - return func(_ *Consequences) (state, string) { +func NotPod(predicate func(p v1.Pod) bool) Expectation { + return func(c *Consequences) (state, string) { pods, err := pods() if err != nil { return failed, err.Error() @@ -273,24 +275,24 @@ func NotPod(predicate func(p corev1.Pod) bool) Expectation { } } -func pods() (*corev1.PodList, error) { +func pods() (*v1.PodList, error) { fixture.KubeClientset.CoreV1() pods, err := fixture.KubeClientset.CoreV1().Pods(fixture.DeploymentNamespace()).List(context.Background(), metav1.ListOptions{}) return pods, err } func NoNamespace(name string) Expectation { - return func(_ *Consequences) (state, string) { + return func(c *Consequences) (state, string) { _, err := namespace(name) if err != nil { return succeeded, "namespace not found" } - return failed, "found namespace " + name + return failed, fmt.Sprintf("found namespace %s", name) } } -func namespace(name string) (*corev1.Namespace, error) { +func namespace(name string) (*v1.Namespace, error) { fixture.KubeClientset.CoreV1() return fixture.KubeClientset.CoreV1().Namespaces().Get(context.Background(), name, metav1.GetOptions{}) } @@ -370,7 +372,7 @@ func Error(message, err string, matchers ...func(string, string) bool) Expectati return failed, fmt.Sprintf("output does not contain '%s'", message) } if !match(c.actions.lastError.Error(), err) { - return failed, fmt.Sprintf("error does not contain '%s'", err) + return failed, fmt.Sprintf("error does not contain '%s'", message) } return succeeded, fmt.Sprintf("error '%s'", message) } diff --git a/test/e2e/fixture/applicationsets/actions.go b/test/e2e/fixture/applicationsets/actions.go index 990139c2e2..27adae8497 100644 --- a/test/e2e/fixture/applicationsets/actions.go +++ b/test/e2e/fixture/applicationsets/actions.go @@ -7,21 +7,21 @@ import ( "strings" "time" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" log "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" + v1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/dynamic" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets/utils" - "github.com/argoproj/argo-cd/v3/util/clusterauth" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" + "github.com/argoproj/argo-cd/v2/util/clusterauth" ) // this implements the "when" part of given/when/then @@ -61,7 +61,6 @@ func (a *Actions) And(block func()) *Actions { func (a *Actions) Then() *Consequences { a.context.t.Helper() - time.Sleep(fixture.WhenThenSleepInterval) return &Consequences{a.context, a} } @@ -80,8 +79,7 @@ func (a *Actions) SwitchToArgoCDNamespace() *Actions { // CreateClusterSecret creates a faux cluster secret, with the given cluster server and cluster name (this cluster // will not actually be used by the Argo CD controller, but that's not needed for our E2E tests) func (a *Actions) CreateClusterSecret(secretName string, clusterName string, clusterServer string) *Actions { - a.context.t.Helper() - fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t) + fixtureClient := utils.GetE2EFixtureK8sClient() var serviceAccountName string @@ -154,8 +152,7 @@ func (a *Actions) CreateClusterSecret(secretName string, clusterName string, clu // DeleteClusterSecret deletes a faux cluster secret func (a *Actions) DeleteClusterSecret(secretName string) *Actions { - a.context.t.Helper() - err := utils.GetE2EFixtureK8sClient(a.context.t).KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Delete(context.Background(), secretName, metav1.DeleteOptions{}) + err := utils.GetE2EFixtureK8sClient().KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Delete(context.Background(), secretName, metav1.DeleteOptions{}) a.describeAction = fmt.Sprintf("deleting cluster Secret '%s'", secretName) a.lastOutput, a.lastError = "", err @@ -166,8 +163,7 @@ func (a *Actions) DeleteClusterSecret(secretName string) *Actions { // DeleteConfigMap deletes a faux cluster secret func (a *Actions) DeleteConfigMap(configMapName string) *Actions { - a.context.t.Helper() - err := utils.GetE2EFixtureK8sClient(a.context.t).KubeClientset.CoreV1().ConfigMaps(fixture.TestNamespace()).Delete(context.Background(), configMapName, metav1.DeleteOptions{}) + err := utils.GetE2EFixtureK8sClient().KubeClientset.CoreV1().ConfigMaps(fixture.TestNamespace()).Delete(context.Background(), configMapName, metav1.DeleteOptions{}) a.describeAction = fmt.Sprintf("deleting configMap '%s'", configMapName) a.lastOutput, a.lastError = "", err @@ -178,8 +174,7 @@ func (a *Actions) DeleteConfigMap(configMapName string) *Actions { // DeletePlacementDecision deletes a faux cluster secret func (a *Actions) DeletePlacementDecision(placementDecisionName string) *Actions { - a.context.t.Helper() - err := utils.GetE2EFixtureK8sClient(a.context.t).DynamicClientset.Resource(pdGVR).Namespace(fixture.TestNamespace()).Delete(context.Background(), placementDecisionName, metav1.DeleteOptions{}) + err := utils.GetE2EFixtureK8sClient().DynamicClientset.Resource(pdGVR).Namespace(fixture.TestNamespace()).Delete(context.Background(), placementDecisionName, metav1.DeleteOptions{}) a.describeAction = fmt.Sprintf("deleting placement decision '%s'", placementDecisionName) a.lastOutput, a.lastError = "", err @@ -193,7 +188,7 @@ func (a *Actions) DeletePlacementDecision(placementDecisionName string) *Actions func (a *Actions) CreateNamespace(namespace string) *Actions { a.context.t.Helper() - fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t) + fixtureClient := utils.GetE2EFixtureK8sClient() _, err := fixtureClient.KubeClientset.CoreV1().Namespaces().Create(context.Background(), &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}, metav1.CreateOptions{}) @@ -209,7 +204,7 @@ func (a *Actions) CreateNamespace(namespace string) *Actions { func (a *Actions) Create(appSet v1alpha1.ApplicationSet) *Actions { a.context.t.Helper() - fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t) + fixtureClient := utils.GetE2EFixtureK8sClient() appSet.APIVersion = "argoproj.io/v1alpha1" appSet.Kind = "ApplicationSet" @@ -217,9 +212,9 @@ func (a *Actions) Create(appSet v1alpha1.ApplicationSet) *Actions { var appSetClientSet dynamic.ResourceInterface if a.context.switchToNamespace != "" { - externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[a.context.switchToNamespace] + externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[utils.ExternalNamespace(a.context.switchToNamespace)] if !found { - a.lastOutput, a.lastError = "", fmt.Errorf("no external clientset found for %s", a.context.switchToNamespace) + a.lastOutput, a.lastError = "", fmt.Errorf("No external clientset found for %s", a.context.switchToNamespace) return a } appSetClientSet = externalAppSetClientset @@ -243,14 +238,13 @@ func (a *Actions) Create(appSet v1alpha1.ApplicationSet) *Actions { // Create Role/RoleBinding to allow ApplicationSet to list the PlacementDecisions func (a *Actions) CreatePlacementRoleAndRoleBinding() *Actions { - a.context.t.Helper() - fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t) + fixtureClient := utils.GetE2EFixtureK8sClient() var err error - _, err = fixtureClient.KubeClientset.RbacV1().Roles(fixture.TestNamespace()).Create(context.Background(), &rbacv1.Role{ + _, err = fixtureClient.KubeClientset.RbacV1().Roles(fixture.TestNamespace()).Create(context.Background(), &v1.Role{ ObjectMeta: metav1.ObjectMeta{Name: "placement-role", Namespace: fixture.TestNamespace()}, - Rules: []rbacv1.PolicyRule{ + Rules: []v1.PolicyRule{ { Verbs: []string{"get", "list", "watch"}, APIGroups: []string{"cluster.open-cluster-management.io"}, @@ -264,16 +258,16 @@ func (a *Actions) CreatePlacementRoleAndRoleBinding() *Actions { if err == nil { _, err = fixtureClient.KubeClientset.RbacV1().RoleBindings(fixture.TestNamespace()).Create(context.Background(), - &rbacv1.RoleBinding{ + &v1.RoleBinding{ ObjectMeta: metav1.ObjectMeta{Name: "placement-role-binding", Namespace: fixture.TestNamespace()}, - Subjects: []rbacv1.Subject{ + Subjects: []v1.Subject{ { Name: "argocd-applicationset-controller", Namespace: fixture.TestNamespace(), Kind: "ServiceAccount", }, }, - RoleRef: rbacv1.RoleRef{ + RoleRef: v1.RoleRef{ Kind: "Role", APIGroup: "rbac.authorization.k8s.io", Name: "placement-role", @@ -295,7 +289,7 @@ func (a *Actions) CreatePlacementRoleAndRoleBinding() *Actions { func (a *Actions) CreatePlacementDecisionConfigMap(configMapName string) *Actions { a.context.t.Helper() - fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t) + fixtureClient := utils.GetE2EFixtureK8sClient() _, err := fixtureClient.KubeClientset.CoreV1().ConfigMaps(fixture.TestNamespace()).Get(context.Background(), configMapName, metav1.GetOptions{}) @@ -327,7 +321,7 @@ func (a *Actions) CreatePlacementDecisionConfigMap(configMapName string) *Action func (a *Actions) CreatePlacementDecision(placementDecisionName string) *Actions { a.context.t.Helper() - fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t).DynamicClientset + fixtureClient := utils.GetE2EFixtureK8sClient().DynamicClientset _, err := fixtureClient.Resource(pdGVR).Namespace(fixture.TestNamespace()).Get( context.Background(), @@ -339,14 +333,14 @@ func (a *Actions) CreatePlacementDecision(placementDecisionName string) *Actions } placementDecision := &unstructured.Unstructured{ - Object: map[string]any{ - "metadata": map[string]any{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ "name": placementDecisionName, "namespace": fixture.TestNamespace(), }, "kind": "PlacementDecision", "apiVersion": "cluster.open-cluster-management.io/v1alpha1", - "status": map[string]any{}, + "status": map[string]interface{}{}, }, } @@ -362,16 +356,16 @@ func (a *Actions) CreatePlacementDecision(placementDecisionName string) *Actions return a } -func (a *Actions) StatusUpdatePlacementDecision(placementDecisionName string, clusterList []any) *Actions { +func (a *Actions) StatusUpdatePlacementDecision(placementDecisionName string, clusterList []interface{}) *Actions { a.context.t.Helper() - fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t).DynamicClientset + fixtureClient := utils.GetE2EFixtureK8sClient().DynamicClientset placementDecision, err := fixtureClient.Resource(pdGVR).Namespace(fixture.TestNamespace()).Get( context.Background(), placementDecisionName, metav1.GetOptions{}) - placementDecision.Object["status"] = map[string]any{ + placementDecision.Object["status"] = map[string]interface{}{ "decisions": clusterList, } @@ -392,14 +386,14 @@ func (a *Actions) StatusUpdatePlacementDecision(placementDecisionName string, cl func (a *Actions) Delete() *Actions { a.context.t.Helper() - fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t) + fixtureClient := utils.GetE2EFixtureK8sClient() var appSetClientSet dynamic.ResourceInterface if a.context.switchToNamespace != "" { - externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[a.context.switchToNamespace] + externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[utils.ExternalNamespace(a.context.switchToNamespace)] if !found { - a.lastOutput, a.lastError = "", fmt.Errorf("no external clientset found for %s", a.context.switchToNamespace) + a.lastOutput, a.lastError = "", fmt.Errorf("No external clientset found for %s", a.context.switchToNamespace) return a } appSetClientSet = externalAppSetClientset @@ -420,14 +414,14 @@ func (a *Actions) Delete() *Actions { func (a *Actions) get() (*v1alpha1.ApplicationSet, error) { appSet := v1alpha1.ApplicationSet{} - fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t) + fixtureClient := utils.GetE2EFixtureK8sClient() var appSetClientSet dynamic.ResourceInterface if a.context.switchToNamespace != "" { - externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[a.context.switchToNamespace] + externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[utils.ExternalNamespace(a.context.switchToNamespace)] if !found { - return nil, fmt.Errorf("no external clientset found for %s", a.context.switchToNamespace) + return nil, fmt.Errorf("No external clientset found for %s", a.context.switchToNamespace) } appSetClientSet = externalAppSetClientset } else { @@ -483,14 +477,14 @@ func (a *Actions) Update(toUpdate func(*v1alpha1.ApplicationSet)) *Actions { toUpdate(appSet) a.describeAction = fmt.Sprintf("updating ApplicationSet '%s/%s'", appSet.Namespace, appSet.Name) - fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t) + fixtureClient := utils.GetE2EFixtureK8sClient() var appSetClientSet dynamic.ResourceInterface if a.context.switchToNamespace != "" { - externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[a.context.switchToNamespace] + externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[utils.ExternalNamespace(a.context.switchToNamespace)] if !found { - a.lastOutput, a.lastError = "", fmt.Errorf("no external clientset found for %s", a.context.switchToNamespace) + a.lastOutput, a.lastError = "", fmt.Errorf("No external clientset found for %s", a.context.switchToNamespace) return a } appSetClientSet = externalAppSetClientset @@ -500,11 +494,12 @@ func (a *Actions) Update(toUpdate func(*v1alpha1.ApplicationSet)) *Actions { _, err = appSetClientSet.Update(context.Background(), utils.MustToUnstructured(&appSet), metav1.UpdateOptions{}) - if err == nil { + if err != nil { + mostRecentError = err + } else { mostRecentError = nil break } - mostRecentError = err } } @@ -543,6 +538,6 @@ func (a *Actions) runCli(args ...string) { func (a *Actions) AddSignedFile(fileName, fileContents string) *Actions { a.context.t.Helper() - fixture.AddSignedFile(a.context.t, a.context.path+"/"+fileName, fileContents) + fixture.AddSignedFile(a.context.path+"/"+fileName, fileContents) return a } diff --git a/test/e2e/fixture/applicationsets/consequences.go b/test/e2e/fixture/applicationsets/consequences.go index 1cab2b8e00..a8a9dc8dd3 100644 --- a/test/e2e/fixture/applicationsets/consequences.go +++ b/test/e2e/fixture/applicationsets/consequences.go @@ -5,14 +5,15 @@ import ( "encoding/json" "time" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets/utils" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/pkg/errors" log "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/dynamic" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" ) // this implements the "then" part of given/when/then @@ -71,7 +72,6 @@ func (c *Consequences) Given() *Context { } func (c *Consequences) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return c.actions } @@ -88,7 +88,6 @@ func (c *Consequences) app(name string) *v1alpha1.Application { } func (c *Consequences) apps() []v1alpha1.Application { - c.context.t.Helper() var namespace string if c.context.switchToNamespace != "" { namespace = string(c.context.switchToNamespace) @@ -96,7 +95,7 @@ func (c *Consequences) apps() []v1alpha1.Application { namespace = fixture.TestNamespace() } - fixtureClient := utils.GetE2EFixtureK8sClient(c.context.t) + fixtureClient := utils.GetE2EFixtureK8sClient() list, err := fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(namespace).List(context.Background(), metav1.ListOptions{}) errors.CheckError(err) @@ -108,8 +107,7 @@ func (c *Consequences) apps() []v1alpha1.Application { } func (c *Consequences) applicationSet(applicationSetName string) *v1alpha1.ApplicationSet { - c.context.t.Helper() - fixtureClient := utils.GetE2EFixtureK8sClient(c.context.t) + fixtureClient := utils.GetE2EFixtureK8sClient() var appSetClientSet dynamic.ResourceInterface diff --git a/test/e2e/fixture/applicationsets/context.go b/test/e2e/fixture/applicationsets/context.go index 00bd71a1d0..a08e11c91c 100644 --- a/test/e2e/fixture/applicationsets/context.go +++ b/test/e2e/fixture/applicationsets/context.go @@ -4,10 +4,8 @@ import ( "testing" "time" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets/utils" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/gpgkeys" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/repos" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/gpgkeys" ) // Context implements the "given" part of given/when/then @@ -29,7 +27,6 @@ func Given(t *testing.T) *Context { } func (c *Context) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return &Actions{context: c} } @@ -54,11 +51,6 @@ func (c *Context) Path(path string) *Context { } func (c *Context) GPGPublicKeyAdded() *Context { - gpgkeys.AddGPGPublicKey(c.t) - return c -} - -func (c *Context) HTTPSInsecureRepoURLAdded(project string) *Context { - repos.AddHTTPSRepo(c.t, true, true, project, fixture.RepoURLTypeHTTPS) + gpgkeys.AddGPGPublicKey() return c } diff --git a/test/e2e/fixture/applicationsets/expectation.go b/test/e2e/fixture/applicationsets/expectation.go index 2aab83ee4b..fc8de495fe 100644 --- a/test/e2e/fixture/applicationsets/expectation.go +++ b/test/e2e/fixture/applicationsets/expectation.go @@ -1,17 +1,17 @@ package applicationsets import ( + "context" "fmt" "reflect" "strings" - "testing" "github.com/argoproj/gitops-engine/pkg/diff" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets/utils" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" ) type state = string @@ -115,10 +115,9 @@ func ApplicationsDoNotExist(expectedApps []v1alpha1.Application) Expectation { } // Pod checks whether a specified condition is true for any of the pods in the namespace -func Pod(t *testing.T, predicate func(p corev1.Pod) bool) Expectation { - t.Helper() - return func(_ *Consequences) (state, string) { - pods, err := pods(t, utils.ApplicationsResourcesNamespace) +func Pod(predicate func(p corev1.Pod) bool) Expectation { + return func(c *Consequences) (state, string) { + pods, err := pods(utils.ApplicationsResourcesNamespace) if err != nil { return failed, err.Error() } @@ -131,11 +130,10 @@ func Pod(t *testing.T, predicate func(p corev1.Pod) bool) Expectation { } } -func pods(t *testing.T, namespace string) (*corev1.PodList, error) { - t.Helper() - fixtureClient := utils.GetE2EFixtureK8sClient(t) +func pods(namespace string) (*corev1.PodList, error) { + fixtureClient := utils.GetE2EFixtureK8sClient() - pods, err := fixtureClient.KubeClientset.CoreV1().Pods(namespace).List(t.Context(), metav1.ListOptions{}) + pods, err := fixtureClient.KubeClientset.CoreV1().Pods(namespace).List(context.Background(), metav1.ListOptions{}) return pods, err } diff --git a/test/e2e/fixture/applicationsets/utils/cmd.go b/test/e2e/fixture/applicationsets/utils/cmd.go index 434e9454d7..866bc72263 100644 --- a/test/e2e/fixture/applicationsets/utils/cmd.go +++ b/test/e2e/fixture/applicationsets/utils/cmd.go @@ -5,7 +5,7 @@ import ( "os/exec" "strings" - argoexec "github.com/argoproj/argo-cd/v3/util/exec" + argoexec "github.com/argoproj/pkg/exec" ) func Run(workDir, name string, args ...string) (string, error) { diff --git a/test/e2e/fixture/applicationsets/utils/errrors.go b/test/e2e/fixture/applicationsets/utils/errrors.go new file mode 100644 index 0000000000..e88fb05d8a --- /dev/null +++ b/test/e2e/fixture/applicationsets/utils/errrors.go @@ -0,0 +1,61 @@ +package utils + +import ( + "os" + "runtime/debug" + + log "github.com/sirupsen/logrus" +) + +const ( + // ErrorCommandSpecific is reserved for command specific indications + ErrorCommandSpecific = 1 + // ErrorConnectionFailure is returned on connection failure to API endpoint + ErrorConnectionFailure = 11 + // ErrorAPIResponse is returned on unexpected API response, i.e. authorization failure + ErrorAPIResponse = 12 + // ErrorResourceDoesNotExist is returned when the requested resource does not exist + ErrorResourceDoesNotExist = 13 + // ErrorGeneric is returned for generic error + ErrorGeneric = 20 +) + +// CheckError logs a fatal message and exits with ErrorGeneric if err is not nil +func CheckError(err error) { + if err != nil { + debug.PrintStack() + Fatal(ErrorGeneric, err) + } +} + +// CheckErrorWithCode is a convenience function to exit if an error is non-nil and exit if it was +func CheckErrorWithCode(err error, exitcode int) { + if err != nil { + Fatal(exitcode, err) + } +} + +// FailOnErr panics if there is an error. It returns the first value so you can use it if you cast it: +// text := FailOrErr(Foo)).(string) +func FailOnErr(v interface{}, err error) interface{} { + CheckError(err) + return v +} + +// Fatal is a wrapper for logrus.Fatal() to exit with custom code +func Fatal(exitcode int, args ...interface{}) { + exitfunc := func() { + os.Exit(exitcode) + } + log.RegisterExitHandler(exitfunc) + log.Fatal(args...) +} + +// Fatalf is a wrapper for logrus.Fatalf() to exit with custom code +func Fatalf(exitcode int, format string, args ...interface{}) { + exitfunc := func() { + os.Exit(exitcode) + } + log.RegisterExitHandler(exitfunc) + log.Fatalf(format, args...) +} diff --git a/test/e2e/fixture/applicationsets/utils/fixture.go b/test/e2e/fixture/applicationsets/utils/fixture.go index b7164ba84b..571e8148a2 100644 --- a/test/e2e/fixture/applicationsets/utils/fixture.go +++ b/test/e2e/fixture/applicationsets/utils/fixture.go @@ -12,11 +12,10 @@ import ( "time" log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/api/equality" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apierr "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/dynamic" @@ -24,11 +23,10 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/util/errors" + "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/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/errors" ) type ExternalNamespace string @@ -86,12 +84,11 @@ func TestNamespace() string { // GetE2EFixtureK8sClient initializes the Kubernetes clients (if needed), and returns the most recently initialized value. // Note: this requires a local Kubernetes configuration (for example, while running the E2E tests). -func GetE2EFixtureK8sClient(t *testing.T) *E2EFixtureK8sClient { - t.Helper() +func GetE2EFixtureK8sClient() *E2EFixtureK8sClient { // Initialize the Kubernetes clients only on first use clientInitialized.Do(func() { // set-up variables - config := getKubeConfig(t, "", clientcmd.ConfigOverrides{}) + config := getKubeConfig("", clientcmd.ConfigOverrides{}) internalClientVars = &E2EFixtureK8sClient{ AppClientset: appclientset.NewForConfigOrDie(config), @@ -113,45 +110,31 @@ func EnsureCleanState(t *testing.T) { t.Helper() start := time.Now() - fixtureClient := GetE2EFixtureK8sClient(t) + fixtureClient := GetE2EFixtureK8sClient() - policy := metav1.DeletePropagationForeground + policy := v1.DeletePropagationForeground fixture.RunFunctionsInParallelAndCheckErrors(t, []func() error{ - func() error { - // kubectl delete secrets -l argocd.argoproj.io/secret-type=repository - return fixtureClient.KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection( - t.Context(), - metav1.DeleteOptions{PropagationPolicy: &policy}, - metav1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepository}) - }, - func() error { - // kubectl delete secrets -l argocd.argoproj.io/secret-type=repo-creds - return fixtureClient.KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection( - t.Context(), - metav1.DeleteOptions{PropagationPolicy: &policy}, - metav1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepoCreds}) - }, func() error { // Delete the applicationset-e2e namespace, if it exists - err := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(t.Context(), ApplicationsResourcesNamespace, metav1.DeleteOptions{PropagationPolicy: &policy}) - if err != nil && !apierrors.IsNotFound(err) { // 'not found' error is expected + err := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), ApplicationsResourcesNamespace, v1.DeleteOptions{PropagationPolicy: &policy}) + if err != nil && !apierr.IsNotFound(err) { // 'not found' error is expected return err } return nil }, func() error { // Delete the argocd-e2e-external namespace, if it exists - err := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(t.Context(), string(ArgoCDExternalNamespace), metav1.DeleteOptions{PropagationPolicy: &policy}) - if err != nil && !apierrors.IsNotFound(err) { // 'not found' error is expected + err := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), string(ArgoCDExternalNamespace), v1.DeleteOptions{PropagationPolicy: &policy}) + if err != nil && !apierr.IsNotFound(err) { // 'not found' error is expected return err } return nil }, func() error { // Delete the argocd-e2e-external namespace, if it exists - err := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(t.Context(), string(ArgoCDExternalNamespace2), metav1.DeleteOptions{PropagationPolicy: &policy}) - if err != nil && !apierrors.IsNotFound(err) { // 'not found' error is expected + err := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), string(ArgoCDExternalNamespace2), v1.DeleteOptions{PropagationPolicy: &policy}) + if err != nil && !apierr.IsNotFound(err) { // 'not found' error is expected return err } return nil @@ -159,31 +142,31 @@ func EnsureCleanState(t *testing.T) { // delete resources func() error { // kubectl delete applicationsets --all - return fixtureClient.AppSetClientset.DeleteCollection(t.Context(), metav1.DeleteOptions{PropagationPolicy: &policy}, metav1.ListOptions{}) + return fixtureClient.AppSetClientset.DeleteCollection(context.Background(), v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{}) }, func() error { // kubectl delete apps --all - return fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).DeleteCollection(t.Context(), metav1.DeleteOptions{PropagationPolicy: &policy}, metav1.ListOptions{}) + return fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).DeleteCollection(context.Background(), v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{}) }, func() error { // kubectl delete secrets -l e2e.argoproj.io=true return fixtureClient.KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection( - t.Context(), - metav1.DeleteOptions{PropagationPolicy: &policy}, - metav1.ListOptions{LabelSelector: TestingLabel + "=true"}) + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{LabelSelector: TestingLabel + "=true"}) }, }) // First we wait up to 30 seconds for all the ApplicationSets to delete, but we don't fail if they don't. // Why? We want to give Argo CD time to delete the Application's child resources, before we remove the finalizers below. _ = waitForSuccess(func() error { - list, err := fixtureClient.AppSetClientset.List(t.Context(), metav1.ListOptions{}) + list, err := fixtureClient.AppSetClientset.List(context.Background(), v1.ListOptions{}) if err != nil { return err } if list != nil && len(list.Items) > 0 { // Fail - return fmt.Errorf("waiting for list of ApplicationSets to be size zero: %d", len(list.Items)) + return fmt.Errorf("Waiting for list of ApplicationSets to be size zero: %d", len(list.Items)) } return nil // Pass @@ -191,57 +174,56 @@ func EnsureCleanState(t *testing.T) { // Remove finalizers from Argo CD Application resources in the namespace err := waitForSuccess(func() error { - appList, err := fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).List(t.Context(), metav1.ListOptions{}) + appList, err := fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).List(context.Background(), v1.ListOptions{}) if err != nil { return err } for _, app := range appList.Items { t.Log("Removing finalizer for: ", app.Name) app.Finalizers = []string{} - _, err := fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).Update(t.Context(), &app, metav1.UpdateOptions{}) + _, err := fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).Update(context.TODO(), &app, v1.UpdateOptions{}) if err != nil { return err } } return nil }, time.Now().Add(120*time.Second)) - require.NoError(t, err) + CheckError(err) - require.NoError(t, waitForExpectedClusterState(t)) + CheckError(waitForExpectedClusterState()) // remove tmp dir - require.NoError(t, os.RemoveAll(TmpDir)) + CheckError(os.RemoveAll(TmpDir)) // create tmp dir - errors.NewHandler(t).FailOnErr(Run("", "mkdir", "-p", TmpDir)) + FailOnErr(Run("", "mkdir", "-p", TmpDir)) // We can switch user and as result in previous state we will have non-admin user, this case should be reset - require.NoError(t, fixture.LoginAs("admin")) + CheckError(fixture.LoginAs("admin")) log.WithFields(log.Fields{"duration": time.Since(start), "name": t.Name(), "id": id, "username": "admin", "password": "password"}).Info("clean state") } -func waitForExpectedClusterState(t *testing.T) error { - t.Helper() - fixtureClient := GetE2EFixtureK8sClient(t) +func waitForExpectedClusterState() error { + fixtureClient := GetE2EFixtureK8sClient() - SetProjectSpec(t, fixtureClient, "default", v1alpha1.AppProjectSpec{ + SetProjectSpec(fixtureClient, "default", v1alpha1.AppProjectSpec{ OrphanedResources: nil, SourceRepos: []string{"*"}, Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "*"}}, - ClusterResourceWhitelist: []metav1.GroupKind{{Group: "*", Kind: "*"}}, + ClusterResourceWhitelist: []v1.GroupKind{{Group: "*", Kind: "*"}}, SourceNamespaces: []string{string(ArgoCDExternalNamespace), string(ArgoCDExternalNamespace2)}, }) // Wait up to 60 seconds for all the ApplicationSets to delete if err := waitForSuccess(func() error { - list, err := fixtureClient.AppSetClientset.List(t.Context(), metav1.ListOptions{}) + list, err := fixtureClient.AppSetClientset.List(context.Background(), v1.ListOptions{}) if err != nil { return err } if list != nil && len(list.Items) > 0 { // Fail - return fmt.Errorf("waiting for list of ApplicationSets to be size zero: %d", len(list.Items)) + return fmt.Errorf("Waiting for list of ApplicationSets to be size zero: %d", len(list.Items)) } return nil // Pass @@ -251,13 +233,13 @@ func waitForExpectedClusterState(t *testing.T) error { // Wait up to 60 seconds for all the Applications to delete if err := waitForSuccess(func() error { - appList, err := fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).List(t.Context(), metav1.ListOptions{}) + appList, err := fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).List(context.Background(), v1.ListOptions{}) if err != nil { return err } if appList != nil && len(appList.Items) > 0 { // Fail - return fmt.Errorf("waiting for list of Applications to be size zero: %d", len(appList.Items)) + return fmt.Errorf("Waiting for list of Applications to be size zero: %d", len(appList.Items)) } return nil // Pass }, time.Now().Add(60*time.Second)); err != nil { @@ -277,17 +259,16 @@ func waitForExpectedClusterState(t *testing.T) error { return nil } -func SetProjectSpec(t *testing.T, fixtureClient *E2EFixtureK8sClient, project string, spec v1alpha1.AppProjectSpec) { - t.Helper() - proj, err := fixtureClient.AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Get(t.Context(), project, metav1.GetOptions{}) - require.NoError(t, err) +func SetProjectSpec(fixtureClient *E2EFixtureK8sClient, project string, spec v1alpha1.AppProjectSpec) { + proj, err := fixtureClient.AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Get(context.Background(), project, v1.GetOptions{}) + errors.CheckError(err) proj.Spec = spec - _, err = fixtureClient.AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Update(t.Context(), proj, metav1.UpdateOptions{}) - require.NoError(t, err) + _, err = fixtureClient.AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Update(context.Background(), proj, v1.UpdateOptions{}) + errors.CheckError(err) } func cleanUpNamespace(fixtureClient *E2EFixtureK8sClient, namespace string) error { - _, err := fixtureClient.KubeClientset.CoreV1().Namespaces().Get(context.Background(), namespace, metav1.GetOptions{}) + _, err := fixtureClient.KubeClientset.CoreV1().Namespaces().Get(context.Background(), namespace, v1.GetOptions{}) msg := "" @@ -295,7 +276,7 @@ func cleanUpNamespace(fixtureClient *E2EFixtureK8sClient, namespace string) erro msg = fmt.Sprintf("namespace '%s' still exists, after delete", namespace) } - if msg == "" && err != nil && apierrors.IsNotFound(err) { + if msg == "" && err != nil && apierr.IsNotFound(err) { // Success is an error containing 'applicationset-e2e' not found. return nil } @@ -325,15 +306,20 @@ func waitForSuccess(condition func() error, expireTime time.Time) error { } sleepIntervalsIdx := -1 - for !time.Now().After(expireTime) { + for { + if time.Now().After(expireTime) { + break + } + conditionErr := condition() - if conditionErr == nil { + if conditionErr != nil { + // Fail! + mostRecentError = conditionErr + } else { // Pass! mostRecentError = nil break } - // Fail! - mostRecentError = conditionErr // Wait on fail if sleepIntervalsIdx < len(sleepIntervals)-1 { @@ -345,14 +331,13 @@ func waitForSuccess(condition func() error, expireTime time.Time) error { } // getKubeConfig creates new kubernetes client config using specified config path and config overrides variables -func getKubeConfig(t *testing.T, configPath string, overrides clientcmd.ConfigOverrides) *rest.Config { - t.Helper() +func getKubeConfig(configPath string, overrides clientcmd.ConfigOverrides) *rest.Config { loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() loadingRules.ExplicitPath = configPath clientConfig := clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, &overrides, os.Stdin) restConfig, err := clientConfig.ClientConfig() - require.NoError(t, err) + CheckError(err) return restConfig } @@ -364,7 +349,7 @@ func init() { } // PrettyPrintJson is a utility function for debugging purposes -func PrettyPrintJson(obj any) string { //nolint:revive //FIXME(var-naming) +func PrettyPrintJson(obj interface{}) string { bytes, err := json.MarshalIndent(obj, "", " ") if err != nil { return err.Error() @@ -373,7 +358,7 @@ func PrettyPrintJson(obj any) string { //nolint:revive //FIXME(var-naming) } // returns dns friends string which is no longer than 63 characters and has specified postfix at the end -func DnsFriendly(str string, postfix string) string { //nolint:revive //FIXME(var-naming) +func DnsFriendly(str string, postfix string) string { matchFirstCap := regexp.MustCompile("(.)([A-Z][a-z]+)") matchAllCap := regexp.MustCompile("([a-z0-9])([A-Z])") @@ -387,7 +372,7 @@ func DnsFriendly(str string, postfix string) string { //nolint:revive //FIXME(va return str + postfix } -func MustToUnstructured(obj any) *unstructured.Unstructured { +func MustToUnstructured(obj interface{}) *unstructured.Unstructured { uObj, err := ToUnstructured(obj) if err != nil { panic(err) @@ -396,7 +381,7 @@ func MustToUnstructured(obj any) *unstructured.Unstructured { } // ToUnstructured converts a concrete K8s API type to an unstructured object -func ToUnstructured(obj any) (*unstructured.Unstructured, error) { +func ToUnstructured(obj interface{}) (*unstructured.Unstructured, error) { uObj, err := runtime.NewTestUnstructuredConverter(equality.Semantic).ToUnstructured(obj) if err != nil { return nil, err diff --git a/test/e2e/fixture/certs/certs.go b/test/e2e/fixture/certs/certs.go index 0ec2449161..40db06a18f 100644 --- a/test/e2e/fixture/certs/certs.go +++ b/test/e2e/fixture/certs/certs.go @@ -3,63 +3,58 @@ package certs import ( "os" "path/filepath" - "testing" - "github.com/stretchr/testify/require" - - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/errors" ) // Add a custom CA certificate to the test and also create the certificate file // on the file system, so argocd-server and argocd-repo-server can use it. -func AddCustomCACert(t *testing.T) { - t.Helper() +func AddCustomCACert() { caCertPath, err := filepath.Abs("../fixture/certs/argocd-test-ca.crt") - require.NoError(t, err) + errors.CheckError(err) // We need to setup TLS certs according to whether we are running tests // against a local workload (repositories available as localhost) and // against remote workloads (repositories available as argocd-e2e-server) if fixture.IsLocal() { args := []string{"cert", "add-tls", "localhost", "--from", caCertPath} - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) args = []string{"cert", "add-tls", "127.0.0.1", "--from", caCertPath} - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) certData, err := os.ReadFile(caCertPath) - require.NoError(t, err) + errors.CheckError(err) err = os.WriteFile(fixture.TmpDir+"/app/config/tls/localhost", certData, 0o644) - require.NoError(t, err) + errors.CheckError(err) err = os.WriteFile(fixture.TmpDir+"/app/config/tls/127.0.0.1", certData, 0o644) - require.NoError(t, err) + errors.CheckError(err) } else { args := []string{"cert", "add-tls", "argocd-e2e-server", "--from", caCertPath} - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) - fixture.RestartAPIServer(t) - fixture.RestartRepoServer(t) + errors.FailOnErr(fixture.RunCli(args...)) + fixture.RestartAPIServer() + fixture.RestartRepoServer() } } // AddCustomSSHKnownHostsKeys adds SSH known hosts data to the Argo CD server // being tested against. The env ARGOCD_E2E_SSH_KNOWN_HOSTS lets you specify // an optional path to the known hosts file, instead of using the default one. -func AddCustomSSHKnownHostsKeys(t *testing.T) { - t.Helper() +func AddCustomSSHKnownHostsKeys() { source := os.Getenv("ARGOCD_E2E_SSH_KNOWN_HOSTS") if source == "" { source = "../fixture/testrepos/ssh_known_hosts" } knownHostsPath, err := filepath.Abs(source) - require.NoError(t, err) + errors.CheckError(err) args := []string{"cert", "add-ssh", "--upsert", "--batch", "--from", knownHostsPath} - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) if fixture.IsLocal() { knownHostsData, err := os.ReadFile(knownHostsPath) - require.NoError(t, err) + errors.CheckError(err) err = os.WriteFile(fixture.TmpDir+"/app/config/ssh/ssh_known_hosts", knownHostsData, 0o644) - require.NoError(t, err) + errors.CheckError(err) } else { - fixture.RestartAPIServer(t) - fixture.RestartRepoServer(t) + fixture.RestartAPIServer() + fixture.RestartRepoServer() } } diff --git a/test/e2e/fixture/cluster/actions.go b/test/e2e/fixture/cluster/actions.go index 66112efb78..ac114bad0c 100644 --- a/test/e2e/fixture/cluster/actions.go +++ b/test/e2e/fixture/cluster/actions.go @@ -5,17 +5,16 @@ import ( "errors" "log" "strings" - "time" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/clusterauth" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/clusterauth" - clusterpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + clusterpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" ) // this implements the "when" part of given/when/then @@ -39,7 +38,7 @@ func (a *Actions) DoNotIgnoreErrors() *Actions { return a } -func (a *Actions) Create() *Actions { +func (a *Actions) Create(args ...string) *Actions { _, clusterClient, _ := fixture.ArgoCDClientset.NewClusterClient() _, err := clusterClient.Create(context.Background(), &clusterpkg.ClusterCreateRequest{ @@ -68,7 +67,7 @@ func (a *Actions) Create() *Actions { return a } -func (a *Actions) CreateWithRBAC() *Actions { +func (a *Actions) CreateWithRBAC(args ...string) *Actions { pathOpts := clientcmd.NewDefaultPathOptions() config, err := pathOpts.GetStartingConfig() if err != nil { @@ -132,7 +131,6 @@ func (a *Actions) DeleteByServer() *Actions { func (a *Actions) Then() *Consequences { a.context.t.Helper() - time.Sleep(fixture.WhenThenSleepInterval) return &Consequences{a.context, a} } diff --git a/test/e2e/fixture/cluster/consequences.go b/test/e2e/fixture/cluster/consequences.go index 97a456b53e..5e35f942cc 100644 --- a/test/e2e/fixture/cluster/consequences.go +++ b/test/e2e/fixture/cluster/consequences.go @@ -2,12 +2,11 @@ package cluster import ( "context" - "errors" - "time" + "fmt" - clusterpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + clusterpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" ) // this implements the "then" part of given/when/then @@ -47,7 +46,7 @@ func (c *Consequences) get() (*v1alpha1.Cluster, error) { } } - return nil, errors.New("cluster not found") + return nil, fmt.Errorf("cluster not found") } func (c *Consequences) Given() *Context { @@ -55,6 +54,5 @@ func (c *Consequences) Given() *Context { } func (c *Consequences) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return c.actions } diff --git a/test/e2e/fixture/cluster/context.go b/test/e2e/fixture/cluster/context.go index 8668797065..7ac01134f2 100644 --- a/test/e2e/fixture/cluster/context.go +++ b/test/e2e/fixture/cluster/context.go @@ -2,10 +2,9 @@ package cluster import ( "testing" - "time" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/env" ) // this implements the "given" part of given/when/then @@ -60,7 +59,6 @@ func (c *Context) And(block func()) *Context { } func (c *Context) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return &Actions{context: c} } diff --git a/test/e2e/fixture/cmd.go b/test/e2e/fixture/cmd.go index 1d2e62d45a..ca3af0daf1 100644 --- a/test/e2e/fixture/cmd.go +++ b/test/e2e/fixture/cmd.go @@ -5,7 +5,7 @@ import ( "os/exec" "strings" - argoexec "github.com/argoproj/argo-cd/v3/util/exec" + argoexec "github.com/argoproj/pkg/exec" ) func Run(workDir, name string, args ...string) (string, error) { diff --git a/test/e2e/fixture/fixture.go b/test/e2e/fixture/fixture.go index 76e9e769c9..082d7cc197 100644 --- a/test/e2e/fixture/fixture.go +++ b/test/e2e/fixture/fixture.go @@ -3,7 +3,7 @@ package fixture import ( "bufio" "context" - stderrors "errors" + goerrors "errors" "fmt" "os" "path" @@ -14,34 +14,32 @@ import ( "testing" "time" - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - jsonpatch "github.com/evanphx/json-patch" log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apiclient" - sessionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/session" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/errors" - grpcutil "github.com/argoproj/argo-cd/v3/util/grpc" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/rand" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient" + sessionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" + "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/env" + "github.com/argoproj/argo-cd/v2/util/errors" + . "github.com/argoproj/argo-cd/v2/util/errors" + grpcutil "github.com/argoproj/argo-cd/v2/util/grpc" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/rand" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( - defaultAPIServer = "localhost:8080" + defaultApiServer = "localhost:8080" defaultAdminPassword = "password" defaultAdminUsername = "admin" DefaultTestUserPassword = "password" @@ -66,9 +64,6 @@ const ( PluginSockFilePath = "/app/config/plugin" E2ETestPrefix = "e2e-test-" - - // Account for batch events processing (set to 1ms in e2e tests) - WhenThenSleepInterval = 5 * time.Millisecond ) const ( @@ -126,7 +121,6 @@ const ( RepoURLTypeHelmOCI = "helm-oci" GitUsername = "admin" GitPassword = "password" - GitBearerToken = "test" GithubAppID = "2978632978" GithubAppInstallationID = "7893789433789" GpgGoodKeyID = "D56C4FCA57A46444" @@ -150,7 +144,7 @@ func getKubeConfig(configPath string, overrides clientcmd.ConfigOverrides) *rest clientConfig := clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, &overrides, os.Stdin) restConfig, err := clientConfig.ClientConfig() - errors.CheckError(err) + CheckError(err) return restConfig } @@ -185,7 +179,7 @@ func init() { DynamicClientset = dynamic.NewForConfigOrDie(config) KubeConfig = config - apiServerAddress = GetEnvWithDefault(apiclient.EnvArgoCDServer, defaultAPIServer) + apiServerAddress = GetEnvWithDefault(apiclient.EnvArgoCDServer, defaultApiServer) adminUsername = GetEnvWithDefault(EnvAdminUsername, defaultAdminUsername) AdminPassword = GetEnvWithDefault(EnvAdminPassword, defaultAdminPassword) @@ -197,7 +191,7 @@ func init() { dialTime := 30 * time.Second tlsTestResult, err := grpcutil.TestTLS(apiServerAddress, dialTime) - errors.CheckError(err) + CheckError(err) ArgoCDClientset, err = apiclient.NewClient(&apiclient.ClientOptions{ Insecure: true, @@ -209,11 +203,11 @@ func init() { RepoServerName: argoCDRepoServerName, AppControllerName: argoCDAppControllerName, }) - errors.CheckError(err) + CheckError(err) plainText = !tlsTestResult.TLS - errors.CheckError(LoginAs(adminUsername)) + CheckError(LoginAs(adminUsername)) log.WithFields(log.Fields{"apiServerAddress": apiServerAddress}).Info("initialized") @@ -225,10 +219,11 @@ func init() { } f, err := os.Open(rf) if err != nil { - if stderrors.Is(err, os.ErrNotExist) { + if goerrors.Is(err, os.ErrNotExist) { return + } else { + panic(fmt.Sprintf("Could not read record file %s: %v", rf, err)) } - panic(fmt.Sprintf("Could not read record file %s: %v", rf, err)) } defer func() { err := f.Close() @@ -247,7 +242,7 @@ func loginAs(username, password string) error { if err != nil { return err } - defer utilio.Close(closer) + defer io.Close(closer) userInfoResponse, err := client.GetUserInfo(context.Background(), &sessionpkg.GetUserInfoRequest{}) if err != nil { @@ -348,7 +343,7 @@ func RepoURL(urlType RepoURLType) string { case RepoURLTypeHelmOCI: return HelmOCIRegistryURL default: - return GetEnvWithDefault(EnvRepoURLDefault, "file://"+repoDirectory()) + return GetEnvWithDefault(EnvRepoURLDefault, fmt.Sprintf("file://%s", repoDirectory())) } } @@ -360,6 +355,17 @@ func DeploymentNamespace() string { return deploymentNamespace } +// creates a secret for the current test, this currently can only create a single secret +func CreateSecret(username, password string) string { + secretName := fmt.Sprintf("argocd-e2e-%s", name) + FailOnErr(Run("", "kubectl", "create", "secret", "generic", secretName, + "--from-literal=username="+username, + "--from-literal=password="+password, + "-n", TestNamespace())) + FailOnErr(Run("", "kubectl", "label", "secret", secretName, TestingLabel+"=true", "-n", TestNamespace())) + return secretName +} + // Convenience wrapper for updating argocd-cm func updateSettingConfigMap(updater func(cm *corev1.ConfigMap) error) error { return updateGenericConfigMap(common.ArgoCDConfigMapName, updater) @@ -386,7 +392,7 @@ func configMapsEquivalent(a *corev1.ConfigMap, b *corev1.ConfigMap) bool { // Updates a given config map in argocd-e2e namespace func updateGenericConfigMap(name string, updater func(cm *corev1.ConfigMap) error) error { - cm, err := KubeClientset.CoreV1().ConfigMaps(TestNamespace()).Get(context.Background(), name, metav1.GetOptions{}) + cm, err := KubeClientset.CoreV1().ConfigMaps(TestNamespace()).Get(context.Background(), name, v1.GetOptions{}) if err != nil { return err } @@ -399,7 +405,7 @@ func updateGenericConfigMap(name string, updater func(cm *corev1.ConfigMap) erro return err } if !configMapsEquivalent(cm, oldCm) { - _, err = KubeClientset.CoreV1().ConfigMaps(TestNamespace()).Update(context.Background(), cm, metav1.UpdateOptions{}) + _, err = KubeClientset.CoreV1().ConfigMaps(TestNamespace()).Update(context.Background(), cm, v1.UpdateOptions{}) if err != nil { return err } @@ -410,7 +416,7 @@ func updateGenericConfigMap(name string, updater func(cm *corev1.ConfigMap) erro func SetEnableManifestGeneration(val map[v1alpha1.ApplicationSourceType]bool) error { return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { for k, v := range val { - cm.Data[strings.ToLower(string(k))+".enable"] = strconv.FormatBool(v) + cm.Data[fmt.Sprintf("%s.enable", strings.ToLower(string(k)))] = strconv.FormatBool(v) } return nil }) @@ -457,57 +463,6 @@ func SetTrackingLabel(trackingLabel string) error { }) } -func SetImpersonationEnabled(impersonationEnabledFlag string) error { - return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { - cm.Data["application.sync.impersonation.enabled"] = impersonationEnabledFlag - return nil - }) -} - -func CreateRBACResourcesForImpersonation(serviceAccountName string, policyRules []rbacv1.PolicyRule) error { - sa := &corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: serviceAccountName, - }, - } - _, err := KubeClientset.CoreV1().ServiceAccounts(DeploymentNamespace()).Create(context.Background(), sa, metav1.CreateOptions{}) - if err != nil { - return err - } - role := &rbacv1.Role{ - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%s-%s", serviceAccountName, "role"), - }, - Rules: policyRules, - } - _, err = KubeClientset.RbacV1().Roles(DeploymentNamespace()).Create(context.Background(), role, metav1.CreateOptions{}) - if err != nil { - return err - } - rolebinding := &rbacv1.RoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%s-%s", serviceAccountName, "rolebinding"), - }, - RoleRef: rbacv1.RoleRef{ - APIGroup: "rbac.authorization.k8s.io", - Kind: "Role", - Name: fmt.Sprintf("%s-%s", serviceAccountName, "role"), - }, - Subjects: []rbacv1.Subject{ - { - Kind: "ServiceAccount", - Name: serviceAccountName, - Namespace: DeploymentNamespace(), - }, - }, - } - _, err = KubeClientset.RbacV1().RoleBindings(DeploymentNamespace()).Create(context.Background(), rolebinding, metav1.CreateOptions{}) - if err != nil { - return err - } - return nil -} - func SetResourceOverridesSplitKeys(overrides map[string]v1alpha1.ResourceOverride) error { return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { for k, v := range overrides { @@ -551,7 +506,7 @@ func getResourceOverrideSplitKey(key string, customizeType string) string { func SetAccounts(accounts map[string][]string) error { return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { for k, v := range accounts { - cm.Data["accounts."+k] = strings.Join(v, ",") + cm.Data[fmt.Sprintf("accounts.%s", k)] = strings.Join(v, ",") } return nil }) @@ -588,13 +543,35 @@ func SetResourceFilter(filters settings.ResourcesFilter) error { }) } +func SetHelmRepos(repos ...settings.HelmRepoCredentials) error { + return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { + yamlBytes, err := yaml.Marshal(repos) + if err != nil { + return err + } + cm.Data["helm.repositories"] = string(yamlBytes) + return nil + }) +} + +func SetRepos(repos ...settings.RepositoryCredentials) error { + return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { + yamlBytes, err := yaml.Marshal(repos) + if err != nil { + return err + } + cm.Data["repositories"] = string(yamlBytes) + return nil + }) +} + func SetProjectSpec(project string, spec v1alpha1.AppProjectSpec) error { - proj, err := AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Get(context.Background(), project, metav1.GetOptions{}) + proj, err := AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Get(context.Background(), project, v1.GetOptions{}) if err != nil { return err } proj.Spec = spec - _, err = AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Update(context.Background(), proj, metav1.UpdateOptions{}) + _, err = AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Update(context.Background(), proj, v1.UpdateOptions{}) return err } @@ -645,57 +622,57 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) { }) start := time.Now() - policy := metav1.DeletePropagationBackground + policy := v1.DeletePropagationBackground RunFunctionsInParallelAndCheckErrors(t, []func() error{ func() error { // kubectl delete apps ... return AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).DeleteCollection( - t.Context(), - metav1.DeleteOptions{PropagationPolicy: &policy}, - metav1.ListOptions{}) + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{}) }, func() error { // kubectl delete apps ... return AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).DeleteCollection( - t.Context(), - metav1.DeleteOptions{PropagationPolicy: &policy}, - metav1.ListOptions{}) + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{}) }, func() error { // kubectl delete appprojects --field-selector metadata.name!=default return AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).DeleteCollection( - t.Context(), - metav1.DeleteOptions{PropagationPolicy: &policy}, - metav1.ListOptions{FieldSelector: "metadata.name!=default"}) + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{FieldSelector: "metadata.name!=default"}) }, func() error { // kubectl delete secrets -l argocd.argoproj.io/secret-type=repo-config return KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection( - t.Context(), - metav1.DeleteOptions{PropagationPolicy: &policy}, - metav1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepository}) + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepository}) }, func() error { // kubectl delete secrets -l argocd.argoproj.io/secret-type=repo-creds return KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection( - t.Context(), - metav1.DeleteOptions{PropagationPolicy: &policy}, - metav1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepoCreds}) + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepoCreds}) }, func() error { // kubectl delete secrets -l argocd.argoproj.io/secret-type=cluster return KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection( - t.Context(), - metav1.DeleteOptions{PropagationPolicy: &policy}, - metav1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeCluster}) + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeCluster}) }, func() error { // kubectl delete secrets -l e2e.argoproj.io=true return KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection( - t.Context(), - metav1.DeleteOptions{PropagationPolicy: &policy}, - metav1.ListOptions{LabelSelector: TestingLabel + "=true"}) + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{LabelSelector: TestingLabel + "=true"}) }, }) @@ -703,8 +680,8 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) { func() error { // delete old namespaces which were created by tests namespaces, err := KubeClientset.CoreV1().Namespaces().List( - t.Context(), - metav1.ListOptions{ + context.Background(), + v1.ListOptions{ LabelSelector: TestingLabel + "=true", FieldSelector: "status.phase=Active", }, @@ -723,7 +700,7 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) { } } - namespaces, err = KubeClientset.CoreV1().Namespaces().List(t.Context(), metav1.ListOptions{}) + namespaces, err = KubeClientset.CoreV1().Namespaces().List(context.Background(), v1.ListOptions{}) if err != nil { return err } @@ -751,8 +728,8 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) { func() error { // delete old ClusterRoles which were created by tests clusterRoles, err := KubeClientset.RbacV1().ClusterRoles().List( - t.Context(), - metav1.ListOptions{ + context.Background(), + v1.ListOptions{ LabelSelector: fmt.Sprintf("%s=%s", TestingLabel, "true"), }, ) @@ -770,7 +747,7 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) { } } - clusterRoles, err = KubeClientset.RbacV1().ClusterRoles().List(t.Context(), metav1.ListOptions{}) + clusterRoles, err = KubeClientset.RbacV1().ClusterRoles().List(context.Background(), v1.ListOptions{}) if err != nil { return err } @@ -792,7 +769,7 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) { }, func() error { // delete old ClusterRoleBindings which were created by tests - clusterRoleBindings, err := KubeClientset.RbacV1().ClusterRoleBindings().List(t.Context(), metav1.ListOptions{}) + clusterRoleBindings, err := KubeClientset.RbacV1().ClusterRoleBindings().List(context.Background(), v1.ListOptions{}) if err != nil { return err } @@ -851,7 +828,7 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) { OrphanedResources: nil, SourceRepos: []string{"*"}, Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "*"}}, - ClusterResourceWhitelist: []metav1.GroupKind{{Group: "*", Kind: "*"}}, + ClusterResourceWhitelist: []v1.GroupKind{{Group: "*", Kind: "*"}}, SourceNamespaces: []string{AppNamespace()}, }) if err != nil { @@ -860,21 +837,21 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) { // Create separate project for testing gpg signature verification _, err = AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Create( - t.Context(), + context.Background(), &v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "gpg", }, Spec: v1alpha1.AppProjectSpec{ OrphanedResources: nil, SourceRepos: []string{"*"}, Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "*"}}, - ClusterResourceWhitelist: []metav1.GroupKind{{Group: "*", Kind: "*"}}, + ClusterResourceWhitelist: []v1.GroupKind{{Group: "*", Kind: "*"}}, SignatureKeys: []v1alpha1.SignatureKey{{KeyID: GpgGoodKeyID}}, SourceNamespaces: []string{AppNamespace()}, }, }, - metav1.CreateOptions{}, + v1.CreateOptions{}, ) return err }, @@ -910,14 +887,14 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) { return err } prevGnuPGHome := os.Getenv("GNUPGHOME") - t.Setenv("GNUPGHOME", TmpDir+"/gpg") - //nolint:errcheck + os.Setenv("GNUPGHOME", TmpDir+"/gpg") + // nolint:errcheck Run("", "pkill", "-9", "gpg-agent") _, err = Run("", "gpg", "--import", "../fixture/gpg/signingkey.asc") if err != nil { return err } - t.Setenv("GNUPGHOME", prevGnuPGHome) + os.Setenv("GNUPGHOME", prevGnuPGHome) // recreate GPG directories if IsLocal() { @@ -986,7 +963,7 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) { postFix := "-" + strings.ToLower(randString) id = t.Name() + postFix name = DnsFriendly(t.Name(), "") - deploymentNamespace = DnsFriendly("argocd-e2e-"+t.Name(), postFix) + deploymentNamespace = DnsFriendly(fmt.Sprintf("argocd-e2e-%s", t.Name()), postFix) // create namespace _, err = Run("", "kubectl", "create", "ns", DeploymentNamespace()) if err != nil { @@ -1006,7 +983,6 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) { }).Info("clean state") } -// RunCliWithRetry executes an Argo CD CLI command with retry logic. func RunCliWithRetry(maxRetries int, args ...string) (string, error) { var out string var err error @@ -1020,12 +996,10 @@ func RunCliWithRetry(maxRetries int, args ...string) (string, error) { return out, err } -// RunCli executes an Argo CD CLI command with no stdin input and default server authentication. func RunCli(args ...string) (string, error) { return RunCliWithStdin("", false, args...) } -// RunCliWithStdin executes an Argo CD CLI command with optional stdin input and authentication. func RunCliWithStdin(stdin string, isKubeConextOnlyCli bool, args ...string) (string, error) { if plainText { args = append(args, "--plaintext") @@ -1041,115 +1015,103 @@ func RunCliWithStdin(stdin string, isKubeConextOnlyCli bool, args ...string) (st return RunWithStdin(stdin, "", "../../dist/argocd", args...) } -// RunPluginCli executes an Argo CD CLI plugin with optional stdin input. -func RunPluginCli(stdin string, args ...string) (string, error) { - return RunWithStdin(stdin, "", "../../dist/argocd", args...) -} - -func Patch(t *testing.T, path string, jsonPatch string) { - t.Helper() +func Patch(path string, jsonPatch string) { log.WithFields(log.Fields{"path": path, "jsonPatch": jsonPatch}).Info("patching") filename := filepath.Join(repoDirectory(), path) bytes, err := os.ReadFile(filename) - require.NoError(t, err) + CheckError(err) patch, err := jsonpatch.DecodePatch([]byte(jsonPatch)) - require.NoError(t, err) + CheckError(err) isYaml := strings.HasSuffix(filename, ".yaml") if isYaml { log.Info("converting YAML to JSON") bytes, err = yaml.YAMLToJSON(bytes) - require.NoError(t, err) + CheckError(err) } log.WithFields(log.Fields{"bytes": string(bytes)}).Info("JSON") bytes, err = patch.Apply(bytes) - require.NoError(t, err) + CheckError(err) if isYaml { log.Info("converting JSON back to YAML") bytes, err = yaml.JSONToYAML(bytes) - require.NoError(t, err) + CheckError(err) } - require.NoError(t, os.WriteFile(filename, bytes, 0o644)) - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "diff")) - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "commit", "-am", "patch")) + CheckError(os.WriteFile(filename, bytes, 0o644)) + FailOnErr(Run(repoDirectory(), "git", "diff")) + FailOnErr(Run(repoDirectory(), "git", "commit", "-am", "patch")) if IsRemote() { - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "push", "-f", "origin", "master")) + FailOnErr(Run(repoDirectory(), "git", "push", "-f", "origin", "master")) } } -func Delete(t *testing.T, path string) { - t.Helper() +func Delete(path string) { log.WithFields(log.Fields{"path": path}).Info("deleting") - require.NoError(t, os.Remove(filepath.Join(repoDirectory(), path))) + CheckError(os.Remove(filepath.Join(repoDirectory(), path))) - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "diff")) - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "commit", "-am", "delete")) + FailOnErr(Run(repoDirectory(), "git", "diff")) + FailOnErr(Run(repoDirectory(), "git", "commit", "-am", "delete")) if IsRemote() { - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "push", "-f", "origin", "master")) + FailOnErr(Run(repoDirectory(), "git", "push", "-f", "origin", "master")) } } -func WriteFile(t *testing.T, path, contents string) { - t.Helper() +func WriteFile(path, contents string) { log.WithFields(log.Fields{"path": path}).Info("adding") - require.NoError(t, os.WriteFile(filepath.Join(repoDirectory(), path), []byte(contents), 0o644)) + CheckError(os.WriteFile(filepath.Join(repoDirectory(), path), []byte(contents), 0o644)) } -func AddFile(t *testing.T, path, contents string) { - t.Helper() - WriteFile(t, path, contents) +func AddFile(path, contents string) { + WriteFile(path, contents) - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "diff")) - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "add", ".")) - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "commit", "-am", "add file")) + FailOnErr(Run(repoDirectory(), "git", "diff")) + FailOnErr(Run(repoDirectory(), "git", "add", ".")) + FailOnErr(Run(repoDirectory(), "git", "commit", "-am", "add file")) if IsRemote() { - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "push", "-f", "origin", "master")) + FailOnErr(Run(repoDirectory(), "git", "push", "-f", "origin", "master")) } } -func AddSignedFile(t *testing.T, path, contents string) { - t.Helper() - WriteFile(t, path, contents) +func AddSignedFile(path, contents string) { + WriteFile(path, contents) prevGnuPGHome := os.Getenv("GNUPGHOME") - t.Setenv("GNUPGHOME", TmpDir+"/gpg") - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "diff")) - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "add", ".")) - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "-c", "user.signingkey="+GpgGoodKeyID, "commit", "-S", "-am", "add file")) - t.Setenv("GNUPGHOME", prevGnuPGHome) + os.Setenv("GNUPGHOME", TmpDir+"/gpg") + FailOnErr(Run(repoDirectory(), "git", "diff")) + FailOnErr(Run(repoDirectory(), "git", "add", ".")) + FailOnErr(Run(repoDirectory(), "git", "-c", fmt.Sprintf("user.signingkey=%s", GpgGoodKeyID), "commit", "-S", "-am", "add file")) + os.Setenv("GNUPGHOME", prevGnuPGHome) if IsRemote() { - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "push", "-f", "origin", "master")) + FailOnErr(Run(repoDirectory(), "git", "push", "-f", "origin", "master")) } } -func AddSignedTag(t *testing.T, name string) { - t.Helper() +func AddSignedTag(name string) { prevGnuPGHome := os.Getenv("GNUPGHOME") - t.Setenv("GNUPGHOME", TmpDir+"/gpg") - defer t.Setenv("GNUPGHOME", prevGnuPGHome) - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "-c", "user.signingkey="+GpgGoodKeyID, "tag", "-sm", "add signed tag", name)) + os.Setenv("GNUPGHOME", TmpDir+"/gpg") + defer os.Setenv("GNUPGHOME", prevGnuPGHome) + FailOnErr(Run(repoDirectory(), "git", "-c", fmt.Sprintf("user.signingkey=%s", GpgGoodKeyID), "tag", "-sm", "add signed tag", name)) if IsRemote() { - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "push", "--tags", "-f", "origin", "master")) + FailOnErr(Run(repoDirectory(), "git", "push", "--tags", "-f", "origin", "master")) } } -func AddTag(t *testing.T, name string) { - t.Helper() +func AddTag(name string) { prevGnuPGHome := os.Getenv("GNUPGHOME") - t.Setenv("GNUPGHOME", TmpDir+"/gpg") - defer t.Setenv("GNUPGHOME", prevGnuPGHome) - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "tag", name)) + os.Setenv("GNUPGHOME", TmpDir+"/gpg") + defer os.Setenv("GNUPGHOME", prevGnuPGHome) + FailOnErr(Run(repoDirectory(), "git", "tag", name)) if IsRemote() { - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "push", "--tags", "-f", "origin", "master")) + FailOnErr(Run(repoDirectory(), "git", "push", "--tags", "-f", "origin", "master")) } } @@ -1158,91 +1120,96 @@ func AddTagWithForce(t *testing.T, name string) { prevGnuPGHome := os.Getenv("GNUPGHOME") t.Setenv("GNUPGHOME", TmpDir+"/gpg") defer t.Setenv("GNUPGHOME", prevGnuPGHome) - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "tag", "-f", name)) + _, err := Run(repoDirectory(), "git", "tag", "-f", name) + errors.CheckError(err) if IsRemote() { - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "push", "--tags", "-f", "origin", "master")) + _, err := Run(repoDirectory(), "git", "push", "--tags", "-f", "origin", "master") + errors.CheckError(err) } } func AddAnnotatedTag(t *testing.T, name string, message string) { t.Helper() - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "tag", "-f", "-a", name, "-m", message)) + _, err := Run(repoDirectory(), "git", "tag", "-f", "-a", name, "-m", message) + errors.CheckError(err) if IsRemote() { - errors.NewHandler(t).FailOnErr(Run(repoDirectory(), "git", "push", "--tags", "-f", "origin", "master")) + _, err := Run(repoDirectory(), "git", "push", "--tags", "-f", "origin", "master") + errors.CheckError(err) } } // create the resource by creating using "kubectl apply", with bonus templating -func Declarative(t *testing.T, filename string, values any) (string, error) { - t.Helper() +func Declarative(filename string, values interface{}) (string, error) { bytes, err := os.ReadFile(path.Join("testdata", filename)) - require.NoError(t, err) + CheckError(err) - tmpFile, err := os.CreateTemp(t.TempDir(), "") - require.NoError(t, err) - _, err = tmpFile.WriteString(Tmpl(t, string(bytes), values)) - require.NoError(t, err) + tmpFile, err := os.CreateTemp("", "") + CheckError(err) + _, err = tmpFile.WriteString(Tmpl(string(bytes), values)) + CheckError(err) defer tmpFile.Close() return Run("", "kubectl", "-n", TestNamespace(), "apply", "-f", tmpFile.Name()) } -func CreateSubmoduleRepos(t *testing.T, repoType string) { - t.Helper() +func CreateSubmoduleRepos(repoType string) { // set-up submodule repo - errors.NewHandler(t).FailOnErr(Run("", "cp", "-Rf", "testdata/git-submodule/", submoduleDirectory())) - errors.NewHandler(t).FailOnErr(Run(submoduleDirectory(), "chmod", "777", ".")) - errors.NewHandler(t).FailOnErr(Run(submoduleDirectory(), "git", "init", "-b", "master")) - errors.NewHandler(t).FailOnErr(Run(submoduleDirectory(), "git", "add", ".")) - errors.NewHandler(t).FailOnErr(Run(submoduleDirectory(), "git", "commit", "-q", "-m", "initial commit")) + FailOnErr(Run("", "cp", "-Rf", "testdata/git-submodule/", submoduleDirectory())) + FailOnErr(Run(submoduleDirectory(), "chmod", "777", ".")) + FailOnErr(Run(submoduleDirectory(), "git", "init", "-b", "master")) + FailOnErr(Run(submoduleDirectory(), "git", "add", ".")) + FailOnErr(Run(submoduleDirectory(), "git", "commit", "-q", "-m", "initial commit")) if IsRemote() { - errors.NewHandler(t).FailOnErr(Run(submoduleDirectory(), "git", "remote", "add", "origin", os.Getenv("ARGOCD_E2E_GIT_SERVICE_SUBMODULE"))) - errors.NewHandler(t).FailOnErr(Run(submoduleDirectory(), "git", "push", "origin", "master", "-f")) + FailOnErr(Run(submoduleDirectory(), "git", "remote", "add", "origin", os.Getenv("ARGOCD_E2E_GIT_SERVICE_SUBMODULE"))) + FailOnErr(Run(submoduleDirectory(), "git", "push", "origin", "master", "-f")) } // set-up submodule parent repo - errors.NewHandler(t).FailOnErr(Run("", "mkdir", submoduleParentDirectory())) - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "chmod", "777", ".")) - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "init", "-b", "master")) - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "add", ".")) + FailOnErr(Run("", "mkdir", submoduleParentDirectory())) + FailOnErr(Run(submoduleParentDirectory(), "chmod", "777", ".")) + FailOnErr(Run(submoduleParentDirectory(), "git", "init", "-b", "master")) + FailOnErr(Run(submoduleParentDirectory(), "git", "add", ".")) if IsRemote() { - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "submodule", "add", "-b", "master", os.Getenv("ARGOCD_E2E_GIT_SERVICE_SUBMODULE"), "submodule/test")) + FailOnErr(Run(submoduleParentDirectory(), "git", "submodule", "add", "-b", "master", os.Getenv("ARGOCD_E2E_GIT_SERVICE_SUBMODULE"), "submodule/test")) } else { - t.Setenv("GIT_ALLOW_PROTOCOL", "file") - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "submodule", "add", "-b", "master", "../submodule.git", "submodule/test")) + oldAllowProtocol, isAllowProtocolSet := os.LookupEnv("GIT_ALLOW_PROTOCOL") + CheckError(os.Setenv("GIT_ALLOW_PROTOCOL", "file")) + FailOnErr(Run(submoduleParentDirectory(), "git", "submodule", "add", "-b", "master", "../submodule.git", "submodule/test")) + if isAllowProtocolSet { + CheckError(os.Setenv("GIT_ALLOW_PROTOCOL", oldAllowProtocol)) + } else { + CheckError(os.Unsetenv("GIT_ALLOW_PROTOCOL")) + } } - switch repoType { - case "ssh": - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "config", "--file=.gitmodules", "submodule.submodule/test.url", RepoURL(RepoURLTypeSSHSubmodule))) - case "https": - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "config", "--file=.gitmodules", "submodule.submodule/test.url", RepoURL(RepoURLTypeHTTPSSubmodule))) + if repoType == "ssh" { + FailOnErr(Run(submoduleParentDirectory(), "git", "config", "--file=.gitmodules", "submodule.submodule/test.url", RepoURL(RepoURLTypeSSHSubmodule))) + } else if repoType == "https" { + FailOnErr(Run(submoduleParentDirectory(), "git", "config", "--file=.gitmodules", "submodule.submodule/test.url", RepoURL(RepoURLTypeHTTPSSubmodule))) } - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "add", "--all")) - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "commit", "-q", "-m", "commit with submodule")) + FailOnErr(Run(submoduleParentDirectory(), "git", "add", "--all")) + FailOnErr(Run(submoduleParentDirectory(), "git", "commit", "-q", "-m", "commit with submodule")) if IsRemote() { - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "remote", "add", "origin", os.Getenv("ARGOCD_E2E_GIT_SERVICE_SUBMODULE_PARENT"))) - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "push", "origin", "master", "-f")) + FailOnErr(Run(submoduleParentDirectory(), "git", "remote", "add", "origin", os.Getenv("ARGOCD_E2E_GIT_SERVICE_SUBMODULE_PARENT"))) + FailOnErr(Run(submoduleParentDirectory(), "git", "push", "origin", "master", "-f")) } } -func RemoveSubmodule(t *testing.T) { - t.Helper() +func RemoveSubmodule() { log.Info("removing submodule") - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "rm", "submodule/test")) - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "touch", "submodule/.gitkeep")) - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "add", "submodule/.gitkeep")) - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "commit", "-m", "remove submodule")) + FailOnErr(Run(submoduleParentDirectory(), "git", "rm", "submodule/test")) + FailOnErr(Run(submoduleParentDirectory(), "touch", "submodule/.gitkeep")) + FailOnErr(Run(submoduleParentDirectory(), "git", "add", "submodule/.gitkeep")) + FailOnErr(Run(submoduleParentDirectory(), "git", "commit", "-m", "remove submodule")) if IsRemote() { - errors.NewHandler(t).FailOnErr(Run(submoduleParentDirectory(), "git", "push", "-f", "origin", "master")) + FailOnErr(Run(submoduleParentDirectory(), "git", "push", "-f", "origin", "master")) } } // RestartRepoServer performs a restart of the repo server deployment and waits // until the rollout has completed. -func RestartRepoServer(t *testing.T) { - t.Helper() +func RestartRepoServer() { if IsRemote() { log.Infof("Waiting for repo server to restart") prefix := os.Getenv("ARGOCD_E2E_NAME_PREFIX") @@ -1250,8 +1217,8 @@ func RestartRepoServer(t *testing.T) { if prefix != "" { workload = prefix + "-repo-server" } - errors.NewHandler(t).FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "restart", "deployment", workload)) - errors.NewHandler(t).FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "status", "deployment", workload)) + FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "restart", "deployment", workload)) + FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "status", "deployment", workload)) // wait longer to avoid error on s390x time.Sleep(5 * time.Second) } @@ -1259,8 +1226,7 @@ func RestartRepoServer(t *testing.T) { // RestartAPIServer performs a restart of the API server deployemt and waits // until the rollout has completed. -func RestartAPIServer(t *testing.T) { - t.Helper() +func RestartAPIServer() { if IsRemote() { log.Infof("Waiting for API server to restart") prefix := os.Getenv("ARGOCD_E2E_NAME_PREFIX") @@ -1268,8 +1234,8 @@ func RestartAPIServer(t *testing.T) { if prefix != "" { workload = prefix + "-server" } - errors.NewHandler(t).FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "restart", "deployment", workload)) - errors.NewHandler(t).FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "status", "deployment", workload)) + FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "restart", "deployment", workload)) + FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "status", "deployment", workload)) } } @@ -1278,8 +1244,9 @@ func RestartAPIServer(t *testing.T) { func LocalOrRemotePath(base string) string { if IsRemote() { return base + "/remote" + } else { + return base + "/local" } - return base + "/local" } // SkipOnEnv allows to skip a test when a given environment variable is set. @@ -1326,12 +1293,12 @@ func RecordTestRun(t *testing.T) { t.Fatalf("could not close record file %s: %v", rf, err) } }() - if _, err := f.WriteString(t.Name() + "\n"); err != nil { + if _, err := f.WriteString(fmt.Sprintf("%s\n", t.Name())); err != nil { t.Fatalf("could not write to %s: %v", rf, err) } } -func GetApiServerAddress() string { //nolint:revive //FIXME(var-naming) +func GetApiServerAddress() string { return apiServerAddress } diff --git a/test/e2e/fixture/gpgkeys/gpgkeys.go b/test/e2e/fixture/gpgkeys/gpgkeys.go index 78e51a7e00..0751f67ad2 100644 --- a/test/e2e/fixture/gpgkeys/gpgkeys.go +++ b/test/e2e/fixture/gpgkeys/gpgkeys.go @@ -4,39 +4,34 @@ import ( "fmt" "os" "path/filepath" - "testing" - "github.com/stretchr/testify/require" - - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/errors" ) // Add GPG public key via API and create appropriate file where the ConfigMap mount would de it as well -func AddGPGPublicKey(t *testing.T) { - t.Helper() - keyPath, err := filepath.Abs("../fixture/gpg/" + fixture.GpgGoodKeyID) - require.NoError(t, err) +func AddGPGPublicKey() { + keyPath, err := filepath.Abs(fmt.Sprintf("../fixture/gpg/%s", fixture.GpgGoodKeyID)) + errors.CheckError(err) args := []string{"gpg", "add", "--from", keyPath} - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) if fixture.IsLocal() { keyData, err := os.ReadFile(keyPath) - require.NoError(t, err) + errors.CheckError(err) err = os.WriteFile(fmt.Sprintf("%s/app/config/gpg/source/%s", fixture.TmpDir, fixture.GpgGoodKeyID), keyData, 0o644) - require.NoError(t, err) + errors.CheckError(err) } else { - fixture.RestartRepoServer(t) + fixture.RestartRepoServer() } } -func DeleteGPGPublicKey(t *testing.T) { - t.Helper() +func DeleteGPGPublicKey() { args := []string{"gpg", "rm", fixture.GpgGoodKeyID} - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) if fixture.IsLocal() { - require.NoError(t, os.Remove(fmt.Sprintf("%s/app/config/gpg/source/%s", fixture.TmpDir, fixture.GpgGoodKeyID))) + errors.CheckError(os.Remove(fmt.Sprintf("%s/app/config/gpg/source/%s", fixture.TmpDir, fixture.GpgGoodKeyID))) } else { - fixture.RestartRepoServer(t) + fixture.RestartRepoServer() } } diff --git a/test/e2e/fixture/http.go b/test/e2e/fixture/http.go index c2c3fa2cbe..68e674f9f8 100644 --- a/test/e2e/fixture/http.go +++ b/test/e2e/fixture/http.go @@ -8,26 +8,26 @@ import ( "net/http" "net/url" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) // DoHttpRequest executes a http request against the Argo CD API server -func DoHttpRequest(method string, path string, host string, data ...byte) (*http.Response, error) { //nolint:revive //FIXME(var-naming) - reqURL, err := url.Parse(path) +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.Scheme = "http" if host != "" { - reqURL.Host = host + reqUrl.Host = host } else { - reqURL.Host = apiServerAddress + reqUrl.Host = apiServerAddress } var body io.Reader if data != nil { body = bytes.NewReader(data) } - req, err := http.NewRequest(method, reqURL.String(), body) + req, err := http.NewRequest(method, reqUrl.String(), body) if err != nil { return nil, err } @@ -44,7 +44,7 @@ func DoHttpRequest(method string, path string, host string, data ...byte) (*http } // 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 any, data ...byte) error { //nolint:revive //FIXME(var-naming) +func DoHttpJsonRequest(method string, path string, result interface{}, data ...byte) error { 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 6a42eb1d92..1012368cee 100644 --- a/test/e2e/fixture/notification/actions.go +++ b/test/e2e/fixture/notification/actions.go @@ -1,11 +1,8 @@ package notification import ( - "time" - - "github.com/stretchr/testify/require" - - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/errors" ) // this implements the "when" part of given/when/then @@ -19,14 +16,12 @@ type Actions struct { } func (a *Actions) SetParamInNotificationConfigMap(key, value string) *Actions { - a.context.t.Helper() - require.NoError(a.context.t, fixture.SetParamInNotificationsConfigMap(key, value)) + errors.CheckError(fixture.SetParamInNotificationsConfigMap(key, value)) return a } func (a *Actions) Then() *Consequences { a.context.t.Helper() - time.Sleep(fixture.WhenThenSleepInterval) return &Consequences{a.context, a} } diff --git a/test/e2e/fixture/notification/consequences.go b/test/e2e/fixture/notification/consequences.go index 6fdd8df5ee..46e09a4249 100644 --- a/test/e2e/fixture/notification/consequences.go +++ b/test/e2e/fixture/notification/consequences.go @@ -2,10 +2,9 @@ package notification import ( "context" - "time" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/notification" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/notification" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" ) // this implements the "then" part of given/when/then @@ -54,7 +53,6 @@ func (c *Consequences) listTemplates() (*notification.TemplateList, error) { } func (c *Consequences) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return c.actions } diff --git a/test/e2e/fixture/notification/context.go b/test/e2e/fixture/notification/context.go index 86fcad7727..3e257fcfff 100644 --- a/test/e2e/fixture/notification/context.go +++ b/test/e2e/fixture/notification/context.go @@ -2,9 +2,8 @@ package notification import ( "testing" - "time" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" ) // this implements the "given" part of given/when/then @@ -24,6 +23,5 @@ func (c *Context) And(block func()) *Context { } func (c *Context) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return &Actions{context: c} } diff --git a/test/e2e/fixture/project/actions.go b/test/e2e/fixture/project/actions.go index 39e590c463..f4358366c8 100644 --- a/test/e2e/fixture/project/actions.go +++ b/test/e2e/fixture/project/actions.go @@ -3,13 +3,12 @@ package project import ( "context" "strings" - "time" "github.com/stretchr/testify/require" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" ) // this implements the "when" part of given/when/then @@ -47,21 +46,16 @@ func (a *Actions) AddDestination(cluster string, namespace string) *Actions { return a } -func (a *Actions) AddDestinationServiceAccount(cluster string, namespace string) *Actions { - a.runCli("proj", "add-destination-service-account", a.context.name, cluster, namespace) - return a -} - func (a *Actions) AddSource(repo string) *Actions { a.runCli("proj", "add-source", a.context.name, repo) return a } func (a *Actions) UpdateProject(updater func(project *v1alpha1.AppProject)) *Actions { - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.TODO(), a.context.name, metav1.GetOptions{}) + proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.TODO(), a.context.name, v1.GetOptions{}) require.NoError(a.context.t, err) updater(proj) - _, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Update(context.TODO(), proj, metav1.UpdateOptions{}) + _, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Update(context.TODO(), proj, v1.UpdateOptions{}) require.NoError(a.context.t, err) return a } @@ -84,18 +78,6 @@ func (a *Actions) prepareCreateArgs(args []string) []string { if len(a.context.sourceNamespaces) > 0 { args = append(args, "--source-namespaces", strings.Join(a.context.sourceNamespaces, ",")) } - - if len(a.context.repos) > 0 { - for _, repo := range a.context.repos { - args = append(args, "--src", repo) - } - } - - if len(a.context.destinationServiceAccounts) != 0 { - for _, destinationServiceAccount := range a.context.destinationServiceAccounts { - args = append(args, "--dest-service-accounts", destinationServiceAccount) - } - } return args } @@ -113,7 +95,6 @@ func (a *Actions) And(block func()) *Actions { func (a *Actions) Then() *Consequences { a.context.t.Helper() - time.Sleep(fixture.WhenThenSleepInterval) return &Consequences{a.context, a} } diff --git a/test/e2e/fixture/project/consequences.go b/test/e2e/fixture/project/consequences.go index 94d868c06d..e7b2033c46 100644 --- a/test/e2e/fixture/project/consequences.go +++ b/test/e2e/fixture/project/consequences.go @@ -2,11 +2,10 @@ package project import ( "context" - "time" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/project" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/project" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" ) // this implements the "then" part of given/when/then @@ -44,6 +43,5 @@ func (c *Consequences) Given() *Context { } func (c *Consequences) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return c.actions } diff --git a/test/e2e/fixture/project/context.go b/test/e2e/fixture/project/context.go index 6c1aa2bb0d..8ab0a929f7 100644 --- a/test/e2e/fixture/project/context.go +++ b/test/e2e/fixture/project/context.go @@ -2,22 +2,20 @@ package project import ( "testing" - "time" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/env" ) // this implements the "given" part of given/when/then type Context struct { t *testing.T // seconds - timeout int - name string - destination string - destinationServiceAccounts []string - repos []string - sourceNamespaces []string + timeout int + name string + destination string + repos []string + sourceNamespaces []string } func Given(t *testing.T) *Context { @@ -48,11 +46,6 @@ func (c *Context) Destination(destination string) *Context { return c } -func (c *Context) DestinationServiceAccounts(destinationServiceAccounts []string) *Context { - c.destinationServiceAccounts = destinationServiceAccounts - return c -} - func (c *Context) SourceRepositories(repos []string) *Context { c.repos = repos return c @@ -69,6 +62,5 @@ func (c *Context) And(block func()) *Context { } func (c *Context) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return &Actions{context: c} } diff --git a/test/e2e/fixture/repos/actions.go b/test/e2e/fixture/repos/actions.go index 71d483fda7..5fa8c5d3bb 100644 --- a/test/e2e/fixture/repos/actions.go +++ b/test/e2e/fixture/repos/actions.go @@ -2,9 +2,8 @@ package repos import ( "log" - "time" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" ) // this implements the "when" part of given/when/then @@ -78,7 +77,6 @@ func (a *Actions) Project(project string) *Actions { func (a *Actions) Then() *Consequences { a.context.t.Helper() - time.Sleep(fixture.WhenThenSleepInterval) return &Consequences{a.context, a} } diff --git a/test/e2e/fixture/repos/consequences.go b/test/e2e/fixture/repos/consequences.go index 34a891914c..bb150b24ff 100644 --- a/test/e2e/fixture/repos/consequences.go +++ b/test/e2e/fixture/repos/consequences.go @@ -2,12 +2,11 @@ package repos import ( "context" - "errors" - "time" + "fmt" - repositorypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repository" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + repositorypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" ) // this implements the "then" part of given/when/then @@ -47,7 +46,7 @@ func (c *Consequences) get() (*v1alpha1.Repository, error) { } } - return nil, errors.New("repo not found") + return nil, fmt.Errorf("repo not found") } func (c *Consequences) Given() *Context { @@ -55,6 +54,5 @@ func (c *Consequences) Given() *Context { } func (c *Consequences) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return c.actions } diff --git a/test/e2e/fixture/repos/context.go b/test/e2e/fixture/repos/context.go index 57e6b4c127..0adea442fe 100644 --- a/test/e2e/fixture/repos/context.go +++ b/test/e2e/fixture/repos/context.go @@ -2,10 +2,9 @@ package repos import ( "testing" - "time" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/env" ) // this implements the "given" part of given/when/then @@ -55,7 +54,6 @@ func (c *Context) And(block func()) *Context { } func (c *Context) When() *Actions { - time.Sleep(fixture.WhenThenSleepInterval) return &Actions{context: c} } diff --git a/test/e2e/fixture/repos/repos.go b/test/e2e/fixture/repos/repos.go index 0cc7e1e856..e64f6e20fe 100644 --- a/test/e2e/fixture/repos/repos.go +++ b/test/e2e/fixture/repos/repos.go @@ -4,36 +4,26 @@ import ( "fmt" "os" "path/filepath" - "testing" - "github.com/stretchr/testify/require" - - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/errors" ) -func CertPath(t *testing.T) string { - t.Helper() - return mustToAbsPath(t, "../fixture/certs/argocd-test-client.crt") -} +var ( + CertPath = mustToAbsPath("../fixture/certs/argocd-test-client.crt") + CertKeyPath = mustToAbsPath("../fixture/certs/argocd-test-client.key") +) -func CertKeyPath(t *testing.T) string { - t.Helper() - return mustToAbsPath(t, "../fixture/certs/argocd-test-client.key") -} - -func mustToAbsPath(t *testing.T, relativePath string) string { - t.Helper() +func mustToAbsPath(relativePath string) string { res, err := filepath.Abs(relativePath) - require.NoError(t, err) + errors.CheckError(err) return res } // sets the current repo as the default SSH test repo -func AddSSHRepo(t *testing.T, insecure bool, credentials bool, repoURLType fixture.RepoURLType) { - t.Helper() +func AddSSHRepo(insecure bool, credentials bool, repoURLType fixture.RepoURLType) { keyPath, err := filepath.Abs("../fixture/testrepos/id_rsa") - require.NoError(t, err) + errors.CheckError(err) args := []string{"repo", "add", fixture.RepoURL(repoURLType)} if credentials { args = append(args, "--ssh-private-key-path", keyPath) @@ -41,12 +31,11 @@ func AddSSHRepo(t *testing.T, insecure bool, credentials bool, repoURLType fixtu if insecure { args = append(args, "--insecure-ignore-host-key") } - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) } // sets the current repo as the default HTTPS test repo -func AddHTTPSRepo(t *testing.T, insecure bool, credentials bool, project string, repoURLType fixture.RepoURLType) { - t.Helper() +func AddHTTPSRepo(insecure bool, credentials bool, repoURLType fixture.RepoURLType) { // This construct is somewhat necessary to satisfy the compiler args := []string{"repo", "add", fixture.RepoURL(repoURLType)} if credentials { @@ -55,48 +44,42 @@ func AddHTTPSRepo(t *testing.T, insecure bool, credentials bool, project string, if insecure { args = append(args, "--insecure-skip-server-verification") } - if project != "" { - args = append(args, "--project", project) - } - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) } // sets a HTTPS repo using TLS client certificate authentication -func AddHTTPSRepoClientCert(t *testing.T, insecure bool) { - t.Helper() +func AddHTTPSRepoClientCert(insecure bool) { args := []string{ "repo", "add", fixture.RepoURL(fixture.RepoURLTypeHTTPSClientCert), "--username", fixture.GitUsername, "--password", fixture.GitPassword, - "--tls-client-cert-path", CertPath(t), - "--tls-client-cert-key-path", CertKeyPath(t), + "--tls-client-cert-path", CertPath, + "--tls-client-cert-key-path", CertKeyPath, } if insecure { args = append(args, "--insecure-skip-server-verification") } - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) } -func AddHelmRepo(t *testing.T, name string) { - t.Helper() +func AddHelmRepo(name string) { args := []string{ "repo", "add", fixture.RepoURL(fixture.RepoURLTypeHelm), "--username", fixture.GitUsername, "--password", fixture.GitPassword, - "--tls-client-cert-path", CertPath(t), - "--tls-client-cert-key-path", CertKeyPath(t), + "--tls-client-cert-path", CertPath, + "--tls-client-cert-key-path", CertKeyPath, "--type", "helm", "--name", name, } - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) } -func AddHelmOCIRepo(t *testing.T, name string) { - t.Helper() +func AddHelmOCIRepo(name string) { args := []string{ "repo", "add", @@ -105,24 +88,22 @@ func AddHelmOCIRepo(t *testing.T, name string) { "--name", name, "--enable-oci", } - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) } // AddHTTPSRepoCredentialsUserPass adds E2E username/password credentials for HTTPS repos to context -func AddHTTPSCredentialsUserPass(t *testing.T) { - t.Helper() +func AddHTTPSCredentialsUserPass() { var repoURLType fixture.RepoURLType = fixture.RepoURLTypeHTTPS args := []string{"repocreds", "add", fixture.RepoURL(repoURLType), "--username", fixture.GitUsername, "--password", fixture.GitPassword} - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) } // AddHTTPSRepoCredentialsTLSClientCert adds E2E for HTTPS repos to context -func AddHTTPSCredentialsTLSClientCert(t *testing.T) { - t.Helper() +func AddHTTPSCredentialsTLSClientCert() { certPath, err := filepath.Abs("../fixture/certs/argocd-test-client.crt") - require.NoError(t, err) + errors.CheckError(err) keyPath, err := filepath.Abs("../fixture/certs/argocd-test-client.key") - require.NoError(t, err) + errors.CheckError(err) args := []string{ "repocreds", "add", @@ -132,16 +113,15 @@ func AddHTTPSCredentialsTLSClientCert(t *testing.T) { "--tls-client-cert-path", certPath, "--tls-client-cert-key-path", keyPath, } - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) } // AddHelmHTTPSCredentialsTLSClientCert adds credentials for Helm repos to context -func AddHelmHTTPSCredentialsTLSClientCert(t *testing.T) { - t.Helper() +func AddHelmHTTPSCredentialsTLSClientCert() { certPath, err := filepath.Abs("../fixture/certs/argocd-test-client.crt") - require.NoError(t, err) + errors.CheckError(err) keyPath, err := filepath.Abs("../fixture/certs/argocd-test-client.key") - require.NoError(t, err) + errors.CheckError(err) args := []string{ "repocreds", "add", @@ -152,49 +132,46 @@ func AddHelmHTTPSCredentialsTLSClientCert(t *testing.T) { "--tls-client-cert-key-path", keyPath, "--type", "helm", } - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) } // AddHelmoOCICredentialsWithoutUserPass adds credentials for Helm OIC repo to context -func AddHelmoOCICredentialsWithoutUserPass(t *testing.T) { - t.Helper() +func AddHelmoOCICredentialsWithoutUserPass() { args := []string{ "repocreds", "add", fixture.RepoURL(fixture.RepoURLTypeHelmOCI), "--enable-oci", "--type", "helm", } - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) } // AddSSHRepoCredentials adds E2E fixture credentials for SSH repos to context -func AddSSHCredentials(t *testing.T) { - t.Helper() +func AddSSHCredentials() { keyPath, err := filepath.Abs("../fixture/testrepos/id_rsa") - require.NoError(t, err) + errors.CheckError(err) var repoURLType fixture.RepoURLType = fixture.RepoURLTypeSSH args := []string{"repocreds", "add", fixture.RepoBaseURL(repoURLType), "--ssh-private-key-path", keyPath} - errors.NewHandler(t).FailOnErr(fixture.RunCli(args...)) + errors.FailOnErr(fixture.RunCli(args...)) } // PushChartToOCIRegistry adds a helm chart to helm OCI registry -func PushChartToOCIRegistry(t *testing.T, chartPathName, chartName, chartVersion string) { - t.Helper() +func PushChartToOCIRegistry(chartPathName, chartName, chartVersion string) { // create empty temp directory to extract chart from the registry tempDest, err1 := os.MkdirTemp("", "helm") - require.NoError(t, err1) + errors.CheckError(err1) defer func() { _ = os.RemoveAll(tempDest) }() - chartAbsPath, err2 := filepath.Abs("./testdata/" + chartPathName) - require.NoError(t, err2) + chartAbsPath, err2 := filepath.Abs(fmt.Sprintf("./testdata/%s", chartPathName)) + errors.CheckError(err2) - t.Setenv("HELM_EXPERIMENTAL_OCI", "1") - errors.NewHandler(t).FailOnErr(fixture.Run("", "helm", "dependency", "build", chartAbsPath)) - errors.NewHandler(t).FailOnErr(fixture.Run("", "helm", "package", chartAbsPath, "--destination", tempDest)) + _ = os.Setenv("HELM_EXPERIMENTAL_OCI", "1") + errors.FailOnErr(fixture.Run("", "helm", "dependency", "build", chartAbsPath)) + errors.FailOnErr(fixture.Run("", "helm", "package", chartAbsPath, "--destination", tempDest)) _ = os.RemoveAll(fmt.Sprintf("%s/%s", chartAbsPath, "charts")) - errors.NewHandler(t).FailOnErr(fixture.Run( + errors.FailOnErr(fixture.Run( "", "helm", "push", fmt.Sprintf("%s/%s-%s.tgz", tempDest, chartName, chartVersion), - "oci://"+fixture.HelmOCIRegistryURL, + fmt.Sprintf("oci://%s", fixture.HelmOCIRegistryURL), )) } diff --git a/test/e2e/fixture/tmpl.go b/test/e2e/fixture/tmpl.go index f8ec01144d..559c910144 100644 --- a/test/e2e/fixture/tmpl.go +++ b/test/e2e/fixture/tmpl.go @@ -4,20 +4,18 @@ import ( "bytes" "regexp" "strings" - "testing" "text/template" - "github.com/stretchr/testify/require" + . "github.com/argoproj/argo-cd/v2/util/errors" ) // utility method to template a string using a map -func Tmpl(t *testing.T, text string, values any) string { - t.Helper() +func Tmpl(text string, values interface{}) string { parse, err := template.New(text).Parse(text) - require.NoError(t, err) + CheckError(err) buf := new(bytes.Buffer) err = parse.Execute(buf, values) - require.NoError(t, err) + CheckError(err) return buf.String() } diff --git a/test/e2e/fixture/util.go b/test/e2e/fixture/util.go index d6f423f753..0669440f68 100644 --- a/test/e2e/fixture/util.go +++ b/test/e2e/fixture/util.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - "github.com/stretchr/testify/require" + "github.com/argoproj/argo-cd/v2/util/errors" "golang.org/x/sync/errgroup" ) @@ -16,7 +16,7 @@ var ( ) // returns dns friends string which is no longer than 63 characters and has specified postfix at the end -func DnsFriendly(str string, postfix string) string { //nolint:revive //FIXME(var-naming) +func DnsFriendly(str string, postfix string) string { str = matchFirstCap.ReplaceAllString(str, "${1}-${2}") str = matchAllCap.ReplaceAllString(str, "${1}-${2}") str = strings.ToLower(str) @@ -33,5 +33,5 @@ func RunFunctionsInParallelAndCheckErrors(t *testing.T, functions []func() error for _, function := range functions { eg.Go(function) } - require.NoError(t, eg.Wait()) + errors.CheckError(eg.Wait()) } diff --git a/test/e2e/fixture/versions.go b/test/e2e/fixture/versions.go index fc6269e8b4..ebcdbbd9b6 100644 --- a/test/e2e/fixture/versions.go +++ b/test/e2e/fixture/versions.go @@ -4,15 +4,13 @@ import ( "encoding/json" "fmt" "strings" - "testing" "github.com/argoproj/gitops-engine/pkg/cache" "github.com/argoproj/gitops-engine/pkg/utils/kube" - "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/errors" - kubeutil "github.com/argoproj/argo-cd/v3/util/kube" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/errors" + kubeutil "github.com/argoproj/argo-cd/v2/util/kube" ) type Versions struct { @@ -31,17 +29,15 @@ func (v Version) Format(format string) string { return fmt.Sprintf(format, v.Major, v.Minor) } -func GetVersions(t *testing.T) *Versions { - t.Helper() - output := errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "version", "-o", "json")).(string) +func GetVersions() *Versions { + output := errors.FailOnErr(Run(".", "kubectl", "version", "-o", "json")).(string) version := &Versions{} - require.NoError(t, json.Unmarshal([]byte(output), version)) + errors.CheckError(json.Unmarshal([]byte(output), version)) return version } -func GetApiResources(t *testing.T) string { //nolint:revive //FIXME(var-naming) - t.Helper() +func GetApiResources() string { kubectl := kubeutil.NewKubectl() - resources := errors.NewHandler(t).FailOnErr(kubectl.GetAPIResources(KubeConfig, false, cache.NewNoopSettings())).([]kube.APIResourceInfo) + resources := errors.FailOnErr(kubectl.GetAPIResources(KubeConfig, false, cache.NewNoopSettings())).([]kube.APIResourceInfo) return strings.Join(argo.APIResourcesToStrings(resources, true), ",") } diff --git a/test/e2e/git_submodule_test.go b/test/e2e/git_submodule_test.go index 485c858ec8..525c13d4b3 100644 --- a/test/e2e/git_submodule_test.go +++ b/test/e2e/git_submodule_test.go @@ -3,11 +3,12 @@ package e2e import ( "testing" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" ) func TestGitSubmoduleSSHSupport(t *testing.T) { @@ -18,11 +19,11 @@ func TestGitSubmoduleSSHSupport(t *testing.T) { CustomSSHKnownHostsAdded(). SubmoduleSSHRepoURLAdded(true). When(). - CreateFromFile(func(_ *Application) {}). + CreateFromFile(func(app *Application) {}). Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - Expect(Pod(func(p corev1.Pod) bool { return p.Name == "pod-in-submodule" })) + Expect(Pod(func(p v1.Pod) bool { return p.Name == "pod-in-submodule" })) } func TestGitSubmoduleHTTPSSupport(t *testing.T) { @@ -33,11 +34,11 @@ func TestGitSubmoduleHTTPSSupport(t *testing.T) { CustomCACertAdded(). SubmoduleHTTPSRepoURLAdded(true). When(). - CreateFromFile(func(_ *Application) {}). + CreateFromFile(func(app *Application) {}). Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - Expect(Pod(func(p corev1.Pod) bool { return p.Name == "pod-in-submodule" })) + Expect(Pod(func(p v1.Pod) bool { return p.Name == "pod-in-submodule" })) } func TestGitSubmoduleRemovalSupport(t *testing.T) { @@ -48,16 +49,16 @@ func TestGitSubmoduleRemovalSupport(t *testing.T) { CustomSSHKnownHostsAdded(). SubmoduleSSHRepoURLAdded(true). When(). - CreateFromFile(func(_ *Application) {}). + CreateFromFile(func(app *Application) {}). Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - Expect(Pod(func(p corev1.Pod) bool { return p.Name == "pod-in-submodule" })). + Expect(Pod(func(p v1.Pod) bool { return p.Name == "pod-in-submodule" })). When(). RemoveSubmodule(). Refresh(RefreshTypeNormal). Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - Expect(NotPod(func(p corev1.Pod) bool { return p.Name == "pod-in-submodule" })) + Expect(NotPod(func(p v1.Pod) bool { return p.Name == "pod-in-submodule" })) } diff --git a/test/e2e/git_test.go b/test/e2e/git_test.go index a0da0aabe4..f2e5cb2b18 100644 --- a/test/e2e/git_test.go +++ b/test/e2e/git_test.go @@ -6,17 +6,17 @@ import ( "testing" "time" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/util/errors" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/util/errors" ) func TestGitSemverResolutionNotUsingConstraint(t *testing.T) { @@ -71,7 +71,7 @@ func TestGitSemverResolutionUsingConstraint(t *testing.T) { Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - Expect(Pod(func(p corev1.Pod) bool { return strings.HasPrefix(p.Name, "new-app") })) + Expect(Pod(func(p v1.Pod) bool { return strings.HasPrefix(p.Name, "new-app") })) } func TestGitSemverResolutionUsingConstraintWithLeadingZero(t *testing.T) { @@ -96,7 +96,7 @@ func TestGitSemverResolutionUsingConstraintWithLeadingZero(t *testing.T) { Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - Expect(Pod(func(p corev1.Pod) bool { return strings.HasPrefix(p.Name, "new-app") })) + Expect(Pod(func(p v1.Pod) bool { return strings.HasPrefix(p.Name, "new-app") })) } func TestAnnotatedTagInStatusSyncRevision(t *testing.T) { @@ -156,8 +156,8 @@ func TestAutomatedSelfHealingAgainstAnnotatedTag(t *testing.T) { // The Application should update to the new annotated tag value within 10 seconds. And(func() { // Deployment revisionHistoryLimit should switch to 10 - timeoutErr := wait.PollUntilContextTimeout(t.Context(), 1*time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) { - deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + timeoutErr := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) { + deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) if err != nil { return false, nil } @@ -169,14 +169,14 @@ func TestAutomatedSelfHealingAgainstAnnotatedTag(t *testing.T) { }). // Update the Deployment to a different revisionHistoryLimit And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(), + errors.FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(context.Background(), "guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 9}}`), metav1.PatchOptions{})) }). // The revisionHistoryLimit should NOT be self-healed, because selfHealing: false. It should remain at 9. And(func() { // Wait up to 10 seconds to ensure that deployment revisionHistoryLimit does NOT should switch to 10, it should remain at 9. - waitErr := wait.PollUntilContextTimeout(t.Context(), 1*time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) { - deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + waitErr := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) { + deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) if err != nil { return false, nil } @@ -209,8 +209,8 @@ func TestAutomatedSelfHealingAgainstLightweightTag(t *testing.T) { // The Application should update to the new annotated tag value within 10 seconds. And(func() { // Deployment revisionHistoryLimit should switch to 10 - timeoutErr := wait.PollUntilContextTimeout(t.Context(), 1*time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) { - deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + timeoutErr := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) { + deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) if err != nil { return false, nil } @@ -222,14 +222,14 @@ func TestAutomatedSelfHealingAgainstLightweightTag(t *testing.T) { }). // Update the Deployment to a different revisionHistoryLimit And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(), + errors.FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(context.Background(), "guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 9}}`), metav1.PatchOptions{})) }). // The revisionHistoryLimit should NOT be self-healed, because selfHealing: false And(func() { // Wait up to 10 seconds to ensure that deployment revisionHistoryLimit does NOT should switch to 10, it should remain at 9. - waitErr := wait.PollUntilContextTimeout(t.Context(), 1*time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) { - deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}) + waitErr := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) { + deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) if err != nil { return false, nil } diff --git a/test/e2e/graceful_restart_test.go b/test/e2e/graceful_restart_test.go index 5f818c1c7e..6f5c6960a4 100644 --- a/test/e2e/graceful_restart_test.go +++ b/test/e2e/graceful_restart_test.go @@ -1,6 +1,7 @@ package e2e import ( + "context" "net/http" "strings" "testing" @@ -8,13 +9,15 @@ import ( "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/settings" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/settings" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/errors" ) func checkHealth(t *testing.T, requireHealthy bool) { t.Helper() - resp, err := fixture.DoHttpRequest("GET", "/healthz?full=true", "") + resp, err := DoHttpRequest("GET", "/healthz?full=true", "") if requireHealthy { require.NoError(t, err) require.Equal(t, http.StatusOK, resp.StatusCode) @@ -30,12 +33,12 @@ func checkHealth(t *testing.T, requireHealthy bool) { } func TestAPIServerGracefulRestart(t *testing.T) { - fixture.EnsureCleanState(t) + EnsureCleanState(t) // Should be healthy. checkHealth(t, true) // Should trigger API server restart. - require.NoError(t, fixture.SetParamInSettingConfigMap("url", "http://test-api-server-graceful-restart")) + errors.CheckError(fixture.SetParamInSettingConfigMap("url", "http://test-api-server-graceful-restart")) // Wait for ~5 seconds for i := 0; i < 50; i++ { @@ -44,12 +47,12 @@ func TestAPIServerGracefulRestart(t *testing.T) { } // One final time, should be healthy, or restart is considered too slow for tests checkHealth(t, true) - closer, settingsClient, err := fixture.ArgoCDClientset.NewSettingsClient() + closer, settingsClient, err := ArgoCDClientset.NewSettingsClient() if closer != nil { defer closer.Close() } require.NoError(t, err) - settings, err := settingsClient.Get(t.Context(), &settings.SettingsQuery{}) + settings, err := settingsClient.Get(context.Background(), &settings.SettingsQuery{}) require.NoError(t, err) require.Equal(t, "http://test-api-server-graceful-restart", settings.URL) } diff --git a/test/e2e/helm_test.go b/test/e2e/helm_test.go index 2e427a64b2..a893486811 100644 --- a/test/e2e/helm_test.go +++ b/test/e2e/helm_test.go @@ -1,6 +1,7 @@ package e2e import ( + "context" "fmt" "net" "net/http" @@ -11,13 +12,18 @@ import ( "github.com/argoproj/gitops-engine/pkg/health" . "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - projectFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/project" - "github.com/argoproj/argo-cd/v3/util/errors" + . "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" + projectFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/project" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos" + . "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/settings" ) func TestHelmHooksAreCreated(t *testing.T) { @@ -31,7 +37,7 @@ func TestHelmHooksAreCreated(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(HealthIs(health.HealthStatusHealthy)). Expect(SyncStatusIs(SyncStatusCodeSynced)). - Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: fixture.DeploymentNamespace(), Name: "hook", Message: "pod/hook created", HookType: HookTypePreSync, HookPhase: OperationSucceeded, SyncPhase: SyncPhasePreSync})) + Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Name: "hook", Message: "pod/hook created", HookType: HookTypePreSync, HookPhase: OperationSucceeded, SyncPhase: SyncPhasePreSync})) } // make sure we treat Helm weights as a sync wave @@ -63,7 +69,7 @@ func TestHelmHookDeletePolicy(t *testing.T) { Then(). Expect(OperationPhaseIs(OperationSucceeded)). Expect(ResourceResultNumbering(2)). - Expect(NotPod(func(p corev1.Pod) bool { return p.Name == "hook" })) + Expect(NotPod(func(p v1.Pod) bool { return p.Name == "hook" })) } func TestDeclarativeHelm(t *testing.T) { @@ -90,11 +96,11 @@ func TestDeclarativeHelmInvalidValuesFile(t *testing.T) { } func TestHelmRepo(t *testing.T) { - fixture.SkipOnEnv(t, "HELM") + SkipOnEnv(t, "HELM") Given(t). CustomCACertAdded(). HelmRepoAdded("custom-repo"). - RepoURLType(fixture.RepoURLTypeHelm). + RepoURLType(RepoURLTypeHelm). Chart("helm"). Revision("1.0.0"). When(). @@ -217,7 +223,7 @@ func TestHelmValuesLiteralFileRemote(t *testing.T) { // send back the address so that it can be used c <- listener.Addr().String() - http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // return the sentinel text at root URL fmt.Fprint(w, sentinel) }) @@ -249,7 +255,7 @@ func TestHelmValuesLiteralFileRemote(t *testing.T) { } func TestHelmCrdHook(t *testing.T) { - fixture.SkipOnEnv(t, "HELM") + SkipOnEnv(t, "HELM") Given(t). Path("helm-crd"). When(). @@ -321,8 +327,8 @@ func TestHelmSetEnv(t *testing.T) { Then(). Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - assert.Equal(t, fixture.Name(), errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string)) + And(func(app *Application) { + assert.Equal(t, Name(), FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string)) }) } @@ -336,14 +342,14 @@ func TestHelmSetStringEnv(t *testing.T) { Then(). Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - assert.Equal(t, fixture.Name(), errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string)) + And(func(app *Application) { + assert.Equal(t, Name(), FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string)) }) } // make sure kube-version gets passed down to resources func TestKubeVersion(t *testing.T) { - fixture.SkipOnEnv(t, "HELM") + SkipOnEnv(t, "HELM") Given(t). Path("helm-kube-version"). When(). @@ -351,11 +357,11 @@ func TestKubeVersion(t *testing.T) { Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - kubeVersion := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map", + And(func(app *Application) { + kubeVersion := FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.kubeVersion}")).(string) // Capabilities.KubeVersion defaults to 1.9.0, we assume here you are running a later version - assert.LessOrEqual(t, fixture.GetVersions(t).ServerVersion.Format("v%s.%s.0"), kubeVersion) + assert.LessOrEqual(t, GetVersions().ServerVersion.Format("v%s.%s.0"), kubeVersion) }). When(). // Make sure override works. @@ -363,15 +369,15 @@ func TestKubeVersion(t *testing.T) { Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - assert.Equal(t, "v999.999.999", errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map", + And(func(app *Application) { + assert.Equal(t, "v999.999.999", FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.kubeVersion}")).(string)) }) } // make sure api versions gets passed down to resources func TestApiVersions(t *testing.T) { - fixture.SkipOnEnv(t, "HELM") + SkipOnEnv(t, "HELM") Given(t). Path("helm-api-versions"). When(). @@ -379,8 +385,8 @@ func TestApiVersions(t *testing.T) { Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - apiVersions := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map", + And(func(app *Application) { + apiVersions := FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.apiVersions}")).(string) // The v1 API shouldn't be going anywhere. assert.Contains(t, apiVersions, "v1") @@ -391,15 +397,15 @@ func TestApiVersions(t *testing.T) { Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - apiVersions := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map", + And(func(app *Application) { + apiVersions := FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.apiVersions}")).(string) assert.Contains(t, apiVersions, "v1/MyTestResource") }) } func TestHelmNamespaceOverride(t *testing.T) { - fixture.SkipOnEnv(t, "HELM") + SkipOnEnv(t, "HELM") Given(t). Path("helm-namespace"). When(). @@ -415,7 +421,7 @@ func TestHelmNamespaceOverride(t *testing.T) { } func TestHelmValuesHiddenDirectory(t *testing.T) { - fixture.SkipOnEnv(t, "HELM") + SkipOnEnv(t, "HELM") Given(t). Path(".hidden-helm"). When(). @@ -430,28 +436,12 @@ func TestHelmValuesHiddenDirectory(t *testing.T) { } func TestHelmWithDependencies(t *testing.T) { - fixture.SkipOnEnv(t, "HELM") - - ctx := Given(t). - CustomCACertAdded(). - // these are slow tests - Timeout(30). - HelmPassCredentials() - - ctx = ctx.HelmRepoAdded("custom-repo") - - helmVer := "" - - ctx.Path("helm-with-dependencies"). - When(). - CreateApp("--helm-version", helmVer). - Sync(). - Then(). - Expect(SyncStatusIs(SyncStatusCodeSynced)) + SkipOnEnv(t, "HELM") + testHelmWithDependencies(t, "helm-with-dependencies", false) } func TestHelmWithMultipleDependencies(t *testing.T) { - fixture.SkipOnEnv(t, "HELM") + SkipOnEnv(t, "HELM") Given(t).Path("helm-with-multiple-dependencies"). CustomCACertAdded(). @@ -467,7 +457,7 @@ func TestHelmWithMultipleDependencies(t *testing.T) { } func TestHelmDependenciesPermissionDenied(t *testing.T) { - fixture.SkipOnEnv(t, "HELM") + SkipOnEnv(t, "HELM") projName := "argo-helm-project-denied" projectFixture. @@ -476,7 +466,7 @@ func TestHelmDependenciesPermissionDenied(t *testing.T) { Destination("*,*"). When(). Create(). - AddSource(fixture.RepoURL(fixture.RepoURLTypeFile)) + AddSource(RepoURL(RepoURLTypeFile)) expectedErr := fmt.Sprintf("helm repos localhost:5000/myrepo are not permitted in project '%s'", projName) GivenWithSameState(t). @@ -505,8 +495,55 @@ func TestHelmDependenciesPermissionDenied(t *testing.T) { Expect(Error("", expectedErr)) } +func TestHelmWithDependenciesLegacyRepo(t *testing.T) { + SkipOnEnv(t, "HELM") + testHelmWithDependencies(t, "helm-with-dependencies", true) +} + +func testHelmWithDependencies(t *testing.T, chartPath string, legacyRepo bool) { + t.Helper() + ctx := Given(t). + CustomCACertAdded(). + // these are slow tests + Timeout(30). + HelmPassCredentials() + if legacyRepo { + ctx.And(func() { + FailOnErr(fixture.Run("", "kubectl", "create", "secret", "generic", "helm-repo", + "-n", fixture.TestNamespace(), + fmt.Sprintf("--from-file=certSecret=%s", repos.CertPath), + fmt.Sprintf("--from-file=keySecret=%s", repos.CertKeyPath), + fmt.Sprintf("--from-literal=username=%s", GitUsername), + fmt.Sprintf("--from-literal=password=%s", GitPassword), + )) + FailOnErr(fixture.KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Patch(context.Background(), + "helm-repo", types.MergePatchType, []byte(`{"metadata": { "labels": {"e2e.argoproj.io": "true"} }}`), metav1.PatchOptions{})) + + CheckError(fixture.SetHelmRepos(settings.HelmRepoCredentials{ + URL: RepoURL(RepoURLTypeHelm), + Name: "custom-repo", + KeySecret: &v1.SecretKeySelector{LocalObjectReference: v1.LocalObjectReference{Name: "helm-repo"}, Key: "keySecret"}, + CertSecret: &v1.SecretKeySelector{LocalObjectReference: v1.LocalObjectReference{Name: "helm-repo"}, Key: "certSecret"}, + UsernameSecret: &v1.SecretKeySelector{LocalObjectReference: v1.LocalObjectReference{Name: "helm-repo"}, Key: "username"}, + PasswordSecret: &v1.SecretKeySelector{LocalObjectReference: v1.LocalObjectReference{Name: "helm-repo"}, Key: "password"}, + })) + }) + } else { + ctx = ctx.HelmRepoAdded("custom-repo") + } + + helmVer := "" + + ctx.Path(chartPath). + When(). + CreateApp("--helm-version", helmVer). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)) +} + func TestHelm3CRD(t *testing.T) { - fixture.SkipOnEnv(t, "HELM") + SkipOnEnv(t, "HELM") Given(t). Path("helm3-crd"). When(). @@ -518,12 +555,12 @@ func TestHelm3CRD(t *testing.T) { } func TestHelmRepoDiffLocal(t *testing.T) { - fixture.SkipOnEnv(t, "HELM") + SkipOnEnv(t, "HELM") helmTmp := t.TempDir() Given(t). CustomCACertAdded(). HelmRepoAdded("custom-repo"). - RepoURLType(fixture.RepoURLTypeHelm). + RepoURLType(RepoURLTypeHelm). Chart("helm"). Revision("1.0.0"). When(). @@ -536,17 +573,16 @@ func TestHelmRepoDiffLocal(t *testing.T) { Expect(HealthIs(health.HealthStatusHealthy)). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - t.Setenv("XDG_CONFIG_HOME", helmTmp) - errors.NewHandler(t).FailOnErr(fixture.Run("", "helm", "repo", "add", "custom-repo", fixture.GetEnvWithDefault("ARGOCD_E2E_HELM_SERVICE", fixture.RepoURL(fixture.RepoURLTypeHelm)), - "--username", fixture.GitUsername, - "--password", fixture.GitPassword, + _ = os.Setenv("XDG_CONFIG_HOME", helmTmp) + FailOnErr(Run("", "helm", "repo", "add", "custom-repo", GetEnvWithDefault("ARGOCD_E2E_HELM_SERVICE", RepoURL(RepoURLTypeHelm)), + "--username", GitUsername, + "--password", GitPassword, "--cert-file", "../fixture/certs/argocd-test-client.crt", "--key-file", "../fixture/certs/argocd-test-client.key", "--ca-file", "../fixture/certs/argocd-test-ca.crt", )) - diffOutput, err := fixture.RunCli("app", "diff", app.Name, "--local", "testdata/helm") + diffOutput := FailOnErr(RunCli("app", "diff", app.Name, "--local", "testdata/helm")).(string) assert.Empty(t, diffOutput) - assert.NoError(t, err) }) } @@ -554,7 +590,7 @@ func TestHelmOCIRegistry(t *testing.T) { Given(t). PushChartToOCIRegistry("helm-values", "helm-values", "1.0.0"). HelmOCIRepoAdded("myrepo"). - RepoURLType(fixture.RepoURLTypeHelmOCI). + RepoURLType(RepoURLTypeHelmOCI). Chart("helm-values"). Revision("1.0.0"). When(). @@ -589,7 +625,7 @@ func TestHelmOCIRegistryWithDependencies(t *testing.T) { PushChartToOCIRegistry("helm-values", "helm-values", "1.0.0"). PushChartToOCIRegistry("helm-oci-with-dependencies", "helm-oci-with-dependencies", "1.0.0"). HelmOCIRepoAdded("myrepo"). - RepoURLType(fixture.RepoURLTypeHelmOCI). + RepoURLType(RepoURLTypeHelmOCI). Chart("helm-oci-with-dependencies"). Revision("1.0.0"). When(). @@ -624,7 +660,7 @@ func TestTemplatesHelmOCIWithDependencies(t *testing.T) { PushChartToOCIRegistry("helm-values", "helm-values", "1.0.0"). PushChartToOCIRegistry("helm-oci-with-dependencies", "helm-oci-with-dependencies", "1.0.0"). HelmoOCICredentialsWithoutUserPassAdded(). - RepoURLType(fixture.RepoURLTypeHelmOCI). + RepoURLType(RepoURLTypeHelmOCI). Chart("helm-oci-with-dependencies"). Revision("1.0.0"). When(). diff --git a/test/e2e/hook_test.go b/test/e2e/hook_test.go index 71e323bf6e..a538566986 100644 --- a/test/e2e/hook_test.go +++ b/test/e2e/hook_test.go @@ -1,23 +1,23 @@ package e2e import ( + "context" "fmt" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" "github.com/argoproj/gitops-engine/pkg/health" . "github.com/argoproj/gitops-engine/pkg/sync/common" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/util/lua" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + . "github.com/argoproj/argo-cd/v2/util/errors" ) func TestPreSyncHookSuccessful(t *testing.T) { @@ -62,8 +62,8 @@ func TestPostDeleteHook(t *testing.T) { Then(). Expect(DoesNotExist()). AndAction(func() { - hooks, err := KubeClientset.CoreV1().Pods(DeploymentNamespace()).List(t.Context(), metav1.ListOptions{}) - require.NoError(t, err) + hooks, err := KubeClientset.CoreV1().Pods(DeploymentNamespace()).List(context.Background(), metav1.ListOptions{}) + CheckError(err) assert.Len(t, hooks.Items, 1) assert.Equal(t, "hook", hooks.Items[0].Name) }) @@ -96,9 +96,9 @@ func TestPreSyncHookFailure(t *testing.T) { IgnoreErrors(). Sync(). Then(). - Expect(Error("hook Failed Synced PreSync container \"main\" failed", "")). + Expect(Error("hook Failed PreSync", "")). // make sure resource are also printed - Expect(Error("pod OutOfSync Missing", "")). + Expect(Error("pod OutOfSync Missing", "")). Expect(OperationPhaseIs(OperationFailed)). // if a pre-sync hook fails, we should not start the main sync Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). @@ -172,7 +172,7 @@ func TestPostSyncHookPodFailure(t *testing.T) { Expect(ResourceSyncStatusIs("Pod", "pod", SyncStatusCodeSynced)). Expect(ResourceHealthIs("Pod", "pod", health.HealthStatusDegraded)). Expect(ResourceResultNumbering(1)). - Expect(NotPod(func(p corev1.Pod) bool { return p.Name == "hook" })) + Expect(NotPod(func(p v1.Pod) bool { return p.Name == "hook" })) } func TestSyncFailHookPodFailure(t *testing.T) { @@ -264,7 +264,7 @@ func TestHookDeletePolicyHookSucceededHookExit0(t *testing.T) { Sync(). Then(). Expect(OperationPhaseIs(OperationSucceeded)). - Expect(NotPod(func(p corev1.Pod) bool { return p.Name == "hook" })) + Expect(NotPod(func(p v1.Pod) bool { return p.Name == "hook" })) } // make sure that we delete the hook on failure, if policy is set @@ -280,7 +280,7 @@ func TestHookDeletePolicyHookSucceededHookExit1(t *testing.T) { Then(). Expect(OperationPhaseIs(OperationFailed)). Expect(ResourceResultNumbering(2)). - Expect(Pod(func(p corev1.Pod) bool { return p.Name == "hook" })) + Expect(Pod(func(p v1.Pod) bool { return p.Name == "hook" })) } // make sure that we do NOT delete the hook on success if failure policy is set @@ -294,7 +294,7 @@ func TestHookDeletePolicyHookFailedHookExit0(t *testing.T) { Then(). Expect(OperationPhaseIs(OperationSucceeded)). Expect(ResourceResultNumbering(2)). - Expect(Pod(func(p corev1.Pod) bool { return p.Name == "hook" })) + Expect(Pod(func(p v1.Pod) bool { return p.Name == "hook" })) } // make sure that we do delete the hook on failure if failure policy is set @@ -310,7 +310,7 @@ func TestHookDeletePolicyHookFailedHookExit1(t *testing.T) { Then(). Expect(OperationPhaseIs(OperationFailed)). Expect(ResourceResultNumbering(2)). - Expect(NotPod(func(p corev1.Pod) bool { return p.Name == "hook" })) + Expect(NotPod(func(p v1.Pod) bool { return p.Name == "hook" })) } // make sure that we can run the hook twice @@ -328,11 +328,11 @@ func TestHookBeforeHookCreation(t *testing.T) { Expect(HealthIs(health.HealthStatusHealthy)). Expect(ResourceResultNumbering(2)). // the app will be in health+n-sync before this hook has run - Expect(Pod(func(p corev1.Pod) bool { return p.Name == "hook" })). + Expect(Pod(func(p v1.Pod) bool { return p.Name == "hook" })). And(func(_ *Application) { var err error creationTimestamp1, err = getCreationTimestamp() - require.NoError(t, err) + CheckError(err) assert.NotEmpty(t, creationTimestamp1) // pause to ensure that timestamp will change time.Sleep(1 * time.Second) @@ -344,10 +344,10 @@ func TestHookBeforeHookCreation(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). Expect(ResourceResultNumbering(2)). - Expect(Pod(func(p corev1.Pod) bool { return p.Name == "hook" })). + Expect(Pod(func(p v1.Pod) bool { return p.Name == "hook" })). And(func(_ *Application) { creationTimestamp2, err := getCreationTimestamp() - require.NoError(t, err) + CheckError(err) assert.NotEmpty(t, creationTimestamp2) assert.NotEqual(t, creationTimestamp1, creationTimestamp2) }) @@ -389,7 +389,7 @@ func TestHookSkip(t *testing.T) { Then(). Expect(OperationPhaseIs(OperationSucceeded)). Expect(ResourceResultNumbering(1)). - Expect(NotPod(func(p corev1.Pod) bool { return p.Name == "pod" })) + Expect(NotPod(func(p v1.Pod) bool { return p.Name == "pod" })) } // make sure that we do NOT name non-hook resources in they are unnamed @@ -427,56 +427,3 @@ func TestAutomaticallyNamingUnnamedHook(t *testing.T) { assert.Contains(t, resources[2].Name, "postsync") }) } - -func TestHookFinalizerPreSync(t *testing.T) { - testHookFinalizer(t, HookTypePreSync) -} - -func TestHookFinalizerSync(t *testing.T) { - testHookFinalizer(t, HookTypeSync) -} - -func TestHookFinalizerPostSync(t *testing.T) { - testHookFinalizer(t, HookTypePostSync) -} - -func testHookFinalizer(t *testing.T, hookType HookType) { - t.Helper() - Given(t). - And(func() { - require.NoError(t, SetResourceOverrides(map[string]ResourceOverride{ - lua.GetConfigMapKey(schema.FromAPIVersionAndKind("batch/v1", "Job")): { - HealthLua: ` - local hs = {} - hs.status = "Healthy" - if obj.metadata.deletionTimestamp == nil then - hs.status = "Progressing" - hs.message = "Waiting to be externally deleted" - return hs - end - if obj.metadata.finalizers ~= nil then - for i, finalizer in ipairs(obj.metadata.finalizers) do - if finalizer == "argocd.argoproj.io/hook-finalizer" then - hs.message = "Resource has finalizer" - return hs - end - end - end - hs.message = "no finalizer for a hook is wrong" - return hs`, - }, - })) - }). - Path("hook-resource-deleted-externally"). - When(). - PatchFile("hook.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/hook": "%s"}}]`, hookType)). - CreateApp(). - Sync(). - Then(). - Expect(OperationPhaseIs(OperationSucceeded)). - Expect(SyncStatusIs(SyncStatusCodeSynced)). - Expect(ResourceSyncStatusIs("Pod", "pod", SyncStatusCodeSynced)). - Expect(ResourceHealthIs("Pod", "pod", health.HealthStatusHealthy)). - Expect(ResourceResultNumbering(2)). - Expect(ResourceResultIs(ResourceResult{Group: "batch", Version: "v1", Kind: "Job", Namespace: DeploymentNamespace(), Name: "hook", Message: "Resource has finalizer", HookType: hookType, HookPhase: OperationSucceeded, SyncPhase: SyncPhase(hookType)})) -} diff --git a/test/e2e/hydrator_test.go b/test/e2e/hydrator_test.go index 6274bcb7fa..0d36aa240a 100644 --- a/test/e2e/hydrator_test.go +++ b/test/e2e/hydrator_test.go @@ -3,8 +3,8 @@ package e2e import ( "testing" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" . "github.com/argoproj/gitops-engine/pkg/sync/common" ) diff --git a/test/e2e/jsonnet_test.go b/test/e2e/jsonnet_test.go index 759b2ce3e1..3f1113b420 100644 --- a/test/e2e/jsonnet_test.go +++ b/test/e2e/jsonnet_test.go @@ -8,10 +8,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/util/errors" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + . "github.com/argoproj/argo-cd/v2/util/errors" ) func TestJsonnetAppliedCorrectly(t *testing.T) { @@ -83,9 +83,9 @@ func TestJsonnetTlaEnv(t *testing.T) { Then(). Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - assert.Equal(t, Name(), errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string)) - assert.Equal(t, Name(), errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.bar}")).(string)) + And(func(app *Application) { + assert.Equal(t, Name(), FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string)) + assert.Equal(t, Name(), FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.bar}")).(string)) }) } @@ -98,9 +98,9 @@ func TestJsonnetExtVarEnv(t *testing.T) { Then(). Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - assert.Equal(t, Name(), errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string)) - assert.Equal(t, Name(), errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.bar}")).(string)) + And(func(app *Application) { + assert.Equal(t, Name(), FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string)) + assert.Equal(t, Name(), FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.bar}")).(string)) }) } diff --git a/test/e2e/kubectl_metrics_test.go b/test/e2e/kubectl_metrics_test.go deleted file mode 100644 index a53605bdf9..0000000000 --- a/test/e2e/kubectl_metrics_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package e2e - -import ( - "io" - "net/http" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/errors" -) - -func TestKubectlMetrics(t *testing.T) { - // Sync an app so that there are metrics to scrape. - ctx := Given(t) - ctx. - Path(guestbookPath). - When(). - CreateApp(). - Then(). - Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). - And(func(app *Application) { - assert.Equal(t, fixture.Name(), app.Name) - assert.Equal(t, fixture.RepoURL(fixture.RepoURLTypeFile), app.Spec.GetSource().RepoURL) - assert.Equal(t, guestbookPath, app.Spec.GetSource().Path) - assert.Equal(t, fixture.DeploymentNamespace(), app.Spec.Destination.Namespace) - assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) - }). - Expect(Event(argo.EventReasonResourceCreated, "create")). - And(func(_ *Application) { - // app should be listed - output, err := fixture.RunCli("app", "list") - require.NoError(t, err) - assert.Contains(t, output, fixture.Name()) - }). - When(). - // ensure that create is idempotent - CreateApp(). - Then(). - Given(). - Revision("master"). - When(). - // ensure that update replaces spec and merge labels and annotations - And(func() { - errors.NewHandler(t).FailOnErr(fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.TestNamespace()).Patch(t.Context(), - ctx.GetName(), types.MergePatchType, []byte(`{"metadata": {"labels": { "test": "label" }, "annotations": { "test": "annotation" }}}`), metav1.PatchOptions{})) - }). - CreateApp("--upsert"). - Then(). - And(func(app *Application) { - assert.Equal(t, "label", app.Labels["test"]) - assert.Equal(t, "annotation", app.Annotations["test"]) - assert.Equal(t, "master", app.Spec.GetSource().TargetRevision) - }) - - // Make a request to the app controller metrics endpoint and ensure the response contains kubectl metrics. - resp, err := http.Get("http://127.0.0.1:8082/metrics") - require.NoError(t, err) - defer func() { - err = resp.Body.Close() - require.NoError(t, err) - }() - body, err := io.ReadAll(resp.Body) - require.NoError(t, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) - - assert.Contains(t, string(body), "argocd_kubectl_request_duration_seconds", "metrics should have contained argocd_kubectl_request_duration_seconds") - assert.Contains(t, string(body), "argocd_kubectl_request_size_bytes", "metrics should have contained argocd_kubectl_request_size_bytes") - assert.Contains(t, string(body), "argocd_kubectl_response_size_bytes", "metrics should have contained argocd_kubectl_response_size_bytes") - assert.Contains(t, string(body), "argocd_kubectl_rate_limiter_duration_seconds", "metrics should have contained argocd_kubectl_rate_limiter_duration_seconds") - assert.Contains(t, string(body), "argocd_kubectl_requests_total", "metrics should have contained argocd_kubectl_requests_total") - - /* - The following metrics are not being tested: - - argocd_kubectl_client_cert_rotation_age_seconds: The test doesn't use a client certificate, so this metric doesn't get populated. - - argocd_kubectl_dns_resolution_duration_seconds: It's unclear why this metric isn't populated. Possibly because DNS resolution is short-circuited by the test environment. - - argocd_kubectl_exec_plugin_call_total: The test doesn't use an exec plugin, so this metric doesn't get populated. TODO: add a test using an exec plugin to populate this metric. - - argocd_kubectl_request_retries_total: The test is unlikely to encounter a need to retry requests, so this metric is likely unpopulated. - - argocd_kubectl_transport_cache_entries: The transport cache is only used under certain conditions, which this test doesn't encounter. - - argocd_kubectl_transport_create_calls_total: The transport cache is only used under certain conditions, which this test doesn't encounter. - */ - - // Repeat the test for port 8083, i.e. the API server. - resp, err = http.Get("http://127.0.0.1:8083/metrics") - require.NoError(t, err) - defer func() { - err = resp.Body.Close() - require.NoError(t, err) - }() - body, err = io.ReadAll(resp.Body) - require.NoError(t, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) - - assert.Contains(t, string(body), "argocd_kubectl_request_duration_seconds", "metrics should have contained argocd_kubectl_request_duration_seconds") - assert.Contains(t, string(body), "argocd_kubectl_request_size_bytes", "metrics should have contained argocd_kubectl_request_size_bytes") - assert.Contains(t, string(body), "argocd_kubectl_response_size_bytes", "metrics should have contained argocd_kubectl_response_size_bytes") - assert.Contains(t, string(body), "argocd_kubectl_rate_limiter_duration_seconds", "metrics should have contained argocd_kubectl_rate_limiter_duration_seconds") - assert.Contains(t, string(body), "argocd_kubectl_requests_total", "metrics should have contained argocd_kubectl_requests_total") -} diff --git a/test/e2e/kustomize_test.go b/test/e2e/kustomize_test.go index 60061ca9f6..923b9d46fe 100644 --- a/test/e2e/kustomize_test.go +++ b/test/e2e/kustomize_test.go @@ -9,15 +9,17 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/util/errors" + . "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" + . "github.com/argoproj/argo-cd/v2/util/errors" ) func TestKustomize2AppSource(t *testing.T) { patchLabelMatchesFor := func(kind string) func(app *Application) { - return func(_ *Application) { + return func(app *Application) { name := "k2-patched-guestbook-ui-deploy1" labelValue, err := fixture.Run( "", "kubectl", "-n="+fixture.DeploymentNamespace(), @@ -145,7 +147,7 @@ func TestKustomizeBuildOptionsLoadRestrictor(t *testing.T) { Given(t). Path(guestbookPath). And(func() { - errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", + errors.FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", "-n", fixture.TestNamespace(), "-p", `{ "data": { "kustomize.buildOptions": "--load-restrictor LoadRestrictionsNone" } }`)) }). @@ -159,7 +161,7 @@ func TestKustomizeBuildOptionsLoadRestrictor(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). Given(). And(func() { - errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", + errors.FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", "-n", fixture.TestNamespace(), "-p", `{ "data": { "kustomize.buildOptions": "" } }`)) }) @@ -184,7 +186,7 @@ func TestKustomizeReplicas2AppSource(t *testing.T) { deploymentName := "guestbook-ui" deploymentReplicas := 2 checkReplicasFor := func(kind string) func(app *Application) { - return func(_ *Application) { + return func(app *Application) { name := deploymentName replicas, err := fixture.Run( "", "kubectl", "-n="+fixture.DeploymentNamespace(), @@ -292,7 +294,7 @@ func TestKustomizeKubeVersion(t *testing.T) { Given(t). Path("kustomize-kube-version"). And(func() { - errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", + errors.FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", "-n", fixture.TestNamespace(), "-p", `{ "data": { "kustomize.buildOptions": "--enable-helm" } }`)) }). @@ -301,11 +303,11 @@ func TestKustomizeKubeVersion(t *testing.T) { Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - kubeVersion := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map", + And(func(app *Application) { + kubeVersion := FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.kubeVersion}")).(string) // Capabilities.KubeVersion defaults to 1.9.0, we assume here you are running a later version - assert.LessOrEqual(t, fixture.GetVersions(t).ServerVersion.Format("v%s.%s.0"), kubeVersion) + assert.LessOrEqual(t, GetVersions().ServerVersion.Format("v%s.%s.0"), kubeVersion) }). When(). // Make sure override works. @@ -313,8 +315,8 @@ func TestKustomizeKubeVersion(t *testing.T) { Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - assert.Equal(t, "v999.999.999", errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map", + And(func(app *Application) { + assert.Equal(t, "v999.999.999", FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.kubeVersion}")).(string)) }) } @@ -324,7 +326,7 @@ func TestKustomizeApiVersions(t *testing.T) { Given(t). Path("kustomize-api-versions"). And(func() { - errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", + errors.FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", "-n", fixture.TestNamespace(), "-p", `{ "data": { "kustomize.buildOptions": "--enable-helm" } }`)) }). @@ -333,8 +335,8 @@ func TestKustomizeApiVersions(t *testing.T) { Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - apiVersions := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map", + And(func(app *Application) { + apiVersions := FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.apiVersions}")).(string) // The v1 API shouldn't be going anywhere. assert.Contains(t, apiVersions, "v1") @@ -345,8 +347,8 @@ func TestKustomizeApiVersions(t *testing.T) { Sync(). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). - And(func(_ *Application) { - apiVersions := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map", + And(func(app *Application) { + apiVersions := FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.apiVersions}")).(string) assert.Contains(t, apiVersions, "v1/MyTestResource") }) @@ -356,7 +358,7 @@ func TestKustomizeNamespaceOverride(t *testing.T) { Given(t). Path("kustomize-kube-version"). And(func() { - errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", + errors.FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", "-n", fixture.TestNamespace(), "-p", `{ "data": { "kustomize.buildOptions": "--enable-helm" } }`)) }). diff --git a/test/e2e/mask_secret_values_test.go b/test/e2e/mask_secret_values_test.go index 2be5677adc..0b3b8dd01d 100644 --- a/test/e2e/mask_secret_values_test.go +++ b/test/e2e/mask_secret_values_test.go @@ -9,9 +9,9 @@ import ( "github.com/argoproj/gitops-engine/pkg/health" "github.com/argoproj/gitops-engine/pkg/sync/common" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + . "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 diff --git a/test/e2e/matrix_e2e_test.go b/test/e2e/matrix_e2e_test.go index 534c74938b..b2b53ac317 100644 --- a/test/e2e/matrix_e2e_test.go +++ b/test/e2e/matrix_e2e_test.go @@ -7,16 +7,17 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets/utils" + "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/applicationsets" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) func TestListMatrixGenerator(t *testing.T) { - generateExpectedApp := func(cluster, name string) v1alpha1.Application { - return v1alpha1.Application{ + generateExpectedApp := func(cluster, name string) argov1alpha1.Application { + return argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -26,14 +27,14 @@ func TestListMatrixGenerator(t *testing.T) { Namespace: utils.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: name, }, @@ -41,7 +42,7 @@ func TestListMatrixGenerator(t *testing.T) { } } - expectedApps := []v1alpha1.Application{ + expectedApps := []argov1alpha1.Application{ generateExpectedApp("cluster1", "kustomize-guestbook"), generateExpectedApp("cluster1", "helm-guestbook"), @@ -49,8 +50,8 @@ func TestListMatrixGenerator(t *testing.T) { generateExpectedApp("cluster2", "helm-guestbook"), } - var expectedAppsNewNamespace []v1alpha1.Application - var expectedAppsNewMetadata []v1alpha1.Application + var expectedAppsNewNamespace []argov1alpha1.Application + var expectedAppsNewMetadata []argov1alpha1.Application Given(t). // Create a ClusterGenerator-based ApplicationSet @@ -62,14 +63,14 @@ func TestListMatrixGenerator(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{values.name}}-{{path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{path}}", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "{{path.basename}}", }, @@ -138,8 +139,8 @@ func TestListMatrixGenerator(t *testing.T) { } func TestClusterMatrixGenerator(t *testing.T) { - generateExpectedApp := func(cluster, name string) v1alpha1.Application { - return v1alpha1.Application{ + generateExpectedApp := func(cluster, name string) argov1alpha1.Application { + return argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -149,14 +150,14 @@ func TestClusterMatrixGenerator(t *testing.T) { Namespace: utils.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: cluster, Namespace: name, }, @@ -164,7 +165,7 @@ func TestClusterMatrixGenerator(t *testing.T) { } } - expectedApps := []v1alpha1.Application{ + expectedApps := []argov1alpha1.Application{ generateExpectedApp("cluster1", "kustomize-guestbook"), generateExpectedApp("cluster1", "helm-guestbook"), @@ -172,8 +173,8 @@ func TestClusterMatrixGenerator(t *testing.T) { generateExpectedApp("cluster2", "helm-guestbook"), } - var expectedAppsNewNamespace []v1alpha1.Application - var expectedAppsNewMetadata []v1alpha1.Application + var expectedAppsNewNamespace []argov1alpha1.Application + var expectedAppsNewMetadata []argov1alpha1.Application Given(t). // Create a ClusterGenerator-based ApplicationSet @@ -187,14 +188,14 @@ func TestClusterMatrixGenerator(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-{{path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{path}}", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{name}}", Namespace: "{{path.basename}}", }, @@ -264,8 +265,8 @@ func TestClusterMatrixGenerator(t *testing.T) { } func TestMatrixTerminalMatrixGeneratorSelector(t *testing.T) { - generateExpectedApp := func(cluster, name string) v1alpha1.Application { - return v1alpha1.Application{ + generateExpectedApp := func(cluster, name string) argov1alpha1.Application { + return argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -275,14 +276,14 @@ func TestMatrixTerminalMatrixGeneratorSelector(t *testing.T) { Namespace: utils.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: name, }, @@ -290,11 +291,11 @@ func TestMatrixTerminalMatrixGeneratorSelector(t *testing.T) { } } - excludedApps := []v1alpha1.Application{ + expectedApps1 := []argov1alpha1.Application{ generateExpectedApp("cluster1", "kustomize-guestbook"), generateExpectedApp("cluster1", "helm-guestbook"), } - expectedApps := []v1alpha1.Application{ + expectedApps2 := []argov1alpha1.Application{ generateExpectedApp("cluster2", "kustomize-guestbook"), generateExpectedApp("cluster2", "helm-guestbook"), } @@ -307,16 +308,17 @@ func TestMatrixTerminalMatrixGeneratorSelector(t *testing.T) { Name: "matrix-generator-nested-matrix", }, Spec: v1alpha1.ApplicationSetSpec{ + ApplyNestedSelectors: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{values.name}}-{{path.basename}}"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{path}}", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "{{path.basename}}", }, @@ -367,7 +369,7 @@ func TestMatrixTerminalMatrixGeneratorSelector(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist(excludedApps)).Expect(ApplicationsDoNotExist(expectedApps)). + }).Then().Expect(ApplicationsExist(expectedApps1)).Expect(ApplicationsDoNotExist(expectedApps2)). // Update the ApplicationSetTerminalGenerator LabelSelector, and verify the Applications are deleted and created When(). @@ -399,14 +401,22 @@ func TestMatrixTerminalMatrixGeneratorSelector(t *testing.T) { }, }, }) - }).Then().Expect(ApplicationsExist(expectedApps)).Expect(ApplicationsDoNotExist(excludedApps)). + }).Then().Expect(ApplicationsExist(expectedApps2)).Expect(ApplicationsDoNotExist(expectedApps1)). + + // Set ApplyNestedSelector to false and verify all Applications are created When(). - Delete().Then().Expect(ApplicationsDoNotExist(excludedApps)).Expect(ApplicationsDoNotExist(expectedApps)) + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.ApplyNestedSelectors = false + }).Then().Expect(ApplicationsExist(expectedApps1)).Expect(ApplicationsExist(expectedApps2)). + + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedApps1)).Expect(ApplicationsDoNotExist(expectedApps2)) } func TestMatrixTerminalMergeGeneratorSelector(t *testing.T) { - generateExpectedApp := func(name, nameSuffix string) v1alpha1.Application { - return v1alpha1.Application{ + generateExpectedApp := func(name, nameSuffix string) argov1alpha1.Application { + return argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -416,14 +426,14 @@ func TestMatrixTerminalMergeGeneratorSelector(t *testing.T) { Namespace: utils.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: name, }, @@ -431,10 +441,10 @@ func TestMatrixTerminalMergeGeneratorSelector(t *testing.T) { } } - excludedApps := []v1alpha1.Application{ + expectedApps1 := []argov1alpha1.Application{ generateExpectedApp("kustomize-guestbook", "1"), } - expectedApps := []v1alpha1.Application{ + expectedApps2 := []argov1alpha1.Application{ generateExpectedApp("helm-guestbook", "2"), } @@ -446,16 +456,17 @@ func TestMatrixTerminalMergeGeneratorSelector(t *testing.T) { Name: "matrix-generator-nested-merge", }, Spec: v1alpha1.ApplicationSetSpec{ + ApplyNestedSelectors: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}-{{name-suffix}}"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{path}}", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "{{path.basename}}", }, @@ -507,7 +518,7 @@ func TestMatrixTerminalMergeGeneratorSelector(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist(excludedApps)).Expect(ApplicationsDoNotExist(expectedApps)). + }).Then().Expect(ApplicationsExist(expectedApps1)).Expect(ApplicationsDoNotExist(expectedApps2)). // Update the ApplicationSetTerminalGenerator LabelSelector, and verify the Applications are deleted and created When(). @@ -540,7 +551,15 @@ func TestMatrixTerminalMergeGeneratorSelector(t *testing.T) { }, }, }) - }).Then().Expect(ApplicationsExist(expectedApps)).Expect(ApplicationsDoNotExist(excludedApps)). + }).Then().Expect(ApplicationsExist(expectedApps2)).Expect(ApplicationsDoNotExist(expectedApps1)). + + // Set ApplyNestedSelector to false and verify all Applications are created When(). - Delete().Then().Expect(ApplicationsDoNotExist(excludedApps)).Expect(ApplicationsDoNotExist(expectedApps)) + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.ApplyNestedSelectors = false + }).Then().Expect(ApplicationsExist(expectedApps1)).Expect(ApplicationsExist(expectedApps2)). + + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedApps1)).Expect(ApplicationsDoNotExist(expectedApps2)) } diff --git a/test/e2e/merge_e2e_test.go b/test/e2e/merge_e2e_test.go index e799c95fdd..09f1da87de 100644 --- a/test/e2e/merge_e2e_test.go +++ b/test/e2e/merge_e2e_test.go @@ -8,16 +8,17 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets/utils" + "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/applicationsets" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) func TestListMergeGenerator(t *testing.T) { - generateExpectedApp := func(name, nameSuffix string) v1alpha1.Application { - return v1alpha1.Application{ + generateExpectedApp := func(name, nameSuffix string) argov1alpha1.Application { + return argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -27,14 +28,14 @@ func TestListMergeGenerator(t *testing.T) { Namespace: utils.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: name, }, @@ -42,13 +43,13 @@ func TestListMergeGenerator(t *testing.T) { } } - expectedApps := []v1alpha1.Application{ + expectedApps := []argov1alpha1.Application{ generateExpectedApp("kustomize-guestbook", "1"), generateExpectedApp("helm-guestbook", "2"), } - var expectedAppsNewNamespace []v1alpha1.Application - var expectedAppsNewMetadata []v1alpha1.Application + var expectedAppsNewNamespace []argov1alpha1.Application + var expectedAppsNewMetadata []argov1alpha1.Application Given(t). // Create a ClusterGenerator-based ApplicationSet @@ -60,14 +61,14 @@ func TestListMergeGenerator(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}-{{name-suffix}}"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{path}}", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "{{path.basename}}", }, @@ -137,8 +138,8 @@ func TestListMergeGenerator(t *testing.T) { } func TestClusterMergeGenerator(t *testing.T) { - generateExpectedApp := func(cluster, name, nameSuffix string) v1alpha1.Application { - return v1alpha1.Application{ + generateExpectedApp := func(cluster, name, nameSuffix string) argov1alpha1.Application { + return argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -148,14 +149,14 @@ func TestClusterMergeGenerator(t *testing.T) { Namespace: utils.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: cluster, Namespace: name, }, @@ -163,7 +164,7 @@ func TestClusterMergeGenerator(t *testing.T) { } } - expectedApps := []v1alpha1.Application{ + expectedApps := []argov1alpha1.Application{ generateExpectedApp("cluster1", "kustomize-guestbook", "1"), generateExpectedApp("cluster1", "helm-guestbook", "0"), @@ -171,8 +172,8 @@ func TestClusterMergeGenerator(t *testing.T) { generateExpectedApp("cluster2", "helm-guestbook", "2"), } - var expectedAppsNewNamespace []v1alpha1.Application - var expectedAppsNewMetadata []v1alpha1.Application + var expectedAppsNewNamespace []argov1alpha1.Application + var expectedAppsNewMetadata []argov1alpha1.Application Given(t). // Create a ClusterGenerator-based ApplicationSet @@ -186,14 +187,14 @@ func TestClusterMergeGenerator(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-{{path.basename}}-{{values.name-suffix}}"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{path}}", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Name: "{{name}}", Namespace: "{{path.basename}}", }, @@ -281,8 +282,8 @@ func TestClusterMergeGenerator(t *testing.T) { } func TestMergeTerminalMergeGeneratorSelector(t *testing.T) { - generateExpectedApp := func(name, nameSuffix string) v1alpha1.Application { - return v1alpha1.Application{ + generateExpectedApp := func(name, nameSuffix string) argov1alpha1.Application { + return argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: application.ApplicationKind, APIVersion: "argoproj.io/v1alpha1", @@ -292,14 +293,14 @@ func TestMergeTerminalMergeGeneratorSelector(t *testing.T) { Namespace: utils.TestNamespace(), Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: name, }, @@ -307,10 +308,10 @@ func TestMergeTerminalMergeGeneratorSelector(t *testing.T) { } } - excludedApps := []v1alpha1.Application{ + expectedApps1 := []argov1alpha1.Application{ generateExpectedApp("kustomize-guestbook", "1"), } - expectedApps := []v1alpha1.Application{ + expectedApps2 := []argov1alpha1.Application{ generateExpectedApp("helm-guestbook", "2"), } @@ -322,16 +323,17 @@ func TestMergeTerminalMergeGeneratorSelector(t *testing.T) { Name: "merge-generator-nested-merge", }, Spec: v1alpha1.ApplicationSetSpec{ + ApplyNestedSelectors: true, Template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}-{{name-suffix}}"}, - Spec: v1alpha1.ApplicationSpec{ + Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: &v1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{path}}", }, - Destination: v1alpha1.ApplicationDestination{ + Destination: argov1alpha1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "{{path.basename}}", }, @@ -384,7 +386,7 @@ func TestMergeTerminalMergeGeneratorSelector(t *testing.T) { }, }, }, - }).Then().Expect(ApplicationsExist(excludedApps)).Expect(ApplicationsDoNotExist(expectedApps)). + }).Then().Expect(ApplicationsExist(expectedApps1)).Expect(ApplicationsDoNotExist(expectedApps2)). // Update the ApplicationSetTerminalGenerator LabelSelector, and verify the Applications are deleted and created When(). @@ -417,12 +419,20 @@ func TestMergeTerminalMergeGeneratorSelector(t *testing.T) { }, }, }) - }).Then().Expect(ApplicationsExist(expectedApps)).Expect(ApplicationsDoNotExist(excludedApps)). + }).Then().Expect(ApplicationsExist(expectedApps2)).Expect(ApplicationsDoNotExist(expectedApps1)). + + // Set ApplyNestedSelector to false and verify all Applications are created When(). - Delete().Then().Expect(ApplicationsDoNotExist(excludedApps)).Expect(ApplicationsDoNotExist(expectedApps)) + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.ApplyNestedSelectors = false + }).Then().Expect(ApplicationsExist(expectedApps1)).Expect(ApplicationsExist(expectedApps2)). + + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist(expectedApps1)).Expect(ApplicationsDoNotExist(expectedApps2)) } -func toAPIExtensionsJSON(t *testing.T, g any) *apiextensionsv1.JSON { +func toAPIExtensionsJSON(t *testing.T, g interface{}) *apiextensionsv1.JSON { t.Helper() resVal, err := json.Marshal(g) if err != nil { diff --git a/test/e2e/multiarch-container/Dockerfile b/test/e2e/multiarch-container/Dockerfile index 6d07fdd8d3..d023155785 100644 --- a/test/e2e/multiarch-container/Dockerfile +++ b/test/e2e/multiarch-container/Dockerfile @@ -1,2 +1,2 @@ -FROM docker.io/library/busybox@sha256:37f7b378a29ceb4c551b1b5582e27747b855bbfaa73fa11914fe0df028dc581f +FROM docker.io/library/busybox@sha256:2919d0172f7524b2d8df9e50066a682669e6d170ac0f6a49676d54358fe970b5 CMD exec sh -c "trap : TERM INT; echo 'Hi' && tail -f /dev/null" diff --git a/test/e2e/notification_test.go b/test/e2e/notification_test.go index e86acb481a..11ed412a39 100644 --- a/test/e2e/notification_test.go +++ b/test/e2e/notification_test.go @@ -7,8 +7,8 @@ import ( "github.com/stretchr/testify/require" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/notification" - notifFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/notification" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/notification" + notifFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/notification" ) func TestNotificationsListServices(t *testing.T) { diff --git a/test/e2e/project_management_test.go b/test/e2e/project_management_test.go index 45d673970a..169227eea5 100644 --- a/test/e2e/project_management_test.go +++ b/test/e2e/project_management_test.go @@ -16,14 +16,14 @@ import ( "k8s.io/apimachinery/pkg/fields" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/util/argo" + "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/util/argo" ) func assertProjHasEvent(t *testing.T, a *v1alpha1.AppProject, message string, reason string) { t.Helper() - list, err := fixture.KubeClientset.CoreV1().Events(fixture.TestNamespace()).List(t.Context(), metav1.ListOptions{ + list, err := fixture.KubeClientset.CoreV1().Events(fixture.TestNamespace()).List(context.Background(), metav1.ListOptions{ FieldSelector: fields.SelectorFromSet(map[string]string{ "involvedObject.name": a.Name, "involvedObject.uid": string(a.UID), @@ -53,7 +53,7 @@ func TestProjectCreation(t *testing.T) { "--orphaned-resources") require.NoError(t, err) - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + 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.Destinations, 2) @@ -89,7 +89,7 @@ func TestProjectCreation(t *testing.T) { _, err = fixture.RunCliWithStdin(stdinString, false, "proj", "create", "-f", "-", "--upsert") require.NoError(t, err) - proj, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + proj, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, newDescription, proj.Spec.Description) } @@ -99,13 +99,13 @@ func TestProjectDeletion(t *testing.T) { projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( - t.Context(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) + context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) require.NoError(t, err) _, err = fixture.RunCli("proj", "delete", projectName) require.NoError(t, err) - _, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + _, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) assert.True(t, errors.IsNotFound(err)) assertProjHasEvent(t, proj, "delete", argo.EventReasonResourceDeleted) } @@ -115,7 +115,7 @@ func TestSetProject(t *testing.T) { projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( - t.Context(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) + context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) require.NoError(t, err) _, err = fixture.RunCli("proj", "set", projectName, @@ -125,7 +125,7 @@ func TestSetProject(t *testing.T) { "--orphaned-resources-warn=false") require.NoError(t, err) - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + 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.Destinations, 2) @@ -147,7 +147,7 @@ func TestAddProjectDestination(t *testing.T) { projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( - t.Context(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) + context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) require.NoError(t, err, "Unable to create project") _, err = fixture.RunCli("proj", "add-destination", projectName, @@ -174,7 +174,7 @@ func TestAddProjectDestination(t *testing.T) { ) require.ErrorContains(t, err, "namespace has an invalid format, '!*'") - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + 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.Destinations, 1) @@ -189,7 +189,7 @@ func TestAddProjectDestinationWithName(t *testing.T) { projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( - t.Context(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) + context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) require.NoError(t, err, "Unable to create project") _, err = fixture.RunCli("proj", "add-destination", projectName, @@ -199,12 +199,12 @@ func TestAddProjectDestinationWithName(t *testing.T) { ) require.NoError(t, err, "Unable to add project destination") - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + 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.Destinations, 1) - assert.Empty(t, proj.Spec.Destinations[0].Server) + assert.Equal(t, "", proj.Spec.Destinations[0].Server) assert.Equal(t, "in-cluster", proj.Spec.Destinations[0].Name) assert.Equal(t, "test1", proj.Spec.Destinations[0].Namespace) assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated) @@ -214,7 +214,7 @@ func TestRemoveProjectDestination(t *testing.T) { fixture.EnsureCleanState(t) projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) - _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create(t.Context(), &v1alpha1.AppProject{ + _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create(context.Background(), &v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: projectName}, Spec: v1alpha1.AppProjectSpec{ Destinations: []v1alpha1.ApplicationDestination{{ @@ -237,7 +237,7 @@ func TestRemoveProjectDestination(t *testing.T) { ) require.ErrorContains(t, err, "does not exist") - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) require.NoError(t, err, "Unable to get project") assert.Equal(t, projectName, proj.Name) assert.Empty(t, proj.Spec.Destinations) @@ -249,7 +249,7 @@ func TestAddProjectSource(t *testing.T) { projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( - t.Context(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) + context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) require.NoError(t, err, "Unable to create project") _, err = fixture.RunCli("proj", "add-source", projectName, "https://github.com/argoproj/argo-cd.git") @@ -258,7 +258,7 @@ func TestAddProjectSource(t *testing.T) { _, err = fixture.RunCli("proj", "add-source", projectName, "https://github.com/argoproj/argo-cd.git") require.NoError(t, err) - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + 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.SourceRepos, 1) @@ -270,7 +270,7 @@ func TestRemoveProjectSource(t *testing.T) { fixture.EnsureCleanState(t) projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) - _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create(t.Context(), &v1alpha1.AppProject{ + _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create(context.Background(), &v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: projectName}, Spec: v1alpha1.AppProjectSpec{ SourceRepos: []string{"https://github.com/argoproj/argo-cd.git"}, @@ -286,7 +286,7 @@ func TestRemoveProjectSource(t *testing.T) { _, err = fixture.RunCli("proj", "remove-source", projectName, "https://github.com/argoproj/argo-cd.git") require.NoError(t, err) - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + 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.Empty(t, proj.Spec.SourceRepos) @@ -316,7 +316,7 @@ func TestUseJWTToken(t *testing.T) { Project: projectName, }, } - _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create(t.Context(), &v1alpha1.AppProject{ + _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create(context.Background(), &v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: projectName}, Spec: v1alpha1.AppProjectSpec{ Destinations: []v1alpha1.ApplicationDestination{{ @@ -328,7 +328,7 @@ func TestUseJWTToken(t *testing.T) { }, metav1.CreateOptions{}) require.NoError(t, err) - _, err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.TestNamespace()).Create(t.Context(), testApp, metav1.CreateOptions{}) + _, err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.TestNamespace()).Create(context.Background(), testApp, metav1.CreateOptions{}) require.NoError(t, err) _, err = fixture.RunCli("proj", "role", "create", projectName, roleName) @@ -355,7 +355,7 @@ func TestUseJWTToken(t *testing.T) { require.NoError(t, err) } - newProj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + newProj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) require.NoError(t, err) assert.Len(t, newProj.Status.JWTTokensByRole[roleName].Items, 1) assert.ElementsMatch(t, newProj.Status.JWTTokensByRole[roleName].Items, newProj.Spec.Roles[0].JWTTokens) @@ -366,7 +366,7 @@ func TestUseJWTToken(t *testing.T) { _, err = fixture.RunCli("proj", "role", "delete-token", projectName, roleName, strconv.FormatInt(newProj.Status.JWTTokensByRole[roleName].Items[0].IssuedAt, 10)) require.NoError(t, err) - newProj, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + newProj, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) require.NoError(t, err) assert.Nil(t, newProj.Status.JWTTokensByRole[roleName].Items) assert.Nil(t, newProj.Spec.Roles[0].JWTTokens) @@ -377,7 +377,7 @@ func TestAddOrphanedIgnore(t *testing.T) { projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( - t.Context(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) + context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) require.NoError(t, err, "Unable to create project") _, err = fixture.RunCli("proj", "add-orphaned-ignore", projectName, @@ -396,7 +396,7 @@ func TestAddOrphanedIgnore(t *testing.T) { ) require.ErrorContains(t, err, "already defined") - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + 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.OrphanedResources.Ignore, 1) @@ -411,7 +411,7 @@ func TestRemoveOrphanedIgnore(t *testing.T) { fixture.EnsureCleanState(t) projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) - _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create(t.Context(), &v1alpha1.AppProject{ + _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create(context.Background(), &v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: projectName}, Spec: v1alpha1.AppProjectSpec{ OrphanedResources: &v1alpha1.OrphanedResourcesMonitorSettings{ @@ -438,7 +438,7 @@ func TestRemoveOrphanedIgnore(t *testing.T) { ) require.ErrorContains(t, err, "does not exist") - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) require.NoError(t, err, "Unable to get project") assert.Equal(t, projectName, proj.Name) assert.Empty(t, proj.Spec.OrphanedResources.Ignore) @@ -520,12 +520,12 @@ func TestGetVirtualProjectNoMatch(t *testing.T) { projectName := "proj-" + fixture.Name() _, err = fixture.RunCli("proj", "create", projectName, "--description", "Test description", - "-d", v1alpha1.KubernetesInternalAPIServerAddr+",*", + "-d", fmt.Sprintf("%s,*", v1alpha1.KubernetesInternalAPIServerAddr), "-s", "*", "--orphaned-resources") require.NoError(t, err) - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) require.NoError(t, err) // Create an app belongs to proj project @@ -551,17 +551,17 @@ func TestGetVirtualProjectMatch(t *testing.T) { projectName := "proj-" + fixture.Name() _, err = fixture.RunCli("proj", "create", projectName, "--description", "Test description", - "-d", v1alpha1.KubernetesInternalAPIServerAddr+",*", + "-d", fmt.Sprintf("%s,*", v1alpha1.KubernetesInternalAPIServerAddr), "-s", "*", "--orphaned-resources") require.NoError(t, err) - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) require.NoError(t, err) // Add a label to this project so that this project match global project selector proj.Labels = map[string]string{"opt": "me"} - _, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Update(t.Context(), proj, metav1.UpdateOptions{}) + _, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Update(context.Background(), proj, metav1.UpdateOptions{}) require.NoError(t, err) // Create an app belongs to proj project @@ -583,7 +583,7 @@ func TestAddProjectDestinationServiceAccount(t *testing.T) { projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( - t.Context(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) + context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) require.NoError(t, err, "Unable to create project") // Given, an existing project @@ -758,7 +758,7 @@ func TestAddProjectDestinationServiceAccount(t *testing.T) { ) require.ErrorContains(t, err, "namespace has an invalid format, '[[ech*'") - proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(t.Context(), projectName, metav1.GetOptions{}) + 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) @@ -768,7 +768,7 @@ func TestAddProjectDestinationServiceAccount(t *testing.T) { 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.Empty(t, proj.Spec.DestinationServiceAccounts[1].Namespace) + 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) diff --git a/test/e2e/pruning_required_test.go b/test/e2e/pruning_required_test.go index 22dbdf9e2e..cb10233a00 100644 --- a/test/e2e/pruning_required_test.go +++ b/test/e2e/pruning_required_test.go @@ -5,7 +5,7 @@ import ( . "github.com/argoproj/gitops-engine/pkg/sync/common" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" ) // check we fail with message if we delete a non-prunable resource diff --git a/test/e2e/repo_creds_test.go b/test/e2e/repo_creds_test.go index c5e3aa212d..59df113605 100644 --- a/test/e2e/repo_creds_test.go +++ b/test/e2e/repo_creds_test.go @@ -1,11 +1,12 @@ package e2e import ( + "fmt" "testing" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/util/errors" + "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" ) // make sure you cannot create an app from a private repo without set-up @@ -32,14 +33,37 @@ func TestCannotAddAppFromClientCertRepoWithoutCfg(t *testing.T) { Expect(Error("", "repository not accessible")) } -// make sure you can create an app from a private repo, if the repo is set-up +// make sure you can create an app from a private repo, if the repo is set-up in the CM func TestCanAddAppFromPrivateRepoWithRepoCfg(t *testing.T) { Given(t). RepoURLType(fixture.RepoURLTypeHTTPS). Path(fixture.LocalOrRemotePath("https-kustomize-base")). And(func() { // I use CLI, but you could also modify the settings, we get a free test of the CLI here - errors.NewHandler(t).FailOnErr(fixture.RunCli("repo", "add", fixture.RepoURL(fixture.RepoURLTypeHTTPS), "--username", fixture.GitUsername, "--password", fixture.GitPassword, "--insecure-skip-server-verification")) + FailOnErr(fixture.RunCli("repo", "add", fixture.RepoURL(fixture.RepoURLTypeHTTPS), "--username", fixture.GitUsername, "--password", fixture.GitPassword, "--insecure-skip-server-verification")) + }). + When(). + CreateApp(). + Then(). + Expect(Success("")) +} + +// make sure you can create an app from a private repo, if the creds are set-up in the CM +func TestCanAddAppFromInsecurePrivateRepoWithCredCfg(t *testing.T) { + Given(t). + CustomCACertAdded(). + RepoURLType(fixture.RepoURLTypeHTTPS). + Path(fixture.LocalOrRemotePath("https-kustomize-base")). + And(func() { + secretName := fixture.CreateSecret(fixture.GitUsername, fixture.GitPassword) + FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", + "-n", fixture.TestNamespace(), + "-p", fmt.Sprintf( + `{"data": {"repository.credentials": "- passwordSecret:\n key: password\n name: %s\n url: %s\n insecure: true\n usernameSecret:\n key: username\n name: %s\n"}}`, + secretName, + fixture.RepoURL(fixture.RepoURLTypeHTTPS), + secretName, + ))) }). When(). CreateApp(). @@ -56,6 +80,42 @@ func TestCanAddAppFromPrivateRepoWithCredCfg(t *testing.T) { HTTPSRepoURLAdded(false). RepoURLType(fixture.RepoURLTypeHTTPS). Path(fixture.LocalOrRemotePath("https-kustomize-base")). + And(func() { + secretName := fixture.CreateSecret(fixture.GitUsername, fixture.GitPassword) + FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", + "-n", fixture.TestNamespace(), + "-p", fmt.Sprintf( + `{"data": {"repository.credentials": "- passwordSecret:\n key: password\n name: %s\n url: %s\n usernameSecret:\n key: username\n name: %s\n"}}`, + secretName, + fixture.RepoURL(fixture.RepoURLTypeHTTPS), + secretName, + ))) + }). + When(). + CreateApp(). + Then(). + Expect(Success("")) +} + +// make sure we can create an app from a private repo, in a secure manner using +// a custom CA certificate bundle +func TestCanAddAppFromClientCertRepoWithCredCfg(t *testing.T) { + Given(t). + CustomCACertAdded(). + HTTPSRepoURLWithClientCertAdded(). + RepoURLType(fixture.RepoURLTypeHTTPSClientCert). + Path(fixture.LocalOrRemotePath("https-kustomize-base")). + And(func() { + secretName := fixture.CreateSecret(fixture.GitUsername, fixture.GitPassword) + FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", + "-n", fixture.TestNamespace(), + "-p", fmt.Sprintf( + `{"data": {"repository.credentials": "- passwordSecret:\n key: password\n name: %s\n url: %s\n usernameSecret:\n key: username\n name: %s\n"}}`, + secretName, + fixture.RepoURL(fixture.RepoURLTypeHTTPS), + secretName, + ))) + }). When(). CreateApp(). Then(). diff --git a/test/e2e/repo_management_test.go b/test/e2e/repo_management_test.go index 5d5b25b39d..97627d84f3 100644 --- a/test/e2e/repo_management_test.go +++ b/test/e2e/repo_management_test.go @@ -1,50 +1,52 @@ package e2e import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - repositorypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repository" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/repos" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" + repositorypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos" + . "github.com/argoproj/argo-cd/v2/util/errors" + argoio "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/settings" ) func TestAddRemovePublicRepo(t *testing.T) { app.Given(t).And(func() { - repoURL := fixture.RepoURL(fixture.RepoURLTypeFile) - _, err := fixture.RunCli("repo", "add", repoURL) + repoUrl := fixture.RepoURL(fixture.RepoURLTypeFile) + _, err := fixture.RunCli("repo", "add", repoUrl) require.NoError(t, err) conn, repoClient, err := fixture.ArgoCDClientset.NewRepoClient() require.NoError(t, err) - defer utilio.Close(conn) + defer argoio.Close(conn) - repo, err := repoClient.ListRepositories(t.Context(), &repositorypkg.RepoQuery{}) + repo, err := repoClient.ListRepositories(context.Background(), &repositorypkg.RepoQuery{}) require.NoError(t, err) exists := false for i := range repo.Items { - if repo.Items[i].Repo == repoURL { + if repo.Items[i].Repo == repoUrl { exists = true break } } assert.True(t, exists) - _, err = fixture.RunCli("repo", "rm", repoURL) + _, err = fixture.RunCli("repo", "rm", repoUrl) require.NoError(t, err) - repo, err = repoClient.ListRepositories(t.Context(), &repositorypkg.RepoQuery{}) + repo, err = repoClient.ListRepositories(context.Background(), &repositorypkg.RepoQuery{}) require.NoError(t, err) exists = false for i := range repo.Items { - if repo.Items[i].Repo == repoURL { + if repo.Items[i].Repo == repoUrl { exists = true break } @@ -56,45 +58,46 @@ func TestAddRemovePublicRepo(t *testing.T) { func TestGetRepoWithInheritedCreds(t *testing.T) { app.Given(t).And(func() { // create repo credentials - errors.NewHandler(t).FailOnErr(fixture.RunCli("repocreds", "add", fixture.RepoURL(fixture.RepoURLTypeHTTPSOrg), "--github-app-id", fixture.GithubAppID, "--github-app-installation-id", fixture.GithubAppInstallationID, "--github-app-private-key-path", repos.CertKeyPath(t))) + FailOnErr(fixture.RunCli("repocreds", "add", fixture.RepoURL(fixture.RepoURLTypeHTTPSOrg), "--github-app-id", fixture.GithubAppID, "--github-app-installation-id", fixture.GithubAppInstallationID, "--github-app-private-key-path", repos.CertKeyPath)) - repoURL := fixture.RepoURL(fixture.RepoURLTypeHTTPS) + repoUrl := fixture.RepoURL(fixture.RepoURLTypeHTTPS) // Hack: First we need to create repo with valid credentials - errors.NewHandler(t).FailOnErr(fixture.RunCli("repo", "add", repoURL, "--username", fixture.GitUsername, "--password", fixture.GitPassword, "--insecure-skip-server-verification")) + FailOnErr(fixture.RunCli("repo", "add", repoUrl, "--username", fixture.GitUsername, "--password", fixture.GitPassword, "--insecure-skip-server-verification")) // Then, we remove username/password so that the repo inherits the credentials from our repocreds conn, repoClient, err := fixture.ArgoCDClientset.NewRepoClient() require.NoError(t, err) - defer utilio.Close(conn) + defer argoio.Close(conn) - _, err = repoClient.UpdateRepository(t.Context(), &repositorypkg.RepoUpdateRequest{ + _, err = repoClient.UpdateRepository(context.Background(), &repositorypkg.RepoUpdateRequest{ Repo: &v1alpha1.Repository{ - Repo: repoURL, + Repo: repoUrl, }, }) require.NoError(t, err) // CLI output should indicate that repo has inherited credentials - out, err := fixture.RunCli("repo", "get", repoURL) + out, err := fixture.RunCli("repo", "get", repoUrl) require.NoError(t, err) assert.Contains(t, out, "inherited") - _, err = fixture.RunCli("repo", "rm", repoURL) + _, err = fixture.RunCli("repo", "rm", repoUrl) require.NoError(t, err) }) } func TestUpsertExistingRepo(t *testing.T) { app.Given(t).And(func() { - repoURL := fixture.RepoURL(fixture.RepoURLTypeFile) - _, err := fixture.RunCli("repo", "add", repoURL) + CheckError(fixture.SetRepos(settings.RepositoryCredentials{URL: fixture.RepoURL(fixture.RepoURLTypeFile)})) + repoUrl := fixture.RepoURL(fixture.RepoURLTypeFile) + _, err := fixture.RunCli("repo", "add", repoUrl) require.NoError(t, err) - _, err = fixture.RunCli("repo", "add", repoURL, "--username", fixture.GitUsername, "--password", fixture.GitPassword) + _, err = fixture.RunCli("repo", "add", repoUrl, "--username", fixture.GitUsername, "--password", fixture.GitPassword) require.Error(t, err) - _, err = fixture.RunCli("repo", "add", repoURL, "--upsert", "--username", fixture.GitUsername, "--password", fixture.GitPassword) + _, err = fixture.RunCli("repo", "add", repoUrl, "--upsert", "--username", fixture.GitUsername, "--password", fixture.GitPassword) require.NoError(t, err) }) } @@ -106,15 +109,15 @@ func TestAddRemoveHelmRepo(t *testing.T) { "--type", "helm", "--username", fixture.GitUsername, "--password", fixture.GitPassword, - "--tls-client-cert-path", repos.CertPath(t), - "--tls-client-cert-key-path", repos.CertKeyPath(t)) + "--tls-client-cert-path", repos.CertPath, + "--tls-client-cert-key-path", repos.CertKeyPath) require.NoError(t, err) conn, repoClient, err := fixture.ArgoCDClientset.NewRepoClient() require.NoError(t, err) - defer utilio.Close(conn) + defer argoio.Close(conn) - repo, err := repoClient.ListRepositories(t.Context(), &repositorypkg.RepoQuery{}) + repo, err := repoClient.ListRepositories(context.Background(), &repositorypkg.RepoQuery{}) require.NoError(t, err) exists := false @@ -129,7 +132,7 @@ func TestAddRemoveHelmRepo(t *testing.T) { _, err = fixture.RunCli("repo", "rm", fixture.RepoURL(fixture.RepoURLTypeHelm)) require.NoError(t, err) - repo, err = repoClient.ListRepositories(t.Context(), &repositorypkg.RepoQuery{}) + repo, err = repoClient.ListRepositories(context.Background(), &repositorypkg.RepoQuery{}) require.NoError(t, err) exists = false for i := range repo.Items { @@ -150,17 +153,17 @@ func TestAddHelmRepoInsecureSkipVerify(t *testing.T) { "--username", fixture.GitUsername, "--password", fixture.GitPassword, "--insecure-skip-server-verification", - "--tls-client-cert-path", repos.CertPath(t), - "--tls-client-cert-key-path", repos.CertKeyPath(t)) + "--tls-client-cert-path", repos.CertPath, + "--tls-client-cert-key-path", repos.CertKeyPath) require.NoError(t, err) conn, repoClient, err := fixture.ArgoCDClientset.NewRepoClient() require.NoError(t, err) - defer utilio.Close(conn) + defer argoio.Close(conn) - repo, err := repoClient.ListRepositories(t.Context(), &repositorypkg.RepoQuery{}) + repo, err := repoClient.ListRepositories(context.Background(), &repositorypkg.RepoQuery{}) require.NoError(t, err) @@ -174,32 +177,3 @@ func TestAddHelmRepoInsecureSkipVerify(t *testing.T) { assert.True(t, exists) }) } - -func TestFailOnPrivateRepoCreationWithPasswordAndBearerToken(t *testing.T) { - app.Given(t).And(func() { - repoURL := fixture.RepoURL(fixture.RepoURLTypeFile) - _, err := fixture.RunCli("repo", "add", repoURL, "--password", fixture.GitPassword, "--bearer-token", fixture.GitBearerToken) - require.ErrorContains(t, err, "only --bearer-token or --password is allowed, not both") - }) -} - -func TestFailOnCreatePrivateNonHTTPSRepoWithBearerToken(t *testing.T) { - app.Given(t).And(func() { - repoURL := fixture.RepoURL(fixture.RepoURLTypeFile) - _, err := fixture.RunCli("repo", "add", repoURL, "--bearer-token", fixture.GitBearerToken) - require.ErrorContains(t, err, "--bearer-token is only supported for HTTPS repositories") - }) -} - -func TestFailOnCreatePrivateNonGitRepoWithBearerToken(t *testing.T) { - app.Given(t).And(func() { - repoURL := fixture.RepoURL(fixture.RepoURLTypeHelm) - _, err := fixture.RunCli("repo", "add", repoURL, "--bearer-token", fixture.GitBearerToken, - "--insecure-skip-server-verification", - "--tls-client-cert-path", repos.CertPath(t), - "--tls-client-cert-key-path", repos.CertKeyPath(t), - "--name", "testrepo", - "--type", "helm") - require.ErrorContains(t, err, "--bearer-token is only supported for Git repositories") - }) -} diff --git a/test/e2e/scoped_repository_test.go b/test/e2e/scoped_repository_test.go index b8fbf02b48..3d4fd71dc9 100644 --- a/test/e2e/scoped_repository_test.go +++ b/test/e2e/scoped_repository_test.go @@ -3,16 +3,16 @@ package e2e import ( "testing" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/project" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/project" "github.com/stretchr/testify/assert" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - accountFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/account" - projectFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/project" - repoFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/repos" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + accountFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/account" + projectFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/project" + repoFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos" ) func TestCreateRepositoryWithProject(t *testing.T) { @@ -29,11 +29,11 @@ func TestCreateRepositoryWithProject(t *testing.T) { Project("argo-project"). Create(). Then(). - And(func(r *Repository, _ error) { + And(func(r *Repository, err error) { assert.Equal(t, r.Repo, path) assert.Equal(t, "argo-project", r.Project) - prjConsequence.And(func(projectResponse *project.DetailedProjectsResponse, _ error) { + prjConsequence.And(func(projectResponse *project.DetailedProjectsResponse, err error) { assert.Len(t, projectResponse.Repositories, 1) assert.Equal(t, projectResponse.Repositories[0].Repo, path) }) @@ -55,7 +55,7 @@ func TestCreateRepositoryNonAdminUserPermissionDenied(t *testing.T) { IgnoreErrors(). Create(). Then(). - AndCLIOutput(func(_ string, err error) { + AndCLIOutput(func(output string, err error) { assert.ErrorContains(t, err, "PermissionDenied desc = permission denied: repositories, create") }) } @@ -82,7 +82,7 @@ func TestCreateRepositoryNonAdminUserWithWrongProject(t *testing.T) { IgnoreErrors(). Create(). Then(). - AndCLIOutput(func(_ string, err error) { + AndCLIOutput(func(output string, err error) { assert.ErrorContains(t, err, "PermissionDenied desc = permission denied: repositories, create") }) } @@ -118,14 +118,14 @@ func TestDeleteRepositoryRbacAllowed(t *testing.T) { Project("argo-project"). Create(). Then(). - And(func(r *Repository, _ error) { + And(func(r *Repository, err error) { assert.Equal(t, r.Repo, path) assert.Equal(t, "argo-project", r.Project) }). When(). Delete(). Then(). - AndCLIOutput(func(output string, _ error) { + AndCLIOutput(func(output string, err error) { assert.Contains(t, output, "Repository 'https://github.com/argoproj/argo-cd.git' removed") }) } @@ -161,7 +161,7 @@ func TestDeleteRepositoryRbacDenied(t *testing.T) { Project("argo-project"). Create(). Then(). - And(func(r *Repository, _ error) { + And(func(r *Repository, err error) { assert.Equal(t, r.Repo, path) assert.Equal(t, "argo-project", r.Project) }). @@ -169,7 +169,7 @@ func TestDeleteRepositoryRbacDenied(t *testing.T) { IgnoreErrors(). Delete(). Then(). - AndCLIOutput(func(_ string, err error) { + AndCLIOutput(func(output string, err error) { assert.ErrorContains(t, err, "PermissionDenied desc = permission denied: repositories, delete") }) } @@ -182,14 +182,14 @@ func TestDeleteRepository(t *testing.T) { Project("argo-project"). Create(). Then(). - And(func(r *Repository, _ error) { + And(func(r *Repository, err error) { assert.Equal(t, r.Repo, path) }). When(). Delete(). Then(). - And(func(_ *Repository, err error) { - assert.EqualError(t, err, "repo not found") + And(func(r *Repository, err error) { + assert.Equal(t, "repo not found", err.Error()) }) } @@ -201,13 +201,13 @@ func TestListRepoCLIOutput(t *testing.T) { Project("argo-project"). Create(). Then(). - AndCLIOutput(func(output string, _ error) { + AndCLIOutput(func(output string, err error) { assert.Equal(t, `Repository 'https://github.com/argoproj/argo-cd.git' added`, output) }). When(). List(). Then(). - AndCLIOutput(func(output string, _ error) { + AndCLIOutput(func(output string, err error) { assert.Equal(t, `TYPE NAME REPO INSECURE OCI LFS CREDS STATUS MESSAGE PROJECT git https://github.com/argoproj/argo-cd.git false false false false Successful argo-project`, output) }) @@ -221,13 +221,13 @@ func TestGetRepoCLIOutput(t *testing.T) { Project("argo-project"). Create(). Then(). - AndCLIOutput(func(output string, _ error) { + AndCLIOutput(func(output string, err error) { assert.Equal(t, `Repository 'https://github.com/argoproj/argo-cd.git' added`, output) }). When(). Get(). Then(). - AndCLIOutput(func(output string, _ error) { + AndCLIOutput(func(output string, err error) { assert.Equal(t, `TYPE NAME REPO INSECURE OCI LFS CREDS STATUS MESSAGE PROJECT git https://github.com/argoproj/argo-cd.git false false false false Successful argo-project`, output) }) diff --git a/test/e2e/selective_sync_test.go b/test/e2e/selective_sync_test.go index 4107c742af..2f7704aa6b 100644 --- a/test/e2e/selective_sync_test.go +++ b/test/e2e/selective_sync_test.go @@ -9,11 +9,12 @@ import ( . "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/util/errors" - "github.com/argoproj/argo-cd/v3/util/rand" + . "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" + "github.com/argoproj/argo-cd/v2/util/rand" ) // when you selectively sync, only selected resources should be synced, but the app will be out of sync @@ -54,14 +55,14 @@ func TestSelectiveSyncWithoutNamespace(t *testing.T) { selectedResourceNamespace := getNewNamespace(t) defer func() { if !t.Skipped() { - errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "delete", "namespace", selectedResourceNamespace)) + FailOnErr(Run("", "kubectl", "delete", "namespace", selectedResourceNamespace)) } }() Given(t). Prune(true). Path("guestbook-with-namespace"). And(func() { - errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "create", "namespace", selectedResourceNamespace)) + FailOnErr(Run("", "kubectl", "create", "namespace", selectedResourceNamespace)) }). SelectedResource("apps:Deployment:guestbook-ui"). When(). @@ -84,14 +85,14 @@ func TestSelectiveSyncWithNamespace(t *testing.T) { selectedResourceNamespace := getNewNamespace(t) defer func() { if !t.Skipped() { - errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "delete", "namespace", selectedResourceNamespace)) + FailOnErr(Run("", "kubectl", "delete", "namespace", selectedResourceNamespace)) } }() Given(t). Prune(true). Path("guestbook-with-namespace"). And(func() { - errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "create", "namespace", selectedResourceNamespace)) + FailOnErr(Run("", "kubectl", "create", "namespace", selectedResourceNamespace)) }). SelectedResource(fmt.Sprintf("apps:Deployment:%s/guestbook-ui", selectedResourceNamespace)). When(). @@ -115,5 +116,5 @@ func getNewNamespace(t *testing.T) string { require.NoError(t, err) postFix := "-" + strings.ToLower(randStr) name := fixture.DnsFriendly(t.Name(), "") - return fixture.DnsFriendly("argocd-e2e-"+name, postFix) + return fixture.DnsFriendly(fmt.Sprintf("argocd-e2e-%s", name), postFix) } diff --git a/test/e2e/ssh_repo_test.go b/test/e2e/ssh_repo_test.go index a0c5c5519c..7aae394612 100644 --- a/test/e2e/ssh_repo_test.go +++ b/test/e2e/ssh_repo_test.go @@ -5,8 +5,8 @@ import ( . "github.com/argoproj/gitops-engine/pkg/sync/common" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" ) func TestCanAccessInsecureSSHRepo(t *testing.T) { diff --git a/test/e2e/sync_options_test.go b/test/e2e/sync_options_test.go index 9567a7552a..fae78ed616 100644 --- a/test/e2e/sync_options_test.go +++ b/test/e2e/sync_options_test.go @@ -1,18 +1,18 @@ package e2e import ( + "context" "os" "testing" . "github.com/argoproj/gitops-engine/pkg/sync/common" - "github.com/stretchr/testify/require" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" - "github.com/argoproj/argo-cd/v3/util/errors" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/util/errors" ) // TestSyncOptionsValidateFalse verifies we can disable validation during kubectl apply, using the @@ -53,7 +53,7 @@ func TestSyncWithStatusIgnored(t *testing.T) { Path(guestbookPath). When(). And(func() { - require.NoError(t, fixture.SetResourceOverrides(map[string]ResourceOverride{ + errors.CheckError(fixture.SetResourceOverrides(map[string]ResourceOverride{ "/": { IgnoreDifferences: OverrideIgnoreDiff{JSONPointers: []string{"/status"}}, }, @@ -73,8 +73,8 @@ func TestSyncWithStatusIgnored(t *testing.T) { // app should remain synced if k8s change detected When(). And(func() { - errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(), - "guestbook-ui", types.JSONPatchType, []byte(`[{ "op": "replace", "path": "/status/observedGeneration", "value": 2 }]`), metav1.PatchOptions{})) + errors.FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(context.Background(), + "guestbook-ui", types.JSONPatchType, []byte(`[{ "op": "replace", "path": "/status/observedGeneration", "value": 2 }]`), v1.PatchOptions{})) }). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)) diff --git a/test/e2e/sync_waves_test.go b/test/e2e/sync_waves_test.go index 9c407be648..8beda162e5 100644 --- a/test/e2e/sync_waves_test.go +++ b/test/e2e/sync_waves_test.go @@ -2,27 +2,26 @@ package e2e import ( "testing" - "time" + + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/util/errors" "github.com/argoproj/gitops-engine/pkg/health" . "github.com/argoproj/gitops-engine/pkg/sync/common" - "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + v1 "k8s.io/api/core/v1" ) func TestFixingDegradedApp(t *testing.T) { - var lastTransitionTime string Given(t). Path("sync-waves"). When(). IgnoreErrors(). CreateApp(). And(func() { - require.NoError(t, SetResourceOverrides(map[string]ResourceOverride{ + errors.CheckError(SetResourceOverrides(map[string]ResourceOverride{ "ConfigMap": { HealthLua: `return { status = obj.metadata.annotations and obj.metadata.annotations['health'] or 'Degraded' }`, }, @@ -39,11 +38,6 @@ func TestFixingDegradedApp(t *testing.T) { Expect(ResourceSyncStatusIs("ConfigMap", "cm-2", SyncStatusCodeOutOfSync)). Expect(ResourceHealthIs("ConfigMap", "cm-2", health.HealthStatusMissing)). When(). - Then(). - And(func(app *Application) { - lastTransitionTime = app.Status.Health.LastTransitionTime.UTC().Format(time.RFC3339) - }). - When(). PatchFile("cm-1.yaml", `[{"op": "replace", "path": "/metadata/annotations/health", "value": "Healthy"}]`). PatchFile("cm-2.yaml", `[{"op": "replace", "path": "/metadata/annotations/health", "value": "Healthy"}]`). // need to force a refresh here @@ -60,13 +54,7 @@ func TestFixingDegradedApp(t *testing.T) { Expect(ResourceSyncStatusIs("ConfigMap", "cm-1", SyncStatusCodeSynced)). Expect(ResourceHealthIs("ConfigMap", "cm-1", health.HealthStatusHealthy)). Expect(ResourceSyncStatusIs("ConfigMap", "cm-2", SyncStatusCodeSynced)). - Expect(ResourceHealthIs("ConfigMap", "cm-2", health.HealthStatusHealthy)). - When(). - Then(). - And(func(app *Application) { - // check that the last transition time is updated - require.NotEqual(t, lastTransitionTime, app.Status.Health.LastTransitionTime.UTC().Format(time.RFC3339)) - }) + Expect(ResourceHealthIs("ConfigMap", "cm-2", health.HealthStatusHealthy)) } func TestOneProgressingDeploymentIsSucceededAndSynced(t *testing.T) { @@ -155,6 +143,6 @@ func TestSyncPruneOrderWithSyncWaves(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - Expect(NotPod(func(p corev1.Pod) bool { return p.Name == "pod-with-finalizers" })). + Expect(NotPod(func(p v1.Pod) bool { return p.Name == "pod-with-finalizers" })). Expect(ResourceResultNumbering(4)) } diff --git a/test/e2e/sync_with_impersonate_test.go b/test/e2e/sync_with_impersonate_test.go index d2e6ef9348..4c7cf166f4 100644 --- a/test/e2e/sync_with_impersonate_test.go +++ b/test/e2e/sync_with_impersonate_test.go @@ -1,20 +1,20 @@ package e2e import ( + "context" "fmt" "testing" "time" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture/project" - "github.com/stretchr/testify/require" - rbacv1 "k8s.io/api/rbac/v1" + v1 "k8s.io/api/core/v1" + rbac "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test/e2e/fixture" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" + "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" ) const ( @@ -26,7 +26,7 @@ func TestSyncWithFeatureDisabled(t *testing.T) { Given(t). Path("guestbook"). When(). - WithImpersonationDisabled(). + SetParamInSettingConfigMap("application.sync.impersonation.enabled", "false"). CreateFromFile(func(app *v1alpha1.Application) { app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}} }). @@ -41,10 +41,10 @@ func TestSyncWithNoDestinationServiceAccountsInProject(t *testing.T) { Given(t). Path("guestbook"). When(). + SetParamInSettingConfigMap("application.sync.impersonation.enabled", "true"). CreateFromFile(func(app *v1alpha1.Application) { app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}} }). - WithImpersonationEnabled("", nil). Then(). // With the impersonation feature enabled, Application sync must fail // when there are no destination service accounts configured in AppProject @@ -55,40 +55,45 @@ func TestSyncWithNoDestinationServiceAccountsInProject(t *testing.T) { func TestSyncWithImpersonateWithSyncServiceAccount(t *testing.T) { projectName := "sync-test-project" serviceAccountName := "test-account" - - projectCtx := project.Given(t) - appCtx := Given(t) - - projectCtx. - Name(projectName). - SourceNamespaces([]string{"*"}). - SourceRepositories([]string{"*"}). - Destination("*,*"). - DestinationServiceAccounts( - []string{ - fmt.Sprintf("%s,%s,%s", "*", fixture.DeploymentNamespace(), serviceAccountName), - fmt.Sprintf("%s,%s,%s", v1alpha1.KubernetesInternalAPIServerAddr, fixture.DeploymentNamespace(), "missing-serviceAccount"), - }). - When(). - Create(). - Then(). - Expect() - - appCtx. + roleName := "test-account-sa-role" + Given(t). SetTrackingMethod("annotation"). Path("guestbook"). When(). - WithImpersonationEnabled(serviceAccountName, []rbacv1.PolicyRule{ - { - APIGroups: []string{"apps", ""}, - Resources: []string{"deployments"}, - Verbs: []string{"*"}, - }, - { - APIGroups: []string{""}, - Resources: []string{"services"}, - Verbs: []string{"*"}, - }, + SetParamInSettingConfigMap("application.sync.impersonation.enabled", "true"). + And(func() { + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "*", + Namespace: fixture.DeploymentNamespace(), + DefaultServiceAccount: serviceAccountName, + }, + { + Server: "*", + Namespace: fixture.DeploymentNamespace(), + DefaultServiceAccount: "missing-serviceAccount", + }, + } + err := createTestServiceAccount(serviceAccountName, fixture.DeploymentNamespace()) + require.NoError(t, err) + err = createTestAppProject(projectName, fixture.TestNamespace(), destinationServiceAccounts) + require.NoError(t, err) + 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, serviceAccountName, fixture.DeploymentNamespace()) + require.NoError(t, err) }). CreateFromFile(func(app *v1alpha1.Application) { app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}} @@ -104,40 +109,45 @@ func TestSyncWithImpersonateWithSyncServiceAccount(t *testing.T) { func TestSyncWithMissingServiceAccount(t *testing.T) { projectName := "false-test-project" serviceAccountName := "test-account" - - projectCtx := project.Given(t) - appCtx := Given(t) - - projectCtx. - Name(projectName). - SourceNamespaces([]string{"*"}). - SourceRepositories([]string{"*"}). - Destination("*,*"). - DestinationServiceAccounts( - []string{ - fmt.Sprintf("%s,%s,%s", v1alpha1.KubernetesInternalAPIServerAddr, fixture.DeploymentNamespace(), "missing-serviceAccount"), - fmt.Sprintf("%s,%s,%s", "*", fixture.DeploymentNamespace(), serviceAccountName), - }). - When(). - Create(). - Then(). - Expect() - - appCtx. + roleName := "test-account-sa-role" + Given(t). SetTrackingMethod("annotation"). Path("guestbook"). When(). - WithImpersonationEnabled(serviceAccountName, []rbacv1.PolicyRule{ - { - APIGroups: []string{"apps", ""}, - Resources: []string{"deployments"}, - Verbs: []string{"*"}, - }, - { - APIGroups: []string{""}, - Resources: []string{"services"}, - Verbs: []string{"*"}, - }, + SetParamInSettingConfigMap("application.sync.impersonation.enabled", "true"). + And(func() { + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "*", + Namespace: fixture.DeploymentNamespace(), + DefaultServiceAccount: "missing-serviceAccount", + }, + { + Server: "*", + Namespace: fixture.DeploymentNamespace(), + DefaultServiceAccount: serviceAccountName, + }, + } + err := createTestServiceAccount(serviceAccountName, fixture.DeploymentNamespace()) + require.NoError(t, err) + err = createTestAppProject(projectName, fixture.TestNamespace(), destinationServiceAccounts) + require.NoError(t, err) + 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, serviceAccountName, fixture.DeploymentNamespace()) + require.NoError(t, err) }). CreateFromFile(func(app *v1alpha1.Application) { app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}} @@ -154,39 +164,39 @@ func TestSyncWithMissingServiceAccount(t *testing.T) { func TestSyncWithValidSAButDisallowedDestination(t *testing.T) { projectName := "negation-test-project" serviceAccountName := "test-account" - - projectCtx := project.Given(t) - appCtx := Given(t) - - projectCtx. - Name(projectName). - SourceNamespaces([]string{"*"}). - SourceRepositories([]string{"*"}). - Destination("*,*"). - DestinationServiceAccounts( - []string{ - fmt.Sprintf("%s,%s,%s", "*", fixture.DeploymentNamespace(), serviceAccountName), - }). - When(). - Create(). - Then(). - Expect() - - appCtx. + roleName := "test-account-sa-role" + Given(t). SetTrackingMethod("annotation"). Path("guestbook"). When(). - WithImpersonationEnabled(serviceAccountName, []rbacv1.PolicyRule{ - { - APIGroups: []string{"apps", ""}, - Resources: []string{"deployments"}, - Verbs: []string{"*"}, - }, - { - APIGroups: []string{""}, - Resources: []string{"services"}, - Verbs: []string{"*"}, - }, + SetParamInSettingConfigMap("application.sync.impersonation.enabled", "true"). + And(func() { + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "*", + Namespace: fixture.DeploymentNamespace(), + DefaultServiceAccount: serviceAccountName, + }, + } + err := createTestServiceAccount(serviceAccountName, fixture.DeploymentNamespace()) + require.NoError(t, err) + err = createTestAppProject(projectName, fixture.TestNamespace(), destinationServiceAccounts) + require.NoError(t, err) + 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, serviceAccountName, fixture.DeploymentNamespace()) + require.NoError(t, err) }). CreateFromFile(func(app *v1alpha1.Application) { app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}} @@ -199,7 +209,7 @@ func TestSyncWithValidSAButDisallowedDestination(t *testing.T) { // 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(t.Context(), projectName, types.MergePatchType, patch, metav1.PatchOptions{}) + _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Patch(context.Background(), projectName, types.MergePatchType, patch, metav1.PatchOptions{}) require.NoError(t, err) }). Refresh(v1alpha1.RefreshTypeNormal). @@ -209,3 +219,84 @@ func TestSyncWithValidSAButDisallowedDestination(t *testing.T) { // but the destination namespace is now disallowed. ExpectConsistently(SyncStatusIs(v1alpha1.SyncStatusCodeUnknown), WaitDuration, TimeoutDuration) } + +// createTestAppProject creates a test AppProject resource. +func createTestAppProject(name, namespace string, destinationServiceAccounts []v1alpha1.ApplicationDestinationServiceAccount) error { + appProject := &v1alpha1.AppProject{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha1.AppProjectSpec{ + SourceRepos: []string{"*"}, + SourceNamespaces: []string{"*"}, + Destinations: []v1alpha1.ApplicationDestination{ + { + Server: "*", + Namespace: "*", + }, + }, + ClusterResourceWhitelist: []metav1.GroupKind{ + { + Group: "*", + Kind: "*", + }, + }, + DestinationServiceAccounts: destinationServiceAccounts, + }, + } + + _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(namespace).Create(context.Background(), appProject, metav1.CreateOptions{}) + return err +} + +// createTestRole creates a test Role resource. +func createTestRole(roleName, namespace string, rules []rbac.PolicyRule) error { + role := &rbac.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleName, + Namespace: namespace, + }, + Rules: rules, + } + + _, err := fixture.KubeClientset.RbacV1().Roles(namespace).Create(context.Background(), role, metav1.CreateOptions{}) + return err +} + +// createTestRoleBinding creates a test RoleBinding resource. +func createTestRoleBinding(roleName, serviceAccountName, namespace string) error { + roleBinding := &rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleName + "-binding", + }, + Subjects: []rbac.Subject{ + { + Kind: "ServiceAccount", + Name: serviceAccountName, + Namespace: namespace, + }, + }, + RoleRef: rbac.RoleRef{ + Kind: "Role", + Name: roleName, + APIGroup: "rbac.authorization.k8s.io", + }, + } + + _, err := fixture.KubeClientset.RbacV1().RoleBindings(namespace).Create(context.Background(), roleBinding, metav1.CreateOptions{}) + return err +} + +// createTestServiceAccount creates a test ServiceAccount resource. +func createTestServiceAccount(name, namespace string) error { + serviceAccount := &v1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + } + + _, err := fixture.KubeClientset.CoreV1().ServiceAccounts(namespace).Create(context.Background(), serviceAccount, metav1.CreateOptions{}) + return err +} diff --git a/test/e2e/testdata/cmp-fileName/plugin.yaml b/test/e2e/testdata/cmp-fileName/plugin.yaml index d2e7891671..b3f8068de2 100644 --- a/test/e2e/testdata/cmp-fileName/plugin.yaml +++ b/test/e2e/testdata/cmp-fileName/plugin.yaml @@ -5,7 +5,6 @@ metadata: spec: version: v1.0 generate: - # The -z test is to ensure that environment variables are made available to the plugin, even if they're empty. https://serverfault.com/a/382740/462962 - command: [sh, -c, 'if [ -z "${ARGOCD_ENV_EMPTY+set}" ]; then echo "ARGOCD_ENV_EMPTY should have been set." && exit 1; fi; echo "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"Foo\": \"$ARGOCD_ENV_FOO\", \"KubeVersion\": \"$KUBE_VERSION\", \"KubeApiVersion\": \"$KUBE_API_VERSIONS\",\"Bar\": \"baz\"}}}"'] + command: [sh, -c, 'echo "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"Foo\": \"$ARGOCD_ENV_FOO\", \"KubeVersion\": \"$KUBE_VERSION\", \"KubeApiVersion\": \"$KUBE_API_VERSIONS\",\"Bar\": \"baz\"}}}"'] discover: fileName: "subdir/s*.yaml" diff --git a/test/e2e/testdata/cmp-preserve-file-mode/script.sh b/test/e2e/testdata/cmp-preserve-file-mode/script.sh index fb555ee6e0..1fbb8fde0c 100755 --- a/test/e2e/testdata/cmp-preserve-file-mode/script.sh +++ b/test/e2e/testdata/cmp-preserve-file-mode/script.sh @@ -1,5 +1,3 @@ -#!/usr/bin/env bash - cat << EOF apiVersion: v1 kind: ConfigMap @@ -7,4 +5,4 @@ metadata: name: test-cm data: foo: bar -EOF +EOF \ No newline at end of file diff --git a/test/e2e/testdata/crd-creation/crd.yaml b/test/e2e/testdata/crd-creation/crd.yaml index 098af69b9f..2216607cbf 100644 --- a/test/e2e/testdata/crd-creation/crd.yaml +++ b/test/e2e/testdata/crd-creation/crd.yaml @@ -39,8 +39,6 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: clusterdummies.argoproj.io - labels: - e2e.argoproj.io: "true" spec: conversion: strategy: None diff --git a/test/e2e/testdata/duplicated-resources/duplicates-cluster.yaml b/test/e2e/testdata/duplicated-resources/duplicates-cluster.yaml index 33ba820c49..c8079cb9b3 100644 --- a/test/e2e/testdata/duplicated-resources/duplicates-cluster.yaml +++ b/test/e2e/testdata/duplicated-resources/duplicates-cluster.yaml @@ -5,9 +5,6 @@ metadata: name: clusterdummies.argoproj.io labels: e2e.argoproj.io: "true" - annotations: - # This needs to be synced first so that Argo CD knows these are cluster-scoped resources. - argocd.argoproj.io/sync-wave: "-1" spec: conversion: strategy: None diff --git a/test/e2e/testdata/hook-resource-deleted-externally/hook.yaml b/test/e2e/testdata/hook-resource-deleted-externally/hook.yaml deleted file mode 100644 index 1bb04369c9..0000000000 --- a/test/e2e/testdata/hook-resource-deleted-externally/hook.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: batch/v1 -kind: Job -metadata: - annotations: - argocd.argoproj.io/hook: Sync - name: hook -spec: - ttlSecondsAfterFinished: 0 - backoffLimit: 0 - template: - spec: - containers: - - command: - - "true" - image: quay.io/argoprojlabs/argocd-e2e-container:0.1 - imagePullPolicy: IfNotPresent - name: main - restartPolicy: Never \ No newline at end of file diff --git a/test/e2e/testdata/hook-resource-deleted-externally/pod.yaml b/test/e2e/testdata/hook-resource-deleted-externally/pod.yaml deleted file mode 100644 index 001aa52b04..0000000000 --- a/test/e2e/testdata/hook-resource-deleted-externally/pod.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: pod -spec: - containers: - - name: main - image: quay.io/argoprojlabs/argocd-e2e-container:0.1 - imagePullPolicy: IfNotPresent - command: - - "true" - restartPolicy: Never diff --git a/test/e2e/testdata/jsonnet-tla/guestbook-template.jsonnet b/test/e2e/testdata/jsonnet-tla/guestbook-template.jsonnet index 2c80481256..7ecdfb2b2b 100644 --- a/test/e2e/testdata/jsonnet-tla/guestbook-template.jsonnet +++ b/test/e2e/testdata/jsonnet-tla/guestbook-template.jsonnet @@ -1,6 +1,6 @@ function ( containerPort=80, - image="quay.io/argoprojlabs/argocd-e2e-container:0.2", + image="gcr.io/heptio-images/ks-guestbook-demo:0.2", name="jsonnet-guestbook-ui", replicas=1, servicePort=80, diff --git a/test/e2e/testdata/ksonnet/components/params.libsonnet b/test/e2e/testdata/ksonnet/components/params.libsonnet index 5d8b017c83..a43a50ab1c 100644 --- a/test/e2e/testdata/ksonnet/components/params.libsonnet +++ b/test/e2e/testdata/ksonnet/components/params.libsonnet @@ -8,7 +8,7 @@ // Each object below should correspond to a component in the components/ directory "guestbook-ui": { containerPort: 80, - image: "quay.io/argoprojlabs/argocd-e2e-container:0.2", + image: "gcr.io/heptio-images/ks-guestbook-demo:0.2", name: "ks-guestbook-ui", replicas: 0, servicePort: 80, diff --git a/test/e2e/user_info_test.go b/test/e2e/user_info_test.go index f8970d2131..3e852c030f 100644 --- a/test/e2e/user_info_test.go +++ b/test/e2e/user_info_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" ) func TestUserInfo(t *testing.T) { diff --git a/test/fixture/path/files.go b/test/fixture/path/files.go index ec84e418dd..5a7a2ae380 100644 --- a/test/fixture/path/files.go +++ b/test/fixture/path/files.go @@ -79,7 +79,26 @@ func copySingleFile(src string, dest string, mode os.FileInfo) error { // CreateSymlink creates a symlink with name linkName to file destName in // workingDir -func CreateSymlink(t *testing.T, destName, linkName string) error { +func CreateSymlink(t *testing.T, workingDir, destName, linkName string) error { t.Helper() - return os.Symlink(destName, linkName) + oldWorkingDir, err := os.Getwd() + if err != nil { + return err + } + if workingDir != "" { + err = os.Chdir(workingDir) + if err != nil { + return err + } + defer func() { + if err := os.Chdir(oldWorkingDir); err != nil { + t.Fatal(err.Error()) + } + }() + } + err = os.Symlink(destName, linkName) + if err != nil { + return err + } + return nil } diff --git a/test/fixture/path/hack_path.go b/test/fixture/path/hack_path.go index 9b03007748..41bf98961c 100644 --- a/test/fixture/path/hack_path.go +++ b/test/fixture/path/hack_path.go @@ -4,9 +4,8 @@ import ( "fmt" "os" "path/filepath" - "testing" - "github.com/stretchr/testify/require" + "github.com/argoproj/argo-cd/v2/util/errors" ) type AddBinDirToPath struct { @@ -18,11 +17,11 @@ func (h AddBinDirToPath) Close() { } // add the hack path which has the argocd binary -func NewBinDirToPath(t *testing.T) AddBinDirToPath { - t.Helper() +func NewBinDirToPath() AddBinDirToPath { originalPath := os.Getenv("PATH") binDir, err := filepath.Abs("../../dist") - require.NoError(t, err) - t.Setenv("PATH", fmt.Sprintf("%s:%s", originalPath, binDir)) + errors.CheckError(err) + err = os.Setenv("PATH", fmt.Sprintf("%s:%s", originalPath, binDir)) + errors.CheckError(err) return AddBinDirToPath{originalPath} } diff --git a/test/fixture/revision_metadata/author.go b/test/fixture/revision_metadata/author.go index cc83e6c81f..ccc5f0952c 100644 --- a/test/fixture/revision_metadata/author.go +++ b/test/fixture/revision_metadata/author.go @@ -4,8 +4,9 @@ import ( "fmt" "strings" - "github.com/argoproj/argo-cd/v3/util/errors" - argoexec "github.com/argoproj/argo-cd/v3/util/exec" + argoexec "github.com/argoproj/pkg/exec" + + "github.com/argoproj/argo-cd/v2/util/errors" ) var Author string diff --git a/test/manifests_test.go b/test/manifests_test.go index 8b6b7b60e9..9c30714041 100644 --- a/test/manifests_test.go +++ b/test/manifests_test.go @@ -6,11 +6,11 @@ import ( "path/filepath" "testing" + argoexec "github.com/argoproj/pkg/exec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/test/fixture/test" - argoexec "github.com/argoproj/argo-cd/v3/util/exec" + "github.com/argoproj/argo-cd/v2/test/fixture/test" ) func TestKustomizeVersion(t *testing.T) { @@ -22,7 +22,7 @@ func TestKustomizeVersion(t *testing.T) { // TestBuildManifests makes sure we are consistent in naming, and all kustomization.yamls are buildable func TestBuildManifests(t *testing.T) { - err := filepath.Walk("../manifests", func(path string, _ os.FileInfo, err error) error { + err := filepath.Walk("../manifests", func(path string, f os.FileInfo, err error) error { if err != nil { return err } diff --git a/test/remote/Dockerfile b/test/remote/Dockerfile index 6da0a30c98..f91d9633fd 100644 --- a/test/remote/Dockerfile +++ b/test/remote/Dockerfile @@ -1,6 +1,6 @@ -ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:80dd3c3b9c6cecb9f1667e9290b3bc61b78c2678c02cbdae5f0fea92cc6734ab +ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:3f85b7caad41a95462cf5b787d8a04604c8262cdcdf9a472b8c52ef83375fe15 -FROM docker.io/library/golang:1.24.3@sha256:1bcf8844d2464a6485c87646f9da684610758eb1a2df63c8a6e7ca47c64f8655 AS go +FROM docker.io/library/golang:1.24.4@sha256:db5d0afbfb4ab648af2393b92e87eaae9ad5e01132803d80caef91b5752d289c AS go RUN go install github.com/mattn/goreman@latest && \ go install github.com/kisielk/godepgraph@latest diff --git a/test/testdata.go b/test/testdata.go index bf85f2fa89..2c5c617831 100644 --- a/test/testdata.go +++ b/test/testdata.go @@ -6,18 +6,18 @@ import ( "github.com/alicebob/miniredis/v2" "github.com/argoproj/gitops-engine/pkg/utils/testing" "github.com/redis/go-redis/v9" - corev1 "k8s.io/api/core/v1" + apiv1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - apps "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - appclient "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1" - appinformer "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions" - applister "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + apps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + appclient "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1" + appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions" + applister "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" ) const ( @@ -101,8 +101,8 @@ func NewConfigMap() *unstructured.Unstructured { return testing.Unstructured(ConfigMapManifest) } -func NewFakeConfigMap() *corev1.ConfigMap { - cm := corev1.ConfigMap{ +func NewFakeConfigMap() *apiv1.ConfigMap { + cm := apiv1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", APIVersion: "v1", @@ -119,8 +119,8 @@ func NewFakeConfigMap() *corev1.ConfigMap { return &cm } -func NewFakeSecret() *corev1.Secret { - secret := corev1.Secret{ +func NewFakeSecret(policy ...string) *apiv1.Secret { + secret := apiv1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", APIVersion: "v1", @@ -163,7 +163,7 @@ func NewFakeProjListerFromInterface(appProjects appclient.AppProjectInterface) a func NewFakeProjLister(objects ...runtime.Object) applister.AppProjectNamespaceLister { fakeAppClientset := apps.NewSimpleClientset(objects...) - factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppClientset, 0, appinformer.WithNamespace(""), appinformer.WithTweakListOptions(func(_ *metav1.ListOptions) {})) + factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppClientset, 0, appinformer.WithNamespace(""), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) projInformer := factory.Argoproj().V1alpha1().AppProjects().Informer() cancel := StartInformer(projInformer) defer cancel() diff --git a/test/testutil.go b/test/testutil.go index f2245f59af..3ad755bfdc 100644 --- a/test/testutil.go +++ b/test/testutil.go @@ -15,7 +15,7 @@ import ( "k8s.io/client-go/tools/cache" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) // StartInformer is a helper to start an informer, wait for its cache to sync and return a cancel func @@ -78,7 +78,7 @@ func MustLoadFileToString(path string) string { } func YamlToUnstructured(yamlStr string) *unstructured.Unstructured { - obj := make(map[string]any) + obj := make(map[string]interface{}) err := yaml.Unmarshal([]byte(yamlStr), &obj) if err != nil { panic(err) @@ -95,13 +95,13 @@ func YamlToApplication(yamlStr string) *v1alpha1.Application { return &app } -// ToMap converts any object to a map[string]any -func ToMap(obj any) map[string]any { +// ToMap converts any object to a map[string]interface{} +func ToMap(obj interface{}) map[string]interface{} { data, err := json.Marshal(obj) if err != nil { panic(err) } - var res map[string]any + var res map[string]interface{} err = json.Unmarshal(data, &res) if err != nil { panic(err) diff --git a/tools/cmd-docs/main.go b/tools/cmd-docs/main.go index 786ed14bae..27c26195c8 100644 --- a/tools/cmd-docs/main.go +++ b/tools/cmd-docs/main.go @@ -9,12 +9,11 @@ import ( "github.com/spf13/cobra/doc" - controller "github.com/argoproj/argo-cd/v3/cmd/argocd-application-controller/commands" - argocdappsetcontroller "github.com/argoproj/argo-cd/v3/cmd/argocd-applicationset-controller/commands" - argocddex "github.com/argoproj/argo-cd/v3/cmd/argocd-dex/commands" - reposerver "github.com/argoproj/argo-cd/v3/cmd/argocd-repo-server/commands" - argocdserver "github.com/argoproj/argo-cd/v3/cmd/argocd-server/commands" - argocdcli "github.com/argoproj/argo-cd/v3/cmd/argocd/commands" + controller "github.com/argoproj/argo-cd/v2/cmd/argocd-application-controller/commands" + argocddex "github.com/argoproj/argo-cd/v2/cmd/argocd-dex/commands" + reposerver "github.com/argoproj/argo-cd/v2/cmd/argocd-repo-server/commands" + argocdserver "github.com/argoproj/argo-cd/v2/cmd/argocd-server/commands" + argocdcli "github.com/argoproj/argo-cd/v2/cmd/argocd/commands" ) func main() { @@ -55,9 +54,4 @@ func main() { if err != nil { log.Fatal(err) } - - err = doc.GenMarkdownTreeCustom(argocdappsetcontroller.NewCommand(), "./docs/operator-manual/server-commands", headerPrepender, identity) - if err != nil { - log.Fatal(err) - } } diff --git a/ui-test/package.json b/ui-test/package.json index 44f1be1306..73a695aff8 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.28", + "@types/selenium-webdriver": "^4.1.27", "assert": "^2.1.0", - "chromedriver": "^136.0.2", - "selenium-webdriver": "^4.32.0" + "chromedriver": "^131.0.3", + "selenium-webdriver": "^4.27.0" }, "devDependencies": { - "@types/mocha": "^10.0.10", - "@types/node": "^22.15.21", - "dotenv": "^16.5.0", - "mocha": "^11.4.0", + "@types/mocha": "^10.0.9", + "@types/node": "^22.9.3", + "dotenv": "^16.4.7", + "mocha": "^10.7.3", "prettier": "^2.8.8", "tslint": "^6.1.3", "tslint-config-prettier": "^1.18.0", "tslint-plugin-prettier": "^2.0.1", - "typescript": "^5.8.3", + "typescript": "^5.7.2", "yarn": "^1.22.22" } } diff --git a/ui-test/src/UiTestUtilities.ts b/ui-test/src/UiTestUtilities.ts index bdc1e201e1..ac38790ca1 100644 --- a/ui-test/src/UiTestUtilities.ts +++ b/ui-test/src/UiTestUtilities.ts @@ -49,20 +49,21 @@ export default class UiTestUtilities { */ public static async init(): Promise { const options = new chrome.Options(); - UiTestUtilities.log('Env var IS_HEADLESS = ' + process.env.IS_HEADLESS); - if (process.env.IS_HEADLESS !== 'false') { - UiTestUtilities.log('Adding headless option'); + if (process.env.IS_HEADLESS) { options.addArguments('headless'); } options.addArguments('window-size=1400x1200'); - const driver = await new Builder().forBrowser('chrome').setChromeOptions(options).build(); + const driver = await new Builder() + .forBrowser('chrome') + .setChromeOptions(options) + .build(); UiTestUtilities.log('Environment variables are:'); UiTestUtilities.log(require('dotenv').config({path: __dirname + '/../.env'})); // Navigate to the ArgoCD URL await driver.get(Configuration.ARGOCD_URL); - UiTestUtilities.log('Navigate to Argo CD URL successful: driver.get'); + return new Navigation(driver); } diff --git a/ui-test/src/application-create-panel/application-create-panel.ts b/ui-test/src/application-create-panel/application-create-panel.ts index 713845c2df..a153611aa4 100644 --- a/ui-test/src/application-create-panel/application-create-panel.ts +++ b/ui-test/src/application-create-panel/application-create-panel.ts @@ -31,8 +31,7 @@ export class ApplicationCreatePanel extends Base { try { const appNameField = await UiTestUtilities.findUiElement(this.driver, CREATE_APPLICATION_FIELD_APP_NAME); await appNameField.sendKeys(appName); - } catch (err: any) { - UiTestUtilities.log('Error caught while setting app name: ' + err); + } catch (err) { throw new Error(err); } } @@ -41,8 +40,7 @@ export class ApplicationCreatePanel extends Base { try { const project = await UiTestUtilities.findUiElement(this.driver, CREATE_APPLICATION_FIELD_PROJECT); await project.sendKeys(projectName); - } catch (err: any) { - UiTestUtilities.log('Error caught while setting project name: ' + err); + } catch (err) { throw new Error(err); } } @@ -51,8 +49,7 @@ export class ApplicationCreatePanel extends Base { try { const reposUrl = await UiTestUtilities.findUiElement(this.driver, CREATE_APPLICATION_FIELD_REPOSITORY_URL); await reposUrl.sendKeys(sourceRepoUrl); - } catch (err: any) { - UiTestUtilities.log('Error caught while setting source repo URL: ' + err); + } catch (err) { throw new Error(err); } } @@ -61,8 +58,7 @@ export class ApplicationCreatePanel extends Base { try { const path = await UiTestUtilities.findUiElement(this.driver, CREATE_APPLICATION_FIELD_REPOSITORY_PATH); await path.sendKeys(sourceRepoPath); - } catch (err: any) { - UiTestUtilities.log('Error caught while setting source repo path: ' + err); + } catch (err) { throw new Error(err); } } @@ -82,8 +78,7 @@ export class ApplicationCreatePanel extends Base { if (destinationClusterFieldValue) { await this.setDestinationClusterUrl(destinationClusterFieldValue); } - } catch (err: any) { - UiTestUtilities.log('Error caught while selecting destination cluster URL menu: ' + err); + } catch (err) { throw new Error(err); } } @@ -103,8 +98,7 @@ export class ApplicationCreatePanel extends Base { if (destinationClusterFieldValue) { await this.setDestinationClusterName(destinationClusterFieldValue); } - } catch (err: any) { - UiTestUtilities.log('Error caught while selecting destination cluster name menu: ' + err); + } catch (err) { throw new Error(err); } } @@ -114,8 +108,7 @@ export class ApplicationCreatePanel extends Base { const clusterName = await UiTestUtilities.findUiElement(this.driver, CREATE_APPLICATION_FIELD_CLUSTER_NAME); await clusterName.sendKeys(destinationClusterName); // await clusterName.sendKeys('\r'); - } catch (err: any) { - UiTestUtilities.log('Error caught while setting destination cluster name: ' + err); + } catch (err) { throw new Error(err); } } @@ -124,8 +117,7 @@ export class ApplicationCreatePanel extends Base { try { const clusterUrl = await UiTestUtilities.findUiElement(this.driver, CREATE_APPLICATION_FIELD_CLUSTER_URL); await clusterUrl.sendKeys(destinationClusterUrl); - } catch (err: any) { - UiTestUtilities.log('Error caught while setting destination cluster URL: ' + err); + } catch (err) { throw new Error(err); } } @@ -134,8 +126,7 @@ export class ApplicationCreatePanel extends Base { try { const namespace = await UiTestUtilities.findUiElement(this.driver, CREATE_APPLICATION_FIELD_CLUSTER_NAMESPACE); await namespace.sendKeys(destinationNamespace); - } catch (err: any) { - UiTestUtilities.log('Error caught while setting destination namespace: ' + err); + } catch (err) { throw new Error(err); } } @@ -149,13 +140,12 @@ export class ApplicationCreatePanel extends Base { await createButton.click(); // Wait until the Create Application Sliding Panel disappears - await this.driver.wait(until.elementIsNotVisible(createButton), Const.TEST_SLIDING_PANEL_TIMEOUT).catch((e) => { + await this.driver.wait(until.elementIsNotVisible(createButton), Const.TEST_SLIDING_PANEL_TIMEOUT).catch(e => { UiTestUtilities.logError('The Create Application Sliding Panel did not disappear'); throw e; }); await this.driver.sleep(1000); - } catch (err: any) { - UiTestUtilities.log('Error caught while clicking Create button: ' + err); + } catch (err) { throw new Error(err); } } @@ -169,12 +159,11 @@ export class ApplicationCreatePanel extends Base { await cancelButton.click(); // Wait until the Create Application Sliding Panel disappears - await this.driver.wait(until.elementIsNotVisible(cancelButton), Const.TEST_SLIDING_PANEL_TIMEOUT).catch((e) => { + await this.driver.wait(until.elementIsNotVisible(cancelButton), Const.TEST_SLIDING_PANEL_TIMEOUT).catch(e => { UiTestUtilities.logError('The Create Application Sliding Panel did not disappear'); throw e; }); - } catch (err: any) { - UiTestUtilities.log('Error caught while clicking Cancel button: ' + err); + } catch (err) { throw new Error(err); } } @@ -209,7 +198,7 @@ export class ApplicationCreatePanel extends Base { await this.selectDestinationClusterNameMenu(destinationClusterName); await this.setDestinationNamespace(destinationNamespace); await this.clickCreateButton(); - } catch (err: any) { + } catch (err) { throw new Error(err); } } diff --git a/ui-test/src/applications-list/applications-list.ts b/ui-test/src/applications-list/applications-list.ts index 90dfb791a9..ae76b9d80c 100644 --- a/ui-test/src/applications-list/applications-list.ts +++ b/ui-test/src/applications-list/applications-list.ts @@ -27,7 +27,7 @@ export class ApplicationsList extends Base { try { const tile = await UiTestUtilities.findUiElement(this.driver, this.getApplicationTileLocator(appName)); await tile.click(); - } catch (err: any) { + } catch (err) { throw new Error(err); } } @@ -39,7 +39,7 @@ export class ApplicationsList extends Base { try { const newAppButton = await UiTestUtilities.findUiElement(this.driver, NEW_APP_BUTTON); await newAppButton.click(); - } catch (err: any) { + } catch (err) { throw new Error(err); } return this.applicationCreatePanel; @@ -57,7 +57,7 @@ export class ApplicationsList extends Base { // Wait until the Synchronize sliding panel appears const synchronizeButton = await this.driver.wait(until.elementLocated(SYNC_PANEL_SYNCHRONIZE_BUTTON), Const.TEST_TIMEOUT); await this.driver.wait(until.elementIsVisible(synchronizeButton), Const.TEST_TIMEOUT); - } catch (err: any) { + } catch (err) { throw new Error(err); } return this.applicationsSyncPanel; @@ -72,7 +72,7 @@ export class ApplicationsList extends Base { try { const deleteButton = await UiTestUtilities.findUiElement(this.driver, this.getDeleteButtonLocatorForApp(appName)); await deleteButton.click(); - } catch (err: any) { + } catch (err) { throw new Error(err); } return this.popupManager; @@ -95,7 +95,7 @@ export class ApplicationsList extends Base { const refreshButton = await UiTestUtilities.findUiElement(this.driver, this.getRefreshButtonLocatorForApp(appName)); await this.driver.wait(until.elementIsVisible(refreshButton), Const.TEST_TIMEOUT); await refreshButton.click(); - } catch (err: any) { + } catch (err) { throw new Error(err); } } @@ -111,7 +111,7 @@ export class ApplicationsList extends Base { await this.driver.wait(async () => { return UiTestUtilities.untilAttributeIs(healthStatusElement, 'title', 'Healthy'); }, Const.TEST_TIMEOUT); - } catch (err: any) { + } catch (err) { throw new Error(err); } } @@ -127,7 +127,7 @@ export class ApplicationsList extends Base { await this.driver.wait(async () => { return UiTestUtilities.untilAttributeIs(statusElement, 'title', 'Synced'); }, Const.TEST_TIMEOUT); - } catch (err: any) { + } catch (err) { throw new Error(err); } } diff --git a/ui-test/src/applications-sync-panel/applications-sync-panel.ts b/ui-test/src/applications-sync-panel/applications-sync-panel.ts index dfd4b8c601..9a5f266de5 100644 --- a/ui-test/src/applications-sync-panel/applications-sync-panel.ts +++ b/ui-test/src/applications-sync-panel/applications-sync-panel.ts @@ -23,12 +23,12 @@ export class ApplicationsSyncPanel extends Base { await this.driver.wait(until.elementIsEnabled(synchronizeButton), Const.TEST_TIMEOUT); await synchronizeButton.click(); - await this.driver.wait(until.elementIsNotVisible(synchronizeButton), Const.TEST_SLIDING_PANEL_TIMEOUT).catch((e) => { + await this.driver.wait(until.elementIsNotVisible(synchronizeButton), Const.TEST_SLIDING_PANEL_TIMEOUT).catch(e => { UiTestUtilities.logError('The Synchronization Sliding Panel did not disappear'); throw e; }); UiTestUtilities.log('Synchronize sliding panel disappeared'); - } catch (err: any) { + } catch (err) { throw new Error(err); } } diff --git a/ui-test/src/navigation.ts b/ui-test/src/navigation.ts index 79618405f3..8baaff37e4 100644 --- a/ui-test/src/navigation.ts +++ b/ui-test/src/navigation.ts @@ -31,7 +31,7 @@ export class Navigation extends Base { try { const navBarButton = await UiTestUtilities.findUiElement(this.driver, NAVBAR_APPLICATIONS_BUTTON); await navBarButton.click(); - } catch (err: any) { + } catch (err) { throw new Error(err); } return this.applicationsList; @@ -45,7 +45,7 @@ export class Navigation extends Base { try { const navBarButton = await UiTestUtilities.findUiElement(this.driver, NAVBAR_SETTINGS_BUTTON); await navBarButton.click(); - } catch (err: any) { + } catch (err) { throw new Error(err); } } @@ -58,7 +58,7 @@ export class Navigation extends Base { try { const navBarButton = await UiTestUtilities.findUiElement(this.driver, NAVBAR_USER_INFO_BUTTON); await navBarButton.click(); - } catch (err: any) { + } catch (err) { throw new Error(err); } } @@ -71,7 +71,7 @@ export class Navigation extends Base { try { const navBarButton = await UiTestUtilities.findUiElement(this.driver, NAVBAR_DOCS_BUTTON); await navBarButton.click(); - } catch (err: any) { + } catch (err) { throw new Error(err); } } diff --git a/ui-test/yarn.lock b/ui-test/yarn.lock index 5c0cdfb9cf..d8845dc582 100644 --- a/ui-test/yarn.lock +++ b/ui-test/yarn.lock @@ -28,23 +28,6 @@ resolved "https://registry.yarnpkg.com/@bazel/runfiles/-/runfiles-6.3.1.tgz#3f8824b2d82853377799d42354b4df78ab0ace0b" integrity sha512-1uLNT5NZsUVIGS4syuHwTzZ8HycMPyr6POA3FCE4GbMtc4rhoJk8aZKtNIRthJYfL+iioppi+rTfH3olMPr9nA== -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - "@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" @@ -55,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.10": - version "10.0.10" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.10.tgz#91f62905e8d23cbd66225312f239454a23bebfa0" - integrity sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q== +"@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.15.21": - version "22.15.21" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.21.tgz#196ef14fe20d87f7caf1e7b39832767f9a995b77" - integrity sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ== +"@types/node@*", "@types/node@^22.9.3": + version "22.9.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.9.3.tgz#08f3d64b3bc6d74b162d36f60213e8a6704ef2b4" + integrity sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw== dependencies: - undici-types "~6.21.0" + undici-types "~6.19.8" -"@types/selenium-webdriver@^4.1.28": - version "4.1.28" - resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.1.28.tgz#7b4f3c50a67494f8fd6d396a2eaab7d9df1f9f34" - integrity sha512-Au7CXegiS7oapbB16zxPToY4Cjzi9UQQMf3W2ZZM8PigMLTGR3iUAHjPUTddyE5g1SBjT/qpmvlsAQLBfNAdKg== +"@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" "*" @@ -96,16 +79,16 @@ agent-base@^7.0.2, agent-base@^7.1.0, agent-base@^7.1.1: dependencies: debug "^4.3.4" +ansi-colors@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-regex@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" - integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== - ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" @@ -120,10 +103,13 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" argparse@^1.0.7: version "1.0.10" @@ -173,9 +159,9 @@ available-typed-arrays@^1.0.2: array-filter "^1.0.0" axios@^1.7.4: - version "1.8.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.2.tgz#fabe06e241dfe83071d4edfbcaa7b1c3a40f7979" - integrity sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg== + version "1.7.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2" + integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw== dependencies: follow-redirects "^1.15.6" form-data "^4.0.0" @@ -191,6 +177,11 @@ basic-ftp@^5.0.2: resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.5.tgz#14a474f5fffecca1f4f406f1c26b18f800225ac0" integrity sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg== +binary-extensions@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz" + integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -206,6 +197,13 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" +braces@~3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + browser-stdout@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" @@ -254,17 +252,25 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chokidar@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" - integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== +chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== dependencies: - readdirp "^4.0.1" + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" -chromedriver@^136.0.2: - version "136.0.2" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-136.0.2.tgz#736f81899ebff7569abc0f938fc5742bb446a39f" - integrity sha512-yJ52GN01edLYWYK/OspYBv3plzF08Ucdq4ukYigJGOX8dWr/tP5PXSZPWFPVarmbmcO57pNLP9Im8hsYljMEjw== +chromedriver@^131.0.3: + version "131.0.3" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-131.0.3.tgz#55f13389b855dbd681399aadd87a003bb0ab1186" + integrity sha512-DKHFt0ilcA/RJzY1ApBiJAil6fh08f9mXM8XbdDE1u+S1V5YVUNTUi4bOtJFZoAwS9nlV0H5W6InWrpXqSs2xg== dependencies: "@testim/chrome-version" "^1.1.4" axios "^1.7.4" @@ -274,13 +280,13 @@ chromedriver@^136.0.2: proxy-from-env "^1.1.0" tcp-port-used "^1.0.2" -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: string-width "^4.2.0" - strip-ansi "^6.0.1" + strip-ansi "^6.0.0" wrap-ansi "^7.0.0" color-convert@^1.9.0: @@ -334,15 +340,6 @@ core-util-is@~1.0.0: resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cross-spawn@^7.0.0: - version "7.0.6" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" - integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - data-uri-to-buffer@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz#8a58bb67384b261a38ef18bea1810cb01badd28b" @@ -416,31 +413,21 @@ diff@^4.0.1: resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== -diff@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-7.0.0.tgz#3fb34d387cd76d803f6eebea67b921dab0182a9a" - integrity sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw== +diff@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" + integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== -dotenv@^16.5.0: - version "16.5.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.5.0.tgz#092b49f25f808f020050051d1ff258e404c78692" - integrity sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg== - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +dotenv@^16.4.7: + version "16.4.7" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26" + integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ== emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -559,6 +546,13 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" @@ -582,14 +576,6 @@ foreach@^2.0.5: resolved "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz" integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= -foreground-child@^3.1.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" - integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -613,6 +599,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" @@ -656,17 +647,12 @@ get-uri@^6.0.1: debug "^4.3.4" fs-extra "^11.2.0" -glob@^10.4.5: - version "10.4.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" - integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: - foreground-child "^3.1.0" - jackspeak "^3.1.2" - minimatch "^9.0.4" - minipass "^7.1.2" - package-json-from-dist "^1.0.0" - path-scurry "^1.11.1" + is-glob "^4.0.1" glob@^7.1.1: version "7.2.0" @@ -680,6 +666,17 @@ glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + gopd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" @@ -797,6 +794,13 @@ is-arguments@^1.0.4: dependencies: call-bind "^1.0.0" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-callable@^1.1.4, is-callable@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz" @@ -814,6 +818,11 @@ is-date-object@^1.0.1: resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz" integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -824,6 +833,20 @@ is-generator-function@^1.0.7: resolved "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz" integrity sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ== +is-glob@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + is-nan@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" @@ -837,6 +860,11 @@ is-negative-zero@^2.0.0: resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + is-plain-obj@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" @@ -891,20 +919,6 @@ isarray@~1.0.0: resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -jackspeak@^3.1.2: - version "3.4.3" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" - integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - jest-docblock@^21.0.0: version "21.2.0" resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz" @@ -981,11 +995,6 @@ log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -lru-cache@^10.2.0: - version "10.4.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" - integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== - lru-cache@^7.14.1: version "7.18.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" @@ -1010,30 +1019,18 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimatch@^5.1.6: +minimatch@^5.0.1, minimatch@^5.1.6: version "5.1.6" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.4: - version "9.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" - integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== - dependencies: - brace-expansion "^2.0.1" - minimist@^1.2.5: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" - integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== - mkdirp@^0.5.3: version "0.5.5" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" @@ -1041,30 +1038,30 @@ mkdirp@^0.5.3: dependencies: minimist "^1.2.5" -mocha@^11.4.0: - version "11.4.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-11.4.0.tgz#6e873ee0beed4475e06f782bc9dd076670f932fd" - integrity sha512-O6oi5Y9G6uu8f9iqXR6iKNLWHLRex3PKbmHynfpmUnMJJGrdgXh8ZmS85Ei5KR2Gnl+/gQ9s+Ktv5CqKybNw4A== +mocha@^10.7.3: + version "10.7.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.7.3.tgz#ae32003cabbd52b59aece17846056a68eb4b0752" + integrity sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A== dependencies: + ansi-colors "^4.1.3" browser-stdout "^1.3.1" - chokidar "^4.0.1" + chokidar "^3.5.3" debug "^4.3.5" - diff "^7.0.0" + diff "^5.2.0" escape-string-regexp "^4.0.0" find-up "^5.0.0" - glob "^10.4.5" + glob "^8.1.0" he "^1.2.0" js-yaml "^4.1.0" log-symbols "^4.1.0" minimatch "^5.1.6" ms "^2.1.3" - picocolors "^1.1.1" serialize-javascript "^6.0.2" strip-json-comments "^3.1.1" supports-color "^8.1.1" workerpool "^6.5.1" - yargs "^17.7.2" - yargs-parser "^21.1.1" + yargs "^16.2.0" + yargs-parser "^20.2.9" yargs-unparser "^2.0.0" ms@2.1.2: @@ -1082,6 +1079,11 @@ netmask@^2.0.2: resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + object-inspect@^1.8.0: version "1.9.0" resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz" @@ -1153,11 +1155,6 @@ pac-resolver@^7.0.0: degenerator "^5.0.0" netmask "^2.0.2" -package-json-from-dist@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" - integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== - pako@~1.0.2: version "1.0.11" resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz" @@ -1173,33 +1170,25 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - path-parse@^1.0.6: version "1.0.7" resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.11.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" - integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== - dependencies: - lru-cache "^10.2.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= -picocolors@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" - integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== +picomatch@^2.0.4: + version "2.2.2" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +picomatch@^2.2.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== prettier@^2.8.8: version "2.8.8" @@ -1258,10 +1247,12 @@ readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readdirp@^4.0.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d" - integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg== +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" require-directory@^2.1.1: version "2.1.1" @@ -1281,10 +1272,10 @@ 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.32.0: - version "4.32.0" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.32.0.tgz#9bfe160cdac14d2d2876bba6eb369a09e9bd13ed" - integrity sha512-dG48JJnB96Aea1iVaZOKGmd6yT6aemeI1heWI/i8DtfD3pDX7uIlwpDBoGauNhtXAaFaamP+U4hIab8zZkg3Ag== +selenium-webdriver@^4.27.0: + version "4.27.0" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.27.0.tgz#f0f26ce453805e7dc77151040442c67e441dbe7a" + integrity sha512-LkTJrNz5socxpPnWPODQ2bQ65eYx9JK+DQMYNihpTjMCqHwgWGYQnQTCAAche2W3ZP87alA+1zYPvgS8tHNzMQ== dependencies: "@bazel/runfiles" "^6.3.1" jszip "^3.10.1" @@ -1320,23 +1311,6 @@ setimmediate@^1.0.5: resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" @@ -1374,7 +1348,7 @@ sprintf-js@~1.0.2: resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -"string-width-cjs@npm:string-width@^4.2.0": +string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -1383,24 +1357,6 @@ sprintf-js@~1.0.2: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - string.prototype.trimend@^1.0.1: version "1.0.3" resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz" @@ -1424,13 +1380,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -1438,13 +1387,6 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -1484,6 +1426,13 @@ tmp@^0.2.3: resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + tslib@^1.13.0, tslib@^1.7.1, tslib@^1.8.1: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" @@ -1534,15 +1483,15 @@ tsutils@^2.29.0: dependencies: tslib "^1.8.1" -typescript@^5.8.3: - version "5.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" - integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== +typescript@^5.7.2: + version "5.7.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6" + integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg== -undici-types@~6.21.0: - version "6.21.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" - integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== +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== universalify@^2.0.0: version "2.0.1" @@ -1578,27 +1527,11 @@ which-typed-array@^1.1.2: has-symbols "^1.0.1" is-typed-array "^1.1.3" -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - workerpool@^6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -1608,15 +1541,6 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -1632,10 +1556,10 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== +yargs-parser@^20.2.2, yargs-parser@^20.2.9: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== yargs-unparser@^2.0.0: version "2.0.0" @@ -1647,18 +1571,18 @@ yargs-unparser@^2.0.0: flat "^5.0.2" is-plain-obj "^2.1.0" -yargs@^17.7.2: - version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== dependencies: - cliui "^8.0.1" + cliui "^7.0.2" escalade "^3.1.1" get-caller-file "^2.0.5" require-directory "^2.1.1" - string-width "^4.2.3" + string-width "^4.2.0" y18n "^5.0.5" - yargs-parser "^21.1.1" + yargs-parser "^20.2.2" yarn@^1.22.22: version "1.22.22" diff --git a/ui/jest.config.js b/ui/jest.config.js index 9e154efab8..524b493f54 100644 --- a/ui/jest.config.js +++ b/ui/jest.config.js @@ -4,17 +4,15 @@ module.exports = { reporters: ['default', 'jest-junit'], collectCoverage: true, transformIgnorePatterns: ['node_modules/(?!(argo-ui)/)'], - transform: { - '^.+\\.tsx?$': ['ts-jest', { - isolatedModules: true, - }] - }, globals: { - 'self': {} + 'self': {}, + 'ts-jest': { + isolatedModules: true, + }, }, moduleNameMapper: { // https://github.com/facebook/jest/issues/3094 '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '/__mocks__/fileMock.js', - '.+\\.(css|styl|less|sass|scss)$': '/__mocks__/fileMock.js', + '.+\\.(css|styl|less|sass|scss)$': 'jest-transform-css', }, }; diff --git a/ui/package.json b/ui/package.json index b0ec7e709e..f0d6c39191 100644 --- a/ui/package.json +++ b/ui/package.json @@ -97,17 +97,18 @@ "babel-loader": "^8.0.6", "codecov": "^3.8.3", "copy-webpack-plugin": "^6.1.1", - "esbuild-loader": "^4.3.0", - "eslint": "^9.15.0", + "esbuild-loader": "^2.18.0", + "eslint": "^9.1.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-react": "^7.37.2", + "eslint-plugin-react": "^7.34.1", "globals": "^15.1.0", "html-webpack-plugin": "^5.6.0", "identity-obj-proxy": "^3.0.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "jest-junit": "^6.4.0", + "jest-transform-css": "^2.0.0", "monaco-editor-webpack-plugin": "^7.1.0", "postcss": "^8.4.38", "prettier": "^3.2.5", diff --git a/ui/scripts/build_docker.sh b/ui/scripts/build_docker.sh index 68c0ed1fff..9ad796a8b1 100755 --- a/ui/scripts/build_docker.sh +++ b/ui/scripts/build_docker.sh @@ -4,9 +4,9 @@ set -e TAG=${IMAGE_TAG:-'latest'} -docker build --build-arg ARGO_VERSION=${TAG} -t ${IMAGE_NAMESPACE:-$(whoami)}/argocd-ui:${TAG} . +docker build --build-arg ARGO_VERSION=${TAG} -t ${IMAGE_NAMESPACE:-`whoami`}/argocd-ui:${TAG} . if [ "$DOCKER_PUSH" == "true" ] then - docker push ${IMAGE_NAMESPACE:-$(whoami)}/argocd-ui:${TAG} + docker push ${IMAGE_NAMESPACE:-`whoami`}/argocd-ui:${TAG} fi diff --git a/ui/src/app/app.tsx b/ui/src/app/app.tsx index bc3629ffc5..17851489dd 100644 --- a/ui/src/app/app.tsx +++ b/ui/src/app/app.tsx @@ -88,7 +88,10 @@ async function isExpiredSSO() { return false; } -export class App extends React.Component<{}, {popupProps: PopupProps; showVersionPanel: boolean; error: Error; navItems: NavItem[]; routes: Routes; authSettings: AuthSettings}> { +export class App extends React.Component< + {}, + {popupProps: PopupProps; showVersionPanel: boolean; error: Error; navItems: NavItem[]; routes: Routes; extensionsLoaded: boolean; authSettings: AuthSettings} +> { public static childContextTypes = { history: PropTypes.object, apis: PropTypes.object @@ -108,7 +111,7 @@ export class App extends React.Component<{}, {popupProps: PopupProps; showVersio constructor(props: {}) { super(props); - this.state = {popupProps: null, error: null, showVersionPanel: false, navItems: [], routes: null, authSettings: null}; + this.state = {popupProps: null, error: null, showVersionPanel: false, navItems: [], routes: null, extensionsLoaded: false, authSettings: null}; this.popupManager = new PopupManager(); this.notificationsManager = new NotificationsManager(); this.navigationManager = new NavigationManager(history); @@ -148,7 +151,7 @@ export class App extends React.Component<{}, {popupProps: PopupProps; showVersio document.head.appendChild(link); } - this.setState({...this.state, navItems: this.navItems, routes: this.routes, authSettings}); + this.setState({...this.state, navItems: this.navItems, routes: this.routes, extensionsLoaded: false, authSettings}); } public componentWillUnmount() { @@ -219,6 +222,7 @@ export class App extends React.Component<{}, {popupProps: PopupProps; showVersio /> ); })} + {this.state.extensionsLoaded && } @@ -290,6 +294,6 @@ export class App extends React.Component<{}, {popupProps: PopupProps; showVersio extendedRoutes[extension.path] = { component: component as React.ComponentType> }; - this.setState({...this.state, navItems: extendedNavItems, routes: extendedRoutes}); + this.setState({...this.state, navItems: extendedNavItems, routes: extendedRoutes, extensionsLoaded: true}); } } diff --git a/ui/src/app/applications/components/__snapshots__/utils.test.tsx.snap b/ui/src/app/applications/components/__snapshots__/utils.test.tsx.snap index fcdf464603..81af34d623 100644 --- a/ui/src/app/applications/components/__snapshots__/utils.test.tsx.snap +++ b/ui/src/app/applications/components/__snapshots__/utils.test.tsx.snap @@ -33,22 +33,19 @@ exports[`ComparisonStatusIcon.Synced 1`] = ` `; exports[`ComparisonStatusIcon.Unknown 1`] = ` - - - + title="Unknown" + />, + " ", +] `; exports[`HealthStatusIcon.Degraded 1`] = ` @@ -91,22 +88,16 @@ exports[`HealthStatusIcon.Missing 1`] = ` `; exports[`HealthStatusIcon.Progressing 1`] = ` - - - + title="Progressing" +/> `; exports[`HealthStatusIcon.Suspended 1`] = ` @@ -137,22 +128,16 @@ exports[`HealthStatusIcon.Unknown 1`] = ` exports[`OperationState.Deleting 1`] = ` [ - - - , + title="Deleting" + />, " ", "Deleting", ] @@ -211,22 +196,16 @@ exports[`OperationState.Sync failed 1`] = ` exports[`OperationState.Syncing 1`] = ` [ - - - , + title="Syncing" + />, " ", "Syncing", ] @@ -234,22 +213,16 @@ exports[`OperationState.Syncing 1`] = ` exports[`OperationState.Unknown 1`] = ` [ - - - , + title="Unknown" + />, " ", "Unknown", ] @@ -282,22 +255,15 @@ exports[`ResourceResultIcon.Hook.Failed 1`] = ` `; exports[`ResourceResultIcon.Hook.Running 1`] = ` - - - + title="Running: my-message" +/> `; exports[`ResourceResultIcon.Hook.Succeeded 1`] = ` @@ -312,22 +278,14 @@ exports[`ResourceResultIcon.Hook.Succeeded 1`] = ` `; exports[`ResourceResultIcon.Hook.Terminating 1`] = ` - - - +/> `; exports[`ResourceResultIcon.Pruned 1`] = ` diff --git a/ui/src/app/applications/components/application-create-panel/application-create-panel.tsx b/ui/src/app/applications/components/application-create-panel/application-create-panel.tsx index 8e19284a5c..2a56246ad0 100644 --- a/ui/src/app/applications/components/application-create-panel/application-create-panel.tsx +++ b/ui/src/app/applications/components/application-create-panel/application-create-panel.tsx @@ -53,6 +53,7 @@ const AutoSyncFormField = ReactFormField((props: {fieldApi: FieldApi; className: fieldApi: {getValue, setValue} } = props; const automated = getValue() as models.Automated; + return ( @@ -60,16 +61,11 @@ const AutoSyncFormField = ReactFormField((props: {fieldApi: FieldApi; className: value={automated ? auto : manual} options={[manual, auto]} onChange={opt => { - setValue(opt.value === auto ? {prune: false, selfHeal: false, enabled: true} : null); + setValue(opt.value === auto ? {prune: false, selfHeal: false} : null); }} /> {automated && (
        -
        - setValue({...automated, enabled: val})} checked={automated.enabled === undefined ? true : automated.enabled} id='policyEnable' /> - - -
        setValue({...automated, prune: val})} checked={!!automated.prune} id='policyPrune' /> @@ -174,16 +170,6 @@ export const ApplicationCreatePanel = (props: { } } - const onCreateApp = (data: models.Application) => { - if (destinationComboValue === 'URL') { - delete data.spec.destination.name; - } else { - delete data.spec.destination.server; - } - - props.createApp(data); - }; - return ( debouncedOnAppChanged(state.values as any)} - onSubmit={onCreateApp} + onSubmit={props.createApp} getApi={props.getFormApi}> {api => { const generalPanel = () => ( @@ -318,10 +304,7 @@ export const ApplicationCreatePanel = (props: { qeId='application-create-field-repository-url' field='spec.source.repoURL' component={AutocompleteField} - componentProps={{ - items: repos, - filterSuggestions: true - }} + componentProps={{items: repos}} />
        @@ -413,8 +396,7 @@ export const ApplicationCreatePanel = (props: { field='spec.source.targetRevision' component={AutocompleteField} componentProps={{ - items: (selectedChart && selectedChart.versions) || [], - filterSuggestions: true + items: (selectedChart && selectedChart.versions) || [] }} /> @@ -437,10 +419,7 @@ export const ApplicationCreatePanel = (props: { label='Cluster URL' qeId='application-create-field-cluster-url' field='spec.destination.server' - componentProps={{ - items: clusters.map(cluster => cluster.server), - filterSuggestions: true - }} + componentProps={{items: clusters.map(cluster => cluster.server)}} component={AutocompleteField} />
        @@ -451,10 +430,7 @@ export const ApplicationCreatePanel = (props: { label='Cluster Name' qeId='application-create-field-cluster-name' field='spec.destination.name' - componentProps={{ - items: clusters.map(cluster => cluster.name), - filterSuggestions: true - }} + componentProps={{items: clusters.map(cluster => cluster.name)}} component={AutocompleteField} />
        diff --git a/ui/src/app/applications/components/application-details/application-details.scss b/ui/src/app/applications/components/application-details/application-details.scss index 18ec4e52c3..82402ffd0d 100644 --- a/ui/src/app/applications/components/application-details/application-details.scss +++ b/ui/src/app/applications/components/application-details/application-details.scss @@ -144,11 +144,6 @@ $header: 120px; cursor: default !important; color: $argo-color-gray-3 !important; } - - &:focus { - background-color: $argo-color-gray-1; - outline: none; - } } .argo-table-list__row { diff --git a/ui/src/app/applications/components/application-details/application-details.tsx b/ui/src/app/applications/components/application-details/application-details.tsx index 730c5865c0..3955f45d6f 100644 --- a/ui/src/app/applications/components/application-details/application-details.tsx +++ b/ui/src/app/applications/components/application-details/application-details.tsx @@ -40,7 +40,6 @@ interface ApplicationDetailsState { slidingPanelPage?: number; filteredGraph?: any[]; truncateNameOnRight?: boolean; - showFullNodeName?: boolean; collapsedNodes?: string[]; extensions?: AppViewExtension[]; extensionsMap?: {[key: string]: AppViewExtension}; @@ -93,7 +92,6 @@ export class ApplicationDetails extends React.Component { - this.setState({showFullNodeName: !this.state.showFullNodeName}); - }; const toggleNameDirection = () => { this.setState({truncateNameOnRight: !this.state.truncateNameOnRight}); }; @@ -720,19 +715,6 @@ export class ApplicationDetails extends React.Component - { - toggleNodeName(); - }} - title={this.state.showFullNodeName ? 'Show wrapped resource name' : 'Show full resource name'}> - - {(pref.view === 'tree' || pref.view === 'network') && ( )} + expandAll()} title='Expand all child nodes of all parent nodes'> @@ -786,7 +769,6 @@ export class ApplicationDetails extends React.Component { case 'Health': return props.resourceNodes.filter(res => res.health?.status === HealthStatuses[label]).length; case 'Kind': - return props.resourceNodes.reduce((count, res) => (res.group && label === 'Pod' ? res.group.length : res.kind === label ? count + 1 : count), 0); + return props.resourceNodes.filter(res => res.kind === label).length; default: return 0; } 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 bedb91b8b7..20c02bbfb0 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 @@ -1,4 +1,4 @@ -import {Checkbox, DropDown, Duration, NotificationType, Ticker, HelpIcon, Tooltip} from 'argo-ui'; +import {Checkbox, DropDown, Duration, NotificationType, Ticker, HelpIcon} from 'argo-ui'; import * as moment from 'moment'; import * as PropTypes from 'prop-types'; import * as React from 'react'; @@ -15,8 +15,8 @@ interface Props { application: models.Application; operationState: models.OperationState; } -const buildResourceUniqueId = (res: Omit) => `${res.group || ''}-${res.kind || ''}-${res.version || ''}-${res.namespace || ''}-${res.name}`; -const FilterableMessageStatuses = ['Changed', 'Unchanged']; +const buildResourceUniqueId = (res: Omit) => `${res.group}-${res.kind}-${res.version}-${res.namespace}-${res.name}`; +const FilterableMessageStatuses = ['configured', 'unchanged']; const Filter = (props: {filters: string[]; setFilters: (f: string[]) => void; options: string[]; title: string; style?: React.CSSProperties}) => { const {filters, setFilters, options, title, style} = props; @@ -58,24 +58,7 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl const operationAttributes = [ {title: 'OPERATION', value: utils.getOperationType(application)}, {title: 'PHASE', value: operationState.phase}, - ...(operationState.message - ? [ - { - title: 'MESSAGE', - value: ( -
        -                              {utils.formatOperationMessage(operationState.message)}
        -                          
        - ) - } - ] - : []), + ...(operationState.message ? [{title: 'MESSAGE', value: operationState.message}] : []), {title: 'STARTED AT', value: }, { title: 'DURATION', @@ -158,20 +141,13 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl // const hookPhases = ['Running', 'Terminating', 'Failed', 'Error', 'Succeeded']; const resourceHealth = application.status.resources.reduce( (acc, res) => { - acc[buildResourceUniqueId(res)] = { - health: res.health, - syncWave: res.syncWave - }; + if (res.health) { + acc[buildResourceUniqueId(res)] = res.health; + } return acc; }, - {} as Record< - string, - { - health: models.HealthStatus; - syncWave: number; - } - > + {} as Record ); const combinedHealthSyncResult: models.SyncResourceResult[] = syncResult?.resources?.map(syncResultItem => { @@ -183,12 +159,10 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl ...syncResultItem }; - if (healthStatus?.health) { - syncResultWithHealth.health = healthStatus.health; + if (healthStatus) { + syncResultWithHealth.health = healthStatus; } - syncResultWithHealth.syncWave = healthStatus?.syncWave; - return syncResultWithHealth; }); let filtered: models.SyncResourceResult[] = []; @@ -209,12 +183,7 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl } if (pass && messageFilters.length !== 0) { - pass = messageFilters.some(filter => { - if (filter === 'Changed') { - return r.message?.toLowerCase().includes('configured'); - } - return r.message?.toLowerCase().includes(filter.toLowerCase()); - }); + pass = messageFilters.some(filter => r.message?.toLowerCase().includes(filter.toLowerCase())); } return pass; @@ -241,19 +210,14 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl - -
        - -
        -
        +
      -
      SYNC WAVE
      KIND
      -
      NAMESPACE
      +
      NAMESPACE
      NAME
      STATUS
      HEALTH
      @@ -265,16 +229,13 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl filtered.map((resource, i) => (
      -
      +
      {resource.hookType && }
      - {resource.syncWave || '0'} -
      -
      {getKind(resource)}
      -
      +
      {resource.namespace}
      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 a47e295c02..aacbfc6b20 100644 --- a/ui/src/app/applications/components/application-parameters/application-parameters.tsx +++ b/ui/src/app/applications/components/application-parameters/application-parameters.tsx @@ -269,9 +269,8 @@ export const ApplicationParameters = (props: { ); } else { // For single source field, details page where we have to do the load to retrieve repo details - // Input changes frequently due to updates higher in the tree, do not show loading state when reloading return ( - getSingleSource(application)}> + getSingleSource(application)}> {(details: models.RepoAppDetails) => { attributes = []; const attr = gatherDetails( @@ -1092,7 +1091,7 @@ async function getSourceFromAppSources(aSource: models.ApplicationSource, name: // Delete when source field is removed async function getSingleSource(app: models.Application) { - if (app.spec.source || app.spec.sourceHydrator) { + if (app.spec.source) { const repoDetail = await services.repos.appDetails(getAppDefaultSource(app), app.metadata.name, app.spec.project, 0, 0).catch(() => ({ type: 'Directory' as models.AppSourceType, path: getAppDefaultSource(app).path diff --git a/ui/src/app/applications/components/application-pod-view/pod-view.tsx b/ui/src/app/applications/components/application-pod-view/pod-view.tsx index 80f8bb908a..caba162b82 100644 --- a/ui/src/app/applications/components/application-pod-view/pod-view.tsx +++ b/ui/src/app/applications/components/application-pod-view/pod-view.tsx @@ -25,15 +25,8 @@ interface PodViewProps { } export type PodGroupType = 'topLevelResource' | 'parentResource' | 'node'; -export type SortOrder = 'asc' | 'desc'; - -const labelForSortOrder: Record = { - asc: 'Oldest First', - desc: 'Newest First' -}; export interface PodGroup extends Partial { - timestamp?: number; type: PodGroupType; pods: Pod[]; info?: InfoItem[]; @@ -60,18 +53,6 @@ export class PodView extends React.Component { const podPrefs = prefs.appDetails.podView || ({} as PodViewPreferences); const groups = this.processTree(podPrefs.sortMode, this.props.tree.hosts || []) || []; - if (podPrefs.sortMode !== 'node' && podPrefs.sortOrder) { - // Sort the groups in place based on precomputed timestamps - groups.sort((a, b) => { - const timeA = Date.parse(a.createdAt || '0'); - const timeB = Date.parse(b.createdAt || '0'); - a.timestamp = timeA; - b.timestamp = timeB; - - return podPrefs.sortOrder === 'asc' ? timeA - timeB : timeB - timeA; - }); - } - return (
      @@ -87,20 +68,6 @@ export class PodView extends React.Component { items={this.menuItemsFor(['node', 'parentResource', 'topLevelResource'], prefs)} />
      - {podPrefs.sortMode !== 'node' && ( -
      - SORT BY AGE:  - ( - - )} - items={this.sortOrderItemsFor(['asc', 'desc'], prefs)} - /> -
      - )} {podPrefs.sortMode === 'node' && (
      -
      +
      {!rootNode &&
      {ResourceLabel({kind: node.kind})}
      }
      -
      +
      graphNodesFilter.nodes().forEach(nodeId => { const node: ResourceTreeNode = graphNodesFilter.node(nodeId) as any; const parentIds = graphNodesFilter.predecessors(nodeId); - - const shouldKeepNode = () => { - //case for podgroup in group node view - if (node.podGroup) { - return predicate(node) || node.podGroup.pods.some(pod => predicate({...node, kind: 'Pod', name: pod.name})); - } - return predicate(node); - }; - - if (node.root != null && !shouldKeepNode() && appKey !== nodeId) { + if (node.root != null && !predicate(node) && appKey !== nodeId) { const childIds = graphNodesFilter.successors(nodeId); graphNodesFilter.removeNode(nodeId); filtered++; @@ -957,14 +939,8 @@ export const ApplicationResourceTree = (props: ApplicationResourceTreeProps) => if (node.root != null) filteredNodes.push(node); } }); - if (filtered) { - graphNodesFilter.setNode(FILTERED_INDICATOR_NODE, { - height: NODE_HEIGHT, - width: NODE_WIDTH, - count: filtered, - type: NODE_TYPES.filteredIndicator - }); + graphNodesFilter.setNode(FILTERED_INDICATOR_NODE, {height: NODE_HEIGHT, width: NODE_WIDTH, count: filtered, type: NODE_TYPES.filteredIndicator}); graphNodesFilter.setEdge(filteredIndicatorParent, FILTERED_INDICATOR_NODE); } } diff --git a/ui/src/app/applications/components/application-status-panel/application-status-panel.scss b/ui/src/app/applications/components/application-status-panel/application-status-panel.scss index 48310d6a79..5abceda464 100644 --- a/ui/src/app/applications/components/application-status-panel/application-status-panel.scss +++ b/ui/src/app/applications/components/application-status-panel/application-status-panel.scss @@ -55,11 +55,9 @@ margin-left: auto; font-size: 14px; line-height: 20px; - display: flex; - padding: 1px 5px; + padding: 0 5px; cursor: pointer; color: $argo-color-gray-6; - border: 1px solid $argo-color-gray-5; } &__item { @@ -142,7 +140,6 @@ align-items: center; margin-bottom: 0.5em; font-weight: 500; - padding: 2px 0px; .fa { font-size: 1em; } @@ -182,17 +179,6 @@ padding-left: 8px; margin-bottom: 2px; } - - &__status-button { - display: inline; - border-radius: 5px; - padding: 2px; - border: 1px solid $argo-color-gray-5; - &:hover { - background-color: $argo-color-gray-4; - } - } - } &__hydrator-link { 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 89d54715f1..31b8387410 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 @@ -12,14 +12,11 @@ import { getAppDefaultSyncRevisionExtra, getAppOperationState, HydrateOperationPhaseIcon, - hydrationStatusMessage, - getProgressiveSyncStatusColor, - getProgressiveSyncStatusIcon + hydrationStatusMessage } from '../utils'; import {getConditionCategory, HealthStatusIcon, OperationState, syncStatusMessage, getAppDefaultSyncRevision, getAppDefaultOperationSyncRevision} from '../utils'; import {RevisionMetadataPanel} from './revision-metadata-panel'; import * as utils from '../utils'; -import {COLORS} from '../../../shared/components/colors'; import './application-status-panel.scss'; @@ -50,7 +47,7 @@ const sectionHeader = (info: SectionInfo, onClick?: () => any) => {
      {sectionLabel(info)} {onClick && ( - )} @@ -58,74 +55,7 @@ const sectionHeader = (info: SectionInfo, onClick?: () => any) => { ); }; -const hasRollingSyncEnabled = (application: models.Application): boolean => { - return application.metadata.ownerReferences?.some(ref => ref.kind === 'ApplicationSet') || false; -}; - -const ProgressiveSyncStatus = ({application}: {application: models.Application}) => { - if (!hasRollingSyncEnabled(application)) { - return null; - } - - const appSetRef = application.metadata.ownerReferences.find(ref => ref.kind === 'ApplicationSet'); - if (!appSetRef) { - return null; - } - - return ( - { - const appSet = await services.applications.getApplicationSet(appSetRef.name, application.metadata.namespace); - return appSet?.spec?.strategy?.type === 'RollingSync' ? appSet : null; - }}> - {(appSet: models.ApplicationSet) => { - if (!appSet) { - return ( -
      - {sectionHeader({ - title: 'PROGRESSIVE SYNC', - helpContent: 'Shows the current status of progressive sync for applications managed by an ApplicationSet with RollingSync strategy.' - })} -
      - Unknown -
      -
      - ); - } - - // Get the current application's status from the ApplicationSet resources - const appResource = appSet.status?.applicationStatus?.find(status => status.application === application.metadata.name); - - return ( -
      - {sectionHeader({ - title: 'PROGRESSIVE SYNC', - helpContent: 'Shows the current status of progressive sync for applications managed by an ApplicationSet with RollingSync strategy.' - })} -
      - {getProgressiveSyncStatusIcon({status: appResource.status})} {appResource.status} -
      -
      Wave: {appResource.step}
      -
      - Last Transition:
      - -
      - {appResource.message &&
      {appResource.message}
      } -
      - ); - }} -
      - ); -}; - export const ApplicationStatusPanel = ({application, showDiff, showOperation, showHydrateOperation, showConditions, showExtension, showMetadataInfo}: Props) => { - const [showProgressiveSync, setShowProgressiveSync] = React.useState(false); - - React.useEffect(() => { - setShowProgressiveSync(hasRollingSyncEnabled(application)); - }, [application]); - const today = new Date(); let daysSinceLastSynchronized = 0; @@ -152,7 +82,6 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh const errors = cntByCategory.get('error'); const source = getAppDefaultSource(application); const hasMultipleSources = application.spec.sources?.length > 0; - return (
      @@ -174,7 +103,7 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh
      showHydrateOperation && showHydrateOperation()}> - +   {application.status.sourceHydrator.currentOperation.phase} @@ -213,7 +142,7 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh
      {application.status.sync.status === models.SyncStatuses.OutOfSync ? ( showDiff && showDiff()}> - + ) : ( @@ -261,7 +190,7 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh )}
      showOperation && showOperation()}> - {' '} + {' '} {appOperationState.syncResult && (appOperationState.syncResult.revision || appOperationState.syncResult.revisions) && (
      @@ -290,17 +219,17 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh @@ -332,7 +261,6 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh )} - {showProgressiveSync && } {statusExtensions && statusExtensions.map(ext => showExtension && showExtension(ext.id)} />)}
      ); 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 6ca74cafe5..6dbd508180 100644 --- a/ui/src/app/applications/components/application-summary/application-summary.tsx +++ b/ui/src/app/applications/components/application-summary/application-summary.tsx @@ -1,5 +1,5 @@ /* eslint-disable no-prototype-builtins */ -import {AutocompleteField, Checkbox, DropDownMenu, ErrorNotification, FormField, FormSelect, HelpIcon, NotificationType} from 'argo-ui'; +import {AutocompleteField, DropDownMenu, ErrorNotification, FormField, FormSelect, HelpIcon, NotificationType} from 'argo-ui'; import * as React from 'react'; import {FormApi, Text} from 'react-form'; import { @@ -372,7 +372,7 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { }); } - async function setAutoSync(ctx: ContextApis, confirmationTitle: string, confirmationText: string, prune: boolean, selfHeal: boolean, enable: boolean) { + async function setAutoSync(ctx: ContextApis, confirmationTitle: string, confirmationText: string, prune: boolean, selfHeal: boolean) { const confirmed = await ctx.popup.confirm(confirmationTitle, confirmationText); if (confirmed) { try { @@ -381,8 +381,7 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { if (!updatedApp.spec.syncPolicy) { updatedApp.spec.syncPolicy = {}; } - - updatedApp.spec.syncPolicy.automated = {prune, selfHeal, enabled: enable}; + updatedApp.spec.syncPolicy.automated = {prune, selfHeal}; await updateApp(updatedApp, {validate: false}); } catch (e) { ctx.notifications.show({ @@ -519,7 +518,7 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { - + ))} )} diff --git a/ui/src/app/applications/components/applications-list/applications-tiles.scss b/ui/src/app/applications/components/applications-list/applications-tiles.scss index de58db1ae5..a4c1856765 100644 --- a/ui/src/app/applications/components/applications-list/applications-tiles.scss +++ b/ui/src/app/applications/components/applications-list/applications-tiles.scss @@ -26,24 +26,4 @@ &__selected { box-shadow: 0 0 0 1px $argo-color-teal-5; } - - .applications-list__title { - white-space: normal !important; - word-break: break-word; - overflow-wrap: break-word; - hyphens: auto; - line-height: 1.4; - width: 100%; - } -} - -.columns:has(> .argo-icon-git), .columns:has(> .argo-icon-helm) { - display: flex; - align-items: center; -} - -@media screen and (min-width: calc(map-get($breakpoints, xxlarge) - 1px)) { - .custom-tooltip { - display: none !important; - } } 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 bdccd72332..ccbbccf75a 100644 --- a/ui/src/app/applications/components/applications-list/applications-tiles.tsx +++ b/ui/src/app/applications/components/applications-list/applications-tiles.tsx @@ -276,31 +276,27 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat Sync   - - { - e.stopPropagation(); - refreshApplication(app.metadata.name, app.metadata.namespace); - }}> - {' '} - Refresh - - + { + e.stopPropagation(); + refreshApplication(app.metadata.name, app.metadata.namespace); + }}> + {' '} + Refresh +   - - { - e.stopPropagation(); - deleteApplication(app.metadata.name, app.metadata.namespace); - }}> - Delete - - + { + e.stopPropagation(); + deleteApplication(app.metadata.name, app.metadata.namespace); + }}> + Delete +
      diff --git a/ui/src/app/applications/components/pod-logs-viewer/match-case-toggle-button.tsx b/ui/src/app/applications/components/pod-logs-viewer/match-case-toggle-button.tsx deleted file mode 100644 index 99ea8001cb..0000000000 --- a/ui/src/app/applications/components/pod-logs-viewer/match-case-toggle-button.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import {ToggleButton} from '../../../shared/components/toggle-button'; -import * as React from 'react'; - -export const MatchCaseToggleButton = ({matchCase, setMatchCase}: {matchCase: boolean; setMatchCase: (matchCase: boolean) => void}) => { - return ( - setMatchCase(!matchCase)} toggled={matchCase}> - Aa - - ); -}; diff --git a/ui/src/app/applications/components/pod-logs-viewer/pod-logs-highlight-button.tsx b/ui/src/app/applications/components/pod-logs-viewer/pod-logs-highlight-button.tsx deleted file mode 100644 index 8f8b6c9136..0000000000 --- a/ui/src/app/applications/components/pod-logs-viewer/pod-logs-highlight-button.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import * as React from 'react'; -import {useState, useRef, useEffect} from 'react'; -import {ToggleButton} from '../../../shared/components/toggle-button'; - -// PodHighlightButton is a component that renders a toggle button that toggles pod highlighting. -export const PodHighlightButton = ({ - selectedPod, - setSelectedPod, - pods, - darkMode -}: { - selectedPod: string | null; - setSelectedPod: (value: string | null) => void; - pods: string[]; - darkMode: boolean; -}) => { - const [isOpen, setIsOpen] = useState(false); - const dropdownRef = useRef(null); - - useEffect(() => { - const handleClickOutside = (event: MouseEvent) => { - if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { - setIsOpen(false); - } - }; - - document.addEventListener('mousedown', handleClickOutside); - return () => document.removeEventListener('mousedown', handleClickOutside); - }, []); - - return ( -
      - setIsOpen(!isOpen)} icon='highlighter' toggled={selectedPod !== null} /> - {isOpen && ( -
      -
      - {pods.map(pod => ( -
      { - setSelectedPod(pod); - setIsOpen(false); - }}> - {pod} -
      - ))} -
      -
      { - setSelectedPod(null); - setIsOpen(false); - }}> - Clear highlight -
      -
      - )} -
      - ); -}; diff --git a/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.scss b/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.scss index a0eb695929..c2dd29f93c 100644 --- a/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.scss +++ b/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.scss @@ -1,13 +1,6 @@ @import 'node_modules/argo-ui/src/styles/config'; @import 'node_modules/argo-ui/src/styles/theme'; -$pod-background-light: $argo-color-teal-3; -$pod-background-dark: $dark-theme-background-2; -:root { - --pod-background-light: #{$pod-background-light}; - --pod-background-dark: #{$pod-background-dark}; -} - .pod-logs-viewer { height: 90%; font-size: 14px; @@ -19,7 +12,6 @@ $pod-background-dark: $dark-theme-background-2; &--inverted { background-color: black; color: white; - scrollbar-color: $argo-color-gray-5 $dark-theme-background-2; } &__settings { @@ -213,82 +205,6 @@ $pod-background-dark: $dark-theme-background-2; transform: translateY(2em); z-index: 1; } - - .pod-name-link { - cursor: pointer; - transition: opacity 0.2s ease; - &:hover { - text-decoration: underline; - opacity: 0.8; - } - } -} - -.select-container { - position: absolute; - top: 100%; - left: 0; - background: white; - border: 1px solid #ccc; - border-radius: 4px; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); - z-index: 1000; - min-width: 200px; // Ensure dropdown is wide enough for pod names - - &.dark-mode { - background: #333; /* Dark background for dark mode */ - border: 1px solid #555; /* Subtle border for dark mode */ - color: #eee; /* Light text for dark mode */ - } -} - -.select-options { - max-height: 200px; - overflow-y: auto; - - .select-option { - padding: 8px 10px; - cursor: pointer; - white-space: nowrap; // Prevent pod names from wrapping - - &:hover { - background-color: #f5f5f5; - } - - &.dark-mode { - background-color: #444; /* Hover effect in dark mode */ - &:hover { - background-color: #555; - } - } - - &.selected { - background-color: #e6f3ff; - } - &.dark-mode.selected { - background-color: #666; /* Selection highlight in dark mode */ - } - } -} - -.clear-highlight { - padding: 8px 10px; - border-top: 1px solid #ccc; - text-align: center; - color: #1750d3; - cursor: pointer; - - &:hover { - background-color: #f0f0f0; - } - - &.dark-mode { - border-top: 1px solid #555; - color: #5a9bd3; - &:hover { - background-color: #333; - } - } } .copySuccess { 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 245d88c2f8..e8cdca83f6 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 @@ -2,7 +2,7 @@ import {DataLoader} from 'argo-ui'; import * as classNames from 'classnames'; import * as React from 'react'; import {useEffect, useState, useRef} from 'react'; -import {bufferTime, catchError, delay, retryWhen} from 'rxjs/operators'; +import {bufferTime, delay, retryWhen} from 'rxjs/operators'; import {LogEntry} from '../../../shared/models'; import {services, ViewPreferences} from '../../../shared/services'; @@ -15,7 +15,6 @@ import {DownloadLogsButton} from './download-logs-button'; import {ContainerSelector} from './container-selector'; import {FollowToggleButton} from './follow-toggle-button'; import {ShowPreviousLogsToggleButton} from './show-previous-logs-toggle-button'; -import {PodHighlightButton} from './pod-logs-highlight-button'; import {TimestampsToggleButton} from './timestamps-toggle-button'; import {DarkModeToggleButton} from './dark-mode-toggle-button'; import {FullscreenButton} from './fullscreen-button'; @@ -26,9 +25,7 @@ import {TailSelector} from './tail-selector'; import {PodNamesToggleButton} from './pod-names-toggle-button'; import {AutoScrollButton} from './auto-scroll-button'; import {WrapLinesButton} from './wrap-lines-button'; -import {MatchCaseToggleButton} from './match-case-toggle-button'; import Ansi from 'ansi-to-react'; -import {EMPTY} from 'rxjs'; export interface PodLogsProps { namespace: string; @@ -50,32 +47,29 @@ export interface PodLogsProps { } // ansi colors, see https://en.wikipedia.org/wiki/ANSI_escape_code#Colors +const red = '\u001b[31m'; +const green = '\u001b[32m'; +const yellow = '\u001b[33m'; const blue = '\u001b[34m'; const magenta = '\u001b[35m'; -const colors = [blue, magenta]; +const cyan = '\u001b[36m'; +const colors = [red, green, yellow, blue, magenta, cyan]; const reset = '\u001b[0m'; const whiteOnYellow = '\u001b[1m\u001b[43;1m\u001b[37m'; -// Default colors using argo-ui theme variables -const POD_COLORS_LIGHT = ['var(--pod-background-light)']; -const POD_COLORS_DARK = ['var(--pod-background-dark)']; - -const getPodColors = (isDark: boolean) => { - const envColors = (window as any).env?.POD_COLORS?.[isDark ? 'dark' : 'light']; - return envColors || (isDark ? POD_COLORS_DARK : POD_COLORS_LIGHT); -}; - -function getPodBackgroundColor(podName: string, darkMode: boolean) { - const colors = getPodColors(darkMode); - return colors[0]; +// cheap string hash function +function stringHashCode(str: string) { + let hash = 0; + for (let i = 0; i < str.length; i++) { + // tslint:disable-next-line:no-bitwise + hash = str.charCodeAt(i) + ((hash << 5) - hash); + } + return hash; } // ansi color for pod name -function podColor(podName: string, isDarkMode: boolean, isSelected: boolean) { - if (!isSelected) { - return ''; - } - return isDarkMode ? colors[1] : colors[0]; +function podColor(podName: string) { + return colors[Math.abs(stringHashCode(podName) % colors.length)]; } // https://2ality.com/2012/09/empty-regexp.html @@ -84,21 +78,17 @@ const matchNothing = /.^/; export const PodsLogsViewer = (props: PodLogsProps) => { const {containerName, onClickContainer, timestamp, containerGroups, applicationName, applicationNamespace, namespace, podName, group, kind, name} = props; const queryParams = new URLSearchParams(location.search); - const [selectedPod, setSelectedPod] = useState(null); const [viewPodNames, setViewPodNames] = useState(queryParams.get('viewPodNames') === 'true'); const [follow, setFollow] = useState(queryParams.get('follow') !== 'false'); const [viewTimestamps, setViewTimestamps] = useState(queryParams.get('viewTimestamps') === 'true'); const [previous, setPreviousLogs] = useState(queryParams.get('showPreviousLogs') === 'true'); const [tail, setTail] = useState(parseInt(queryParams.get('tail'), 10) || 1000); - const [matchCase, setMatchCase] = useState(queryParams.get('matchCase') === 'true'); const [sinceSeconds, setSinceSeconds] = useState(0); const [filter, setFilter] = useState(queryParams.get('filterText') || ''); const [highlight, setHighlight] = useState(matchNothing); const [scrollToBottom, setScrollToBottom] = useState(true); const [logs, setLogs] = useState([]); const logsContainerRef = useRef(null); - const uniquePods = Array.from(new Set(logs.map(log => log.podName))); - const [errorMessage, setErrorMessage] = useState(null); const setWithQueryParams = void>(key: string, cb: T) => { return (val => { @@ -114,7 +104,6 @@ export const PodsLogsViewer = (props: PodLogsProps) => { const setPreviousLogsWithQueryParams = setWithQueryParams('showPreviousLogs', setPreviousLogs); const setTailWithQueryParams = setWithQueryParams('tail', setTail); const setFilterWithQueryParams = setWithQueryParams('filterText', setFilter); - const setMatchCaseWithQueryParams = setWithQueryParams('matchCase', setMatchCase); const onToggleViewPodNames = (val: boolean) => { setViewPodNamesWithQueryParams(val); @@ -127,8 +116,8 @@ export const PodsLogsViewer = (props: PodLogsProps) => { // https://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript // matchNothing this is chosen instead of empty regexp, because that would match everything and break colored logs // eslint-disable-next-line no-useless-escape - setHighlight(filter === '' ? matchNothing : new RegExp(filter.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g' + (matchCase ? '' : 'i'))); - }, [filter, matchCase]); + setHighlight(filter === '' ? matchNothing : new RegExp(filter.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g')); + }, [filter]); if (!containerName || containerName === '') { return
      Pod does not have container with name {containerName}
      ; @@ -159,102 +148,38 @@ export const PodsLogsViewer = (props: PodLogsProps) => { follow, sinceSeconds, filter, - previous, - matchCase - }) - .pipe( - bufferTime(100), - catchError((error: any) => { - const errorBody = JSON.parse(error.body); - if (errorBody.error && errorBody.error.message) { - if (errorBody.error.message.includes('max pods to view logs are reached')) { - setErrorMessage('Max pods to view logs are reached. Please provide more granular query.'); - return EMPTY; // Non-retryable condition, stop the stream and display the error message. - } - } - }), - retryWhen(errors => errors.pipe(delay(500))) - ) - .subscribe(log => { - if (log.length) { - setLogs(previousLogs => previousLogs.concat(log)); - } - }); + previous + }) // accumulate log changes and render only once every 100ms to reduce CPU usage + .pipe(bufferTime(100)) + .pipe(retryWhen(errors => errors.pipe(delay(500)))) + .subscribe(log => setLogs(previousLogs => previousLogs.concat(log))); return () => logsSource.unsubscribe(); - }, [applicationName, applicationNamespace, namespace, podName, group, kind, name, containerName, tail, follow, sinceSeconds, filter, previous, matchCase]); + }, [applicationName, applicationNamespace, namespace, podName, group, kind, name, containerName, tail, follow, sinceSeconds, filter, previous]); const handleScroll = (event: React.WheelEvent) => { if (event.deltaY < 0) setScrollToBottom(false); }; - const renderLog = (log: LogEntry, lineNum: number, darkMode: boolean) => { - const podNameContent = viewPodNames - ? (lineNum === 0 || logs[lineNum - 1].podName !== log.podName - ? `${podColor(log.podName, darkMode, selectedPod === log.podName)}${log.podName}${reset}` - : ' '.repeat(log.podName.length)) + ' ' - : ''; - + const renderLog = (log: LogEntry, lineNum: number) => + // show the pod name if there are multiple pods, pad with spaces to align + (viewPodNames ? (lineNum === 0 || logs[lineNum - 1].podName !== log.podName ? podColor(podName) + log.podName + reset : ' '.repeat(log.podName.length)) + ' ' : '') + // show the timestamp if requested, pad with spaces to align - const timestampContent = viewTimestamps ? (lineNum === 0 || logs[lineNum - 1].timeStamp !== log.timeStamp ? log.timeStampStr : '').padEnd(30) + ' ' : ''; - - // show the log content without colors, only highlight search terms - const logContent = log.content?.replace(highlight, (substring: string) => whiteOnYellow + substring + reset); - - return {podNameContent, timestampContent, logContent}; - }; - - const logsContent = (width: number, height: number, isWrapped: boolean, prefs: ViewPreferences) => ( -
      -
      - {logs.map((log, lineNum) => { - const {podNameContent, timestampContent, logContent} = renderLog(log, lineNum, prefs.appDetails.darkMode); - return ( -
      - {viewPodNames && (lineNum === 0 || logs[lineNum - 1].podName !== log.podName) && ( - setSelectedPod(selectedPod === log.podName ? null : log.podName)} style={{cursor: 'pointer'}} className='pod-name-link'> - {podNameContent} - - )} - {viewPodNames && !(lineNum === 0 || logs[lineNum - 1].podName !== log.podName) && ( - - {podNameContent} - - )} - {timestampContent + logContent} -
      - ); - })} -
      + (viewTimestamps ? (lineNum === 0 || logs[lineNum - 1].timeStamp !== log.timeStamp ? log.timeStampStr : '').padEnd(30) + ' ' : '') + + // show the log content, highlight the filter text + log.content?.replace(highlight, (substring: string) => whiteOnYellow + substring + reset); + const logsContent = (width: number, height: number, isWrapped: boolean) => ( +
      + {logs.map((log, lineNum) => ( +
      + {renderLog(log, lineNum)} +
      + ))}
      ); - const preferenceLoader = React.useCallback(() => services.viewPreferences.getPreferences(), []); return ( - + services.viewPreferences.getPreferences()}> {(prefs: ViewPreferences) => { return ( @@ -264,8 +189,6 @@ export const PodsLogsViewer = (props: PodLogsProps) => { {follow && } - - {!follow && ( @@ -278,7 +201,6 @@ export const PodsLogsViewer = (props: PodLogsProps) => { - @@ -292,11 +214,7 @@ export const PodsLogsViewer = (props: PodLogsProps) => {
      - {errorMessage ? ( -
      {errorMessage}
      - ) : ( - {({width, height}: {width: number; height: number}) => logsContent(width, height, prefs.appDetails.wrapLines, prefs)} - )} + {({width, height}: {width: number; height: number}) => logsContent(width, height, prefs.appDetails.wrapLines)}
      ); diff --git a/ui/src/app/applications/components/pod-terminal-viewer/pod-terminal-viewer.scss b/ui/src/app/applications/components/pod-terminal-viewer/pod-terminal-viewer.scss index 24b4cbc615..3ce4575be2 100644 --- a/ui/src/app/applications/components/pod-terminal-viewer/pod-terminal-viewer.scss +++ b/ui/src/app/applications/components/pod-terminal-viewer/pod-terminal-viewer.scss @@ -6,42 +6,6 @@ } } -.pod-terminal-viewer__tab { - cursor: pointer; - border-radius: 3px; - display: flex; - padding: 0.25rem 1rem !important; - align-items: center; - - &:hover { - background-color: rgba(0, 0, 0, 0.1); - } - - &--disabled { - opacity: 0.6; - cursor: not-allowed !important; - - &:hover { - background-color: transparent; - } - } - - - .pod-terminal-viewer__icon { - top: 0.4rem; - } - - .negative-space-arrow { - margin-left: 0.3rem; - } -} - -.theme-light { - .pod-terminal-viewer__container { - .tooltip { - background-color: #fff; - border-color: #fff; - color: #191826; - } - } +.negative-space-arrow { + margin-left: -10px; } \ No newline at end of file diff --git a/ui/src/app/applications/components/pod-terminal-viewer/pod-terminal-viewer.tsx b/ui/src/app/applications/components/pod-terminal-viewer/pod-terminal-viewer.tsx index 4feef4e629..2757d69d98 100644 --- a/ui/src/app/applications/components/pod-terminal-viewer/pod-terminal-viewer.tsx +++ b/ui/src/app/applications/components/pod-terminal-viewer/pod-terminal-viewer.tsx @@ -8,7 +8,6 @@ import {useCallback, useEffect} from 'react'; import {debounceTime, takeUntil} from 'rxjs/operators'; import {fromEvent, ReplaySubject, Subject} from 'rxjs'; import {Context} from '../../../shared/context'; -import {Tooltip} from 'argo-ui/v2'; import {ErrorNotification, NotificationType} from 'argo-ui'; export interface PodTerminalViewerProps { applicationName: string; @@ -26,16 +25,6 @@ export interface ShellFrame { cols?: number; } -const TooltipWrapper = (props: {content: React.ReactNode | string; disabled?: boolean; inverted?: boolean} & React.PropsWithRef) => { - return !props.disabled ? ( - - {props.children} - - ) : ( - props.children - ); -}; - export const PodTerminalViewer: React.FC = ({ selectedNode, applicationName, @@ -242,41 +231,26 @@ export const PodTerminalViewer: React.FC = ({ } ]; - const isContainerRunning = (container: any): boolean => { - const containerStatus = - podState.status?.containerStatuses?.find((status: {name: string}) => status.name === container.name) || - podState.status?.initContainerStatuses?.find((status: {name: string}) => status.name === container.name); - return containerStatus?.state?.running != null; - }; - return ( -
      +
      {containerGroups.map(group => (
      {group.containers.length > 0 &&

      {group.title}

      } - {group.containers.map((container: any, i: number) => { - const running = isContainerRunning(container); - return ( - -
      { - if (!running) { - return; - } - if (container.name !== containerName) { - disconnect(); - onClickContainer(group, i, 'exec'); - } - }} - title={!running ? 'Container is not running' : container.name}> - {container.name === containerName && } - {container.name} -
      -
      - ); - })} + {group.containers.map((container: any, i: number) => ( +
      { + if (container.name !== containerName) { + disconnect(); + onClickContainer(group, i, 'exec'); + } + }}> + {container.name === containerName && } + {container.name} +
      + ))}
      ))}
      diff --git a/ui/src/app/applications/components/utils.scss b/ui/src/app/applications/components/utils.scss index 197bcfc87a..94385aec13 100644 --- a/ui/src/app/applications/components/utils.scss +++ b/ui/src/app/applications/components/utils.scss @@ -31,32 +31,4 @@ i.utils-health-status-icon { min-width: 13px; text-align: center; -} - -.status-button { - display: inline; - border-radius: 5px; - vertical-align: middle; - padding: 2px; - border: 1px solid $argo-color-gray-5; - &:hover { - background-color: $argo-color-gray-4; - } -} - -.icon.spin { - animation: spin 2s linear infinite; - width: 0.5em; - height: 0.5em; - vertical-align: -0.05em; - overflow: visible; -} - -@keyframes spin { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } -} +} \ No newline at end of file diff --git a/ui/src/app/applications/components/utils.test.tsx b/ui/src/app/applications/components/utils.test.tsx index a64244c61b..2f42d34b0b 100644 --- a/ui/src/app/applications/components/utils.test.tsx +++ b/ui/src/app/applications/components/utils.test.tsx @@ -758,4 +758,4 @@ status: expect(reason).toBe('SchedulingGated'); }); -}); \ No newline at end of file +}); diff --git a/ui/src/app/applications/components/utils.tsx b/ui/src/app/applications/components/utils.tsx index c069abd2c1..ba690865ce 100644 --- a/ui/src/app/applications/components/utils.tsx +++ b/ui/src/app/applications/components/utils.tsx @@ -49,22 +49,6 @@ export function helpTip(text: string) { ); } - -//CLassic Solid circle-notch icon -// -//this will replace all fa-spin icons as they are currently misbehaving with no fix available. - -export const SpinningIcon = ({color, qeId}: {color: string; qeId: string}) => { - return ( - - - - ); -}; - export async function deleteApplication(appName: string, appNamespace: string, apis: ContextApis): Promise { let confirmed = false; const propagationPolicies: {name: string; message: string}[] = [ @@ -212,7 +196,7 @@ const PropagationPolicyOption = ReactForm.FormField((props: {fieldApi: ReactForm ); }); -export const OperationPhaseIcon = ({app, isButton}: {app: appModels.Application; isButton?: boolean}) => { +export const OperationPhaseIcon = ({app}: {app: appModels.Application}) => { const operationState = getAppOperationState(app); if (operationState === undefined) { return ; @@ -221,15 +205,15 @@ export const OperationPhaseIcon = ({app, isButton}: {app: appModels.Application; let color = ''; switch (operationState.phase) { case appModels.OperationPhases.Succeeded: - className = `fa fa-check-circle${isButton ? ' status-button' : ''}`; + className = 'fa fa-check-circle'; color = COLORS.operation.success; break; case appModels.OperationPhases.Error: - className = `fa fa-times-circle${isButton ? ' status-button' : ''}`; + className = 'fa fa-times-circle'; color = COLORS.operation.error; break; case appModels.OperationPhases.Failed: - className = `fa fa-times-circle${isButton ? ' status-button' : ''}`; + className = 'fa fa-times-circle'; color = COLORS.operation.failed; break; default: @@ -237,14 +221,10 @@ export const OperationPhaseIcon = ({app, isButton}: {app: appModels.Application; color = COLORS.operation.running; break; } - return className.includes('fa-spin') ? ( - - ) : ( - - ); + return ; }; -export const HydrateOperationPhaseIcon = ({operationState, isButton}: {operationState?: appModels.HydrateOperation; isButton?: boolean}) => { +export const HydrateOperationPhaseIcon = ({operationState}: {operationState?: appModels.HydrateOperation}) => { if (operationState === undefined) { return ; } @@ -252,11 +232,11 @@ export const HydrateOperationPhaseIcon = ({operationState, isButton}: {operation let color = ''; switch (operationState.phase) { case appModels.HydrateOperationPhases.Hydrated: - className = `fa fa-check-circle${isButton ? ' status-button' : ''}`; + className = 'fa fa-check-circle'; color = COLORS.operation.success; break; case appModels.HydrateOperationPhases.Failed: - className = `fa fa-times-circle${isButton ? ' status-button' : ''}`; + className = 'fa fa-times-circle'; color = COLORS.operation.failed; break; default: @@ -264,39 +244,34 @@ export const HydrateOperationPhaseIcon = ({operationState, isButton}: {operation color = COLORS.operation.running; break; } - return className.includes('fa-spin') ? ( - - ) : ( - - ); + return ; }; export const ComparisonStatusIcon = ({ status, resource, label, - noSpin, - isButton + noSpin }: { status: appModels.SyncStatusCode; resource?: {requiresPruning?: boolean}; label?: boolean; noSpin?: boolean; - isButton?: boolean; }) => { let className = 'fas fa-question-circle'; let color = COLORS.sync.unknown; let title: string = 'Unknown'; + switch (status) { case appModels.SyncStatuses.Synced: - className = `fa fa-check-circle${isButton ? ' status-button' : ''}`; + className = 'fa fa-check-circle'; color = COLORS.sync.synced; title = 'Synced'; break; case appModels.SyncStatuses.OutOfSync: // eslint-disable-next-line no-case-declarations const requiresPruning = resource && resource.requiresPruning; - className = requiresPruning ? `fa fa-trash${isButton ? ' status-button' : ''}` : `fa fa-arrow-alt-circle-up${isButton ? ' status-button' : ''}`; + className = requiresPruning ? 'fa fa-trash' : 'fa fa-arrow-alt-circle-up'; title = 'OutOfSync'; if (requiresPruning) { title = `${title} (This resource is not present in the application's source. It will be deleted from Kubernetes if the prune option is enabled during sync.)`; @@ -304,12 +279,10 @@ export const ComparisonStatusIcon = ({ color = COLORS.sync.out_of_sync; break; case appModels.SyncStatuses.Unknown: - className = `fa fa-circle-notch ${noSpin ? '' : 'fa-spin'}${isButton ? ' status-button' : ''}`; + className = `fa fa-circle-notch ${noSpin ? '' : 'fa-spin'}`; break; } - return className.includes('fa-spin') ? ( - - ) : ( + return ( {label && title} @@ -547,45 +520,22 @@ export const deletePopup = async ( ); }; -export async function getResourceActionsMenuItems(resource: ResourceTreeNode, metadata: models.ObjectMeta, apis: ContextApis): Promise { - return services.applications.getResourceActions(metadata.name, metadata.namespace, resource).then(actions => { - return actions.map(action => ({ - title: action.displayName ?? action.name, - disabled: !!action.disabled, - iconClassName: action.iconClass, - action: async () => { - const confirmed = false; - const title = action.params ? `Enter input parameters for action: ${action.name}` : `Perform ${action.name} action?`; - await apis.popup.prompt( - title, - api => ( -
      - {!action.params && ( -
      -
      Are you sure you want to perform {action.name} action?
      -
      - )} - {action.params && - action.params.map((param, index) => ( -
      - -
      - ))} -
      - ), - { - submit: async (vals, _, close) => { +export function getResourceActionsMenuItems(resource: ResourceTreeNode, metadata: models.ObjectMeta, apis: ContextApis): Promise { + return services.applications + .getResourceActions(metadata.name, metadata.namespace, resource) + .then(actions => { + return actions.map( + action => + ({ + title: action.displayName ?? action.name, + disabled: !!action.disabled, + iconClassName: action.iconClass, + action: async () => { try { - const resourceActionParameters = action.params - ? action.params.map(param => ({ - name: param.name, - value: vals[param.name] || param.default, - type: param.type, - default: param.default - })) - : []; - await services.applications.runResourceAction(metadata.name, metadata.namespace, resource, action.name, resourceActionParameters); - close(); + const confirmed = await apis.popup.confirm(`Execute '${action.name}' action?`, `Are you sure you want to execute '${action.name}' action?`); + if (confirmed) { + await services.applications.runResourceAction(metadata.name, metadata.namespace, resource, action.name); + } } catch (e) { apis.notifications.show({ content: , @@ -593,20 +543,10 @@ export async function getResourceActionsMenuItems(resource: ResourceTreeNode, me }); } } - }, - null, - null, - action.params - ? action.params.reduce((acc, res) => { - acc[res.name] = res.default; - return acc; - }, {} as any) - : {} - ); - return confirmed; - } - })); - }); + }) as MenuItem + ); + }) + .catch(() => [] as MenuItem[]); } function getActionItems( @@ -740,7 +680,6 @@ export function renderResourceMenu( {items.map((item, i) => (
    • { e.stopPropagation(); @@ -748,15 +687,6 @@ export function renderResourceMenu( item.action(); document.body.click(); } - }} - onKeyDown={e => { - if (e.keyCode === 13 || e.key === 'Enter') { - e.stopPropagation(); - setTimeout(() => { - item.action(); - document.body.click(); - }); - } }}> {item.tooltip ? ( @@ -961,11 +891,7 @@ export const HealthStatusIcon = ({state, noSpin}: {state: appModels.HealthStatus if (state.message) { title = `${state.status}: ${state.message}`; } - return icon.includes('fa-spin') ? ( - - ) : ( - - ); + return ; }; export const PodHealthIcon = ({state}: {state: appModels.HealthStatus}) => { @@ -989,11 +915,7 @@ export const PodHealthIcon = ({state}: {state: appModels.HealthStatus}) => { if (state.message) { title = `${state.status}: ${state.message}`; } - return icon.includes('fa-spin') ? ( - - ) : ( - - ); + return ; }; export const PodPhaseIcon = ({state}: {state: appModels.PodPhase}) => { @@ -1015,7 +937,7 @@ export const PodPhaseIcon = ({state}: {state: appModels.PodPhase}) => { className = 'fa fa-question-circle'; break; } - return className.includes('fa-spin') ? : ; + return ; }; export const ResourceResultIcon = ({resource}: {resource: appModels.ResourceResult}) => { @@ -1074,7 +996,7 @@ export const ResourceResultIcon = ({resource}: {resource: appModels.ResourceResu if (resource.message) { title = `${resource.hookPhase}: ${resource.message}`; } - return className.includes('fa-spin') ? : ; + return ; } return null; }; @@ -1133,7 +1055,7 @@ const getOperationStateTitle = (app: appModels.Application) => { return 'Unknown'; }; -export const OperationState = ({app, quiet, isButton}: {app: appModels.Application; quiet?: boolean; isButton?: boolean}) => { +export const OperationState = ({app, quiet}: {app: appModels.Application; quiet?: boolean}) => { const appOperationState = getAppOperationState(app); if (appOperationState === undefined) { return ; @@ -1144,7 +1066,7 @@ export const OperationState = ({app, quiet, isButton}: {app: appModels.Applicati return ( - {getOperationStateTitle(app)} + {getOperationStateTitle(app)} ); }; @@ -1625,44 +1547,6 @@ export function formatCreationTimestamp(creationTimestamp: string) { ); } -/* - * formatStatefulSetChange reformats a single line describing changes to immutable fields in a StatefulSet. - * It extracts the field name and its "from" and "to" values for better readability. - */ -function formatStatefulSetChange(line: string): string { - if (line.startsWith('-')) { - // Remove leading "- " from the line and split into field and changes - const [field, changes] = line.substring(2).split(':'); - if (changes) { - // Split "from: X to: Y" into separate lines with aligned values - const [from, to] = changes.split('to:').map(s => s.trim()); - return ` - ${field}:\n from: ${from.replace('from:', '').trim()}\n to: ${to}`; - } - } - return line; -} - -export function formatOperationMessage(message: string): string { - if (!message) { - return message; - } - - // Format immutable fields error message - if (message.includes('attempting to change immutable fields:')) { - const [header, ...details] = message.split('\n'); - const formattedDetails = details - // Remove empty lines - .filter(line => line.trim()) - // Use helper function - .map(formatStatefulSetChange) - .join('\n'); - - return `${header}\n${formattedDetails}`; - } - - return message; -} - export const selectPostfix = (arr: string[], singular: string, plural: string) => (arr.length > 1 ? plural : singular); export function getUsrMsgKeyToDisplay(appName: string, msgKey: string, usrMessages: appModels.UserMessages[]) { @@ -1685,43 +1569,3 @@ export function getAppUrl(app: appModels.Application): string { } return `applications/${app.metadata.namespace}/${app.metadata.name}`; } - -export const getProgressiveSyncStatusIcon = ({status, isButton}: {status: string; isButton?: boolean}) => { - const getIconProps = () => { - switch (status) { - case 'Healthy': - return {icon: 'fa-check-circle', color: COLORS.health.healthy}; - case 'Progressing': - return {icon: 'fa-circle-notch fa-spin', color: COLORS.health.progressing}; - case 'Pending': - return {icon: 'fa-clock', color: COLORS.health.degraded}; - case 'Waiting': - return {icon: 'fa-clock', color: COLORS.sync.out_of_sync}; - case 'Error': - return {icon: 'fa-times-circle', color: COLORS.health.degraded}; - default: - return {icon: 'fa-question-circle', color: COLORS.sync.unknown}; - } - }; - - const {icon, color} = getIconProps(); - const className = `fa ${icon}${isButton ? ' application-status-panel__item-value__status-button' : ''}`; - return ; -}; - -export const getProgressiveSyncStatusColor = (status: string): string => { - switch (status) { - case 'Waiting': - return COLORS.sync.out_of_sync; - case 'Pending': - return COLORS.health.degraded; - case 'Progressing': - return COLORS.health.progressing; - case 'Healthy': - return COLORS.health.healthy; - case 'Error': - return COLORS.health.degraded; - default: - return COLORS.sync.unknown; - } -}; 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 ca33d0426b..19ef81867d 100644 --- a/ui/src/app/settings/components/cluster-details/cluster-details.tsx +++ b/ui/src/app/settings/components/cluster-details/cluster-details.tsx @@ -2,7 +2,7 @@ import * as classNames from 'classnames'; import * as moment from 'moment'; import * as React from 'react'; import {FieldApi, FormField as ReactFormField, Text} from 'react-form'; -import {RouteComponentProps, Link} from 'react-router-dom'; +import {RouteComponentProps} from 'react-router-dom'; import {from, timer} from 'rxjs'; import {mergeMap} from 'rxjs/operators'; @@ -10,7 +10,6 @@ import {FormField, Ticker} from 'argo-ui'; import {ConnectionStateIcon, DataLoader, EditablePanel, Page, Timestamp, MapInputField} from '../../../shared/components'; import {Cluster} from '../../../shared/models'; import {services} from '../../../shared/services'; -import {formatClusterQueryParam} from '../../../shared/utils'; function isRefreshRequested(cluster: Cluster): boolean { return cluster.info.connectionState.attemptedAt && cluster.refreshRequestedAt && moment(cluster.info.connectionState.attemptedAt).isBefore(moment(cluster.refreshRequestedAt)); @@ -87,23 +86,6 @@ export const ClusterDetails = (props: RouteComponentProps<{server: string}>) => view: ((cluster.namespaces || []).length === 0 && 'All namespaces') || cluster.namespaces.join(', '), edit: formApi => }, - { - title: 'APPLICATIONS', - view: ( -
      - services.applications.list([])}> - {apps => ( - - { - apps.items.filter(app => app.spec.destination.name === cluster.name || app.spec.destination.server === cluster.server) - .length - } - - )} - -
      - ) - }, { title: 'LABELS', view: Object.keys(cluster.labels || []) diff --git a/ui/src/app/settings/components/project-details/project-details.scss b/ui/src/app/settings/components/project-details/project-details.scss index 76bd2943dc..4b41852e74 100644 --- a/ui/src/app/settings/components/project-details/project-details.scss +++ b/ui/src/app/settings/components/project-details/project-details.scss @@ -36,9 +36,4 @@ margin-top: 1em; } } - - .small-8-elements { - flex: 0 0 12.5%; - max-width: 12.5%; - } } \ No newline at end of file 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 0766a2aa49..96110c2ff9 100644 --- a/ui/src/app/settings/components/project-details/project-details.tsx +++ b/ui/src/app/settings/components/project-details/project-details.tsx @@ -4,7 +4,6 @@ import * as PropTypes from 'prop-types'; import * as React from 'react'; import {FormApi, Text} from 'react-form'; import {RouteComponentProps} from 'react-router'; -import {Link} from 'react-router-dom'; import {BadgePanel, CheckboxField, DataLoader, EditablePanel, ErrorNotification, MapInputField, Page, Query} from '../../../shared/components'; import {AppContext, Consumer, AuthSettingsCtx} from '../../../shared/context'; @@ -488,7 +487,7 @@ export class ProjectDetails extends React.Component
      -
      +
      STATUS {helpTip( 'If a window is active or inactive and what the current ' + @@ -498,53 +497,43 @@ export class ProjectDetails extends React.Component -
      +
      WINDOW {helpTip('The kind, start time and duration of the window')}
      -
      +
      APPLICATIONS {helpTip('The applications assigned to the window, wildcards are supported')}
      -
      +
      NAMESPACES {helpTip('The namespaces assigned to the window, wildcards are supported')}
      -
      +
      CLUSTERS {helpTip('The clusters assigned to the window, wildcards are supported')}
      -
      +
      MANUALSYNC {helpTip('If the window allows manual syncs')}
      -
      - USE AND OPERATOR - {helpTip('Use AND operator while selecting the apps that match the configured selectors')} -
      -
      - DESCRIPTION - {helpTip('Add a description to your sync window (eg "Ticket 12345")')} -
      {(proj.spec.syncWindows || []).map((window, i) => (
      ctx.navigation.goto(`.`, {editWindow: `${i}`})}>
      -
      +
      -
      +
      {window.kind}:{window.schedule}:{window.duration}:{window.timeZone}
      -
      {(window.applications || ['-']).join(',')}
      -
      {(window.namespaces || ['-']).join(',')}
      -
      {(window.clusters || ['-']).join(',')}
      -
      {window.manualSync ? 'Enabled' : 'Disabled'}
      -
      {window.andOperator ? 'Enabled' : 'Disabled'}
      -
      {window.description || ''}
      +
      {(window.applications || ['-']).join(',')}
      +
      {(window.namespaces || ['-']).join(',')}
      +
      {(window.clusters || ['-']).join(',')}
      +
      {window.manualSync ? 'Enabled' : 'Disabled'}
      ))} @@ -616,16 +605,6 @@ export class ProjectDetails extends React.Component services.projects.getLinks(proj.metadata.name)}>{links => }
      ) - }, - { - title: 'APPLICATIONS', - view: ( -
      - services.applications.list([proj.metadata.name])}> - {apps => {apps.items.length}} - -
      - ) } ]} /> diff --git a/ui/src/app/settings/components/project-role-edit-panel/project-role-edit-panel.tsx b/ui/src/app/settings/components/project-role-edit-panel/project-role-edit-panel.tsx index 0939394239..b2591b061a 100644 --- a/ui/src/app/settings/components/project-role-edit-panel/project-role-edit-panel.tsx +++ b/ui/src/app/settings/components/project-role-edit-panel/project-role-edit-panel.tsx @@ -19,8 +19,8 @@ interface ProjectRoleDefaultParams { interface ProjectRoleEditPanelProps { nameReadonly?: boolean; submit: (params: ProjectRoleParams) => any; - createJWTToken: (params: CreateJWTTokenParams) => Promise; - deleteJWTToken: (params: DeleteJWTTokenParams) => Promise; + createJWTToken: (params: CreateJWTTokenParams) => void; + deleteJWTToken: (params: DeleteJWTTokenParams) => void; hideJWTToken: () => void; token: string; getApi?: (formApi: FormApi) => void; diff --git a/ui/src/app/settings/components/project-role-jwt-tokens/project-role-jwt-tokens.scss b/ui/src/app/settings/components/project-role-jwt-tokens/project-role-jwt-tokens.scss index c72688ba72..110eef8545 100644 --- a/ui/src/app/settings/components/project-role-jwt-tokens/project-role-jwt-tokens.scss +++ b/ui/src/app/settings/components/project-role-jwt-tokens/project-role-jwt-tokens.scss @@ -3,29 +3,4 @@ right: 1em; top: 1em; cursor: pointer; -} - -.project-role-jwt-tokens__id { - display: flex; - align-items: center; -} - -.project-role-jwt-tokens__id-tooltip { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.project-role-jwt-tokens__expired-token { - color: white; - font-size: 1.2em; - padding-left: 0.5em; - padding-right: 0.5em; - line-height: 1.4em; - background-color: #8FA4B1; - margin-left: 0.2em; - border-radius: 0.2em; - transform: scale(0.8); - flex: 0; - min-width: fit-content; -} +} \ No newline at end of file diff --git a/ui/src/app/settings/components/project-role-jwt-tokens/project-role-jwt-tokens.tsx b/ui/src/app/settings/components/project-role-jwt-tokens/project-role-jwt-tokens.tsx index c7aa689763..51461bf92b 100644 --- a/ui/src/app/settings/components/project-role-jwt-tokens/project-role-jwt-tokens.tsx +++ b/ui/src/app/settings/components/project-role-jwt-tokens/project-role-jwt-tokens.tsx @@ -1,4 +1,4 @@ -import {FormField, NotificationType, Tooltip} from 'argo-ui'; +import {FormField, Tooltip} from 'argo-ui'; import * as React from 'react'; import {Form, FormApi, Text} from 'react-form'; @@ -6,16 +6,14 @@ import {Consumer, ContextApis} from '../../../shared/context'; import {JwtToken} from '../../../shared/models'; import {CreateJWTTokenParams, DeleteJWTTokenParams} from '../../../shared/services'; import {convertExpiresInToSeconds, validExpiresIn} from '../utils'; -import {Button} from '../../../shared/components/button'; -import {ProgressPopup} from '../../../shared/components'; interface ProjectRoleJWTTokensProps { projName: string; roleName: string; tokens: JwtToken[]; token: string; - createJWTToken: (params: CreateJWTTokenParams) => Promise; - deleteJWTToken: (params: DeleteJWTTokenParams) => Promise; + createJWTToken: (params: CreateJWTTokenParams) => void; + deleteJWTToken: (params: DeleteJWTTokenParams) => void; hideJWTToken: () => void; getApi?: (formApi: FormApi) => void; } @@ -23,32 +21,11 @@ interface ProjectRoleJWTTokensProps { require('./project-role-jwt-tokens.scss'); export const ProjectRoleJWTTokens = (props: ProjectRoleJWTTokensProps) => { - const [progress, setProgress] = React.useState<{percentage: number; title: string} | null>(null); - return ( {ctx => ( -

      - JWT Tokens - {progress !== null && setProgress(null)} />} - -

      +

      JWT Tokens

      Generate JWT tokens to bind to this role
      {props.tokens && props.tokens.length > 0 && (
      @@ -144,45 +121,17 @@ async function deleteJWTToken(props: ProjectRoleJWTTokensProps, iat: number, ctx } } -async function deleteJWTTokens(props: ProjectRoleJWTTokensProps, ctx: any, tokens: JwtToken[], setProgress: (progress: {percentage: number; title: string}) => void) { - const confirmed = await ctx.popup.confirm( - 'Delete Expired JWT Tokens', - `Are you sure you want to delete all ${tokens.length} expired tokens for role '${props.roleName}' in project '${props.projName}'?` - ); - if (confirmed) { - setProgress({percentage: 0, title: 'Deleting Expired Tokens'}); - let i = 0; - const promises = tokens.map(token => - props.deleteJWTToken({project: props.projName, role: props.roleName, iat: token.iat} as DeleteJWTTokenParams).then(() => { - setProgress({percentage: Number(((i / tokens.length) * 100).toFixed(2)), title: `Deleting token ${i + 1} of ${tokens.length}(${token.id})`}); - i++; - }) - ); - await Promise.all(promises); - - setProgress({percentage: 100, title: 'Delete Expired Tokens Complete'}); - } -} - function renderJWTRow(props: ProjectRoleJWTTokensProps, ctx: ContextApis, jwToken: JwtToken): React.ReactFragment { const issuedAt = new Date(jwToken.iat * 1000).toISOString(); const expiresAt = jwToken.exp == null ? 'Never' : new Date(jwToken.exp * 1000).toISOString(); - const isExpired = jwToken.exp && jwToken.exp < Date.now() / 1000; return (
      -
      - - {jwToken.id} - - {isExpired && ( - - Expired - - )} -
      + +
      {jwToken.id}
      +
      {issuedAt}
      diff --git a/ui/src/app/settings/components/project-sync-windows-edit-panel/project-sync-windows-edit-panel.tsx b/ui/src/app/settings/components/project-sync-windows-edit-panel/project-sync-windows-edit-panel.tsx index 2e2bfcf0c1..1a0fb520dc 100644 --- a/ui/src/app/settings/components/project-sync-windows-edit-panel/project-sync-windows-edit-panel.tsx +++ b/ui/src/app/settings/components/project-sync-windows-edit-panel/project-sync-windows-edit-panel.tsx @@ -67,17 +67,6 @@ export const ProjectSyncWindowsEditPanel = (props: ProjectSyncWindowsEditPanelPr
      -
      - -
      -
      - -
      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 3e21e7009f..dc67d69835 100644 --- a/ui/src/app/settings/components/repo-details/repo-details.tsx +++ b/ui/src/app/settings/components/repo-details/repo-details.tsx @@ -37,14 +37,6 @@ export const RepoDetails = (props: {repo: models.Repository; save?: (params: New } ]; - if (repository.type === 'git') { - items.push({ - title: 'Bearer token (optional, for BitBucket Data Center only)', - view: repository.bearerToken ? '******' : '', - edit: (formApi: FormApi) => - }); - } - if (useAuthSettingsCtx?.hydratorEnabled) { // Insert this item at index 1. const item = { @@ -85,7 +77,6 @@ export const RepoDetails = (props: {repo: models.Repository; save?: (params: New url: repo.repo, username: repo.username || '', password: repo.password || '', - bearerToken: repo.bearerToken || '', tlsClientCertData: repo.tlsClientCertData || '', tlsClientCertKey: repo.tlsClientCertKey || '', insecure: repo.insecure || false, @@ -94,8 +85,7 @@ export const RepoDetails = (props: {repo: models.Repository; save?: (params: New noProxy: repo.noProxy || '', project: repo.project || '', enableOCI: repo.enableOCI || false, - forceHttpBasicAuth: repo.forceHttpBasicAuth || false, - useAzureWorkloadIdentity: repo.useAzureWorkloadIdentity || false + forceHttpBasicAuth: repo.forceHttpBasicAuth || false }; return ( @@ -103,15 +93,13 @@ export const RepoDetails = (props: {repo: models.Repository; save?: (params: New values={repo} validate={input => ({ username: !input.username && input.password && 'Username is required if password is given.', - password: !input.password && input.username && 'Password is required if username is given.', - bearerToken: input.password && input.bearerToken && 'Either the password or the bearer token must be set, but not both.' + password: !input.password && input.username && 'Password is required if username is given.' })} save={async input => { const params: NewHTTPSRepoParams = {...newRepo, write}; params.name = input.name || ''; params.username = input.username || ''; params.password = input.password || ''; - params.bearerToken = input.bearerToken || ''; save(params); }} title='CONNECTED REPOSITORY' 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 96050d3425..92f7c63f53 100644 --- a/ui/src/app/settings/components/repos-list/repos-list.tsx +++ b/ui/src/app/settings/components/repos-list/repos-list.tsx @@ -33,7 +33,6 @@ export interface NewHTTPSRepoParams { url: string; username: string; password: string; - bearerToken: string; tlsClientCertData: string; tlsClientCertKey: string; insecure: boolean; @@ -45,7 +44,6 @@ export interface NewHTTPSRepoParams { enableOCI: boolean; // write should be true if saving as a write credential. write: boolean; - useAzureWorkloadIdentity: boolean; } interface NewGitHubAppRepoParams { @@ -90,7 +88,6 @@ interface NewHTTPSRepoCredsParams { url: string; username: string; password: string; - bearerToken: string; tlsClientCertData: string; tlsClientCertKey: string; proxy: string; @@ -99,7 +96,6 @@ interface NewHTTPSRepoCredsParams { enableOCI: boolean; // write should be true if saving as a write credential. write: boolean; - useAzureWorkloadIdentity: boolean; } interface NewGitHubAppRepoCredsParams { @@ -125,7 +121,7 @@ interface NewGoogleCloudSourceRepoCredsParams { export enum ConnectionMethod { SSH = 'via SSH', - HTTPS = 'via HTTP/HTTPS', + HTTPS = 'via HTTPS', GITHUBAPP = 'via GitHub App', GOOGLECLOUD = 'via Google Cloud' } @@ -208,25 +204,20 @@ export class ReposList extends React.Component< url: !sshValues.url && 'Repository URL is required' }; case ConnectionMethod.HTTPS: - const validURLValues = params as NewHTTPSRepoParams; + const httpsValues = params as NewHTTPSRepoParams; return { url: - (!validURLValues.url && 'Repository URL is required') || - (this.credsTemplate && !this.isHTTPOrHTTPSUrl(validURLValues.url) && !validURLValues.enableOCI && 'Not a valid HTTP/HTTPS URL'), - name: validURLValues.type === 'helm' && !validURLValues.name && 'Name is required', - username: !validURLValues.username && validURLValues.password && 'Username is required if password is given.', - password: !validURLValues.password && validURLValues.username && 'Password is required if username is given.', - tlsClientCertKey: !validURLValues.tlsClientCertKey && validURLValues.tlsClientCertData && 'TLS client cert key is required if TLS client cert is given.', - bearerToken: - (validURLValues.password && validURLValues.bearerToken && 'Either the password or the bearer token must be set, but not both.') || - (validURLValues.bearerToken && validURLValues.type != 'git' && 'Bearer token is only supported for Git BitBucket Data Center repositories.') + (!httpsValues.url && 'Repository URL is required') || + (this.credsTemplate && !this.isHTTPSUrl(httpsValues.url) && !httpsValues.enableOCI && 'Not a valid HTTPS URL'), + name: httpsValues.type === 'helm' && !httpsValues.name && 'Name is required', + username: !httpsValues.username && httpsValues.password && 'Username is required if password is given.', + password: !httpsValues.password && httpsValues.username && 'Password is required if username is given.', + tlsClientCertKey: !httpsValues.tlsClientCertKey && httpsValues.tlsClientCertData && 'TLS client cert key is required if TLS client cert is given.' }; case ConnectionMethod.GITHUBAPP: const githubAppValues = params as NewGitHubAppRepoParams; return { - url: - (!githubAppValues.url && 'Repository URL is required') || - (this.credsTemplate && !this.isHTTPOrHTTPSUrl(githubAppValues.url) && 'Not a valid HTTP/HTTPS URL'), + url: (!githubAppValues.url && 'Repository URL is required') || (this.credsTemplate && !this.isHTTPSUrl(githubAppValues.url) && 'Not a valid HTTPS URL'), githubAppId: !githubAppValues.githubAppId && 'GitHub App ID is required', githubAppInstallationId: !githubAppValues.githubAppInstallationId && 'GitHub App installation ID is required', githubAppPrivateKey: !githubAppValues.githubAppPrivateKey && 'GitHub App private Key is required' @@ -234,8 +225,7 @@ export class ReposList extends React.Component< case ConnectionMethod.GOOGLECLOUD: const googleCloudValues = params as NewGoogleCloudSourceRepoParams; return { - url: - (!googleCloudValues.url && 'Repo URL is required') || (this.credsTemplate && !this.isHTTPOrHTTPSUrl(googleCloudValues.url) && 'Not a valid HTTP/HTTPS URL'), + url: (!googleCloudValues.url && 'Repo URL is required') || (this.credsTemplate && !this.isHTTPSUrl(googleCloudValues.url) && 'Not a valid HTTPS URL'), gcpServiceAccountKey: !googleCloudValues.gcpServiceAccountKey && 'GCP service account key is required' }; } @@ -649,7 +639,7 @@ export class ReposList extends React.Component< )} {this.state.method === ConnectionMethod.HTTPS && (
      -

      CONNECT REPO USING HTTP/HTTPS

      +

      CONNECT REPO USING HTTPS

      @@ -689,29 +679,18 @@ export class ReposList extends React.Component< componentProps={{type: 'password'}} />
      - {formApi.getFormState().values.type === 'git' && ( -
      - -
      - )}
      -
      - - -
      {formApi.getFormState().values.type === 'git' && ( +
      + + +
      @@ -730,14 +709,6 @@ export class ReposList extends React.Component<
      -
      - -
      )} {this.state.method === ConnectionMethod.GITHUBAPP && ( @@ -863,9 +834,9 @@ export class ReposList extends React.Component< this.setState({displayEditPanel: true}); } - // Whether url is a http or https url - private isHTTPOrHTTPSUrl(url: string) { - if (url.match(/^https?:\/\/.*$/gi)) { + // Whether url is a https url (simple version) + private isHTTPSUrl(url: string) { + if (url.match(/^https:\/\/.*$/gi)) { return true; } else { return false; @@ -878,7 +849,7 @@ export class ReposList extends React.Component< // only connections of git type which is not via GitHub App are updatable private isRepoUpdatable(repo: models.Repository) { - return this.isHTTPOrHTTPSUrl(repo.repo) && repo.type === 'git' && !repo.githubAppId; + return this.isHTTPSUrl(repo.repo) && repo.type === 'git' && !repo.githubAppId; } // Forces a reload of configured repositories, circumventing the cache @@ -939,15 +910,13 @@ export class ReposList extends React.Component< url: params.url, username: params.username, password: params.password, - bearerToken: params.bearerToken, tlsClientCertData: params.tlsClientCertData, tlsClientCertKey: params.tlsClientCertKey, proxy: params.proxy, noProxy: params.noProxy, forceHttpBasicAuth: params.forceHttpBasicAuth, enableOCI: params.enableOCI, - write: params.write, - useAzureWorkloadIdentity: params.useAzureWorkloadIdentity + write: params.write }); } else { this.setState({connecting: true}); diff --git a/ui/src/app/shared/components/__snapshots__/revision.test.tsx.snap b/ui/src/app/shared/components/__snapshots__/revision.test.tsx.snap index 2a6d520153..ecdc73d972 100644 --- a/ui/src/app/shared/components/__snapshots__/revision.test.tsx.snap +++ b/ui/src/app/shared/components/__snapshots__/revision.test.tsx.snap @@ -7,10 +7,6 @@ exports[`Revision.Branch.Children 1`] = ` target="_blank" > foo - - `; @@ -21,10 +17,6 @@ exports[`Revision.Branch.NoChildren 1`] = ` target="_blank" > long-branch-name - - `; @@ -35,10 +27,6 @@ exports[`Revision.SHA1.Children 1`] = ` target="_blank" > foo - - `; @@ -49,9 +37,5 @@ exports[`Revision.SHA1.NoChildren 1`] = ` target="_blank" > 24eb0b2 - - `; diff --git a/ui/src/app/shared/components/monaco-editor.tsx b/ui/src/app/shared/components/monaco-editor.tsx index 54a403365f..e0a34a06e9 100644 --- a/ui/src/app/shared/components/monaco-editor.tsx +++ b/ui/src/app/shared/components/monaco-editor.tsx @@ -73,7 +73,7 @@ const MonacoEditorLazy = React.lazy(() => ...props.editor.options, scrollBeyondLastLine: props.vScrollBar, scrollbar: { - alwaysConsumeMouseWheel: false, + handleMouseWheel: false, vertical: props.vScrollBar ? 'visible' : 'hidden' } }); diff --git a/ui/src/app/shared/components/progress/__snapshots__/progress-popup.test.tsx.snap b/ui/src/app/shared/components/progress/__snapshots__/progress-popup.test.tsx.snap index 65dab86932..eb7de1552e 100644 --- a/ui/src/app/shared/components/progress/__snapshots__/progress-popup.test.tsx.snap +++ b/ui/src/app/shared/components/progress/__snapshots__/progress-popup.test.tsx.snap @@ -10,11 +10,7 @@ exports[`ProgressPopup.0% 1`] = `
      - - - +
      -
      -
      + />
      @@ -55,7 +47,11 @@ exports[`ProgressPopup.0% 1`] = ` className="row popup-container__footer" >
      @@ -72,11 +68,7 @@ exports[`ProgressPopup.50% 1`] = `
      - - My Title - + My Title
      -
      -
      + />
      @@ -117,7 +105,11 @@ exports[`ProgressPopup.50% 1`] = ` className="row popup-container__footer" >
      @@ -134,11 +126,7 @@ exports[`ProgressPopup.100% 1`] = `
      - - - +
      -
      -
      + />
      @@ -179,7 +163,11 @@ exports[`ProgressPopup.100% 1`] = ` className="row popup-container__footer" >
      {!props.pref.hideSidebar && (
      - context.history.push('/')} - title={'Go to start page'} - src='assets/images/argologo.svg' - alt='Argo' - className='sidebar__logo__text-logo' - /> + Argo
      {loading ? 'Loading...' : error?.state ? 'Unknown' : version?.Version || 'Unknown'}
      )} - context.history.push('/')} title={'Go to start page'} src='assets/images/logo.png' alt='Argo' className='sidebar__logo__character' />{' '} + Argo{' '}
      {(props.navItems || []).map(item => ( diff --git a/ui/yarn.lock b/ui/yarn.lock index 57dfb4c708..79157e17d6 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -1119,10 +1119,33 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript" "^7.7.2" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.21.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.1.tgz#9fce313d12c9a77507f264de74626e87fd0dc541" - integrity sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog== +"@babel/runtime@^7.1.2", "@babel/runtime@^7.8.4": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.17.8": + version "7.26.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.9.tgz#aa4c6facc65b9cb3f87d75125ffd47781b475433" + integrity sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/runtime@^7.21.0": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" + integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== + dependencies: + regenerator-runtime "^0.13.11" + +"@babel/runtime@^7.7.2", "@babel/runtime@^7.8.7": + version "7.20.13" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b" + integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA== + dependencies: + regenerator-runtime "^0.13.11" "@babel/template@^7.14.5", "@babel/template@^7.7.0": version "7.14.5" @@ -1275,131 +1298,6 @@ es-module-lexer "^0.10.5" get-tsconfig "^3.0.1" -"@esbuild/aix-ppc64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz#499600c5e1757a524990d5d92601f0ac3ce87f64" - integrity sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ== - -"@esbuild/android-arm64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz#b9b8231561a1dfb94eb31f4ee056b92a985c324f" - integrity sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g== - -"@esbuild/android-arm@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.0.tgz#ca6e7888942505f13e88ac9f5f7d2a72f9facd2b" - integrity sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g== - -"@esbuild/android-x64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.0.tgz#e765ea753bac442dfc9cb53652ce8bd39d33e163" - integrity sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg== - -"@esbuild/darwin-arm64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz#fa394164b0d89d4fdc3a8a21989af70ef579fa2c" - integrity sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw== - -"@esbuild/darwin-x64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz#91979d98d30ba6e7d69b22c617cc82bdad60e47a" - integrity sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg== - -"@esbuild/freebsd-arm64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz#b97e97073310736b430a07b099d837084b85e9ce" - integrity sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w== - -"@esbuild/freebsd-x64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz#f3b694d0da61d9910ec7deff794d444cfbf3b6e7" - integrity sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A== - -"@esbuild/linux-arm64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz#f921f699f162f332036d5657cad9036f7a993f73" - integrity sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg== - -"@esbuild/linux-arm@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz#cc49305b3c6da317c900688995a4050e6cc91ca3" - integrity sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg== - -"@esbuild/linux-ia32@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz#3e0736fcfab16cff042dec806247e2c76e109e19" - integrity sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg== - -"@esbuild/linux-loong64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz#ea2bf730883cddb9dfb85124232b5a875b8020c7" - integrity sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw== - -"@esbuild/linux-mips64el@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz#4cababb14eede09248980a2d2d8b966464294ff1" - integrity sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ== - -"@esbuild/linux-ppc64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz#8860a4609914c065373a77242e985179658e1951" - integrity sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw== - -"@esbuild/linux-riscv64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz#baf26e20bb2d38cfb86ee282dff840c04f4ed987" - integrity sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA== - -"@esbuild/linux-s390x@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz#8323afc0d6cb1b6dc6e9fd21efd9e1542c3640a4" - integrity sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA== - -"@esbuild/linux-x64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz#08fcf60cb400ed2382e9f8e0f5590bac8810469a" - integrity sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw== - -"@esbuild/netbsd-arm64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz#935c6c74e20f7224918fbe2e6c6fe865b6c6ea5b" - integrity sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw== - -"@esbuild/netbsd-x64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz#414677cef66d16c5a4d210751eb2881bb9c1b62b" - integrity sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA== - -"@esbuild/openbsd-arm64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz#8fd55a4d08d25cdc572844f13c88d678c84d13f7" - integrity sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw== - -"@esbuild/openbsd-x64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz#0c48ddb1494bbc2d6bcbaa1429a7f465fa1dedde" - integrity sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg== - -"@esbuild/sunos-x64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz#86ff9075d77962b60dd26203d7352f92684c8c92" - integrity sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg== - -"@esbuild/win32-arm64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz#849c62327c3229467f5b5cd681bf50588442e96c" - integrity sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw== - -"@esbuild/win32-ia32@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz#f62eb480cd7cca088cb65bb46a6db25b725dc079" - integrity sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA== - -"@esbuild/win32-x64@0.25.0": - version "0.25.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz#c8e119a30a7c8d60b9d2e22d2073722dde3b710b" - integrity sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ== - "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -1407,36 +1305,15 @@ dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.10.0": +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.6.1": version "4.10.0" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== -"@eslint-community/regexpp@^4.12.1": - version "4.12.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" - integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== - -"@eslint/config-array@^0.19.0": - version "0.19.1" - resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.1.tgz#734aaea2c40be22bbb1f2a9dac687c57a6a4c984" - integrity sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA== - dependencies: - "@eslint/object-schema" "^2.1.5" - debug "^4.3.1" - minimatch "^3.1.2" - -"@eslint/core@^0.9.0": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.9.1.tgz#31763847308ef6b7084a4505573ac9402c51f9d1" - integrity sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q== - dependencies: - "@types/json-schema" "^7.0.15" - -"@eslint/eslintrc@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.2.0.tgz#57470ac4e2e283a6bf76044d63281196e370542c" - integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w== +"@eslint/eslintrc@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.0.2.tgz#36180f8e85bf34d2fe3ccc2261e8e204a411ab4e" + integrity sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -1448,28 +1325,11 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.17.0": - version "9.17.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.17.0.tgz#1523e586791f80376a6f8398a3964455ecc651ec" - integrity sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w== - -"@eslint/js@^9.1.1": +"@eslint/js@9.1.1", "@eslint/js@^9.1.1": version "9.1.1" resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.1.1.tgz#eb0f82461d12779bbafc1b5045cde3143d350a8a" integrity sha512-5WoDz3Y19Bg2BnErkZTp0en+c/i9PvgFS7MBe1+m60HjFr0hrphlAGp4yzI7pxpt4xShln4ZyYp4neJm8hmOkQ== -"@eslint/object-schema@^2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.5.tgz#8670a8f6258a2be5b2c620ff314a1d984c23eb2e" - integrity sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ== - -"@eslint/plugin-kit@^0.2.3": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz#2b78e7bb3755784bb13faa8932a1d994d6537792" - integrity sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg== - dependencies: - levn "^0.4.1" - "@exodus/schemasafe@^1.0.0-rc.2": version "1.0.0-rc.3" resolved "https://registry.yarnpkg.com/@exodus/schemasafe/-/schemasafe-1.0.0-rc.3.tgz#dda2fbf3dafa5ad8c63dadff7e01d3fdf4736025" @@ -1480,33 +1340,29 @@ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.2.tgz#310fe90cb5a8dee9698833171b98e7835404293d" integrity sha512-hRILoInAx8GNT5IMkrtIt9blOdrqHOnPBH+k70aWUAqPZPgopb9G5EQJFpaBx/S8zp2fC+mPW349Bziuk1o28Q== -"@humanfs/core@^0.19.1": - version "0.19.1" - resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" - integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== - -"@humanfs/node@^0.16.6": - version "0.16.6" - resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e" - integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== +"@humanwhocodes/config-array@^0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" + integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw== dependencies: - "@humanfs/core" "^0.19.1" - "@humanwhocodes/retry" "^0.3.0" + "@humanwhocodes/object-schema" "^2.0.3" + debug "^4.3.1" + minimatch "^3.0.5" "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/retry@^0.3.0": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a" - integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== +"@humanwhocodes/object-schema@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" + integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== -"@humanwhocodes/retry@^0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b" - integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA== +"@humanwhocodes/retry@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.2.3.tgz#c9aa036d1afa643f1250e83150f39efb3a15a631" + integrity sha512-X38nUbachlb01YMlvPFojKoiXq+LzZvuSce70KPMPdeM1Rj03k4dR7lDslhbqXn3Ang4EU3+EAmwEAsbrjHW3g== "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" @@ -1834,7 +1690,7 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== -"@nodelib/fs.walk@^1.2.3": +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -2037,11 +1893,6 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== -"@types/estree@^1.0.6": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" - integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== - "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": version "4.17.28" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" @@ -2663,11 +2514,6 @@ acorn@^8.1.0, acorn@^8.11.3, acorn@^8.12.1, acorn@^8.4.1, acorn@^8.5.0, acorn@^8 resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== -acorn@^8.14.0: - version "8.14.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" - integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== - add@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/add/-/add-2.0.6.tgz#248f0a9f6e5a528ef2295dbeec30532130ae2235" @@ -2749,6 +2595,11 @@ ansi-html-community@^0.0.8: resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + ansi-regex@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" @@ -2769,6 +2620,11 @@ ansi-regex@^6.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -2811,7 +2667,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#5cf36101733ce43eed57242a12389f2a7e40bd2b" + resolved "git+https://github.com/argoproj/argo-ui.git#d9a4285dc254bc473b9f26f5d72655296233f003" dependencies: "@fortawesome/fontawesome-free" "^6.2.1" "@tippy.js/react" "^3.1.1" @@ -2866,7 +2722,7 @@ array-flatten@^2.1.0: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== -array-includes@^3.1.6, array-includes@^3.1.8: +array-includes@^3.1.6, array-includes@^3.1.7: version "3.1.8" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.8.tgz#5e370cbe172fdd5dd6530c1d4aadda25281ba97d" integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== @@ -2883,7 +2739,7 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array.prototype.findlast@^1.2.5: +array.prototype.findlast@^1.2.4: version "1.2.5" resolved "https://registry.yarnpkg.com/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz#3e4fbcb30a15a7f5bf64cf2faae22d139c2e4904" integrity sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ== @@ -2915,15 +2771,25 @@ array.prototype.flatmap@^1.3.2: es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" -array.prototype.tosorted@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz#fe954678ff53034e717ea3352a03f0b0b86f7ffc" - integrity sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA== +array.prototype.toreversed@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz#b989a6bf35c4c5051e1dc0325151bf8088954eba" + integrity sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA== dependencies: - call-bind "^1.0.7" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.tosorted@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz#c8c89348337e51b8a3c48a9227f9ce93ceedcba8" + integrity sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg== + dependencies: + call-bind "^1.0.5" define-properties "^1.2.1" - es-abstract "^1.23.3" - es-errors "^1.3.0" + es-abstract "^1.22.3" + es-errors "^1.1.0" es-shim-unscopables "^1.0.2" arraybuffer.prototype.slice@^1.0.3: @@ -2940,19 +2806,6 @@ arraybuffer.prototype.slice@^1.0.3: is-array-buffer "^3.0.4" is-shared-array-buffer "^1.0.2" -arraybuffer.prototype.slice@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz#9d760d84dbdd06d0cbf92c8849615a1a7ab3183c" - integrity sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ== - dependencies: - array-buffer-byte-length "^1.0.1" - call-bind "^1.0.8" - define-properties "^1.2.1" - es-abstract "^1.23.5" - es-errors "^1.3.0" - get-intrinsic "^1.2.6" - is-array-buffer "^3.0.4" - asap@^2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -3077,6 +2930,11 @@ batch@0.6.1: resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -3219,14 +3077,6 @@ cacache@^15.0.5: tar "^6.0.2" unique-filename "^1.1.1" -call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz#32e5892e6361b29b0b545ba6f7763378daca2840" - integrity sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -3246,24 +3096,6 @@ call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: get-intrinsic "^1.2.4" set-function-length "^1.2.1" -call-bind@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" - integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== - dependencies: - call-bind-apply-helpers "^1.0.0" - es-define-property "^1.0.0" - get-intrinsic "^1.2.4" - set-function-length "^1.2.2" - -call-bound@^1.0.2, call-bound@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.3.tgz#41cfd032b593e39176a71533ab4f384aa04fd681" - integrity sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA== - dependencies: - call-bind-apply-helpers "^1.0.1" - get-intrinsic "^1.2.6" - call-me-maybe@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" @@ -3305,7 +3137,18 @@ chalk@4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.2: +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -3382,16 +3225,11 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== -classnames@^2.2.5, classnames@^2.2.6: +classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== -classnames@^2.3.2: - version "2.5.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" - integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== - clean-css@^5.2.2: version "5.2.4" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.2.4.tgz#982b058f8581adb2ae062520808fb2429bd487a4" @@ -3534,6 +3372,11 @@ commander@^8.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +common-tags@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" + integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -3658,6 +3501,25 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +cosmiconfig@5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.6.tgz#dca6cf680a0bd03589aff684700858c81abeeb39" + integrity sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ== + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + +cosmiconfig@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" + integrity sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ== + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + require-from-string "^2.0.1" + create-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" @@ -3676,15 +3538,38 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-spawn@^7.0.3, cross-spawn@^7.0.6: - version "7.0.6" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" - integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== +cross-spawn@6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" which "^2.0.1" +css-modules-loader-core@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz#5908668294a1becd261ae0a4ce21b0b551f21d16" + integrity sha1-WQhmgpShvs0mGuCkziGwtVHyHRY= + dependencies: + icss-replace-symbols "1.1.0" + postcss "6.0.1" + postcss-modules-extract-imports "1.1.0" + postcss-modules-local-by-default "1.2.0" + postcss-modules-scope "1.1.0" + postcss-modules-values "1.3.0" + css-select@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067" @@ -3696,11 +3581,24 @@ css-select@^4.1.3: domutils "^2.6.0" nth-check "^2.0.0" +css-selector-tokenizer@^0.7.0: + version "0.7.3" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz#735f26186e67c749aaf275783405cf0661fae8f1" + integrity sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg== + dependencies: + cssesc "^3.0.0" + fastparse "^1.1.2" + css-what@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.0.1.tgz#3efa820131f4669a8ac2408f9c32e7c7de9f4cad" integrity sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg== +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + cssom@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" @@ -4062,15 +3960,6 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" -dunder-proto@^1.0.0, dunder-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" - integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== - dependencies: - call-bind-apply-helpers "^1.0.1" - es-errors "^1.3.0" - gopd "^1.2.0" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -4091,6 +3980,11 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" @@ -4143,61 +4037,7 @@ error-stack-parser@^1.3.6: dependencies: stackframe "^0.3.1" -es-abstract@^1.17.5, es-abstract@^1.23.5, es-abstract@^1.23.6: - version "1.23.6" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.6.tgz#55f0e1ce7128995cc04ace0a57d7dca348345108" - integrity sha512-Ifco6n3yj2tMZDWNLyloZrytt9lqqlwvS83P3HtaETR0NUOYnIULGGHpktqYGObGy+8wc1okO25p8TjemhImvA== - dependencies: - array-buffer-byte-length "^1.0.1" - arraybuffer.prototype.slice "^1.0.4" - available-typed-arrays "^1.0.7" - call-bind "^1.0.8" - call-bound "^1.0.3" - data-view-buffer "^1.0.1" - data-view-byte-length "^1.0.1" - data-view-byte-offset "^1.0.0" - es-define-property "^1.0.1" - es-errors "^1.3.0" - es-object-atoms "^1.0.0" - es-set-tostringtag "^2.0.3" - es-to-primitive "^1.3.0" - function.prototype.name "^1.1.7" - get-intrinsic "^1.2.6" - get-symbol-description "^1.0.2" - globalthis "^1.0.4" - gopd "^1.2.0" - has-property-descriptors "^1.0.2" - has-proto "^1.2.0" - has-symbols "^1.1.0" - hasown "^2.0.2" - internal-slot "^1.1.0" - is-array-buffer "^3.0.4" - is-callable "^1.2.7" - is-data-view "^1.0.2" - is-negative-zero "^2.0.3" - is-regex "^1.2.1" - is-shared-array-buffer "^1.0.3" - is-string "^1.1.1" - is-typed-array "^1.1.13" - is-weakref "^1.1.0" - math-intrinsics "^1.0.0" - object-inspect "^1.13.3" - object-keys "^1.1.1" - object.assign "^4.1.5" - regexp.prototype.flags "^1.5.3" - safe-array-concat "^1.1.3" - safe-regex-test "^1.1.0" - string.prototype.trim "^1.2.10" - string.prototype.trimend "^1.0.9" - string.prototype.trimstart "^1.0.8" - typed-array-buffer "^1.0.2" - typed-array-byte-length "^1.0.1" - typed-array-byte-offset "^1.0.3" - typed-array-length "^1.0.7" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.16" - -es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.2, es-abstract@^1.23.3: +es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.1, es-abstract@^1.23.2, es-abstract@^1.23.3: version "1.23.3" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0" integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== @@ -4256,20 +4096,15 @@ es-define-property@^1.0.0: dependencies: get-intrinsic "^1.2.4" -es-define-property@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" - integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== - -es-errors@^1.2.1, es-errors@^1.3.0: +es-errors@^1.1.0, es-errors@^1.2.1, es-errors@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -es-iterator-helpers@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.2.0.tgz#2f1a3ab998b30cb2d10b195b587c6d9ebdebf152" - integrity sha512-tpxqxncxnpw3c93u8n3VOzACmRFoVmWJqbWXvX/JfKbkhBw1oslgPrUfeSt2psuqyEJFD6N/9lg5i7bsKpoq+Q== +es-iterator-helpers@^1.0.17: + version "1.0.19" + resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz#117003d0e5fec237b4b5c08aded722e0c6d50ca8" + integrity sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw== dependencies: call-bind "^1.0.7" define-properties "^1.2.1" @@ -4278,13 +4113,12 @@ es-iterator-helpers@^1.1.0: es-set-tostringtag "^2.0.3" function-bind "^1.1.2" get-intrinsic "^1.2.4" - globalthis "^1.0.4" - gopd "^1.0.1" + globalthis "^1.0.3" has-property-descriptors "^1.0.2" has-proto "^1.0.3" has-symbols "^1.0.3" internal-slot "^1.0.7" - iterator.prototype "^1.1.3" + iterator.prototype "^1.1.2" safe-array-concat "^1.1.2" es-module-lexer@^0.10.5: @@ -4329,125 +4163,218 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es-to-primitive@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.3.0.tgz#96c89c82cc49fd8794a24835ba3e1ff87f214e18" - integrity sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g== - dependencies: - is-callable "^1.2.7" - is-date-object "^1.0.5" - is-symbol "^1.0.4" - es6-promise@^3.2.1: version "3.3.1" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" integrity sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM= +esbuild-android-64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.27.tgz#b868bbd9955a92309c69df628d8dd1945478b45c" + integrity sha512-LuEd4uPuj/16Y8j6kqy3Z2E9vNY9logfq8Tq+oTE2PZVuNs3M1kj5Qd4O95ee66yDGb3isaOCV7sOLDwtMfGaQ== + esbuild-android-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.38.tgz#5b94a1306df31d55055f64a62ff6b763a47b7f64" integrity sha512-aRFxR3scRKkbmNuGAK+Gee3+yFxkTJO/cx83Dkyzo4CnQl/2zVSurtG6+G86EQIZ+w+VYngVyK7P3HyTBKu3nw== +esbuild-android-arm64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.27.tgz#e7d6430555e8e9c505fd87266bbc709f25f1825c" + integrity sha512-E8Ktwwa6vX8q7QeJmg8yepBYXaee50OdQS3BFtEHKrzbV45H4foMOeEE7uqdjGQZFBap5VAqo7pvjlyA92wznQ== + esbuild-android-arm64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.38.tgz#78acc80773d16007de5219ccce544c036abd50b8" integrity sha512-L2NgQRWuHFI89IIZIlpAcINy9FvBk6xFVZ7xGdOwIm8VyhX1vNCEqUJO3DPSSy945Gzdg98cxtNt8Grv1CsyhA== +esbuild-darwin-64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.27.tgz#4dc7484127564e89b4445c0a560a3cb50b3d68e1" + integrity sha512-czw/kXl/1ZdenPWfw9jDc5iuIYxqUxgQ/Q+hRd4/3udyGGVI31r29LCViN2bAJgGvQkqyLGVcG03PJPEXQ5i2g== + esbuild-darwin-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.38.tgz#e02b1291f629ebdc2aa46fabfacc9aa28ff6aa46" integrity sha512-5JJvgXkX87Pd1Og0u/NJuO7TSqAikAcQQ74gyJ87bqWRVeouky84ICoV4sN6VV53aTW+NE87qLdGY4QA2S7KNA== +esbuild-darwin-arm64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.27.tgz#469e59c665f84a8ed323166624c5e7b9b2d22ac1" + integrity sha512-BEsv2U2U4o672oV8+xpXNxN9bgqRCtddQC6WBh4YhXKDcSZcdNh7+6nS+DM2vu7qWIWNA4JbRG24LUUYXysimQ== + esbuild-darwin-arm64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.38.tgz#01eb6650ec010b18c990e443a6abcca1d71290a9" integrity sha512-eqF+OejMI3mC5Dlo9Kdq/Ilbki9sQBw3QlHW3wjLmsLh+quNfHmGMp3Ly1eWm981iGBMdbtSS9+LRvR2T8B3eQ== +esbuild-freebsd-64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.27.tgz#895df03bf5f87094a56c9a5815bf92e591903d70" + integrity sha512-7FeiFPGBo+ga+kOkDxtPmdPZdayrSzsV9pmfHxcyLKxu+3oTcajeZlOO1y9HW+t5aFZPiv7czOHM4KNd0tNwCA== + esbuild-freebsd-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.38.tgz#790b8786729d4aac7be17648f9ea8e0e16475b5e" integrity sha512-epnPbhZUt93xV5cgeY36ZxPXDsQeO55DppzsIgWM8vgiG/Rz+qYDLmh5ts3e+Ln1wA9dQ+nZmVHw+RjaW3I5Ig== +esbuild-freebsd-arm64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.27.tgz#0b72a41a6b8655e9a8c5608f2ec1afdcf6958441" + integrity sha512-8CK3++foRZJluOWXpllG5zwAVlxtv36NpHfsbWS7TYlD8S+QruXltKlXToc/5ZNzBK++l6rvRKELu/puCLc7jA== + esbuild-freebsd-arm64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.38.tgz#b66340ab28c09c1098e6d9d8ff656db47d7211e6" integrity sha512-/9icXUYJWherhk+y5fjPI5yNUdFPtXHQlwP7/K/zg8t8lQdHVj20SqU9/udQmeUo5pDFHMYzcEFfJqgOVeKNNQ== +esbuild-linux-32@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.27.tgz#43b8ba3803b0bbe7f051869c6a8bf6de1e95de28" + integrity sha512-qhNYIcT+EsYSBClZ5QhLzFzV5iVsP1YsITqblSaztr3+ZJUI+GoK8aXHyzKd7/CKKuK93cxEMJPpfi1dfsOfdw== + esbuild-linux-32@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.38.tgz#7927f950986fd39f0ff319e92839455912b67f70" integrity sha512-QfgfeNHRFvr2XeHFzP8kOZVnal3QvST3A0cgq32ZrHjSMFTdgXhMhmWdKzRXP/PKcfv3e2OW9tT9PpcjNvaq6g== +esbuild-linux-64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.27.tgz#dc8072097327ecfadba1735562824ce8c05dd0bd" + integrity sha512-ESjck9+EsHoTaKWlFKJpPZRN26uiav5gkI16RuI8WBxUdLrrAlYuYSndxxKgEn1csd968BX/8yQZATYf/9+/qg== + esbuild-linux-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.38.tgz#4893d07b229d9cfe34a2b3ce586399e73c3ac519" integrity sha512-uuZHNmqcs+Bj1qiW9k/HZU3FtIHmYiuxZ/6Aa+/KHb/pFKr7R3aVqvxlAudYI9Fw3St0VCPfv7QBpUITSmBR1Q== +esbuild-linux-arm64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.27.tgz#c52b58cbe948426b1559910f521b0a3f396f10b8" + integrity sha512-no6Mi17eV2tHlJnqBHRLekpZ2/VYx+NfGxKcBE/2xOMYwctsanCaXxw4zapvNrGE9X38vefVXLz6YCF8b1EHiQ== + esbuild-linux-arm64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.38.tgz#8442402e37d0b8ae946ac616784d9c1a2041056a" integrity sha512-HlMGZTEsBrXrivr64eZ/EO0NQM8H8DuSENRok9d+Jtvq8hOLzrxfsAT9U94K3KOGk2XgCmkaI2KD8hX7F97lvA== +esbuild-linux-arm@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.27.tgz#df869dbd67d4ee3a04b3c7273b6bd2b233e78a18" + integrity sha512-JnnmgUBdqLQO9hoNZQqNHFWlNpSX82vzB3rYuCJMhtkuaWQEmQz6Lec1UIxJdC38ifEghNTBsF9bbe8dFilnCw== + esbuild-linux-arm@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.38.tgz#d5dbf32d38b7f79be0ec6b5fb2f9251fd9066986" integrity sha512-FiFvQe8J3VKTDXG01JbvoVRXQ0x6UZwyrU4IaLBZeq39Bsbatd94Fuc3F1RGqPF5RbIWW7RvkVQjn79ejzysnA== +esbuild-linux-mips64le@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.27.tgz#a2b646d9df368b01aa970a7b8968be6dd6b01d19" + integrity sha512-NolWP2uOvIJpbwpsDbwfeExZOY1bZNlWE/kVfkzLMsSgqeVcl5YMen/cedRe9mKnpfLli+i0uSp7N+fkKNU27A== + esbuild-linux-mips64le@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.38.tgz#95081e42f698bbe35d8ccee0e3a237594b337eb5" integrity sha512-qd1dLf2v7QBiI5wwfil9j0HG/5YMFBAmMVmdeokbNAMbcg49p25t6IlJFXAeLzogv1AvgaXRXvgFNhScYEUXGQ== +esbuild-linux-ppc64le@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.27.tgz#9a21af766a0292578a3009c7408b8509cac7cefd" + integrity sha512-/7dTjDvXMdRKmsSxKXeWyonuGgblnYDn0MI1xDC7J1VQXny8k1qgNp6VmrlsawwnsymSUUiThhkJsI+rx0taNA== + esbuild-linux-ppc64le@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.38.tgz#dceb0a1b186f5df679618882a7990bd422089b47" integrity sha512-mnbEm7o69gTl60jSuK+nn+pRsRHGtDPfzhrqEUXyCl7CTOCLtWN2bhK8bgsdp6J/2NyS/wHBjs1x8aBWwP2X9Q== +esbuild-linux-riscv64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.27.tgz#344a27f91568056a5903ad5841b447e00e78d740" + integrity sha512-D+aFiUzOJG13RhrSmZgrcFaF4UUHpqj7XSKrIiCXIj1dkIkFqdrmqMSOtSs78dOtObWiOrFCDDzB24UyeEiNGg== + esbuild-linux-riscv64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.38.tgz#61fb8edb75f475f9208c4a93ab2bfab63821afd2" integrity sha512-+p6YKYbuV72uikChRk14FSyNJZ4WfYkffj6Af0/Tw63/6TJX6TnIKE+6D3xtEc7DeDth1fjUOEqm+ApKFXbbVQ== +esbuild-linux-s390x@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.27.tgz#73a7309bd648a07ef58f069658f989a5096130db" + integrity sha512-CD/D4tj0U4UQjELkdNlZhQ8nDHU5rBn6NGp47Hiz0Y7/akAY5i0oGadhEIg0WCY/HYVXFb3CsSPPwaKcTOW3bg== + esbuild-linux-s390x@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.38.tgz#34c7126a4937406bf6a5e69100185fd702d12fe0" integrity sha512-0zUsiDkGJiMHxBQ7JDU8jbaanUY975CdOW1YDrurjrM0vWHfjv9tLQsW9GSyEb/heSK1L5gaweRjzfUVBFoybQ== -esbuild-loader@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esbuild-loader/-/esbuild-loader-4.3.0.tgz#70a19717290cf59c6ac55b26782dbcf84378ccb4" - integrity sha512-D7HeJNdkDKKMarPQO/3dlJT6RwN2YJO7ENU6RPlpOz5YxSHnUNi2yvW41Bckvi1EVwctIaLzlb0ni5ag2GINYA== +esbuild-loader@^2.18.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/esbuild-loader/-/esbuild-loader-2.18.0.tgz#7b9548578ab954574fd94655693d22aa5ec74120" + integrity sha512-AKqxM3bI+gvGPV8o6NAhR+cBxVO8+dh+O0OXBHIXXwuSGumckbPWHzZ17subjBGI2YEGyJ1STH7Haj8aCrwL/w== dependencies: - esbuild "^0.25.0" - get-tsconfig "^4.7.0" - loader-utils "^2.0.4" - webpack-sources "^1.4.3" + esbuild "^0.14.6" + joycon "^3.0.1" + json5 "^2.2.0" + loader-utils "^2.0.0" + tapable "^2.2.0" + webpack-sources "^2.2.0" + +esbuild-netbsd-64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.27.tgz#482a587cdbd18a6c264a05136596927deb46c30a" + integrity sha512-h3mAld69SrO1VoaMpYl3a5FNdGRE/Nqc+E8VtHOag4tyBwhCQXxtvDDOAKOUQexBGca0IuR6UayQ4ntSX5ij1Q== esbuild-netbsd-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.38.tgz#322ea9937d9e529183ee281c7996b93eb38a5d95" integrity sha512-cljBAApVwkpnJZfnRVThpRBGzCi+a+V9Ofb1fVkKhtrPLDYlHLrSYGtmnoTVWDQdU516qYI8+wOgcGZ4XIZh0Q== +esbuild-openbsd-64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.27.tgz#e99f8cdc63f1628747b63edd124d53cf7796468d" + integrity sha512-xwSje6qIZaDHXWoPpIgvL+7fC6WeubHHv18tusLYMwL+Z6bEa4Pbfs5IWDtQdHkArtfxEkIZz77944z8MgDxGw== + esbuild-openbsd-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.38.tgz#1ca29bb7a2bf09592dcc26afdb45108f08a2cdbd" integrity sha512-CDswYr2PWPGEPpLDUO50mL3WO/07EMjnZDNKpmaxUPsrW+kVM3LoAqr/CE8UbzugpEiflYqJsGPLirThRB18IQ== +esbuild-sunos-64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.27.tgz#8611d825bcb8239c78d57452e83253a71942f45c" + integrity sha512-/nBVpWIDjYiyMhuqIqbXXsxBc58cBVH9uztAOIfWShStxq9BNBik92oPQPJ57nzWXRNKQUEFWr4Q98utDWz7jg== + esbuild-sunos-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.38.tgz#c9446f7d8ebf45093e7bb0e7045506a88540019b" integrity sha512-2mfIoYW58gKcC3bck0j7lD3RZkqYA7MmujFYmSn9l6TiIcAMpuEvqksO+ntBgbLep/eyjpgdplF7b+4T9VJGOA== +esbuild-windows-32@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.27.tgz#c06374206d4d92dd31d4fda299b09f51a35e82f6" + integrity sha512-Q9/zEjhZJ4trtWhFWIZvS/7RUzzi8rvkoaS9oiizkHTTKd8UxFwn/Mm2OywsAfYymgUYm8+y2b+BKTNEFxUekw== + esbuild-windows-32@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.38.tgz#f8e9b4602fd0ccbd48e5c8d117ec0ba4040f2ad1" integrity sha512-L2BmEeFZATAvU+FJzJiRLFUP+d9RHN+QXpgaOrs2klshoAm1AE6Us4X6fS9k33Uy5SzScn2TpcgecbqJza1Hjw== +esbuild-windows-64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.27.tgz#756631c1d301dfc0d1a887deed2459ce4079582f" + integrity sha512-b3y3vTSl5aEhWHK66ngtiS/c6byLf6y/ZBvODH1YkBM+MGtVL6jN38FdHUsZasCz9gFwYs/lJMVY9u7GL6wfYg== + esbuild-windows-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.38.tgz#280f58e69f78535f470905ce3e43db1746518107" integrity sha512-Khy4wVmebnzue8aeSXLC+6clo/hRYeNIm0DyikoEqX+3w3rcvrhzpoix0S+MF9vzh6JFskkIGD7Zx47ODJNyCw== +esbuild-windows-arm64@0.14.27: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.27.tgz#ad7e187193dcd18768b16065a950f4441d7173f4" + integrity sha512-I/reTxr6TFMcR5qbIkwRGvldMIaiBu2+MP0LlD7sOlNXrfqIl9uNjsuxFPGEG4IRomjfQ5q8WT+xlF/ySVkqKg== + esbuild-windows-arm64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.38.tgz#d97e9ac0f95a4c236d9173fa9f86c983d6a53f54" @@ -4479,36 +4406,31 @@ esbuild@0.14.38: esbuild-windows-64 "0.14.38" esbuild-windows-arm64 "0.14.38" -esbuild@^0.25.0: - version "0.25.0" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.0.tgz#0de1787a77206c5a79eeb634a623d39b5006ce92" - integrity sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw== +esbuild@^0.14.6: + version "0.14.27" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.27.tgz#41fe0f1b6b68b9f77cac025009bc54bb96e616f1" + integrity sha512-MZQt5SywZS3hA9fXnMhR22dv0oPGh6QtjJRIYbgL1AeqAoQZE+Qn5ppGYQAoHv/vq827flj4tIJ79Mrdiwk46Q== optionalDependencies: - "@esbuild/aix-ppc64" "0.25.0" - "@esbuild/android-arm" "0.25.0" - "@esbuild/android-arm64" "0.25.0" - "@esbuild/android-x64" "0.25.0" - "@esbuild/darwin-arm64" "0.25.0" - "@esbuild/darwin-x64" "0.25.0" - "@esbuild/freebsd-arm64" "0.25.0" - "@esbuild/freebsd-x64" "0.25.0" - "@esbuild/linux-arm" "0.25.0" - "@esbuild/linux-arm64" "0.25.0" - "@esbuild/linux-ia32" "0.25.0" - "@esbuild/linux-loong64" "0.25.0" - "@esbuild/linux-mips64el" "0.25.0" - "@esbuild/linux-ppc64" "0.25.0" - "@esbuild/linux-riscv64" "0.25.0" - "@esbuild/linux-s390x" "0.25.0" - "@esbuild/linux-x64" "0.25.0" - "@esbuild/netbsd-arm64" "0.25.0" - "@esbuild/netbsd-x64" "0.25.0" - "@esbuild/openbsd-arm64" "0.25.0" - "@esbuild/openbsd-x64" "0.25.0" - "@esbuild/sunos-x64" "0.25.0" - "@esbuild/win32-arm64" "0.25.0" - "@esbuild/win32-ia32" "0.25.0" - "@esbuild/win32-x64" "0.25.0" + esbuild-android-64 "0.14.27" + esbuild-android-arm64 "0.14.27" + esbuild-darwin-64 "0.14.27" + esbuild-darwin-arm64 "0.14.27" + esbuild-freebsd-64 "0.14.27" + esbuild-freebsd-arm64 "0.14.27" + esbuild-linux-32 "0.14.27" + esbuild-linux-64 "0.14.27" + esbuild-linux-arm "0.14.27" + esbuild-linux-arm64 "0.14.27" + esbuild-linux-mips64le "0.14.27" + esbuild-linux-ppc64le "0.14.27" + esbuild-linux-riscv64 "0.14.27" + esbuild-linux-s390x "0.14.27" + esbuild-netbsd-64 "0.14.27" + esbuild-openbsd-64 "0.14.27" + esbuild-sunos-64 "0.14.27" + esbuild-windows-32 "0.14.27" + esbuild-windows-64 "0.14.27" + esbuild-windows-arm64 "0.14.27" escalade@^3.1.1: version "3.1.1" @@ -4530,7 +4452,7 @@ escape-html@~1.0.3: resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== -escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -4569,29 +4491,29 @@ eslint-plugin-prettier@^5.1.3: prettier-linter-helpers "^1.0.0" synckit "^0.8.6" -eslint-plugin-react@^7.37.2: - version "7.37.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz#cd0935987876ba2900df2f58339f6d92305acc7a" - integrity sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w== +eslint-plugin-react@^7.34.1: + version "7.34.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz#6806b70c97796f5bbfb235a5d3379ece5f4da997" + integrity sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw== dependencies: - array-includes "^3.1.8" - array.prototype.findlast "^1.2.5" + array-includes "^3.1.7" + array.prototype.findlast "^1.2.4" array.prototype.flatmap "^1.3.2" - array.prototype.tosorted "^1.1.4" + array.prototype.toreversed "^1.1.2" + array.prototype.tosorted "^1.1.3" doctrine "^2.1.0" - es-iterator-helpers "^1.1.0" + es-iterator-helpers "^1.0.17" estraverse "^5.3.0" - hasown "^2.0.2" jsx-ast-utils "^2.4.1 || ^3.0.0" minimatch "^3.1.2" - object.entries "^1.1.8" - object.fromentries "^2.0.8" - object.values "^1.2.0" + object.entries "^1.1.7" + object.fromentries "^2.0.7" + object.hasown "^1.1.3" + object.values "^1.1.7" prop-types "^15.8.1" resolve "^2.0.0-next.5" semver "^6.3.1" - string.prototype.matchall "^4.0.11" - string.prototype.repeat "^1.0.0" + string.prototype.matchall "^4.0.10" eslint-scope@5.1.1: version "5.1.1" @@ -4601,10 +4523,10 @@ eslint-scope@5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.2.0.tgz#377aa6f1cb5dc7592cfd0b7f892fd0cf352ce442" - integrity sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A== +eslint-scope@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.0.1.tgz#a9601e4b81a0b9171657c343fb13111688963cfc" + integrity sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" @@ -4619,37 +4541,28 @@ eslint-visitor-keys@^4.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz#e3adc021aa038a2a8e0b2f8b0ce8f66b9483b1fb" integrity sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw== -eslint-visitor-keys@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" - integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== - -eslint@^9.15.0: - version "9.17.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.17.0.tgz#faa1facb5dd042172fdc520106984b5c2421bb0c" - integrity sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA== +eslint@^9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.1.1.tgz#39ec657ccd12813cb4a1dab2f9229dcc6e468271" + integrity sha512-b4cRQ0BeZcSEzPpY2PjFY70VbO32K7BStTGtBsnIGdTSEEQzBi8hPBcGQmTG2zUvFr9uLe0TK42bw8YszuHEqg== dependencies: "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.12.1" - "@eslint/config-array" "^0.19.0" - "@eslint/core" "^0.9.0" - "@eslint/eslintrc" "^3.2.0" - "@eslint/js" "9.17.0" - "@eslint/plugin-kit" "^0.2.3" - "@humanfs/node" "^0.16.6" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^3.0.2" + "@eslint/js" "9.1.1" + "@humanwhocodes/config-array" "^0.13.0" "@humanwhocodes/module-importer" "^1.0.1" - "@humanwhocodes/retry" "^0.4.1" - "@types/estree" "^1.0.6" - "@types/json-schema" "^7.0.15" + "@humanwhocodes/retry" "^0.2.3" + "@nodelib/fs.walk" "^1.2.8" ajv "^6.12.4" chalk "^4.0.0" - cross-spawn "^7.0.6" + cross-spawn "^7.0.2" debug "^4.3.2" escape-string-regexp "^4.0.0" - eslint-scope "^8.2.0" - eslint-visitor-keys "^4.2.0" - espree "^10.3.0" - esquery "^1.5.0" + eslint-scope "^8.0.1" + eslint-visitor-keys "^4.0.0" + espree "^10.0.1" + esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^8.0.0" @@ -4658,11 +4571,15 @@ eslint@^9.15.0: ignore "^5.2.0" imurmurhash "^0.1.4" is-glob "^4.0.0" + is-path-inside "^3.0.3" json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" lodash.merge "^4.6.2" minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" espree@^10.0.1: version "10.0.1" @@ -4673,24 +4590,15 @@ espree@^10.0.1: acorn-jsx "^5.3.2" eslint-visitor-keys "^4.0.0" -espree@^10.3.0: - version "10.3.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a" - integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== - dependencies: - acorn "^8.14.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^4.2.0" - esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" - integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" @@ -4885,6 +4793,11 @@ fastest-levenshtein@^1.0.12: resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== +fastparse@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" + integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== + fastq@^1.6.0: version "1.11.1" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.1.tgz#5d8175aae17db61947f8b162cfc7f63264d22807" @@ -5070,7 +4983,7 @@ function-bind@^1.1.2: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -function.prototype.name@^1.1.6: +function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== @@ -5080,22 +4993,18 @@ function.prototype.name@^1.1.6: es-abstract "^1.22.1" functions-have-names "^1.2.3" -function.prototype.name@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.7.tgz#9df48ea5f746bf577d7e15b5da89df8952a98e7b" - integrity sha512-2g4x+HqTJKM9zcJqBSpjoRmdcPFtJM60J3xJisTQSXBWka5XqyBN/2tNUgma1mztTXyDuUsEtYe5qcs7xYzYQA== - dependencies: - call-bind "^1.0.8" - define-properties "^1.2.1" - functions-have-names "^1.2.3" - hasown "^2.0.2" - is-callable "^1.2.7" - functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +generic-names@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/generic-names/-/generic-names-1.0.3.tgz#2d786a121aee508876796939e8e3bff836c20917" + integrity sha1-LXhqEhruUIh2eWk56OO/+DbCCRc= + dependencies: + loader-utils "^0.2.16" + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -5126,22 +5035,6 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@ has-symbols "^1.0.3" hasown "^2.0.0" -get-intrinsic@^1.2.5, get-intrinsic@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.6.tgz#43dd3dd0e7b49b82b2dfcad10dc824bf7fc265d5" - integrity sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA== - dependencies: - call-bind-apply-helpers "^1.0.1" - dunder-proto "^1.0.0" - es-define-property "^1.0.1" - es-errors "^1.3.0" - es-object-atoms "^1.0.0" - function-bind "^1.1.2" - gopd "^1.2.0" - has-symbols "^1.1.0" - hasown "^2.0.2" - math-intrinsics "^1.0.0" - get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -5166,13 +5059,6 @@ get-tsconfig@^3.0.1: resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-3.0.1.tgz#02cadb5abc5f0d53033c8b2f3005b84134ba22e9" integrity sha512-+m30eQjbcf3xMNdnacXH5IDAKUMbI7Mhbf3e1BHif1FzBlUhBzBlmOVc7kL4+kB035l8OCyBdI3dNXZ3of9HqA== -get-tsconfig@^4.7.0: - version "4.10.0" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.10.0.tgz#403a682b373a823612475a4c2928c7326fc0f6bb" - integrity sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A== - dependencies: - resolve-pkg-maps "^1.0.0" - git-up@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/git-up/-/git-up-7.0.0.tgz#bace30786e36f56ea341b6f69adfd83286337467" @@ -5242,7 +5128,7 @@ globals@^15.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-15.1.0.tgz#4e03d200c8362201636b8cdfaa316d6cef67ff1e" integrity sha512-926gJqg+4mkxwYKiFvoomM4J0kWESfk3qfTvRL2/oc/tK/eTDBbrfcKnSa2KtfdxB5onoL7D3A3qIHQFpd4+UA== -globalthis@^1.0.3, globalthis@^1.0.4: +globalthis@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== @@ -5281,11 +5167,6 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -gopd@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" - integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== - graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" @@ -5313,11 +5194,23 @@ harmony-reflect@^1.4.6: resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.2.tgz#31ecbd32e648a34d030d86adb67d4d47547fe710" integrity sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g== +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -5340,13 +5233,6 @@ has-proto@^1.0.1, has-proto@^1.0.3: resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== -has-proto@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.2.0.tgz#5de5a6eabd95fdffd9818b43055e8065e39fe9d5" - integrity sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ== - dependencies: - dunder-proto "^1.0.0" - has-symbols@^1.0.1, has-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" @@ -5357,11 +5243,6 @@ has-symbols@^1.0.3: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -has-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" - integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== - has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" @@ -5528,9 +5409,9 @@ http-proxy-agent@^5.0.0: debug "4" http-proxy-middleware@^2.0.0: - version "2.0.9" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz#e9e63d68afaa4eee3d147f39149ab84c0c2815ef" - integrity sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q== + 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" @@ -5595,6 +5476,11 @@ iconv-lite@0.6.3: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +icss-replace-symbols@1.1.0, icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + identity-obj-proxy@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz#94d2bda96084453ef36fbc5aaec37e0f79f1fc14" @@ -5629,6 +5515,13 @@ immutable@^4.0.0: resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23" integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw== +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= + dependencies: + import-from "^2.1.0" + import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -5637,6 +5530,13 @@ import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + integrity sha1-M1238qev/VOqpHHUuAId7ja387E= + dependencies: + resolve-from "^3.0.0" + import-local@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" @@ -5687,15 +5587,6 @@ internal-slot@^1.0.7: hasown "^2.0.0" side-channel "^1.0.4" -internal-slot@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.1.0.tgz#1eac91762947d2f7056bc838d93e13b2e9604961" - integrity sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw== - dependencies: - es-errors "^1.3.0" - hasown "^2.0.2" - side-channel "^1.1.0" - interpret@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" @@ -5762,13 +5653,6 @@ is-bigint@^1.0.1: dependencies: has-bigints "^1.0.1" -is-bigint@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.1.0.tgz#dda7a3445df57a42583db4228682eba7c4170672" - integrity sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ== - dependencies: - has-bigints "^1.0.2" - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -5784,14 +5668,6 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-boolean-object@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.2.1.tgz#c20d0c654be05da4fbc23c562635c019e93daf89" - integrity sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng== - dependencies: - call-bound "^1.0.2" - has-tostringtag "^1.0.2" - is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" @@ -5818,15 +5694,6 @@ is-data-view@^1.0.1: dependencies: is-typed-array "^1.1.13" -is-data-view@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.2.tgz#bae0a41b9688986c2188dda6657e56b8f9e63b8e" - integrity sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw== - dependencies: - call-bound "^1.0.2" - get-intrinsic "^1.2.6" - is-typed-array "^1.1.13" - is-date-object@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" @@ -5839,13 +5706,10 @@ is-date-object@^1.0.5: dependencies: has-tostringtag "^1.0.0" -is-date-object@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.1.0.tgz#ad85541996fc7aa8b2729701d27b7319f95d82f7" - integrity sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg== - dependencies: - call-bound "^1.0.2" - has-tostringtag "^1.0.2" +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" @@ -5857,12 +5721,12 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-finalizationregistry@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz#eefdcdc6c94ddd0674d9c85887bf93f944a97c90" - integrity sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg== +is-finalizationregistry@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz#c8749b65f17c133313e661b1289b95ad3dbd62e6" + integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== dependencies: - call-bound "^1.0.3" + call-bind "^1.0.2" is-fullwidth-code-point@^3.0.0: version "3.0.0" @@ -5912,14 +5776,6 @@ is-number-object@^1.0.4: dependencies: has-tostringtag "^1.0.0" -is-number-object@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.1.1.tgz#144b21e95a1bc148205dcc2814a9134ec41b2541" - integrity sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw== - dependencies: - call-bound "^1.0.3" - has-tostringtag "^1.0.2" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -5930,7 +5786,7 @@ is-path-cwd@^2.2.0: resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== -is-path-inside@^3.0.2: +is-path-inside@^3.0.2, is-path-inside@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== @@ -5968,16 +5824,6 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-regex@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22" - integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g== - dependencies: - call-bound "^1.0.2" - gopd "^1.2.0" - has-tostringtag "^1.0.2" - hasown "^2.0.2" - is-set@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d" @@ -6009,14 +5855,6 @@ is-string@^1.0.5, is-string@^1.0.7: dependencies: has-tostringtag "^1.0.0" -is-string@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.1.1.tgz#92ea3f3d5c5b6e039ca8677e5ac8d07ea773cbb9" - integrity sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA== - dependencies: - call-bound "^1.0.3" - has-tostringtag "^1.0.2" - is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" @@ -6024,15 +5862,6 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-symbol@^1.0.4, is-symbol@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.1.1.tgz#f47761279f532e2b05a7024a7506dbbedacd0634" - integrity sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w== - dependencies: - call-bound "^1.0.2" - has-symbols "^1.1.0" - safe-regex-test "^1.1.0" - is-typed-array@^1.1.13: version "1.1.13" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" @@ -6040,13 +5869,6 @@ is-typed-array@^1.1.13: dependencies: which-typed-array "^1.1.14" -is-typed-array@^1.1.15: - version "1.1.15" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b" - integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ== - dependencies: - which-typed-array "^1.1.16" - is-weakmap@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd" @@ -6059,13 +5881,6 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" -is-weakref@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.1.0.tgz#47e3472ae95a63fa9cf25660bcf0c181c39770ef" - integrity sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q== - dependencies: - call-bound "^1.0.2" - is-weakset@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.3.tgz#e801519df8c0c43e12ff2834eead84ec9e624007" @@ -6159,17 +5974,16 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -iterator.prototype@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.4.tgz#4ae6cf98b97fdc717b7e159d79dc25f8fc9482f1" - integrity sha512-x4WH0BWmrMmg4oHHl+duwubhrvczGlyuGAZu3nvrf0UXOfPu8IhZObFEr7DE/iv01YgVZrsOiRcqw2srkKEDIA== +iterator.prototype@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0" + integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== dependencies: - define-data-property "^1.1.4" - es-object-atoms "^1.0.0" - get-intrinsic "^1.2.6" - has-symbols "^1.1.0" - reflect.getprototypeof "^1.0.8" - set-function-name "^2.0.2" + define-properties "^1.2.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + reflect.getprototypeof "^1.0.4" + set-function-name "^2.0.1" jest-changed-files@^29.7.0: version "29.7.0" @@ -6500,6 +6314,18 @@ jest-snapshot@^29.7.0: pretty-format "^29.7.0" semver "^7.5.3" +jest-transform-css@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jest-transform-css/-/jest-transform-css-2.0.0.tgz#f384ad1922e3726201664c199fd368e657e295d3" + integrity sha512-KV5pD27qUltAVj0mZEVvqd+Ahe+WNPOVWKA1BRpIhBJ5OeUUOM46ivAznJrC5B1JrVNbMzWjPxnKl6QTsAAT3Q== + dependencies: + common-tags "1.8.0" + cosmiconfig "5.0.6" + cross-spawn "6.0.5" + postcss-load-config "2.0.0" + postcss-modules "1.3.2" + style-inject "0.3.0" + jest-util@^29.0.0, jest-util@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" @@ -6579,6 +6405,11 @@ jest@^29.7.0: import-local "^3.0.2" jest-cli "^29.7.0" +joycon@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.0.1.tgz#9074c9b08ccf37a6726ff74a18485f85efcaddaf" + integrity sha512-SJcJNBg32dGgxhPtM0wQqxqV0ax9k/9TaUskGDSJkSFSQOEWWvQ3zzWdGQRIUry2j1zA5+ReH13t0Mf3StuVZA== + js-levenshtein@^1.1.3, js-levenshtein@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" @@ -6589,7 +6420,7 @@ js-levenshtein@^1.1.3, js-levenshtein@^1.1.6: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@3.14.1, js-yaml@^3.13.1: +js-yaml@3.14.1, js-yaml@^3.13.1, js-yaml@^3.9.0: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -6658,6 +6489,11 @@ json-merge-patch@^0.2.3: dependencies: deep-equal "^1.0.0" +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -6685,6 +6521,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + json5@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" @@ -6692,7 +6533,7 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.0, json5@^2.1.2: +json5@^2.1.0, json5@^2.1.2, json5@^2.2.0: version "2.2.2" resolved "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz#64471c5bdcc564c18f7c1d4df2e2297f2457c5ab" integrity sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ== @@ -6752,6 +6593,16 @@ loader-runner@^4.2.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== +loader-utils@^0.2.16: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + loader-utils@^1.0.2, loader-utils@^1.1.0: version "1.4.2" resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" @@ -6761,7 +6612,7 @@ loader-utils@^1.0.2, loader-utils@^1.1.0: emojis-list "^3.0.0" json5 "^1.0.1" -loader-utils@^2.0.0, loader-utils@^2.0.2, loader-utils@^2.0.4: +loader-utils@^2.0.0, loader-utils@^2.0.2: version "2.0.4" resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== @@ -6797,6 +6648,11 @@ lodash-es@^4.17.21, lodash-es@^4.2.1: resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -6882,11 +6738,6 @@ marked@^4.3.0: resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== -math-intrinsics@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" - integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -6971,7 +6822,7 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@^3.0.4, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -7129,6 +6980,11 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + no-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" @@ -7263,11 +7119,6 @@ object-inspect@^1.13.1: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== -object-inspect@^1.13.3: - version "1.13.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.3.tgz#f14c183de51130243d6d18ae149375ff50ea488a" - integrity sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA== - object-inspect@^1.9.0: version "1.12.2" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" @@ -7306,7 +7157,7 @@ object.assign@^4.1.4, object.assign@^4.1.5: has-symbols "^1.0.3" object-keys "^1.1.1" -object.entries@^1.1.8: +object.entries@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.8.tgz#bffe6f282e01f4d17807204a24f8edd823599c41" integrity sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ== @@ -7315,7 +7166,7 @@ object.entries@^1.1.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -object.fromentries@^2.0.8: +object.fromentries@^2.0.7: version "2.0.8" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== @@ -7325,7 +7176,16 @@ object.fromentries@^2.0.8: es-abstract "^1.23.2" es-object-atoms "^1.0.0" -object.values@^1.1.6: +object.hasown@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.4.tgz#e270ae377e4c120cdcb7656ce66884a6218283dc" + integrity sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg== + dependencies: + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + +object.values@^1.1.6, object.values@^1.1.7: version "1.2.0" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.0.tgz#65405a9d92cee68ac2d303002e0b8470a4d9ab1b" integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== @@ -7334,16 +7194,6 @@ object.values@^1.1.6: define-properties "^1.2.1" es-object-atoms "^1.0.0" -object.values@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.1.tgz#deed520a50809ff7f75a7cfd4bc64c7a038c6216" - integrity sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.3" - define-properties "^1.2.1" - es-object-atoms "^1.0.0" - obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" @@ -7475,6 +7325,14 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -7539,6 +7397,11 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" @@ -7654,6 +7517,83 @@ possible-typed-array-names@^1.0.0: resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== +postcss-load-config@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.0.0.tgz#f1312ddbf5912cd747177083c5ef7a19d62ee484" + integrity sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ== + dependencies: + cosmiconfig "^4.0.0" + import-cwd "^2.0.0" + +postcss-modules-extract-imports@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz#b614c9720be6816eaee35fb3a5faa1dba6a05ddb" + integrity sha1-thTJcgvmgW6u41+zpfqh26agXds= + dependencies: + postcss "^6.0.1" + +postcss-modules-local-by-default@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" + integrity sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + +postcss-modules-scope@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" + integrity sha1-1upkmUx5+XtipytCb75gVqGUu5A= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + +postcss-modules-values@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" + integrity sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA= + dependencies: + icss-replace-symbols "^1.1.0" + postcss "^6.0.1" + +postcss-modules@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/postcss-modules/-/postcss-modules-1.3.2.tgz#0a616b84387f1f60dd28a01f597687e85b7b8481" + integrity sha512-QujH5ZpPtr1fBWTKDa43Hx45gm7p19aEtHaAtkMCBZZiB/D5za2wXSMtAf94tDUZHF3F5KZcTXISUNqgEQRiDw== + dependencies: + css-modules-loader-core "^1.1.0" + generic-names "^1.0.3" + lodash.camelcase "^4.3.0" + postcss "^7.0.1" + string-hash "^1.1.1" + +postcss@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.1.tgz#000dbd1f8eef217aa368b9a212c5fc40b2a8f3f2" + integrity sha1-AA29H47vIXqjaLmiEsX8QLKo8/I= + dependencies: + chalk "^1.1.3" + source-map "^0.5.6" + supports-color "^3.2.3" + +postcss@^6.0.1: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + +postcss@^7.0.1: + version "7.0.36" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.36.tgz#056f8cffa939662a8f5905950c07d5285644dfcb" + integrity sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + postcss@^8.4.38: version "8.4.38" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" @@ -7708,9 +7648,9 @@ pretty-format@^29.0.0, pretty-format@^29.7.0: react-is "^18.0.0" prismjs@^1.29.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.30.0.tgz#d9709969d9d4e16403f6f348c63553b19f0975a9" - integrity sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw== + version "1.29.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" + integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== process-nextick-args@~2.0.0: version "2.0.1" @@ -8149,19 +8089,18 @@ redux@^3.7.2: loose-envify "^1.1.0" symbol-observable "^1.0.3" -reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.8, reflect.getprototypeof@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.9.tgz#c905f3386008de95a62315f3ea8630404be19e2f" - integrity sha512-r0Ay04Snci87djAsI4U+WNRcSw5S4pOH7qFjd/veA5gC7TbqESR3tcj28ia95L/fYUDw11JKP7uqUKUAfVvV5Q== +reflect.getprototypeof@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz#3ab04c32a8390b770712b7a8633972702d278859" + integrity sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg== dependencies: - call-bind "^1.0.8" + call-bind "^1.0.7" define-properties "^1.2.1" - dunder-proto "^1.0.1" - es-abstract "^1.23.6" + es-abstract "^1.23.1" es-errors "^1.3.0" - get-intrinsic "^1.2.6" - gopd "^1.2.0" - which-builtin-type "^1.2.1" + get-intrinsic "^1.2.4" + globalthis "^1.0.3" + which-builtin-type "^1.1.3" reftools@^1.1.9: version "1.1.9" @@ -8185,6 +8124,21 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + +regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + regenerator-transform@^0.14.2: version "0.14.5" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" @@ -8210,16 +8164,6 @@ regexp.prototype.flags@^1.5.2: es-errors "^1.3.0" set-function-name "^2.0.1" -regexp.prototype.flags@^1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz#b3ae40b1d2499b8350ab2c3fe6ef3845d3a96f42" - integrity sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-errors "^1.3.0" - set-function-name "^2.0.2" - regexpu-core@^4.7.1: version "4.7.1" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" @@ -8265,7 +8209,7 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-from-string@^2.0.2: +require-from-string@^2.0.1, require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== @@ -8282,6 +8226,11 @@ resolve-cwd@^3.0.0: dependencies: resolve-from "^5.0.0" +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -8297,11 +8246,6 @@ resolve-pathname@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== -resolve-pkg-maps@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" - integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== - resolve.exports@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" @@ -8373,17 +8317,6 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" -safe-array-concat@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz#c9e54ec4f603b0bbb8e7e5007a5ee7aecd1538c3" - integrity sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.2" - get-intrinsic "^1.2.6" - has-symbols "^1.1.0" - isarray "^2.0.5" - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -8403,15 +8336,6 @@ safe-regex-test@^1.0.3: es-errors "^1.3.0" is-regex "^1.1.4" -safe-regex-test@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1" - integrity sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - is-regex "^1.2.1" - "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -8613,7 +8537,7 @@ serve-static@1.16.0: parseurl "~1.3.3" send "0.18.0" -set-function-length@^1.2.1, set-function-length@^1.2.2: +set-function-length@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== @@ -8657,6 +8581,13 @@ shallow-equal@^1.2.1: resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da" integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA== +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -8664,6 +8595,11 @@ shebang-command@^2.0.0: dependencies: shebang-regex "^3.0.0" +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + shebang-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" @@ -8713,35 +8649,6 @@ should@^13.2.1: should-type-adaptors "^1.0.1" should-util "^1.0.0" -side-channel-list@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" - integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== - dependencies: - es-errors "^1.3.0" - object-inspect "^1.13.3" - -side-channel-map@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" - integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - get-intrinsic "^1.2.5" - object-inspect "^1.13.3" - -side-channel-weakmap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" - integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - get-intrinsic "^1.2.5" - object-inspect "^1.13.3" - side-channel-map "^1.0.1" - side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -8761,17 +8668,6 @@ side-channel@^1.0.6: get-intrinsic "^1.2.4" object-inspect "^1.13.1" -side-channel@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" - integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== - dependencies: - es-errors "^1.3.0" - object-inspect "^1.13.3" - side-channel-list "^1.0.0" - side-channel-map "^1.0.1" - side-channel-weakmap "^1.0.2" - signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -8808,7 +8704,7 @@ sockjs@^0.3.21: uuid "^8.3.2" websocket-driver "^0.7.4" -source-list-map@^2.0.0: +source-list-map@^2.0.0, source-list-map@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== @@ -8847,7 +8743,7 @@ source-map@0.5.6: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= -source-map@^0.5.0: +source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -8933,6 +8829,11 @@ stream-events@^1.0.5: dependencies: stubs "^3.0.0" +string-hash@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" + integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs= + string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -8959,7 +8860,7 @@ string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string.prototype.matchall@^4.0.11: +string.prototype.matchall@^4.0.10: version "4.0.11" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz#1092a72c59268d2abaad76582dccc687c0297e0a" integrity sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg== @@ -8977,27 +8878,6 @@ string.prototype.matchall@^4.0.11: set-function-name "^2.0.2" side-channel "^1.0.6" -string.prototype.repeat@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz#e90872ee0308b29435aa26275f6e1b762daee01a" - integrity sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string.prototype.trim@^1.2.10: - version "1.2.10" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz#40b2dd5ee94c959b4dcfb1d65ce72e90da480c81" - integrity sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.2" - define-data-property "^1.1.4" - define-properties "^1.2.1" - es-abstract "^1.23.5" - es-object-atoms "^1.0.0" - has-property-descriptors "^1.0.2" - string.prototype.trim@^1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4" @@ -9017,16 +8897,6 @@ string.prototype.trimend@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -string.prototype.trimend@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz#62e2731272cd285041b36596054e9f66569b6942" - integrity sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.2" - define-properties "^1.2.1" - es-object-atoms "^1.0.0" - string.prototype.trimstart@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" @@ -9043,6 +8913,13 @@ string_decoder@^1.1.1, string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -9096,6 +8973,11 @@ stubs@^3.0.0: resolved "https://registry.yarnpkg.com/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b" integrity sha1-6NK6H6nJBXAwPAMLaQD31fiavls= +style-inject@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/style-inject/-/style-inject-0.3.0.tgz#d21c477affec91811cc82355832a700d22bf8dd3" + integrity sha512-IezA2qp+vcdlhJaVm5SOdPPTUu0FCEqfNSli2vRuSIBbu5Nq5UvygTk/VzeCqfLz2Atj3dVII5QBKGZRZ0edzw== + style-loader@^0.20.1: version "0.20.3" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.20.3.tgz#ebef06b89dec491bcb1fdb3452e913a6fd1c10c4" @@ -9120,13 +9002,32 @@ superagent@^8.1.2: qs "^6.11.0" semver "^7.3.8" -supports-color@^5.3.0: +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -9249,6 +9150,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + thunky@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" @@ -9441,19 +9347,6 @@ typed-array-byte-offset@^1.0.2: has-proto "^1.0.3" is-typed-array "^1.1.13" -typed-array-byte-offset@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz#ae3698b8ec91a8ab945016108aef00d5bff12355" - integrity sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ== - dependencies: - available-typed-arrays "^1.0.7" - call-bind "^1.0.8" - for-each "^0.3.3" - gopd "^1.2.0" - has-proto "^1.2.0" - is-typed-array "^1.1.15" - reflect.getprototypeof "^1.0.9" - typed-array-length@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.6.tgz#57155207c76e64a3457482dfdc1c9d1d3c4c73a3" @@ -9466,18 +9359,6 @@ typed-array-length@^1.0.6: is-typed-array "^1.1.13" possible-typed-array-names "^1.0.0" -typed-array-length@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.7.tgz#ee4deff984b64be1e118b0de8c9c877d5ce73d3d" - integrity sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg== - dependencies: - call-bind "^1.0.7" - for-each "^0.3.3" - gopd "^1.0.1" - is-typed-array "^1.1.13" - possible-typed-array-names "^1.0.0" - reflect.getprototypeof "^1.0.6" - typescript-eslint@^7.8.0: version "7.8.0" resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-7.8.0.tgz#d2a73d4caac35d4d9825bfdfac06a9bf2ba175e4" @@ -9807,6 +9688,14 @@ webpack-sources@^1.4.3: source-list-map "^2.0.0" source-map "~0.6.1" +webpack-sources@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.1.tgz#570de0af163949fe272233c2cefe1b56f74511fd" + integrity sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA== + dependencies: + source-list-map "^2.0.1" + source-map "^0.6.1" + webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" @@ -9906,37 +9795,25 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which-boxed-primitive@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz#d76ec27df7fa165f18d5808374a5fe23c29b176e" - integrity sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA== +which-builtin-type@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.3.tgz#b1b8443707cc58b6e9bf98d32110ff0c2cbd029b" + integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== dependencies: - is-bigint "^1.1.0" - is-boolean-object "^1.2.1" - is-number-object "^1.1.1" - is-string "^1.1.1" - is-symbol "^1.1.1" - -which-builtin-type@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.2.1.tgz#89183da1b4907ab089a6b02029cc5d8d6574270e" - integrity sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q== - dependencies: - call-bound "^1.0.2" - function.prototype.name "^1.1.6" - has-tostringtag "^1.0.2" + function.prototype.name "^1.1.5" + has-tostringtag "^1.0.0" is-async-function "^2.0.0" - is-date-object "^1.1.0" - is-finalizationregistry "^1.1.0" + is-date-object "^1.0.5" + is-finalizationregistry "^1.0.2" is-generator-function "^1.0.10" - is-regex "^1.2.1" + is-regex "^1.1.4" is-weakref "^1.0.2" isarray "^2.0.5" - which-boxed-primitive "^1.1.0" - which-collection "^1.0.2" - which-typed-array "^1.1.16" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" -which-collection@^1.0.2: +which-collection@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.2.tgz#627ef76243920a107e7ce8e96191debe4b16c2a0" integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== @@ -9946,7 +9823,7 @@ which-collection@^1.0.2: is-weakmap "^2.0.2" is-weakset "^2.0.3" -which-typed-array@^1.1.14, which-typed-array@^1.1.15: +which-typed-array@^1.1.14, which-typed-array@^1.1.15, which-typed-array@^1.1.9: version "1.1.15" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== @@ -9957,17 +9834,12 @@ which-typed-array@^1.1.14, which-typed-array@^1.1.15: gopd "^1.0.1" has-tostringtag "^1.0.2" -which-typed-array@^1.1.16: - version "1.1.18" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.18.tgz#df2389ebf3fbb246a71390e90730a9edb6ce17ad" - integrity sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA== +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: - available-typed-arrays "^1.0.7" - call-bind "^1.0.8" - call-bound "^1.0.3" - for-each "^0.3.3" - gopd "^1.2.0" - has-tostringtag "^1.0.2" + isexe "^2.0.0" which@^2.0.1: version "2.0.2" diff --git a/util/app/discovery/discovery.go b/util/app/discovery/discovery.go index 8c734bc308..9f477e3a35 100644 --- a/util/app/discovery/discovery.go +++ b/util/app/discovery/discovery.go @@ -2,7 +2,6 @@ package discovery import ( "context" - "errors" "fmt" "os" "path/filepath" @@ -10,17 +9,17 @@ import ( "github.com/golang/protobuf/ptypes/empty" - "github.com/argoproj/argo-cd/v3/util/io/files" + "github.com/argoproj/argo-cd/v2/util/io/files" - grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/retry" + grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry" log "github.com/sirupsen/logrus" - pluginclient "github.com/argoproj/argo-cd/v3/cmpserver/apiclient" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/cmp" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/kustomize" + pluginclient "github.com/argoproj/argo-cd/v2/cmpserver/apiclient" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cmp" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/kustomize" ) func IsManifestGenerationEnabled(sourceType v1alpha1.ApplicationSourceType, enableGenerateManifests map[string]bool) bool { @@ -41,7 +40,7 @@ func Discover(ctx context.Context, appPath, repoPath string, enableGenerateManif conn, _, err := DetectConfigManagementPlugin(ctx, appPath, repoPath, "", env, tarExcludedGlobs) if err == nil { // Found CMP - utilio.Close(conn) + io.Close(conn) apps["."] = string(v1alpha1.ApplicationSourceTypePlugin) return apps, nil @@ -88,8 +87,8 @@ func AppType(ctx context.Context, appPath, repoPath string, enableGenerateManife // check cmpSupports() // if supported return conn for the cmp-server -func DetectConfigManagementPlugin(ctx context.Context, appPath, repoPath, pluginName string, env []string, tarExcludedGlobs []string) (utilio.Closer, pluginclient.ConfigManagementPluginServiceClient, error) { - var conn utilio.Closer +func DetectConfigManagementPlugin(ctx context.Context, appPath, repoPath, pluginName string, env []string, tarExcludedGlobs []string) (io.Closer, pluginclient.ConfigManagementPluginServiceClient, error) { + var conn io.Closer var cmpClient pluginclient.ConfigManagementPluginServiceClient var connFound bool @@ -108,7 +107,7 @@ func DetectConfigManagementPlugin(ctx context.Context, appPath, repoPath, plugin } else { fileList, err := os.ReadDir(pluginSockFilePath) if err != nil { - return nil, nil, fmt.Errorf("failed to list all plugins in dir: %w", err) + return nil, nil, fmt.Errorf("Failed to list all plugins in dir, error=%w", err) } for _, file := range fileList { if file.Type() == os.ModeSocket { @@ -119,7 +118,7 @@ func DetectConfigManagementPlugin(ctx context.Context, appPath, repoPath, plugin } } if !connFound { - return nil, nil, errors.New("could not find plugin supporting the given repository") + return nil, nil, fmt.Errorf("could not find plugin supporting the given repository") } } return conn, cmpClient, nil @@ -145,7 +144,7 @@ func matchRepositoryCMP(ctx context.Context, appPath, repoPath string, client pl return resp.GetIsSupported(), resp.GetIsDiscoveryEnabled(), nil } -func cmpSupports(ctx context.Context, pluginSockFilePath, appPath, repoPath, fileName string, env []string, tarExcludedGlobs []string, namedPlugin bool) (utilio.Closer, pluginclient.ConfigManagementPluginServiceClient, bool) { +func cmpSupports(ctx context.Context, pluginSockFilePath, appPath, repoPath, fileName string, env []string, tarExcludedGlobs []string, namedPlugin bool) (io.Closer, pluginclient.ConfigManagementPluginServiceClient, bool) { absPluginSockFilePath, err := filepath.Abs(pluginSockFilePath) if err != nil { log.Errorf("error getting absolute path for plugin socket dir %v, %v", pluginSockFilePath, err) @@ -171,7 +170,7 @@ func cmpSupports(ctx context.Context, pluginSockFilePath, appPath, repoPath, fil cfg, err := cmpClient.CheckPluginConfiguration(ctx, &empty.Empty{}) if err != nil { log.Errorf("error checking plugin configuration %s, %v", fileName, err) - utilio.Close(conn) + io.Close(conn) return nil, nil, false } @@ -180,7 +179,7 @@ func cmpSupports(ctx context.Context, pluginSockFilePath, appPath, repoPath, fil if namedPlugin { return conn, cmpClient, true } - utilio.Close(conn) + io.Close(conn) return nil, nil, false } @@ -190,7 +189,7 @@ func cmpSupports(ctx context.Context, pluginSockFilePath, appPath, repoPath, fil common.SecurityField: common.SecurityMedium, common.SecurityCWEField: common.SecurityCWEMissingReleaseOfFileDescriptor, }).Errorf("repository %s is not the match because %v", repoPath, err) - utilio.Close(conn) + io.Close(conn) return nil, nil, false } @@ -203,7 +202,7 @@ func cmpSupports(ctx context.Context, pluginSockFilePath, appPath, repoPath, fil common.SecurityField: common.SecurityLow, common.SecurityCWEField: common.SecurityCWEMissingReleaseOfFileDescriptor, }).Debugf("Response from socket file %s does not support %v", fileName, repoPath) - utilio.Close(conn) + io.Close(conn) return nil, nil, false } return conn, cmpClient, true diff --git a/util/app/discovery/discovery_test.go b/util/app/discovery/discovery_test.go index 82d0b4a737..c8340847e7 100644 --- a/util/app/discovery/discovery_test.go +++ b/util/app/discovery/discovery_test.go @@ -1,16 +1,17 @@ package discovery import ( + "context" "testing" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestDiscover(t *testing.T) { - apps, err := Discover(t.Context(), "./testdata", "./testdata", map[string]bool{}, []string{}, []string{}) + apps, err := Discover(context.Background(), "./testdata", "./testdata", map[string]bool{}, []string{}, []string{}) require.NoError(t, err) assert.Equal(t, map[string]string{ "foo": "Kustomize", @@ -19,15 +20,15 @@ func TestDiscover(t *testing.T) { } func TestAppType(t *testing.T) { - appType, err := AppType(t.Context(), "./testdata/foo", "./testdata", map[string]bool{}, []string{}, []string{}) + appType, err := AppType(context.Background(), "./testdata/foo", "./testdata", map[string]bool{}, []string{}, []string{}) require.NoError(t, err) assert.Equal(t, "Kustomize", appType) - appType, err = AppType(t.Context(), "./testdata/baz", "./testdata", map[string]bool{}, []string{}, []string{}) + appType, err = AppType(context.Background(), "./testdata/baz", "./testdata", map[string]bool{}, []string{}, []string{}) require.NoError(t, err) assert.Equal(t, "Helm", appType) - appType, err = AppType(t.Context(), "./testdata", "./testdata", map[string]bool{}, []string{}, []string{}) + appType, err = AppType(context.Background(), "./testdata", "./testdata", map[string]bool{}, []string{}, []string{}) require.NoError(t, err) assert.Equal(t, "Directory", appType) } @@ -37,15 +38,15 @@ func TestAppType_Disabled(t *testing.T) { string(v1alpha1.ApplicationSourceTypeKustomize): false, string(v1alpha1.ApplicationSourceTypeHelm): false, } - appType, err := AppType(t.Context(), "./testdata/foo", "./testdata", enableManifestGeneration, []string{}, []string{}) + appType, err := AppType(context.Background(), "./testdata/foo", "./testdata", enableManifestGeneration, []string{}, []string{}) require.NoError(t, err) assert.Equal(t, "Directory", appType) - appType, err = AppType(t.Context(), "./testdata/baz", "./testdata", enableManifestGeneration, []string{}, []string{}) + appType, err = AppType(context.Background(), "./testdata/baz", "./testdata", enableManifestGeneration, []string{}, []string{}) require.NoError(t, err) assert.Equal(t, "Directory", appType) - appType, err = AppType(t.Context(), "./testdata", "./testdata", enableManifestGeneration, []string{}, []string{}) + appType, err = AppType(context.Background(), "./testdata", "./testdata", enableManifestGeneration, []string{}, []string{}) require.NoError(t, err) assert.Equal(t, "Directory", appType) } diff --git a/util/app/log/log.go b/util/app/log/log.go deleted file mode 100644 index 819d317e5e..0000000000 --- a/util/app/log/log.go +++ /dev/null @@ -1,15 +0,0 @@ -package log - -import ( - log "github.com/sirupsen/logrus" - - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" -) - -func GetAppLogFields(app *appv1.Application) log.Fields { - return log.Fields{ - "application": app.Name, - "app-namespace": app.Namespace, - "project": app.Spec.Project, - } -} diff --git a/util/app/path/path.go b/util/app/path/path.go index d43622c8d3..66f4fe1c02 100644 --- a/util/app/path/path.go +++ b/util/app/path/path.go @@ -7,9 +7,9 @@ import ( "path/filepath" "strings" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/io/files" - "github.com/argoproj/argo-cd/v3/util/security" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/io/files" + "github.com/argoproj/argo-cd/v2/util/security" ) func Path(root, path string) (string, error) { diff --git a/util/app/path/path_test.go b/util/app/path/path_test.go index 2490361c53..5e75c4345f 100644 --- a/util/app/path/path_test.go +++ b/util/app/path/path_test.go @@ -10,8 +10,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - fileutil "github.com/argoproj/argo-cd/v3/test/fixture/path" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + fileutil "github.com/argoproj/argo-cd/v2/test/fixture/path" ) func TestPathRoot(t *testing.T) { @@ -86,15 +86,9 @@ func TestBadSymlinks3(t *testing.T) { // No absolute symlinks allowed func TestAbsSymlink(t *testing.T) { const testDir = "./testdata/abslink" - wd, err := os.Getwd() - require.NoError(t, err) - t.Cleanup(func() { - os.Remove(path.Join(testDir, "abslink")) - }) - t.Chdir(testDir) - require.NoError(t, fileutil.CreateSymlink(t, "/somethingbad", "abslink")) - t.Chdir(wd) - err = CheckOutOfBoundsSymlinks(testDir) + require.NoError(t, fileutil.CreateSymlink(t, testDir, "/somethingbad", "abslink")) + defer os.Remove(path.Join(testDir, "abslink")) + err := CheckOutOfBoundsSymlinks(testDir) var oobError *OutOfBoundsSymlinkError require.ErrorAs(t, err, &oobError) assert.Equal(t, "abslink", oobError.File) @@ -185,7 +179,9 @@ func Test_AppFilesHaveChanged(t *testing.T) { t.Run(ttc.name, func(t *testing.T) { t.Parallel() refreshPaths := GetAppRefreshPaths(ttc.app) - assert.Equal(t, ttc.changeExpected, AppFilesHaveChanged(refreshPaths, ttc.files), "AppFilesHaveChanged()") + if got := AppFilesHaveChanged(refreshPaths, ttc.files); got != ttc.changeExpected { + t.Errorf("AppFilesHaveChanged() = %v, want %v", got, ttc.changeExpected) + } }) } } @@ -210,7 +206,9 @@ func Test_GetAppRefreshPaths(t *testing.T) { ttc := tt t.Run(ttc.name, func(t *testing.T) { t.Parallel() - assert.ElementsMatch(t, ttc.expectedPaths, GetAppRefreshPaths(ttc.app), "GetAppRefreshPath()") + if got := GetAppRefreshPaths(ttc.app); !assert.ElementsMatch(t, ttc.expectedPaths, got) { + t.Errorf("GetAppRefreshPath() = %v, want %v", got, ttc.expectedPaths) + } }) } } diff --git a/util/argo/argo.go b/util/argo/argo.go index 15ab607970..90bf1c8099 100644 --- a/util/argo/argo.go +++ b/util/argo/argo.go @@ -3,7 +3,6 @@ package argo import ( "context" "encoding/json" - "errors" "fmt" "regexp" "sort" @@ -13,30 +12,28 @@ import ( "github.com/argoproj/gitops-engine/pkg/cache" "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/argoproj/gitops-engine/pkg/utils/kube" - "github.com/r3labs/diff/v3" + "github.com/r3labs/diff" log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - apierrors "k8s.io/apimachinery/pkg/api/errors" + apierr "k8s.io/apimachinery/pkg/api/errors" apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" - "github.com/argoproj/argo-cd/v3/util/gpg" - - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1" - applicationsv1 "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/glob" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/settings" + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1" + applicationsv1 "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/glob" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( - ErrDestinationMissing = "Destination server missing from app spec" + errDestinationMissing = "Destination server missing from app spec" ) var ErrAnotherOperationInProgress = status.Errorf(codes.FailedPrecondition, "another operation is already in progress") @@ -58,7 +55,7 @@ func AugmentSyncMsg(res common.ResourceSyncResult, apiResourceInfoGetter func() default: // Check if the message contains "metadata.annotation: Too long" if strings.Contains(res.Message, "metadata.annotations: Too long: must have at most 262144 bytes") { - res.Message = res.Message + " \n -Additional Info: This error usually means that you are trying to add a large resource on client side. Consider using Server-side apply or syncing with replace enabled. Note: Syncing with Replace enabled is potentially destructive as it may cause resource deletion and re-creation." + res.Message = fmt.Sprintf("%s \n -Additional Info: This error usually means that you are trying to add a large resource on client side. Consider using Server-side apply or syncing with replace enabled. Note: Syncing with Replace enabled is potentially destructive as it may cause resource deletion and re-creation.", res.Message) } } @@ -68,8 +65,8 @@ func AugmentSyncMsg(res common.ResourceSyncResult, apiResourceInfoGetter func() // getAPIResourceInfo gets Kubernetes API resource info for the given group and kind. If there's a matching resource // group _and_ kind, it will return the resource info. If there's a matching kind but no matching group, it will // return the first resource info that matches the kind. If there's no matching kind, it will return nil. -func getAPIResourceInfo(group, kind string, getAPIResourceInfo func() ([]kube.APIResourceInfo, error)) (*kube.APIResourceInfo, error) { - apiResources, err := getAPIResourceInfo() +func getAPIResourceInfo(group, kind string, getApiResourceInfo func() ([]kube.APIResourceInfo, error)) (*kube.APIResourceInfo, error) { + apiResources, err := getApiResourceInfo() if err != nil { return nil, fmt.Errorf("failed to get API resource info: %w", err) } @@ -230,15 +227,15 @@ func FilterByNameP(apps []*argoappv1.Application, name string) []*argoappv1.Appl // RefreshApp updates the refresh annotation of an application to coerce the controller to process it func RefreshApp(appIf v1alpha1.ApplicationInterface, name string, refreshType argoappv1.RefreshType, hydrate bool) (*argoappv1.Application, error) { - metadata := map[string]any{ - "metadata": map[string]any{ + metadata := map[string]interface{}{ + "metadata": map[string]interface{}{ "annotations": map[string]string{ argoappv1.AnnotationKeyRefresh: string(refreshType), }, }, } if hydrate { - metadata["metadata"].(map[string]any)["annotations"].(map[string]string)[argoappv1.AnnotationKeyHydrate] = string(argoappv1.HydrateTypeNormal) + metadata["metadata"].(map[string]interface{})["annotations"].(map[string]string)[argoappv1.AnnotationKeyHydrate] = string(argoappv1.HydrateTypeNormal) } var err error @@ -248,12 +245,13 @@ func RefreshApp(appIf v1alpha1.ApplicationInterface, name string, refreshType ar } for attempt := 0; attempt < 5; attempt++ { app, err := appIf.Patch(context.Background(), name, types.MergePatchType, patch, metav1.PatchOptions{}) - if err == nil { + if err != nil { + if !apierr.IsConflict(err) { + return nil, fmt.Errorf("error patching annotations in application %q: %w", name, err) + } + } else { log.Infof("Requested app '%s' refresh", name) - return app.DeepCopy(), nil - } - if !apierrors.IsConflict(err) { - return nil, fmt.Errorf("error patching annotations in application %q: %w", name, err) + return app, nil } time.Sleep(100 * time.Millisecond) } @@ -303,7 +301,7 @@ func ValidateRepo( if err != nil { return nil, fmt.Errorf("error instantiating new repo server client: %w", err) } - defer utilio.Close(conn) + defer io.Close(conn) helmOptions, err := settingsMgr.GetHelmSettings() if err != nil { @@ -327,7 +325,7 @@ func ValidateRepo( return nil, fmt.Errorf("error getting permitted repo creds: %w", err) } - destCluster, err := GetDestinationCluster(ctx, spec.Destination, db) + cluster, err := db.GetCluster(context.Background(), spec.Destination.Server) if err != nil { conditions = append(conditions, argoappv1.ApplicationCondition{ Type: argoappv1.ApplicationConditionInvalidSpecError, @@ -335,12 +333,12 @@ func ValidateRepo( }) return conditions, nil } - config, err := destCluster.RESTConfig() + config, err := cluster.RESTConfig() if err != nil { return nil, fmt.Errorf("error getting cluster REST config: %w", err) } - //nolint:staticcheck - destCluster.ServerVersion, err = kubectl.GetServerVersion(config) + // nolint:staticcheck + cluster.ServerVersion, err = kubectl.GetServerVersion(config) if err != nil { return nil, fmt.Errorf("error getting k8s server version: %w", err) } @@ -361,7 +359,7 @@ func ValidateRepo( repoClient, permittedHelmRepos, helmOptions, - destCluster, + cluster, apiGroups, proj, permittedHelmCredentials, @@ -442,7 +440,7 @@ func validateRepo(ctx context.Context, proj, sources, repoClient, - //nolint:staticcheck + // nolint:staticcheck cluster.ServerVersion, APIResourcesToStrings(apiGroups, true), permittedHelmCredentials, @@ -469,7 +467,7 @@ func GetRefSources(ctx context.Context, sources argoappv1.ApplicationSources, pr } refKey := "$" + source.Ref if _, ok := refKeys[refKey]; ok { - return nil, errors.New("invalid sources: multiple sources had the same `ref` key") + return nil, fmt.Errorf("invalid sources: multiple sources had the same `ref` key") } refKeys[refKey] = true } @@ -497,6 +495,46 @@ func GetRefSources(ctx context.Context, sources argoappv1.ApplicationSources, pr return refSources, nil } +// ValidateDestination sets the 'Server' or the `Name` value of the ApplicationDestination, if it is not set. +// NOTE: this function WILL write to the object pointed to by the 'dest' parameter. +// If an ApplicationDestination has a Name field, but has an empty Server (URL) field, +// ValidationDestination will look up the cluster by name (to get the server URL), and +// set the corresponding Server field value. Same goes for the opposite case. +// +// It also checks: +// - If we used both name and server then we return an invalid spec error +func ValidateDestination(ctx context.Context, dest *argoappv1.ApplicationDestination, db db.ArgoDB) error { + if dest.IsServerInferred() && dest.IsNameInferred() { + return fmt.Errorf("application destination can't have both name and server inferred: %s %s", dest.Name, dest.Server) + } + if dest.Name != "" { + if dest.Server == "" { + server, err := getDestinationServer(ctx, db, dest.Name) + if err != nil { + return fmt.Errorf("unable to find destination server: %w", err) + } + if server == "" { + return fmt.Errorf("application references destination cluster %s which does not exist", dest.Name) + } + dest.SetInferredServer(server) + } else if !dest.IsServerInferred() && !dest.IsNameInferred() { + return fmt.Errorf("application destination can't have both name and server defined: %s %s", dest.Name, dest.Server) + } + } else if dest.Server != "" { + if dest.Name == "" { + serverName, err := getDestinationServerName(ctx, db, dest.Server) + if err != nil { + return fmt.Errorf("unable to find destination server: %w", err) + } + if serverName == "" { + return fmt.Errorf("application references destination cluster %s which does not exist", dest.Server) + } + dest.SetInferredName(serverName) + } + } + return nil +} + func validateSourcePermissions(source argoappv1.ApplicationSource, hasMultipleSources bool) []argoappv1.ApplicationCondition { var conditions []argoappv1.ApplicationCondition if hasMultipleSources { @@ -554,8 +592,7 @@ func validateSourceHydrator(hydrator *argoappv1.SourceHydrator) []argoappv1.Appl func ValidatePermissions(ctx context.Context, spec *argoappv1.ApplicationSpec, proj *argoappv1.AppProject, db db.ArgoDB) ([]argoappv1.ApplicationCondition, error) { conditions := make([]argoappv1.ApplicationCondition, 0) - switch { - case spec.SourceHydrator != nil: + if spec.SourceHydrator != nil { condition := validateSourceHydrator(spec.SourceHydrator) if len(condition) > 0 { conditions = append(conditions, condition...) @@ -567,7 +604,7 @@ func ValidatePermissions(ctx context.Context, spec *argoappv1.ApplicationSpec, p Message: fmt.Sprintf("application repo %s is not permitted in project '%s'", spec.GetSource().RepoURL, spec.Project), }) } - case spec.HasMultipleSources(): + } else if spec.HasMultipleSources() { for _, source := range spec.Sources { condition := validateSourcePermissions(source, spec.HasMultipleSources()) if len(condition) > 0 { @@ -582,7 +619,7 @@ func ValidatePermissions(ctx context.Context, spec *argoappv1.ApplicationSpec, p }) } } - default: + } else { conditions = validateSourcePermissions(spec.GetSource(), spec.HasMultipleSources()) if len(conditions) > 0 { return conditions, nil @@ -596,8 +633,8 @@ func ValidatePermissions(ctx context.Context, spec *argoappv1.ApplicationSpec, p } } - destCluster, err := GetDestinationCluster(ctx, spec.Destination, db) - if err != nil { + // ValidateDestination will resolve the destination's server address from its name for us, if possible + if err := ValidateDestination(ctx, &spec.Destination, db); err != nil { conditions = append(conditions, argoappv1.ApplicationCondition{ Type: argoappv1.ApplicationConditionInvalidSpecError, Message: err.Error(), @@ -605,8 +642,8 @@ func ValidatePermissions(ctx context.Context, spec *argoappv1.ApplicationSpec, p return conditions, nil } - if destCluster.Server != "" { - permitted, err := proj.IsDestinationPermitted(destCluster, spec.Destination.Namespace, func(project string) ([]*argoappv1.Cluster, error) { + if spec.Destination.Server != "" { + permitted, err := proj.IsDestinationPermitted(spec.Destination, func(project string) ([]*argoappv1.Cluster, error) { return db.GetProjectClusters(ctx, project) }) if err != nil { @@ -618,8 +655,20 @@ func ValidatePermissions(ctx context.Context, spec *argoappv1.ApplicationSpec, p Message: fmt.Sprintf("application destination server '%s' and namespace '%s' do not match any of the allowed destinations in project '%s'", spec.Destination.Server, spec.Destination.Namespace, spec.Project), }) } - } else if destCluster.Server == "" { - conditions = append(conditions, argoappv1.ApplicationCondition{Type: argoappv1.ApplicationConditionInvalidSpecError, Message: ErrDestinationMissing}) + // Ensure the k8s cluster the app is referencing, is configured in Argo CD + _, err = db.GetCluster(ctx, spec.Destination.Server) + if err != nil { + if errStatus, ok := status.FromError(err); ok && errStatus.Code() == codes.NotFound { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: fmt.Sprintf("cluster '%s' has not been configured", spec.Destination.Server), + }) + } else { + return nil, fmt.Errorf("error getting cluster: %w", err) + } + } + } else if spec.Destination.Server == "" { + conditions = append(conditions, argoappv1.ApplicationCondition{Type: argoappv1.ApplicationConditionInvalidSpecError, Message: errDestinationMissing}) } return conditions, nil } @@ -645,7 +694,7 @@ func APIResourcesToStrings(resources []kube.APIResourceInfo, includeKinds bool) } // GetAppProjectWithScopedResources returns a project from an application with scoped resources -func GetAppProjectWithScopedResources(ctx context.Context, name string, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB) (*argoappv1.AppProject, argoappv1.Repositories, []*argoappv1.Cluster, error) { +func GetAppProjectWithScopedResources(name string, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, argoappv1.Repositories, []*argoappv1.Cluster, error) { projOrig, err := projLister.AppProjects(ns).Get(name) if err != nil { return nil, nil, nil, fmt.Errorf("error getting app project %q: %w", name, err) @@ -660,7 +709,7 @@ func GetAppProjectWithScopedResources(ctx context.Context, name string, projList if err != nil { return nil, nil, nil, fmt.Errorf("error getting project clusters: %w", err) } - repos, err := db.GetProjectRepositories(name) + repos, err := db.GetProjectRepositories(ctx, name) if err != nil { return nil, nil, nil, fmt.Errorf("error getting project repos: %w", err) } @@ -668,13 +717,13 @@ func GetAppProjectWithScopedResources(ctx context.Context, name string, projList } // GetAppProjectByName returns a project from an application based on name -func GetAppProjectByName(ctx context.Context, name string, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB) (*argoappv1.AppProject, error) { +func GetAppProjectByName(name string, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { projOrig, err := projLister.AppProjects(ns).Get(name) if err != nil { return nil, fmt.Errorf("error getting app project %q: %w", name, err) } project := projOrig.DeepCopy() - repos, err := db.GetProjectRepositories(name) + repos, err := db.GetProjectRepositories(ctx, name) if err != nil { return nil, fmt.Errorf("error getting project repositories: %w", err) } @@ -699,8 +748,8 @@ func GetAppProjectByName(ctx context.Context, name string, projLister applicatio // GetAppProject returns a project from an application. It will also ensure // that the application is allowed to use the project. -func GetAppProject(ctx context.Context, app *argoappv1.Application, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB) (*argoappv1.AppProject, error) { - proj, err := GetAppProjectByName(ctx, app.Spec.GetProject(), projLister, ns, settingsManager, db) +func GetAppProject(app *argoappv1.Application, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { + proj, err := GetAppProjectByName(app.Spec.GetProject(), projLister, ns, settingsManager, db, ctx) if err != nil { return nil, err } @@ -728,6 +777,12 @@ func verifyGenerateManifests( refSources argoappv1.RefTargetRevisionMapping, ) []argoappv1.ApplicationCondition { var conditions []argoappv1.ApplicationCondition + if app.Spec.Destination.Server == "" { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: errDestinationMissing, + }) + } // If source is Kustomize add build options kustomizeSettings, err := settingsMgr.GetKustomizeSettings() if err != nil { @@ -763,30 +818,6 @@ func verifyGenerateManifests( }) continue } - - appLabelKey, err := settingsMgr.GetAppInstanceLabelKey() - if err != nil { - conditions = append(conditions, argoappv1.ApplicationCondition{ - Type: argoappv1.ApplicationConditionInvalidSpecError, - Message: fmt.Sprintf("Error getting app label key ID: %v", err), - }) - continue - } - - trackingMethod, err := settingsMgr.GetTrackingMethod() - if err != nil { - conditions = append(conditions, argoappv1.ApplicationCondition{ - Type: argoappv1.ApplicationConditionInvalidSpecError, - Message: fmt.Sprintf("Error getting trackingMethod: %v", err), - }) - continue - } - - verifySignature := false - if len(proj.Spec.SignatureKeys) > 0 && gpg.IsGPGEnabled() { - verifySignature = true - } - req := apiclient.ManifestRequest{ Repo: &argoappv1.Repository{ Repo: source.RepoURL, @@ -795,19 +826,17 @@ func verifyGenerateManifests( Proxy: repoRes.Proxy, NoProxy: repoRes.NoProxy, }, - VerifySignature: verifySignature, Repos: helmRepos, Revision: source.TargetRevision, AppName: app.Name, Namespace: app.Spec.Destination.Namespace, ApplicationSource: &source, - AppLabelKey: appLabelKey, KustomizeOptions: kustomizeOptions, KubeVersion: kubeVersion, ApiVersions: apiVersions, HelmOptions: helmOptions, HelmRepoCreds: repositoryCredentials, - TrackingMethod: trackingMethod, + TrackingMethod: string(GetTrackingMethod(settingsMgr)), EnabledSourceTypes: enableGenerateManifests, NoRevisionCache: true, HasMultipleSources: app.Spec.HasMultipleSources(), @@ -842,7 +871,6 @@ func SetAppOperation(appIf v1alpha1.ApplicationInterface, appName string, op *ar if err != nil { return nil, fmt.Errorf("error getting application %q: %w", appName, err) } - a = a.DeepCopy() if a.Operation != nil { return nil, ErrAnotherOperationInProgress } @@ -855,7 +883,7 @@ func SetAppOperation(appIf v1alpha1.ApplicationInterface, appName string, op *ar if err == nil { return a, nil } - if !apierrors.IsConflict(err) { + if !apierr.IsConflict(err) { return nil, fmt.Errorf("error updating application %q: %w", appName, err) } log.Warnf("Failed to set operation for app '%s' due to update conflict. Retrying again...", appName) @@ -943,14 +971,13 @@ func NormalizeSource(source *argoappv1.ApplicationSource) *argoappv1.Application source.Helm = nil } if source.Directory != nil && source.Directory.IsZero() { - switch { - case source.Directory.Exclude != "" && source.Directory.Include != "": + if source.Directory.Exclude != "" && source.Directory.Include != "" { source.Directory = &argoappv1.ApplicationSourceDirectory{Exclude: source.Directory.Exclude, Include: source.Directory.Include} - case source.Directory.Exclude != "": + } else if source.Directory.Exclude != "" { source.Directory = &argoappv1.ApplicationSourceDirectory{Exclude: source.Directory.Exclude} - case source.Directory.Include != "": + } else if source.Directory.Include != "" { source.Directory = &argoappv1.ApplicationSourceDirectory{Include: source.Directory.Include} - default: + } else { source.Directory = nil } } @@ -977,44 +1004,33 @@ func GetPermittedRepos(proj *argoappv1.AppProject, repos []*argoappv1.Repository return permittedRepos, nil } -type ClusterGetter interface { - GetCluster(ctx context.Context, name string) (*argoappv1.Cluster, error) - GetClusterServersByName(ctx context.Context, server string) ([]string, error) +func getDestinationServer(ctx context.Context, db db.ArgoDB, clusterName string) (string, error) { + servers, err := db.GetClusterServersByName(ctx, clusterName) + if err != nil { + return "", fmt.Errorf("error getting cluster server by name %q: %w", clusterName, err) + } + if len(servers) > 1 { + return "", fmt.Errorf("there are %d clusters with the same name: %v", len(servers), servers) + } else if len(servers) == 0 { + return "", fmt.Errorf("there are no clusters with this name: %s", clusterName) + } + return servers[0], nil } -// GetDestinationCluster returns the cluster object based on the destination server or name. If both are provided or -// both are empty, an error is returned. If the destination server is provided, the cluster is fetched by the server -// URL. If the destination name is provided, the cluster is fetched by the name. If multiple clusters have the specified -// name, an error is returned. -func GetDestinationCluster(ctx context.Context, destination argoappv1.ApplicationDestination, db ClusterGetter) (*argoappv1.Cluster, error) { - if destination.Name != "" && destination.Server != "" { - return nil, fmt.Errorf("application destination can't have both name and server defined: %s %s", destination.Name, destination.Server) +func getDestinationServerName(ctx context.Context, db db.ArgoDB, server string) (string, error) { + if db == nil { + return "", fmt.Errorf("there are no clusters registered in the database") } - if destination.Server != "" { - cluster, err := db.GetCluster(ctx, destination.Server) - if err != nil { - return nil, fmt.Errorf("error getting cluster by server %q: %w", destination.Server, err) - } - return cluster, nil - } else if destination.Name != "" { - clusterURLs, err := db.GetClusterServersByName(ctx, destination.Name) - if err != nil { - return nil, fmt.Errorf("error getting cluster by name %q: %w", destination.Name, err) - } - if len(clusterURLs) == 0 { - return nil, fmt.Errorf("there are no clusters with this name: %s", destination.Name) - } - if len(clusterURLs) > 1 { - return nil, fmt.Errorf("there are %d clusters with the same name: [%s]", len(clusterURLs), strings.Join(clusterURLs, " ")) - } - cluster, err := db.GetCluster(ctx, clusterURLs[0]) - if err != nil { - return nil, fmt.Errorf("error getting cluster by URL: %w", err) - } - return cluster, nil + + cluster, err := db.GetCluster(ctx, server) + if err != nil { + return "", fmt.Errorf("error getting cluster name by server %q: %w", server, err) } - // nolint:staticcheck // Error constant is very old, shouldn't lowercase the first letter. - return nil, errors.New(ErrDestinationMissing) + + if cluster.Name == "" { + return "", fmt.Errorf("there are no clusters with this URL: %s", server) + } + return cluster.Name, nil } func GetGlobalProjects(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) []*argoappv1.AppProject { @@ -1090,7 +1106,7 @@ func mergeVirtualProject(proj *argoappv1.AppProject, globalProj *argoappv1.AppPr return proj } -func GenerateSpecIsDifferentErrorMessage(entity string, a, b any) string { +func GenerateSpecIsDifferentErrorMessage(entity string, a, b interface{}) string { basicMsg := fmt.Sprintf("existing %s spec is different; use upsert flag to force update", entity) difference, _ := GetDifferentPathsBetweenStructs(a, b) if len(difference) == 0 { @@ -1099,7 +1115,7 @@ func GenerateSpecIsDifferentErrorMessage(entity string, a, b any) string { return fmt.Sprintf("%s; difference in keys %q", basicMsg, strings.Join(difference, ",")) } -func GetDifferentPathsBetweenStructs(a, b any) ([]string, error) { +func GetDifferentPathsBetweenStructs(a, b interface{}) ([]string, error) { var difference []string changelog, err := diff.Diff(a, b) if err != nil { @@ -1144,8 +1160,9 @@ func ParseInstanceName(appName string, defaultNs string) (string, string) { func AppInstanceName(appName, appNs, defaultNs string) string { if appNs == "" || appNs == defaultNs { return appName + } else { + return appNs + "_" + appName } - return appNs + "_" + appName } // InstanceNameFromQualified returns the value to be used for app @@ -1199,7 +1216,7 @@ func IsValidContainerName(name string) bool { // If matched, the corresponding labels are returned to be added to the generated event. In case of a conflict // between labels on the Application and AppProject, the Application label values are prioritized and added to the event. // Furthermore, labels specified in `resource.excludeEventLabelKeys` in argocd-cm are removed from the event labels, if they were included. -func GetAppEventLabels(ctx context.Context, app *argoappv1.Application, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB) map[string]string { +func GetAppEventLabels(app *argoappv1.Application, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) map[string]string { eventLabels := make(map[string]string) // Get all app & app-project labels @@ -1207,7 +1224,7 @@ func GetAppEventLabels(ctx context.Context, app *argoappv1.Application, projList if labels == nil { labels = make(map[string]string) } - proj, err := GetAppProject(ctx, app, projLister, ns, settingsManager, db) + proj, err := GetAppProject(app, projLister, ns, settingsManager, db, ctx) if err == nil { for k, v := range proj.Labels { _, found := labels[k] diff --git a/util/argo/argo_test.go b/util/argo/argo_test.go index b272e17a36..9096623d5b 100644 --- a/util/argo/argo_test.go +++ b/util/argo/argo_test.go @@ -23,16 +23,16 @@ import ( "github.com/argoproj/gitops-engine/pkg/sync/common" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - "github.com/argoproj/argo-cd/v3/pkg/client/informers/externalversions/application/v1alpha1" - applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient/mocks" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/db" - dbmocks "github.com/argoproj/argo-cd/v3/util/db/mocks" - "github.com/argoproj/argo-cd/v3/util/settings" + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions/application/v1alpha1" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/db" + dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" + "github.com/argoproj/argo-cd/v2/util/settings" ) func TestRefreshApp(t *testing.T) { @@ -45,8 +45,8 @@ func TestRefreshApp(t *testing.T) { require.NoError(t, err) // For some reason, the fake Application interface doesn't reflect the patch status after Patch(), // so can't verify it was set in unit tests. - // _, ok := newApp.Annotations[common.AnnotationKeyRefresh] - // assert.True(t, ok) + //_, ok := newApp.Annotations[common.AnnotationKeyRefresh] + //assert.True(t, ok) } func TestGetAppProjectWithNoProjDefined(t *testing.T) { @@ -71,7 +71,7 @@ func TestGetAppProjectWithNoProjDefined(t *testing.T) { testApp.Name = "test-app" testApp.Namespace = namespace appClientset := appclientset.NewSimpleClientset(testProj) - ctx, cancel := context.WithCancel(t.Context()) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() indexers := cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc} informer := v1alpha1.NewAppProjectInformer(appClientset, namespace, 0, indexers) @@ -79,9 +79,9 @@ func TestGetAppProjectWithNoProjDefined(t *testing.T) { cache.WaitForCacheSync(ctx.Done(), informer.HasSynced) kubeClient := fake.NewClientset(&cm) - settingsMgr := settings.NewSettingsManager(t.Context(), kubeClient, test.FakeArgoCDNamespace) + settingsMgr := settings.NewSettingsManager(context.Background(), kubeClient, test.FakeArgoCDNamespace) argoDB := db.NewDB("default", settingsMgr, kubeClient) - proj, err := GetAppProject(ctx, &testApp, applisters.NewAppProjectLister(informer.GetIndexer()), namespace, settingsMgr, argoDB) + proj, err := GetAppProject(&testApp, applisters.NewAppProjectLister(informer.GetIndexer()), namespace, settingsMgr, argoDB, ctx) require.NoError(t, err) assert.Equal(t, proj.Name, projName) } @@ -260,8 +260,9 @@ func TestContainsSyncResource(t *testing.T) { } for _, table := range tables { - out := ContainsSyncResource(table.u.GetName(), table.u.GetNamespace(), table.u.GroupVersionKind(), table.rr) - assert.Equal(t, table.expected, out, "Expected %t for slice %+v contains resource %+v; instead got %t", table.expected, table.rr, table.u, out) + if out := ContainsSyncResource(table.u.GetName(), table.u.GetNamespace(), table.u.GroupVersionKind(), table.rr); out != table.expected { + t.Errorf("Expected %t for slice %+v contains resource %+v; instead got %t", table.expected, table.rr, table.u, out) + } } } @@ -297,7 +298,7 @@ func TestNilOutZerValueAppSources(t *testing.T) { } func TestValidatePermissionsEmptyDestination(t *testing.T) { - conditions, err := ValidatePermissions(t.Context(), &argoappv1.ApplicationSpec{ + conditions, err := ValidatePermissions(context.Background(), &argoappv1.ApplicationSpec{ Source: &argoappv1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd", Path: "."}, }, &argoappv1.AppProject{ Spec: argoappv1.AppProjectSpec{ @@ -318,7 +319,7 @@ func TestValidateChartWithoutRevision(t *testing.T) { } cluster := &argoappv1.Cluster{Server: "https://kubernetes.default.svc"} db := &dbmocks.ArgoDB{} - ctx := t.Context() + ctx := context.Background() db.On("GetCluster", ctx, appSpec.Destination.Server).Return(cluster, nil) conditions, err := ValidatePermissions(ctx, appSpec, &argoappv1.AppProject{ @@ -365,7 +366,7 @@ func TestValidateRepo(t *testing.T) { }} kubeVersion := "v1.16" kustomizeOptions := &argoappv1.KustomizeOptions{BuildOptions: ""} - repo := &argoappv1.Repository{Repo: "file://" + repoPath} + repo := &argoappv1.Repository{Repo: fmt.Sprintf("file://%s", repoPath)} cluster := &argoappv1.Cluster{Server: "sample server"} app := &argoappv1.Application{ Spec: argoappv1.ApplicationSpec{ @@ -389,7 +390,7 @@ func TestValidateRepo(t *testing.T) { repoClient := &mocks.RepoServerServiceClient{} source := app.Spec.GetSource() - repoClient.On("GetAppDetails", t.Context(), &apiclient.RepoServerAppDetailsQuery{ + repoClient.On("GetAppDetails", context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: repo, Source: &source, Repos: helmRepos, @@ -399,7 +400,7 @@ func TestValidateRepo(t *testing.T) { }).Return(&apiclient.RepoAppDetailsResponse{}, nil) repo.Type = "git" - repoClient.On("TestRepository", t.Context(), &apiclient.TestRepositoryRequest{ + repoClient.On("TestRepository", context.Background(), &apiclient.TestRepositoryRequest{ Repo: repo, }).Return(&apiclient.TestRepositoryResponse{ VerifiedRepository: true, @@ -409,14 +410,14 @@ func TestValidateRepo(t *testing.T) { db := &dbmocks.ArgoDB{} - db.On("GetRepository", t.Context(), app.Spec.Source.RepoURL, "").Return(repo, nil) - db.On("ListHelmRepositories", t.Context()).Return(helmRepos, nil) - db.On("GetCluster", t.Context(), app.Spec.Destination.Server).Return(cluster, nil) - db.On("GetAllHelmRepositoryCredentials", t.Context()).Return(nil, nil) + db.On("GetRepository", context.Background(), app.Spec.Source.RepoURL, "").Return(repo, nil) + db.On("ListHelmRepositories", context.Background()).Return(helmRepos, nil) + db.On("GetCluster", context.Background(), app.Spec.Destination.Server).Return(cluster, nil) + db.On("GetAllHelmRepositoryCredentials", context.Background()).Return(nil, nil) var receivedRequest *apiclient.ManifestRequest - repoClient.On("GenerateManifest", t.Context(), mock.MatchedBy(func(req *apiclient.ManifestRequest) bool { + repoClient.On("GenerateManifest", context.Background(), mock.MatchedBy(func(req *apiclient.ManifestRequest) bool { receivedRequest = req return true })).Return(nil, nil) @@ -446,9 +447,9 @@ func TestValidateRepo(t *testing.T) { } kubeClient := fake.NewClientset(&cm) - settingsMgr := settings.NewSettingsManager(t.Context(), kubeClient, test.FakeArgoCDNamespace) + settingsMgr := settings.NewSettingsManager(context.Background(), kubeClient, test.FakeArgoCDNamespace) - conditions, err := ValidateRepo(t.Context(), app, repoClientSet, db, &kubetest.MockKubectlCmd{Version: kubeVersion, APIResources: apiResources}, proj, settingsMgr) + conditions, err := ValidateRepo(context.Background(), app, repoClientSet, db, &kubetest.MockKubectlCmd{Version: kubeVersion, APIResources: apiResources}, proj, settingsMgr) require.NoError(t, err) assert.Empty(t, conditions) @@ -474,7 +475,7 @@ func TestFormatAppConditions(t *testing.T) { t.Run("Single Condition", func(t *testing.T) { res := FormatAppConditions(conditions[0:1]) assert.NotEmpty(t, res) - assert.Equal(t, EventReasonOperationCompleted+": Foo", res) + assert.Equal(t, fmt.Sprintf("%s: Foo", EventReasonOperationCompleted), res) }) t.Run("Multiple Conditions", func(t *testing.T) { @@ -636,7 +637,7 @@ func TestValidatePermissions(t *testing.T) { } proj := argoappv1.AppProject{} db := &dbmocks.ArgoDB{} - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Len(t, conditions, 1) assert.Equal(t, argoappv1.ApplicationConditionInvalidSpecError, conditions[0].Type) @@ -653,7 +654,7 @@ func TestValidatePermissions(t *testing.T) { } proj := argoappv1.AppProject{} db := &dbmocks.ArgoDB{} - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Len(t, conditions, 1) assert.Equal(t, argoappv1.ApplicationConditionInvalidSpecError, conditions[0].Type) @@ -670,7 +671,7 @@ func TestValidatePermissions(t *testing.T) { } proj := argoappv1.AppProject{} db := &dbmocks.ArgoDB{} - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Len(t, conditions, 1) assert.Equal(t, argoappv1.ApplicationConditionInvalidSpecError, conditions[0].Type) @@ -703,8 +704,8 @@ func TestValidatePermissions(t *testing.T) { } cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443", Name: "test"} db := &dbmocks.ArgoDB{} - db.On("GetCluster", t.Context(), spec.Destination.Server).Return(cluster, nil) - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + db.On("GetCluster", context.Background(), spec.Destination.Server).Return(cluster, nil) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Len(t, conditions, 1) assert.Contains(t, conditions[0].Message, "application repo http://some/where is not permitted") @@ -736,8 +737,8 @@ func TestValidatePermissions(t *testing.T) { } cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443", Name: "test"} db := &dbmocks.ArgoDB{} - db.On("GetCluster", t.Context(), spec.Destination.Server).Return(cluster, nil) - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + db.On("GetCluster", context.Background(), spec.Destination.Server).Return(cluster, nil) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Len(t, conditions, 1) assert.Contains(t, conditions[0].Message, "application destination") @@ -768,11 +769,11 @@ func TestValidatePermissions(t *testing.T) { }, } db := &dbmocks.ArgoDB{} - db.On("GetCluster", t.Context(), spec.Destination.Server).Return(nil, status.Errorf(codes.NotFound, "Cluster does not exist")) - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + db.On("GetCluster", context.Background(), spec.Destination.Server).Return(nil, status.Errorf(codes.NotFound, "Cluster does not exist")) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Len(t, conditions, 1) - assert.Contains(t, conditions[0].Message, "Cluster does not exist") + assert.Contains(t, conditions[0].Message, "unable to find destination server") }) t.Run("Destination cluster name does not exist", func(t *testing.T) { @@ -800,11 +801,11 @@ func TestValidatePermissions(t *testing.T) { }, } db := &dbmocks.ArgoDB{} - db.On("GetClusterServersByName", t.Context(), "does-not-exist").Return(nil, nil) - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + db.On("GetClusterServersByName", context.Background(), "does-not-exist").Return(nil, nil) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Len(t, conditions, 1) - assert.Contains(t, conditions[0].Message, "there are no clusters with this name: does-not-exist") + assert.Contains(t, conditions[0].Message, "unable to find destination server: there are no clusters with this name: does-not-exist") }) t.Run("Cannot get cluster info from DB", func(t *testing.T) { @@ -832,8 +833,8 @@ func TestValidatePermissions(t *testing.T) { }, } db := &dbmocks.ArgoDB{} - db.On("GetCluster", t.Context(), spec.Destination.Server).Return(nil, errors.New("Unknown error occurred")) - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + db.On("GetCluster", context.Background(), spec.Destination.Server).Return(nil, fmt.Errorf("Unknown error occurred")) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Len(t, conditions, 1) assert.Contains(t, conditions[0].Message, "Unknown error occurred") @@ -868,9 +869,9 @@ func TestValidatePermissions(t *testing.T) { Name: "does-exist", Server: "https://127.0.0.1:6443", } - db.On("GetClusterServersByName", t.Context(), "does-exist").Return([]string{"https://127.0.0.1:6443"}, nil) - db.On("GetCluster", t.Context(), "https://127.0.0.1:6443").Return(&cluster, nil) - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + db.On("GetClusterServersByName", context.Background(), "does-exist").Return([]string{"https://127.0.0.1:6443"}, nil) + db.On("GetCluster", context.Background(), "https://127.0.0.1:6443").Return(&cluster, nil) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Empty(t, conditions) }) @@ -925,21 +926,16 @@ func TestSetAppOperations(t *testing.T) { }) } -func TestGetDestinationCluster(t *testing.T) { +func TestValidateDestination(t *testing.T) { t.Run("Validate destination with server url", func(t *testing.T) { dest := argoappv1.ApplicationDestination{ Server: "https://127.0.0.1:6443", Namespace: "default", } - expectedCluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443"} - db := &dbmocks.ArgoDB{} - db.On("GetCluster", t.Context(), "https://127.0.0.1:6443").Return(expectedCluster, nil) - - destCluster, err := GetDestinationCluster(t.Context(), dest, db) - require.NoError(t, err) - require.NotNil(t, expectedCluster) - assert.Equal(t, expectedCluster, destCluster) + appCond := ValidateDestination(context.Background(), &dest, nil) + require.Error(t, appCond) + assert.False(t, dest.IsServerInferred()) }) t.Run("Validate destination with server name", func(t *testing.T) { @@ -948,12 +944,12 @@ func TestGetDestinationCluster(t *testing.T) { } db := &dbmocks.ArgoDB{} - db.On("GetClusterServersByName", t.Context(), "minikube").Return([]string{"https://127.0.0.1:6443"}, nil) - db.On("GetCluster", t.Context(), "https://127.0.0.1:6443").Return(&argoappv1.Cluster{Server: "https://127.0.0.1:6443", Name: "minikube"}, nil) + db.On("GetClusterServersByName", context.Background(), "minikube").Return([]string{"https://127.0.0.1:6443"}, nil) - destCluster, err := GetDestinationCluster(t.Context(), dest, db) - require.NoError(t, err) - assert.Equal(t, "https://127.0.0.1:6443", destCluster.Server) + appCond := ValidateDestination(context.Background(), &dest, db) + require.NoError(t, appCond) + assert.Equal(t, "https://127.0.0.1:6443", dest.Server) + assert.True(t, dest.IsServerInferred()) }) t.Run("Error when having both server url and name", func(t *testing.T) { @@ -963,8 +959,9 @@ func TestGetDestinationCluster(t *testing.T) { Namespace: "default", } - _, err := GetDestinationCluster(t.Context(), dest, nil) - assert.EqualError(t, err, "application destination can't have both name and server defined: minikube https://127.0.0.1:6443") + err := ValidateDestination(context.Background(), &dest, nil) + assert.Equal(t, "application destination can't have both name and server defined: minikube https://127.0.0.1:6443", err.Error()) + assert.False(t, dest.IsServerInferred()) }) t.Run("GetClusterServersByName fails", func(t *testing.T) { @@ -973,10 +970,11 @@ func TestGetDestinationCluster(t *testing.T) { } db := &dbmocks.ArgoDB{} - db.On("GetClusterServersByName", t.Context(), mock.Anything).Return(nil, errors.New("an error occurred")) + db.On("GetClusterServersByName", context.Background(), mock.Anything).Return(nil, fmt.Errorf("an error occurred")) - _, err := GetDestinationCluster(t.Context(), dest, db) + err := ValidateDestination(context.Background(), &dest, db) require.ErrorContains(t, err, "an error occurred") + assert.False(t, dest.IsServerInferred()) }) t.Run("Destination cluster does not exist", func(t *testing.T) { @@ -985,10 +983,11 @@ func TestGetDestinationCluster(t *testing.T) { } db := &dbmocks.ArgoDB{} - db.On("GetClusterServersByName", t.Context(), "minikube").Return(nil, nil) + db.On("GetClusterServersByName", context.Background(), "minikube").Return(nil, nil) - _, err := GetDestinationCluster(t.Context(), dest, db) - assert.EqualError(t, err, "there are no clusters with this name: minikube") + err := ValidateDestination(context.Background(), &dest, db) + assert.Equal(t, "unable to find destination server: there are no clusters with this name: minikube", err.Error()) + assert.False(t, dest.IsServerInferred()) }) t.Run("Validate too many clusters with the same name", func(t *testing.T) { @@ -997,10 +996,11 @@ func TestGetDestinationCluster(t *testing.T) { } db := &dbmocks.ArgoDB{} - db.On("GetClusterServersByName", t.Context(), "dind").Return([]string{"https://127.0.0.1:2443", "https://127.0.0.1:8443"}, nil) + db.On("GetClusterServersByName", context.Background(), "dind").Return([]string{"https://127.0.0.1:2443", "https://127.0.0.1:8443"}, nil) - _, err := GetDestinationCluster(t.Context(), dest, db) - assert.EqualError(t, err, "there are 2 clusters with the same name: [https://127.0.0.1:2443 https://127.0.0.1:8443]") + err := ValidateDestination(context.Background(), &dest, db) + assert.Equal(t, "unable to find destination server: there are 2 clusters with the same name: [https://127.0.0.1:2443 https://127.0.0.1:8443]", err.Error()) + assert.False(t, dest.IsServerInferred()) }) } @@ -1143,7 +1143,7 @@ func TestGetGlobalProjects(t *testing.T) { } projClientset := appclientset.NewSimpleClientset(defaultX, defaultNonX, isX, isNoX) - ctx, cancel := context.WithCancel(t.Context()) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() indexers := cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc} informer := v1alpha1.NewAppProjectInformer(projClientset, namespace, 0, indexers) @@ -1151,7 +1151,7 @@ func TestGetGlobalProjects(t *testing.T) { cache.WaitForCacheSync(ctx.Done(), informer.HasSynced) kubeClient := fake.NewSimpleClientset(&cm) - settingsMgr := settings.NewSettingsManager(t.Context(), kubeClient, test.FakeArgoCDNamespace) + settingsMgr := settings.NewSettingsManager(context.Background(), kubeClient, test.FakeArgoCDNamespace) projLister := applisters.NewAppProjectLister(informer.GetIndexer()) @@ -1294,15 +1294,15 @@ func Test_GetRefSources(t *testing.T) { } } - repo := &argoappv1.Repository{Repo: "file://" + repoPath} + repo := &argoappv1.Repository{Repo: fmt.Sprintf("file://%s", repoPath)} t.Run("target ref exists", func(t *testing.T) { argoSpec := getMultiSourceAppSpec(argoappv1.ApplicationSources{ - {RepoURL: "file://" + repoPath, Ref: "source-1_2"}, - {RepoURL: "file://" + repoPath}, + {RepoURL: fmt.Sprintf("file://%s", repoPath), Ref: "source-1_2"}, + {RepoURL: fmt.Sprintf("file://%s", repoPath)}, }) - refSources, err := GetRefSources(t.Context(), argoSpec.Sources, argoSpec.Project, func(_ context.Context, _ string, _ string) (*argoappv1.Repository, error) { + refSources, err := GetRefSources(context.Background(), argoSpec.Sources, argoSpec.Project, func(ctx context.Context, url string, project string) (*argoappv1.Repository, error) { return repo, nil }, []string{}, false) @@ -1319,10 +1319,10 @@ func Test_GetRefSources(t *testing.T) { t.Run("target ref does not exist", func(t *testing.T) { argoSpec := getMultiSourceAppSpec(argoappv1.ApplicationSources{ {RepoURL: "file://does-not-exist", Ref: "source1"}, - {RepoURL: "file://" + repoPath}, + {RepoURL: fmt.Sprintf("file://%s", repoPath)}, }) - refSources, err := GetRefSources(t.Context(), argoSpec.Sources, argoSpec.Project, func(_ context.Context, _ string, _ string) (*argoappv1.Repository, error) { + refSources, err := GetRefSources(context.Background(), argoSpec.Sources, argoSpec.Project, func(ctx context.Context, url string, project string) (*argoappv1.Repository, error) { return nil, errors.New("repo does not exist") }, []string{}, false) @@ -1333,10 +1333,10 @@ func Test_GetRefSources(t *testing.T) { t.Run("invalid ref", func(t *testing.T) { argoSpec := getMultiSourceAppSpec(argoappv1.ApplicationSources{ {RepoURL: "file://does-not-exist", Ref: "%invalid-name%"}, - {RepoURL: "file://" + repoPath}, + {RepoURL: fmt.Sprintf("file://%s", repoPath)}, }) - refSources, err := GetRefSources(t.Context(), argoSpec.Sources, argoSpec.Project, func(_ context.Context, _ string, _ string) (*argoappv1.Repository, error) { + refSources, err := GetRefSources(context.TODO(), argoSpec.Sources, argoSpec.Project, func(ctx context.Context, url string, project string) (*argoappv1.Repository, error) { return nil, err }, []string{}, false) @@ -1350,7 +1350,7 @@ func Test_GetRefSources(t *testing.T) { {RepoURL: "file://does-not-exist", Ref: "source1"}, }) - refSources, err := GetRefSources(t.Context(), argoSpec.Sources, argoSpec.Project, func(_ context.Context, _ string, _ string) (*argoappv1.Repository, error) { + refSources, err := GetRefSources(context.TODO(), argoSpec.Sources, argoSpec.Project, func(ctx context.Context, url string, project string) (*argoappv1.Repository, error) { return nil, err }, []string{}, false) @@ -1369,7 +1369,7 @@ func TestValidatePermissionsMultipleSources(t *testing.T) { proj := argoappv1.AppProject{} db := &dbmocks.ArgoDB{} - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Len(t, conditions, 1) assert.Equal(t, argoappv1.ApplicationConditionInvalidSpecError, conditions[0].Type) @@ -1389,7 +1389,7 @@ func TestValidatePermissionsMultipleSources(t *testing.T) { } proj := argoappv1.AppProject{} db := &dbmocks.ArgoDB{} - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Len(t, conditions, 1) assert.Equal(t, argoappv1.ApplicationConditionInvalidSpecError, conditions[0].Type) @@ -1424,8 +1424,8 @@ func TestValidatePermissionsMultipleSources(t *testing.T) { } cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443", Name: "test"} db := &dbmocks.ArgoDB{} - db.On("GetCluster", t.Context(), spec.Destination.Server).Return(cluster, nil) - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + db.On("GetCluster", context.Background(), spec.Destination.Server).Return(cluster, nil) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Len(t, conditions, 1) assert.Contains(t, conditions[0].Message, "application repo http://some/where is not permitted") @@ -1462,9 +1462,9 @@ func TestValidatePermissionsMultipleSources(t *testing.T) { Name: "does-exist", Server: "https://127.0.0.1:6443", } - db.On("GetClusterServersByName", t.Context(), "does-exist").Return([]string{"https://127.0.0.1:6443"}, nil) - db.On("GetCluster", t.Context(), "https://127.0.0.1:6443").Return(&cluster, nil) - conditions, err := ValidatePermissions(t.Context(), &spec, &proj, db) + db.On("GetClusterServersByName", context.Background(), "does-exist").Return([]string{"https://127.0.0.1:6443"}, nil) + db.On("GetCluster", context.Background(), "https://127.0.0.1:6443").Return(&cluster, nil) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Empty(t, conditions) }) @@ -1589,7 +1589,8 @@ func TestAugmentSyncMsg(t *testing.T) { tt.res.Message = tt.msg msg, err := AugmentSyncMsg(tt.res, tt.mockFn) if tt.errMsg != "" { - assert.EqualError(t, err, tt.errMsg) + require.Error(t, err) + assert.Equal(t, tt.errMsg, err.Error()) } else { require.NoError(t, err) assert.Equal(t, tt.expectedMessage, msg) @@ -1687,7 +1688,7 @@ func TestGetAppEventLabels(t *testing.T) { app.Namespace = test.FakeArgoCDNamespace app.Labels = tt.appLabels appClientset := appclientset.NewSimpleClientset(proj) - ctx, cancel := context.WithCancel(t.Context()) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() indexers := cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc} informer := v1alpha1.NewAppProjectInformer(appClientset, test.FakeArgoCDNamespace, 0, indexers) @@ -1695,11 +1696,11 @@ func TestGetAppEventLabels(t *testing.T) { cache.WaitForCacheSync(ctx.Done(), informer.HasSynced) kubeClient := fake.NewSimpleClientset(&cm) - settingsMgr := settings.NewSettingsManager(t.Context(), kubeClient, test.FakeArgoCDNamespace) + settingsMgr := settings.NewSettingsManager(context.Background(), kubeClient, test.FakeArgoCDNamespace) argoDB := db.NewDB("default", settingsMgr, kubeClient) - eventLabels := GetAppEventLabels(ctx, &app, applisters.NewAppProjectLister(informer.GetIndexer()), test.FakeArgoCDNamespace, settingsMgr, argoDB) - assert.Len(t, eventLabels, len(tt.expectedEventLabels)) + eventLabels := GetAppEventLabels(&app, applisters.NewAppProjectLister(informer.GetIndexer()), test.FakeArgoCDNamespace, settingsMgr, argoDB, ctx) + assert.Equal(t, len(tt.expectedEventLabels), len(eventLabels)) for ek, ev := range tt.expectedEventLabels { v, found := eventLabels[ek] assert.True(t, found) diff --git a/util/argo/audit_logger.go b/util/argo/audit_logger.go index be1834136a..cffef2d64d 100644 --- a/util/argo/audit_logger.go +++ b/util/argo/audit_logger.go @@ -6,15 +6,15 @@ import ( "time" log "github.com/sirupsen/logrus" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) type AuditLogger struct { @@ -64,16 +64,16 @@ func (l *AuditLogger) logEvent(objMeta ObjectRef, gvk schema.GroupVersionKind, i logCtx = logCtx.WithField("name", objMeta.Name) } t := metav1.Time{Time: time.Now()} - event := corev1.Event{ + event := v1.Event{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("%v.%x", objMeta.Name, t.UnixNano()), Labels: eventLabels, Annotations: logFields, }, - Source: corev1.EventSource{ + Source: v1.EventSource{ Component: l.component, }, - InvolvedObject: corev1.ObjectReference{ + InvolvedObject: v1.ObjectReference{ Kind: gvk.Kind, Name: objMeta.Name, Namespace: objMeta.Namespace, @@ -106,10 +106,10 @@ func (l *AuditLogger) LogAppEvent(app *v1alpha1.Application, info EventInfo, mes } objectMeta := ObjectRef{ - Name: app.Name, - Namespace: app.Namespace, - ResourceVersion: app.ResourceVersion, - UID: app.UID, + Name: app.ObjectMeta.Name, + Namespace: app.ObjectMeta.Namespace, + ResourceVersion: app.ObjectMeta.ResourceVersion, + UID: app.ObjectMeta.UID, } fields := map[string]string{ "dest-server": app.Spec.Destination.Server, @@ -127,10 +127,10 @@ func (l *AuditLogger) LogAppSetEvent(app *v1alpha1.ApplicationSet, info EventInf } objectMeta := ObjectRef{ - Name: app.Name, - Namespace: app.Namespace, - ResourceVersion: app.ResourceVersion, - UID: app.UID, + Name: app.ObjectMeta.Name, + Namespace: app.ObjectMeta.Namespace, + ResourceVersion: app.ObjectMeta.ResourceVersion, + UID: app.ObjectMeta.UID, } fields := map[string]string{} if user != "" { @@ -145,10 +145,10 @@ func (l *AuditLogger) LogResourceEvent(res *v1alpha1.ResourceNode, info EventInf } objectMeta := ObjectRef{ - Name: res.Name, - Namespace: res.Namespace, - ResourceVersion: res.Version, - UID: types.UID(res.UID), + Name: res.ResourceRef.Name, + Namespace: res.ResourceRef.Namespace, + ResourceVersion: res.ResourceRef.Version, + UID: types.UID(res.ResourceRef.UID), } fields := map[string]string{} if user != "" { @@ -167,10 +167,10 @@ func (l *AuditLogger) LogAppProjEvent(proj *v1alpha1.AppProject, info EventInfo, } objectMeta := ObjectRef{ - Name: proj.Name, - Namespace: proj.Namespace, - ResourceVersion: proj.ResourceVersion, - UID: proj.UID, + Name: proj.ObjectMeta.Name, + Namespace: proj.ObjectMeta.Namespace, + ResourceVersion: proj.ObjectMeta.ResourceVersion, + UID: proj.ObjectMeta.UID, } fields := map[string]string{} if user != "" { @@ -192,13 +192,12 @@ func setK8sEventList(enableK8sEvent []string) map[string]bool { enableK8sEventList := make(map[string]bool) for _, event := range enableK8sEvent { - switch event { - case "all": + if event == "all" { enableK8sEventList = map[string]bool{ "all": true, } return enableK8sEventList - case "none": + } else if event == "none" { enableK8sEventList = map[string]bool{} return enableK8sEventList } diff --git a/util/argo/audit_logger_test.go b/util/argo/audit_logger_test.go index 9bc7eb55c8..900bf43c4b 100644 --- a/util/argo/audit_logger_test.go +++ b/util/argo/audit_logger_test.go @@ -8,10 +8,10 @@ import ( log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) const ( @@ -19,7 +19,7 @@ const ( _test = "test" ) -var testEnableEventLog = []string{_somecomponent, _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 { @@ -45,7 +45,7 @@ func TestLogAppProjEvent(t *testing.T) { assert.NotNil(t, logger) proj := argoappv1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "default", Namespace: "argocd", ResourceVersion: "1", @@ -86,7 +86,7 @@ func TestLogAppEvent(t *testing.T) { assert.NotNil(t, logger) app := argoappv1.Application{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "testapp", Namespace: "argocd", ResourceVersion: "1", diff --git a/util/argo/diff/diff.go b/util/argo/diff/diff.go index 6ee4f6c4af..ed0a4e943e 100644 --- a/util/argo/diff/diff.go +++ b/util/argo/diff/diff.go @@ -1,7 +1,6 @@ package diff import ( - "errors" "fmt" "github.com/go-logr/logr" @@ -9,11 +8,11 @@ import ( k8smanagedfields "k8s.io/apimachinery/pkg/util/managedfields" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/argo/managedfields" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" + "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/argo/managedfields" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" + appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" "github.com/argoproj/gitops-engine/pkg/diff" "github.com/argoproj/gitops-engine/pkg/utils/kube" @@ -341,7 +340,7 @@ func StateDiffs(lives, configs []*unstructured.Unstructured, diffConfig DiffConf func diffArrayCached(configArray []*unstructured.Unstructured, liveArray []*unstructured.Unstructured, cachedDiff []*v1alpha1.ResourceDiff, opts ...diff.Option) (*diff.DiffResultList, error) { numItems := len(configArray) if len(liveArray) != numItems { - return nil, errors.New("left and right arrays have mismatched lengths") + return nil, fmt.Errorf("left and right arrays have mismatched lengths") } diffByKey := map[kube.ResourceKey]*v1alpha1.ResourceDiff{} @@ -412,7 +411,7 @@ func (c *diffConfig) DiffFromCache(appName string) (bool, []*v1alpha1.ResourceDi // the diff. None of the attributes in the lives and targets params will be modified. func preDiffNormalize(lives, targets []*unstructured.Unstructured, diffConfig DiffConfig) (*NormalizationResult, error) { if diffConfig == nil { - return nil, errors.New("preDiffNormalize error: diffConfig can not be nil") + return nil, fmt.Errorf("preDiffNormalize error: diffConfig can not be nil") } err := diffConfig.Validate() if err != nil { diff --git a/util/argo/diff/diff_test.go b/util/argo/diff/diff_test.go index a22766b4e2..8912d9bf88 100644 --- a/util/argo/diff/diff_test.go +++ b/util/argo/diff/diff_test.go @@ -7,12 +7,12 @@ import ( "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - testutil "github.com/argoproj/argo-cd/v3/test" - argo "github.com/argoproj/argo-cd/v3/util/argo/diff" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - "github.com/argoproj/argo-cd/v3/util/argo/testdata" - appstatecache "github.com/argoproj/argo-cd/v3/util/cache/appstate" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + testutil "github.com/argoproj/argo-cd/v2/test" + argo "github.com/argoproj/argo-cd/v2/util/argo/diff" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" + "github.com/argoproj/argo-cd/v2/util/argo/testdata" + appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" ) func TestStateDiff(t *testing.T) { @@ -201,7 +201,7 @@ func TestDiffConfigBuilder(t *testing.T) { assert.Equal(t, f.trackingMethod, diffConfig.TrackingMethod()) assert.Equal(t, f.noCache, diffConfig.NoCache()) assert.Equal(t, f.ignoreRoles, diffConfig.IgnoreAggregatedRoles()) - assert.Empty(t, diffConfig.AppName()) + assert.Equal(t, "", diffConfig.AppName()) assert.Nil(t, diffConfig.StateCache()) }) t.Run("will initialize ignore differences if nil is passed", func(t *testing.T) { diff --git a/util/argo/diff/ignore.go b/util/argo/diff/ignore.go index 7b94a7c3e3..68d4850556 100644 --- a/util/argo/diff/ignore.go +++ b/util/argo/diff/ignore.go @@ -3,8 +3,8 @@ package diff import ( "fmt" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/glob" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/glob" ) // IgnoreDiffConfig holds the ignore difference configurations defined in argo-cm diff --git a/util/argo/diff/ignore_test.go b/util/argo/diff/ignore_test.go index 457e9d174c..90c7b0464d 100644 --- a/util/argo/diff/ignore_test.go +++ b/util/argo/diff/ignore_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo/diff" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo/diff" ) func TestIgnoreDiffConfig_HasIgnoreDifference(t *testing.T) { @@ -51,6 +51,7 @@ func TestIgnoreDiffConfig_HasIgnoreDifference(t *testing.T) { assert.True(t, ok) assert.NotNil(t, actual) assert.Equal(t, expectedManagedFields, actual.ManagedFieldsManagers) + // nolint:testifylint assert.Equal(t, expectedJSONPointers, actual.JSONPointers) assert.Equal(t, expectedJQExpression, actual.JQPathExpressions) }) @@ -72,6 +73,7 @@ func TestIgnoreDiffConfig_HasIgnoreDifference(t *testing.T) { assert.True(t, ok) assert.NotNil(t, actual) assert.Equal(t, expectedManagedFields, actual.ManagedFieldsManagers) + // nolint:testifylint assert.Equal(t, expectedJSONPointers, actual.JSONPointers) assert.Equal(t, expectedJQExpression, actual.JQPathExpressions) }) diff --git a/util/argo/diff/normalize.go b/util/argo/diff/normalize.go index 710e5dda4c..88238fdb88 100644 --- a/util/argo/diff/normalize.go +++ b/util/argo/diff/normalize.go @@ -1,8 +1,8 @@ package diff import ( - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" "github.com/argoproj/gitops-engine/pkg/diff" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/util/argo/diff/normalize_test.go b/util/argo/diff/normalize_test.go index ef5cdb80ae..5ac6917d97 100644 --- a/util/argo/diff/normalize_test.go +++ b/util/argo/diff/normalize_test.go @@ -7,11 +7,11 @@ import ( "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/argo/diff" - "github.com/argoproj/argo-cd/v3/util/argo/normalizers" - "github.com/argoproj/argo-cd/v3/util/argo/testdata" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/argo/diff" + "github.com/argoproj/argo-cd/v2/util/argo/normalizers" + "github.com/argoproj/argo-cd/v2/util/argo/testdata" ) func TestNormalize(t *testing.T) { diff --git a/util/argo/managedfields/managed_fields.go b/util/argo/managedfields/managed_fields.go index 5ee6415e10..1ead8f4521 100644 --- a/util/argo/managedfields/managed_fields.go +++ b/util/argo/managedfields/managed_fields.go @@ -5,7 +5,7 @@ import ( "fmt" log "github.com/sirupsen/logrus" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" "sigs.k8s.io/structured-merge-diff/v4/typed" @@ -52,14 +52,14 @@ func Normalize(live, config *unstructured.Unstructured, trustedManagers []string return liveCopy, configCopy, nil } lvu := results.live.AsValue().Unstructured() - l, ok := lvu.(map[string]any) + l, ok := lvu.(map[string]interface{}) if !ok { return nil, nil, fmt.Errorf("error converting live typedValue: expected map got %T", lvu) } normLive := &unstructured.Unstructured{Object: l} cvu := results.config.AsValue().Unstructured() - c, ok := cvu.(map[string]any) + c, ok := cvu.(map[string]interface{}) if !ok { return nil, nil, fmt.Errorf("error converting config typedValue: expected map got %T", cvu) } @@ -70,7 +70,7 @@ func Normalize(live, config *unstructured.Unstructured, trustedManagers []string // normalize will check if the modified set has fields that are present // in the managed fields entry. If so, it will remove the fields from // the live and config objects so it is ignored in diffs. -func normalize(mf metav1.ManagedFieldsEntry, tr *typedResults) error { +func normalize(mf v1.ManagedFieldsEntry, tr *typedResults) error { mfs := &fieldpath.Set{} err := mfs.FromJSON(bytes.NewReader(mf.FieldsV1.Raw)) if err != nil { diff --git a/util/argo/managedfields/managed_fields_test.go b/util/argo/managedfields/managed_fields_test.go index 9dc244a1fb..3034a87858 100644 --- a/util/argo/managedfields/managed_fields_test.go +++ b/util/argo/managedfields/managed_fields_test.go @@ -12,8 +12,8 @@ import ( "github.com/argoproj/gitops-engine/pkg/utils/kube/scheme" - "github.com/argoproj/argo-cd/v3/util/argo/managedfields" - "github.com/argoproj/argo-cd/v3/util/argo/testdata" + "github.com/argoproj/argo-cd/v2/util/argo/managedfields" + "github.com/argoproj/argo-cd/v2/util/argo/testdata" ) func TestNormalize(t *testing.T) { @@ -135,13 +135,13 @@ func TestNormalize(t *testing.T) { err = runtime.DefaultUnstructuredConverter.FromUnstructured(liveResult.Object, &vwcLive) require.NoError(t, err) assert.Len(t, vwcLive.Webhooks, 1) - assert.Empty(t, string(vwcLive.Webhooks[0].ClientConfig.CABundle)) + assert.Equal(t, "", string(vwcLive.Webhooks[0].ClientConfig.CABundle)) var vwcConfig arv1.ValidatingWebhookConfiguration err = runtime.DefaultUnstructuredConverter.FromUnstructured(desiredResult.Object, &vwcConfig) require.NoError(t, err) assert.Len(t, vwcConfig.Webhooks, 1) - assert.Empty(t, string(vwcConfig.Webhooks[0].ClientConfig.CABundle)) + assert.Equal(t, "", string(vwcConfig.Webhooks[0].ClientConfig.CABundle)) }) t.Run("does not fail if object fails validation schema", func(t *testing.T) { desiredState := StrToUnstructured(testdata.DesiredDeploymentYaml) @@ -170,7 +170,7 @@ func getNestedFloat64(t *testing.T, obj *unstructured.Unstructured, fields ...st } func StrToUnstructured(jsonStr string) *unstructured.Unstructured { - obj := make(map[string]any) + obj := make(map[string]interface{}) err := yaml.Unmarshal([]byte(jsonStr), &obj) if err != nil { panic(err) diff --git a/util/argo/normalizers/corev1_known_types.go b/util/argo/normalizers/corev1_known_types.go index 51f655b28b..3f4ef5d184 100644 --- a/util/argo/normalizers/corev1_known_types.go +++ b/util/argo/normalizers/corev1_known_types.go @@ -4,697 +4,697 @@ package normalizers import corev1 "k8s.io/api/core/v1" func init() { - knownTypes["core/v1/AWSElasticBlockStoreVolumeSource"] = func() any { + knownTypes["core/v1/AWSElasticBlockStoreVolumeSource"] = func() interface{} { return &corev1.AWSElasticBlockStoreVolumeSource{} } - knownTypes["core/v1/Affinity"] = func() any { + knownTypes["core/v1/Affinity"] = func() interface{} { return &corev1.Affinity{} } - knownTypes["core/v1/AppArmorProfile"] = func() any { + knownTypes["core/v1/AppArmorProfile"] = func() interface{} { return &corev1.AppArmorProfile{} } - knownTypes["core/v1/AttachedVolume"] = func() any { + knownTypes["core/v1/AttachedVolume"] = func() interface{} { return &corev1.AttachedVolume{} } - knownTypes["core/v1/AvoidPods"] = func() any { + knownTypes["core/v1/AvoidPods"] = func() interface{} { return &corev1.AvoidPods{} } - knownTypes["core/v1/AzureDiskVolumeSource"] = func() any { + knownTypes["core/v1/AzureDiskVolumeSource"] = func() interface{} { return &corev1.AzureDiskVolumeSource{} } - knownTypes["core/v1/AzureFilePersistentVolumeSource"] = func() any { + knownTypes["core/v1/AzureFilePersistentVolumeSource"] = func() interface{} { return &corev1.AzureFilePersistentVolumeSource{} } - knownTypes["core/v1/AzureFileVolumeSource"] = func() any { + knownTypes["core/v1/AzureFileVolumeSource"] = func() interface{} { return &corev1.AzureFileVolumeSource{} } - knownTypes["core/v1/Binding"] = func() any { + knownTypes["core/v1/Binding"] = func() interface{} { return &corev1.Binding{} } - knownTypes["core/v1/CSIPersistentVolumeSource"] = func() any { + knownTypes["core/v1/CSIPersistentVolumeSource"] = func() interface{} { return &corev1.CSIPersistentVolumeSource{} } - knownTypes["core/v1/CSIVolumeSource"] = func() any { + knownTypes["core/v1/CSIVolumeSource"] = func() interface{} { return &corev1.CSIVolumeSource{} } - knownTypes["core/v1/Capabilities"] = func() any { + knownTypes["core/v1/Capabilities"] = func() interface{} { return &corev1.Capabilities{} } - knownTypes["core/v1/CephFSPersistentVolumeSource"] = func() any { + knownTypes["core/v1/CephFSPersistentVolumeSource"] = func() interface{} { return &corev1.CephFSPersistentVolumeSource{} } - knownTypes["core/v1/CephFSVolumeSource"] = func() any { + knownTypes["core/v1/CephFSVolumeSource"] = func() interface{} { return &corev1.CephFSVolumeSource{} } - knownTypes["core/v1/CinderPersistentVolumeSource"] = func() any { + knownTypes["core/v1/CinderPersistentVolumeSource"] = func() interface{} { return &corev1.CinderPersistentVolumeSource{} } - knownTypes["core/v1/CinderVolumeSource"] = func() any { + knownTypes["core/v1/CinderVolumeSource"] = func() interface{} { return &corev1.CinderVolumeSource{} } - knownTypes["core/v1/ClientIPConfig"] = func() any { + knownTypes["core/v1/ClientIPConfig"] = func() interface{} { return &corev1.ClientIPConfig{} } - knownTypes["core/v1/ClusterTrustBundleProjection"] = func() any { + knownTypes["core/v1/ClusterTrustBundleProjection"] = func() interface{} { return &corev1.ClusterTrustBundleProjection{} } - knownTypes["core/v1/ComponentCondition"] = func() any { + knownTypes["core/v1/ComponentCondition"] = func() interface{} { return &corev1.ComponentCondition{} } - knownTypes["core/v1/ComponentStatus"] = func() any { + knownTypes["core/v1/ComponentStatus"] = func() interface{} { return &corev1.ComponentStatus{} } - knownTypes["core/v1/ComponentStatusList"] = func() any { + knownTypes["core/v1/ComponentStatusList"] = func() interface{} { return &corev1.ComponentStatusList{} } - knownTypes["core/v1/ConfigMap"] = func() any { + knownTypes["core/v1/ConfigMap"] = func() interface{} { return &corev1.ConfigMap{} } - knownTypes["core/v1/ConfigMapEnvSource"] = func() any { + knownTypes["core/v1/ConfigMapEnvSource"] = func() interface{} { return &corev1.ConfigMapEnvSource{} } - knownTypes["core/v1/ConfigMapKeySelector"] = func() any { + knownTypes["core/v1/ConfigMapKeySelector"] = func() interface{} { return &corev1.ConfigMapKeySelector{} } - knownTypes["core/v1/ConfigMapList"] = func() any { + knownTypes["core/v1/ConfigMapList"] = func() interface{} { return &corev1.ConfigMapList{} } - knownTypes["core/v1/ConfigMapNodeConfigSource"] = func() any { + knownTypes["core/v1/ConfigMapNodeConfigSource"] = func() interface{} { return &corev1.ConfigMapNodeConfigSource{} } - knownTypes["core/v1/ConfigMapProjection"] = func() any { + knownTypes["core/v1/ConfigMapProjection"] = func() interface{} { return &corev1.ConfigMapProjection{} } - knownTypes["core/v1/ConfigMapVolumeSource"] = func() any { + knownTypes["core/v1/ConfigMapVolumeSource"] = func() interface{} { return &corev1.ConfigMapVolumeSource{} } - knownTypes["core/v1/Container"] = func() any { + knownTypes["core/v1/Container"] = func() interface{} { return &corev1.Container{} } - knownTypes["core/v1/ContainerImage"] = func() any { + knownTypes["core/v1/ContainerImage"] = func() interface{} { return &corev1.ContainerImage{} } - knownTypes["core/v1/ContainerPort"] = func() any { + knownTypes["core/v1/ContainerPort"] = func() interface{} { return &corev1.ContainerPort{} } - knownTypes["core/v1/ContainerResizePolicy"] = func() any { + knownTypes["core/v1/ContainerResizePolicy"] = func() interface{} { return &corev1.ContainerResizePolicy{} } - knownTypes["core/v1/ContainerState"] = func() any { + knownTypes["core/v1/ContainerState"] = func() interface{} { return &corev1.ContainerState{} } - knownTypes["core/v1/ContainerStateRunning"] = func() any { + knownTypes["core/v1/ContainerStateRunning"] = func() interface{} { return &corev1.ContainerStateRunning{} } - knownTypes["core/v1/ContainerStateTerminated"] = func() any { + knownTypes["core/v1/ContainerStateTerminated"] = func() interface{} { return &corev1.ContainerStateTerminated{} } - knownTypes["core/v1/ContainerStateWaiting"] = func() any { + knownTypes["core/v1/ContainerStateWaiting"] = func() interface{} { return &corev1.ContainerStateWaiting{} } - knownTypes["core/v1/ContainerStatus"] = func() any { + knownTypes["core/v1/ContainerStatus"] = func() interface{} { return &corev1.ContainerStatus{} } - knownTypes["core/v1/ContainerUser"] = func() any { + knownTypes["core/v1/ContainerUser"] = func() interface{} { return &corev1.ContainerUser{} } - knownTypes["core/v1/DaemonEndpoint"] = func() any { + knownTypes["core/v1/DaemonEndpoint"] = func() interface{} { return &corev1.DaemonEndpoint{} } - knownTypes["core/v1/DownwardAPIProjection"] = func() any { + knownTypes["core/v1/DownwardAPIProjection"] = func() interface{} { return &corev1.DownwardAPIProjection{} } - knownTypes["core/v1/DownwardAPIVolumeFile"] = func() any { + knownTypes["core/v1/DownwardAPIVolumeFile"] = func() interface{} { return &corev1.DownwardAPIVolumeFile{} } - knownTypes["core/v1/DownwardAPIVolumeSource"] = func() any { + knownTypes["core/v1/DownwardAPIVolumeSource"] = func() interface{} { return &corev1.DownwardAPIVolumeSource{} } - knownTypes["core/v1/EmptyDirVolumeSource"] = func() any { + knownTypes["core/v1/EmptyDirVolumeSource"] = func() interface{} { return &corev1.EmptyDirVolumeSource{} } - knownTypes["core/v1/EndpointAddress"] = func() any { + knownTypes["core/v1/EndpointAddress"] = func() interface{} { return &corev1.EndpointAddress{} } - knownTypes["core/v1/EndpointPort"] = func() any { + knownTypes["core/v1/EndpointPort"] = func() interface{} { return &corev1.EndpointPort{} } - knownTypes["core/v1/EndpointSubset"] = func() any { + knownTypes["core/v1/EndpointSubset"] = func() interface{} { return &corev1.EndpointSubset{} } - knownTypes["core/v1/Endpoints"] = func() any { + knownTypes["core/v1/Endpoints"] = func() interface{} { return &corev1.Endpoints{} } - knownTypes["core/v1/EndpointsList"] = func() any { + knownTypes["core/v1/EndpointsList"] = func() interface{} { return &corev1.EndpointsList{} } - knownTypes["core/v1/EnvFromSource"] = func() any { + knownTypes["core/v1/EnvFromSource"] = func() interface{} { return &corev1.EnvFromSource{} } - knownTypes["core/v1/EnvVar"] = func() any { + knownTypes["core/v1/EnvVar"] = func() interface{} { return &corev1.EnvVar{} } - knownTypes["core/v1/EnvVarSource"] = func() any { + knownTypes["core/v1/EnvVarSource"] = func() interface{} { return &corev1.EnvVarSource{} } - knownTypes["core/v1/EphemeralContainer"] = func() any { + knownTypes["core/v1/EphemeralContainer"] = func() interface{} { return &corev1.EphemeralContainer{} } - knownTypes["core/v1/EphemeralContainerCommon"] = func() any { + knownTypes["core/v1/EphemeralContainerCommon"] = func() interface{} { return &corev1.EphemeralContainerCommon{} } - knownTypes["core/v1/EphemeralVolumeSource"] = func() any { + knownTypes["core/v1/EphemeralVolumeSource"] = func() interface{} { return &corev1.EphemeralVolumeSource{} } - knownTypes["core/v1/Event"] = func() any { + knownTypes["core/v1/Event"] = func() interface{} { return &corev1.Event{} } - knownTypes["core/v1/EventList"] = func() any { + knownTypes["core/v1/EventList"] = func() interface{} { return &corev1.EventList{} } - knownTypes["core/v1/EventSeries"] = func() any { + knownTypes["core/v1/EventSeries"] = func() interface{} { return &corev1.EventSeries{} } - knownTypes["core/v1/EventSource"] = func() any { + knownTypes["core/v1/EventSource"] = func() interface{} { return &corev1.EventSource{} } - knownTypes["core/v1/ExecAction"] = func() any { + knownTypes["core/v1/ExecAction"] = func() interface{} { return &corev1.ExecAction{} } - knownTypes["core/v1/FCVolumeSource"] = func() any { + knownTypes["core/v1/FCVolumeSource"] = func() interface{} { return &corev1.FCVolumeSource{} } - knownTypes["core/v1/FlexPersistentVolumeSource"] = func() any { + knownTypes["core/v1/FlexPersistentVolumeSource"] = func() interface{} { return &corev1.FlexPersistentVolumeSource{} } - knownTypes["core/v1/FlexVolumeSource"] = func() any { + knownTypes["core/v1/FlexVolumeSource"] = func() interface{} { return &corev1.FlexVolumeSource{} } - knownTypes["core/v1/FlockerVolumeSource"] = func() any { + knownTypes["core/v1/FlockerVolumeSource"] = func() interface{} { return &corev1.FlockerVolumeSource{} } - knownTypes["core/v1/GCEPersistentDiskVolumeSource"] = func() any { + knownTypes["core/v1/GCEPersistentDiskVolumeSource"] = func() interface{} { return &corev1.GCEPersistentDiskVolumeSource{} } - knownTypes["core/v1/GRPCAction"] = func() any { + knownTypes["core/v1/GRPCAction"] = func() interface{} { return &corev1.GRPCAction{} } - knownTypes["core/v1/GitRepoVolumeSource"] = func() any { + knownTypes["core/v1/GitRepoVolumeSource"] = func() interface{} { return &corev1.GitRepoVolumeSource{} } - knownTypes["core/v1/GlusterfsPersistentVolumeSource"] = func() any { + knownTypes["core/v1/GlusterfsPersistentVolumeSource"] = func() interface{} { return &corev1.GlusterfsPersistentVolumeSource{} } - knownTypes["core/v1/GlusterfsVolumeSource"] = func() any { + knownTypes["core/v1/GlusterfsVolumeSource"] = func() interface{} { return &corev1.GlusterfsVolumeSource{} } - knownTypes["core/v1/HTTPGetAction"] = func() any { + knownTypes["core/v1/HTTPGetAction"] = func() interface{} { return &corev1.HTTPGetAction{} } - knownTypes["core/v1/HTTPHeader"] = func() any { + knownTypes["core/v1/HTTPHeader"] = func() interface{} { return &corev1.HTTPHeader{} } - knownTypes["core/v1/HostAlias"] = func() any { + knownTypes["core/v1/HostAlias"] = func() interface{} { return &corev1.HostAlias{} } - knownTypes["core/v1/HostIP"] = func() any { + knownTypes["core/v1/HostIP"] = func() interface{} { return &corev1.HostIP{} } - knownTypes["core/v1/HostPathVolumeSource"] = func() any { + knownTypes["core/v1/HostPathVolumeSource"] = func() interface{} { return &corev1.HostPathVolumeSource{} } - knownTypes["core/v1/ISCSIPersistentVolumeSource"] = func() any { + knownTypes["core/v1/ISCSIPersistentVolumeSource"] = func() interface{} { return &corev1.ISCSIPersistentVolumeSource{} } - knownTypes["core/v1/ISCSIVolumeSource"] = func() any { + knownTypes["core/v1/ISCSIVolumeSource"] = func() interface{} { return &corev1.ISCSIVolumeSource{} } - knownTypes["core/v1/ImageVolumeSource"] = func() any { + knownTypes["core/v1/ImageVolumeSource"] = func() interface{} { return &corev1.ImageVolumeSource{} } - knownTypes["core/v1/KeyToPath"] = func() any { + knownTypes["core/v1/KeyToPath"] = func() interface{} { return &corev1.KeyToPath{} } - knownTypes["core/v1/Lifecycle"] = func() any { + knownTypes["core/v1/Lifecycle"] = func() interface{} { return &corev1.Lifecycle{} } - knownTypes["core/v1/LifecycleHandler"] = func() any { + knownTypes["core/v1/LifecycleHandler"] = func() interface{} { return &corev1.LifecycleHandler{} } - knownTypes["core/v1/LimitRange"] = func() any { + knownTypes["core/v1/LimitRange"] = func() interface{} { return &corev1.LimitRange{} } - knownTypes["core/v1/LimitRangeItem"] = func() any { + knownTypes["core/v1/LimitRangeItem"] = func() interface{} { return &corev1.LimitRangeItem{} } - knownTypes["core/v1/LimitRangeList"] = func() any { + knownTypes["core/v1/LimitRangeList"] = func() interface{} { return &corev1.LimitRangeList{} } - knownTypes["core/v1/LimitRangeSpec"] = func() any { + knownTypes["core/v1/LimitRangeSpec"] = func() interface{} { return &corev1.LimitRangeSpec{} } - knownTypes["core/v1/LinuxContainerUser"] = func() any { + knownTypes["core/v1/LinuxContainerUser"] = func() interface{} { return &corev1.LinuxContainerUser{} } - knownTypes["core/v1/List"] = func() any { + knownTypes["core/v1/List"] = func() interface{} { return &corev1.List{} } - knownTypes["core/v1/LoadBalancerIngress"] = func() any { + knownTypes["core/v1/LoadBalancerIngress"] = func() interface{} { return &corev1.LoadBalancerIngress{} } - knownTypes["core/v1/LoadBalancerStatus"] = func() any { + knownTypes["core/v1/LoadBalancerStatus"] = func() interface{} { return &corev1.LoadBalancerStatus{} } - knownTypes["core/v1/LocalObjectReference"] = func() any { + knownTypes["core/v1/LocalObjectReference"] = func() interface{} { return &corev1.LocalObjectReference{} } - knownTypes["core/v1/LocalVolumeSource"] = func() any { + knownTypes["core/v1/LocalVolumeSource"] = func() interface{} { return &corev1.LocalVolumeSource{} } - knownTypes["core/v1/ModifyVolumeStatus"] = func() any { + knownTypes["core/v1/ModifyVolumeStatus"] = func() interface{} { return &corev1.ModifyVolumeStatus{} } - knownTypes["core/v1/NFSVolumeSource"] = func() any { + knownTypes["core/v1/NFSVolumeSource"] = func() interface{} { return &corev1.NFSVolumeSource{} } - knownTypes["core/v1/Namespace"] = func() any { + knownTypes["core/v1/Namespace"] = func() interface{} { return &corev1.Namespace{} } - knownTypes["core/v1/NamespaceCondition"] = func() any { + knownTypes["core/v1/NamespaceCondition"] = func() interface{} { return &corev1.NamespaceCondition{} } - knownTypes["core/v1/NamespaceList"] = func() any { + knownTypes["core/v1/NamespaceList"] = func() interface{} { return &corev1.NamespaceList{} } - knownTypes["core/v1/NamespaceSpec"] = func() any { + knownTypes["core/v1/NamespaceSpec"] = func() interface{} { return &corev1.NamespaceSpec{} } - knownTypes["core/v1/NamespaceStatus"] = func() any { + knownTypes["core/v1/NamespaceStatus"] = func() interface{} { return &corev1.NamespaceStatus{} } - knownTypes["core/v1/Node"] = func() any { + knownTypes["core/v1/Node"] = func() interface{} { return &corev1.Node{} } - knownTypes["core/v1/NodeAddress"] = func() any { + knownTypes["core/v1/NodeAddress"] = func() interface{} { return &corev1.NodeAddress{} } - knownTypes["core/v1/NodeAffinity"] = func() any { + knownTypes["core/v1/NodeAffinity"] = func() interface{} { return &corev1.NodeAffinity{} } - knownTypes["core/v1/NodeCondition"] = func() any { + knownTypes["core/v1/NodeCondition"] = func() interface{} { return &corev1.NodeCondition{} } - knownTypes["core/v1/NodeConfigSource"] = func() any { + knownTypes["core/v1/NodeConfigSource"] = func() interface{} { return &corev1.NodeConfigSource{} } - knownTypes["core/v1/NodeConfigStatus"] = func() any { + knownTypes["core/v1/NodeConfigStatus"] = func() interface{} { return &corev1.NodeConfigStatus{} } - knownTypes["core/v1/NodeDaemonEndpoints"] = func() any { + knownTypes["core/v1/NodeDaemonEndpoints"] = func() interface{} { return &corev1.NodeDaemonEndpoints{} } - knownTypes["core/v1/NodeFeatures"] = func() any { + knownTypes["core/v1/NodeFeatures"] = func() interface{} { return &corev1.NodeFeatures{} } - knownTypes["core/v1/NodeList"] = func() any { + knownTypes["core/v1/NodeList"] = func() interface{} { return &corev1.NodeList{} } - knownTypes["core/v1/NodeProxyOptions"] = func() any { + knownTypes["core/v1/NodeProxyOptions"] = func() interface{} { return &corev1.NodeProxyOptions{} } - knownTypes["core/v1/NodeRuntimeHandler"] = func() any { + knownTypes["core/v1/NodeRuntimeHandler"] = func() interface{} { return &corev1.NodeRuntimeHandler{} } - knownTypes["core/v1/NodeRuntimeHandlerFeatures"] = func() any { + knownTypes["core/v1/NodeRuntimeHandlerFeatures"] = func() interface{} { return &corev1.NodeRuntimeHandlerFeatures{} } - knownTypes["core/v1/NodeSelector"] = func() any { + knownTypes["core/v1/NodeSelector"] = func() interface{} { return &corev1.NodeSelector{} } - knownTypes["core/v1/NodeSelectorRequirement"] = func() any { + knownTypes["core/v1/NodeSelectorRequirement"] = func() interface{} { return &corev1.NodeSelectorRequirement{} } - knownTypes["core/v1/NodeSelectorTerm"] = func() any { + knownTypes["core/v1/NodeSelectorTerm"] = func() interface{} { return &corev1.NodeSelectorTerm{} } - knownTypes["core/v1/NodeSpec"] = func() any { + knownTypes["core/v1/NodeSpec"] = func() interface{} { return &corev1.NodeSpec{} } - knownTypes["core/v1/NodeStatus"] = func() any { + knownTypes["core/v1/NodeStatus"] = func() interface{} { return &corev1.NodeStatus{} } - knownTypes["core/v1/NodeSystemInfo"] = func() any { + knownTypes["core/v1/NodeSystemInfo"] = func() interface{} { return &corev1.NodeSystemInfo{} } - knownTypes["core/v1/ObjectFieldSelector"] = func() any { + knownTypes["core/v1/ObjectFieldSelector"] = func() interface{} { return &corev1.ObjectFieldSelector{} } - knownTypes["core/v1/ObjectReference"] = func() any { + knownTypes["core/v1/ObjectReference"] = func() interface{} { return &corev1.ObjectReference{} } - knownTypes["core/v1/PersistentVolume"] = func() any { + knownTypes["core/v1/PersistentVolume"] = func() interface{} { return &corev1.PersistentVolume{} } - knownTypes["core/v1/PersistentVolumeClaim"] = func() any { + knownTypes["core/v1/PersistentVolumeClaim"] = func() interface{} { return &corev1.PersistentVolumeClaim{} } - knownTypes["core/v1/PersistentVolumeClaimCondition"] = func() any { + knownTypes["core/v1/PersistentVolumeClaimCondition"] = func() interface{} { return &corev1.PersistentVolumeClaimCondition{} } - knownTypes["core/v1/PersistentVolumeClaimList"] = func() any { + knownTypes["core/v1/PersistentVolumeClaimList"] = func() interface{} { return &corev1.PersistentVolumeClaimList{} } - knownTypes["core/v1/PersistentVolumeClaimSpec"] = func() any { + knownTypes["core/v1/PersistentVolumeClaimSpec"] = func() interface{} { return &corev1.PersistentVolumeClaimSpec{} } - knownTypes["core/v1/PersistentVolumeClaimStatus"] = func() any { + knownTypes["core/v1/PersistentVolumeClaimStatus"] = func() interface{} { return &corev1.PersistentVolumeClaimStatus{} } - knownTypes["core/v1/PersistentVolumeClaimTemplate"] = func() any { + knownTypes["core/v1/PersistentVolumeClaimTemplate"] = func() interface{} { return &corev1.PersistentVolumeClaimTemplate{} } - knownTypes["core/v1/PersistentVolumeClaimVolumeSource"] = func() any { + knownTypes["core/v1/PersistentVolumeClaimVolumeSource"] = func() interface{} { return &corev1.PersistentVolumeClaimVolumeSource{} } - knownTypes["core/v1/PersistentVolumeList"] = func() any { + knownTypes["core/v1/PersistentVolumeList"] = func() interface{} { return &corev1.PersistentVolumeList{} } - knownTypes["core/v1/PersistentVolumeSource"] = func() any { + knownTypes["core/v1/PersistentVolumeSource"] = func() interface{} { return &corev1.PersistentVolumeSource{} } - knownTypes["core/v1/PersistentVolumeSpec"] = func() any { + knownTypes["core/v1/PersistentVolumeSpec"] = func() interface{} { return &corev1.PersistentVolumeSpec{} } - knownTypes["core/v1/PersistentVolumeStatus"] = func() any { + knownTypes["core/v1/PersistentVolumeStatus"] = func() interface{} { return &corev1.PersistentVolumeStatus{} } - knownTypes["core/v1/PhotonPersistentDiskVolumeSource"] = func() any { + knownTypes["core/v1/PhotonPersistentDiskVolumeSource"] = func() interface{} { return &corev1.PhotonPersistentDiskVolumeSource{} } - knownTypes["core/v1/Pod"] = func() any { + knownTypes["core/v1/Pod"] = func() interface{} { return &corev1.Pod{} } - knownTypes["core/v1/PodAffinity"] = func() any { + knownTypes["core/v1/PodAffinity"] = func() interface{} { return &corev1.PodAffinity{} } - knownTypes["core/v1/PodAffinityTerm"] = func() any { + knownTypes["core/v1/PodAffinityTerm"] = func() interface{} { return &corev1.PodAffinityTerm{} } - knownTypes["core/v1/PodAntiAffinity"] = func() any { + knownTypes["core/v1/PodAntiAffinity"] = func() interface{} { return &corev1.PodAntiAffinity{} } - knownTypes["core/v1/PodAttachOptions"] = func() any { + knownTypes["core/v1/PodAttachOptions"] = func() interface{} { return &corev1.PodAttachOptions{} } - knownTypes["core/v1/PodCondition"] = func() any { + knownTypes["core/v1/PodCondition"] = func() interface{} { return &corev1.PodCondition{} } - knownTypes["core/v1/PodDNSConfig"] = func() any { + knownTypes["core/v1/PodDNSConfig"] = func() interface{} { return &corev1.PodDNSConfig{} } - knownTypes["core/v1/PodDNSConfigOption"] = func() any { + knownTypes["core/v1/PodDNSConfigOption"] = func() interface{} { return &corev1.PodDNSConfigOption{} } - knownTypes["core/v1/PodExecOptions"] = func() any { + knownTypes["core/v1/PodExecOptions"] = func() interface{} { return &corev1.PodExecOptions{} } - knownTypes["core/v1/PodIP"] = func() any { + knownTypes["core/v1/PodIP"] = func() interface{} { return &corev1.PodIP{} } - knownTypes["core/v1/PodList"] = func() any { + knownTypes["core/v1/PodList"] = func() interface{} { return &corev1.PodList{} } - knownTypes["core/v1/PodLogOptions"] = func() any { + knownTypes["core/v1/PodLogOptions"] = func() interface{} { return &corev1.PodLogOptions{} } - knownTypes["core/v1/PodOS"] = func() any { + knownTypes["core/v1/PodOS"] = func() interface{} { return &corev1.PodOS{} } - knownTypes["core/v1/PodPortForwardOptions"] = func() any { + knownTypes["core/v1/PodPortForwardOptions"] = func() interface{} { return &corev1.PodPortForwardOptions{} } - knownTypes["core/v1/PodProxyOptions"] = func() any { + knownTypes["core/v1/PodProxyOptions"] = func() interface{} { return &corev1.PodProxyOptions{} } - knownTypes["core/v1/PodReadinessGate"] = func() any { + knownTypes["core/v1/PodReadinessGate"] = func() interface{} { return &corev1.PodReadinessGate{} } - knownTypes["core/v1/PodResourceClaim"] = func() any { + knownTypes["core/v1/PodResourceClaim"] = func() interface{} { return &corev1.PodResourceClaim{} } - knownTypes["core/v1/PodResourceClaimStatus"] = func() any { + knownTypes["core/v1/PodResourceClaimStatus"] = func() interface{} { return &corev1.PodResourceClaimStatus{} } - knownTypes["core/v1/PodSchedulingGate"] = func() any { + knownTypes["core/v1/PodSchedulingGate"] = func() interface{} { return &corev1.PodSchedulingGate{} } - knownTypes["core/v1/PodSecurityContext"] = func() any { + knownTypes["core/v1/PodSecurityContext"] = func() interface{} { return &corev1.PodSecurityContext{} } - knownTypes["core/v1/PodSignature"] = func() any { + knownTypes["core/v1/PodSignature"] = func() interface{} { return &corev1.PodSignature{} } - knownTypes["core/v1/PodSpec"] = func() any { + knownTypes["core/v1/PodSpec"] = func() interface{} { return &corev1.PodSpec{} } - knownTypes["core/v1/PodStatus"] = func() any { + knownTypes["core/v1/PodStatus"] = func() interface{} { return &corev1.PodStatus{} } - knownTypes["core/v1/PodStatusResult"] = func() any { + knownTypes["core/v1/PodStatusResult"] = func() interface{} { return &corev1.PodStatusResult{} } - knownTypes["core/v1/PodTemplate"] = func() any { + knownTypes["core/v1/PodTemplate"] = func() interface{} { return &corev1.PodTemplate{} } - knownTypes["core/v1/PodTemplateList"] = func() any { + knownTypes["core/v1/PodTemplateList"] = func() interface{} { return &corev1.PodTemplateList{} } - knownTypes["core/v1/PodTemplateSpec"] = func() any { + knownTypes["core/v1/PodTemplateSpec"] = func() interface{} { return &corev1.PodTemplateSpec{} } - knownTypes["core/v1/PortStatus"] = func() any { + knownTypes["core/v1/PortStatus"] = func() interface{} { return &corev1.PortStatus{} } - knownTypes["core/v1/PortworxVolumeSource"] = func() any { + knownTypes["core/v1/PortworxVolumeSource"] = func() interface{} { return &corev1.PortworxVolumeSource{} } - knownTypes["core/v1/Preconditions"] = func() any { + knownTypes["core/v1/Preconditions"] = func() interface{} { return &corev1.Preconditions{} } - knownTypes["core/v1/PreferAvoidPodsEntry"] = func() any { + knownTypes["core/v1/PreferAvoidPodsEntry"] = func() interface{} { return &corev1.PreferAvoidPodsEntry{} } - knownTypes["core/v1/PreferredSchedulingTerm"] = func() any { + knownTypes["core/v1/PreferredSchedulingTerm"] = func() interface{} { return &corev1.PreferredSchedulingTerm{} } - knownTypes["core/v1/Probe"] = func() any { + knownTypes["core/v1/Probe"] = func() interface{} { return &corev1.Probe{} } - knownTypes["core/v1/ProbeHandler"] = func() any { + knownTypes["core/v1/ProbeHandler"] = func() interface{} { return &corev1.ProbeHandler{} } - knownTypes["core/v1/ProjectedVolumeSource"] = func() any { + knownTypes["core/v1/ProjectedVolumeSource"] = func() interface{} { return &corev1.ProjectedVolumeSource{} } - knownTypes["core/v1/QuobyteVolumeSource"] = func() any { + knownTypes["core/v1/QuobyteVolumeSource"] = func() interface{} { return &corev1.QuobyteVolumeSource{} } - knownTypes["core/v1/RBDPersistentVolumeSource"] = func() any { + knownTypes["core/v1/RBDPersistentVolumeSource"] = func() interface{} { return &corev1.RBDPersistentVolumeSource{} } - knownTypes["core/v1/RBDVolumeSource"] = func() any { + knownTypes["core/v1/RBDVolumeSource"] = func() interface{} { return &corev1.RBDVolumeSource{} } - knownTypes["core/v1/RangeAllocation"] = func() any { + knownTypes["core/v1/RangeAllocation"] = func() interface{} { return &corev1.RangeAllocation{} } - knownTypes["core/v1/ReplicationController"] = func() any { + knownTypes["core/v1/ReplicationController"] = func() interface{} { return &corev1.ReplicationController{} } - knownTypes["core/v1/ReplicationControllerCondition"] = func() any { + knownTypes["core/v1/ReplicationControllerCondition"] = func() interface{} { return &corev1.ReplicationControllerCondition{} } - knownTypes["core/v1/ReplicationControllerList"] = func() any { + knownTypes["core/v1/ReplicationControllerList"] = func() interface{} { return &corev1.ReplicationControllerList{} } - knownTypes["core/v1/ReplicationControllerSpec"] = func() any { + knownTypes["core/v1/ReplicationControllerSpec"] = func() interface{} { return &corev1.ReplicationControllerSpec{} } - knownTypes["core/v1/ReplicationControllerStatus"] = func() any { + knownTypes["core/v1/ReplicationControllerStatus"] = func() interface{} { return &corev1.ReplicationControllerStatus{} } - knownTypes["core/v1/ResourceClaim"] = func() any { + knownTypes["core/v1/ResourceClaim"] = func() interface{} { return &corev1.ResourceClaim{} } - knownTypes["core/v1/ResourceFieldSelector"] = func() any { + knownTypes["core/v1/ResourceFieldSelector"] = func() interface{} { return &corev1.ResourceFieldSelector{} } - knownTypes["core/v1/ResourceHealth"] = func() any { + knownTypes["core/v1/ResourceHealth"] = func() interface{} { return &corev1.ResourceHealth{} } - knownTypes["core/v1/ResourceList"] = func() any { + knownTypes["core/v1/ResourceList"] = func() interface{} { return &corev1.ResourceList{} } - knownTypes["core/v1/ResourceQuota"] = func() any { + knownTypes["core/v1/ResourceQuota"] = func() interface{} { return &corev1.ResourceQuota{} } - knownTypes["core/v1/ResourceQuotaList"] = func() any { + knownTypes["core/v1/ResourceQuotaList"] = func() interface{} { return &corev1.ResourceQuotaList{} } - knownTypes["core/v1/ResourceQuotaSpec"] = func() any { + knownTypes["core/v1/ResourceQuotaSpec"] = func() interface{} { return &corev1.ResourceQuotaSpec{} } - knownTypes["core/v1/ResourceQuotaStatus"] = func() any { + knownTypes["core/v1/ResourceQuotaStatus"] = func() interface{} { return &corev1.ResourceQuotaStatus{} } - knownTypes["core/v1/ResourceRequirements"] = func() any { + knownTypes["core/v1/ResourceRequirements"] = func() interface{} { return &corev1.ResourceRequirements{} } - knownTypes["core/v1/ResourceStatus"] = func() any { + knownTypes["core/v1/ResourceStatus"] = func() interface{} { return &corev1.ResourceStatus{} } - knownTypes["core/v1/SELinuxOptions"] = func() any { + knownTypes["core/v1/SELinuxOptions"] = func() interface{} { return &corev1.SELinuxOptions{} } - knownTypes["core/v1/ScaleIOPersistentVolumeSource"] = func() any { + knownTypes["core/v1/ScaleIOPersistentVolumeSource"] = func() interface{} { return &corev1.ScaleIOPersistentVolumeSource{} } - knownTypes["core/v1/ScaleIOVolumeSource"] = func() any { + knownTypes["core/v1/ScaleIOVolumeSource"] = func() interface{} { return &corev1.ScaleIOVolumeSource{} } - knownTypes["core/v1/ScopeSelector"] = func() any { + knownTypes["core/v1/ScopeSelector"] = func() interface{} { return &corev1.ScopeSelector{} } - knownTypes["core/v1/ScopedResourceSelectorRequirement"] = func() any { + knownTypes["core/v1/ScopedResourceSelectorRequirement"] = func() interface{} { return &corev1.ScopedResourceSelectorRequirement{} } - knownTypes["core/v1/SeccompProfile"] = func() any { + knownTypes["core/v1/SeccompProfile"] = func() interface{} { return &corev1.SeccompProfile{} } - knownTypes["core/v1/Secret"] = func() any { + knownTypes["core/v1/Secret"] = func() interface{} { return &corev1.Secret{} } - knownTypes["core/v1/SecretEnvSource"] = func() any { + knownTypes["core/v1/SecretEnvSource"] = func() interface{} { return &corev1.SecretEnvSource{} } - knownTypes["core/v1/SecretKeySelector"] = func() any { + knownTypes["core/v1/SecretKeySelector"] = func() interface{} { return &corev1.SecretKeySelector{} } - knownTypes["core/v1/SecretList"] = func() any { + knownTypes["core/v1/SecretList"] = func() interface{} { return &corev1.SecretList{} } - knownTypes["core/v1/SecretProjection"] = func() any { + knownTypes["core/v1/SecretProjection"] = func() interface{} { return &corev1.SecretProjection{} } - knownTypes["core/v1/SecretReference"] = func() any { + knownTypes["core/v1/SecretReference"] = func() interface{} { return &corev1.SecretReference{} } - knownTypes["core/v1/SecretVolumeSource"] = func() any { + knownTypes["core/v1/SecretVolumeSource"] = func() interface{} { return &corev1.SecretVolumeSource{} } - knownTypes["core/v1/SecurityContext"] = func() any { + knownTypes["core/v1/SecurityContext"] = func() interface{} { return &corev1.SecurityContext{} } - knownTypes["core/v1/SerializedReference"] = func() any { + knownTypes["core/v1/SerializedReference"] = func() interface{} { return &corev1.SerializedReference{} } - knownTypes["core/v1/Service"] = func() any { + knownTypes["core/v1/Service"] = func() interface{} { return &corev1.Service{} } - knownTypes["core/v1/ServiceAccount"] = func() any { + knownTypes["core/v1/ServiceAccount"] = func() interface{} { return &corev1.ServiceAccount{} } - knownTypes["core/v1/ServiceAccountList"] = func() any { + knownTypes["core/v1/ServiceAccountList"] = func() interface{} { return &corev1.ServiceAccountList{} } - knownTypes["core/v1/ServiceAccountTokenProjection"] = func() any { + knownTypes["core/v1/ServiceAccountTokenProjection"] = func() interface{} { return &corev1.ServiceAccountTokenProjection{} } - knownTypes["core/v1/ServiceList"] = func() any { + knownTypes["core/v1/ServiceList"] = func() interface{} { return &corev1.ServiceList{} } - knownTypes["core/v1/ServicePort"] = func() any { + knownTypes["core/v1/ServicePort"] = func() interface{} { return &corev1.ServicePort{} } - knownTypes["core/v1/ServiceProxyOptions"] = func() any { + knownTypes["core/v1/ServiceProxyOptions"] = func() interface{} { return &corev1.ServiceProxyOptions{} } - knownTypes["core/v1/ServiceSpec"] = func() any { + knownTypes["core/v1/ServiceSpec"] = func() interface{} { return &corev1.ServiceSpec{} } - knownTypes["core/v1/ServiceStatus"] = func() any { + knownTypes["core/v1/ServiceStatus"] = func() interface{} { return &corev1.ServiceStatus{} } - knownTypes["core/v1/SessionAffinityConfig"] = func() any { + knownTypes["core/v1/SessionAffinityConfig"] = func() interface{} { return &corev1.SessionAffinityConfig{} } - knownTypes["core/v1/SleepAction"] = func() any { + knownTypes["core/v1/SleepAction"] = func() interface{} { return &corev1.SleepAction{} } - knownTypes["core/v1/StorageOSPersistentVolumeSource"] = func() any { + knownTypes["core/v1/StorageOSPersistentVolumeSource"] = func() interface{} { return &corev1.StorageOSPersistentVolumeSource{} } - knownTypes["core/v1/StorageOSVolumeSource"] = func() any { + knownTypes["core/v1/StorageOSVolumeSource"] = func() interface{} { return &corev1.StorageOSVolumeSource{} } - knownTypes["core/v1/Sysctl"] = func() any { + knownTypes["core/v1/Sysctl"] = func() interface{} { return &corev1.Sysctl{} } - knownTypes["core/v1/TCPSocketAction"] = func() any { + knownTypes["core/v1/TCPSocketAction"] = func() interface{} { return &corev1.TCPSocketAction{} } - knownTypes["core/v1/Taint"] = func() any { + knownTypes["core/v1/Taint"] = func() interface{} { return &corev1.Taint{} } - knownTypes["core/v1/Toleration"] = func() any { + knownTypes["core/v1/Toleration"] = func() interface{} { return &corev1.Toleration{} } - knownTypes["core/v1/TopologySelectorLabelRequirement"] = func() any { + knownTypes["core/v1/TopologySelectorLabelRequirement"] = func() interface{} { return &corev1.TopologySelectorLabelRequirement{} } - knownTypes["core/v1/TopologySelectorTerm"] = func() any { + knownTypes["core/v1/TopologySelectorTerm"] = func() interface{} { return &corev1.TopologySelectorTerm{} } - knownTypes["core/v1/TopologySpreadConstraint"] = func() any { + knownTypes["core/v1/TopologySpreadConstraint"] = func() interface{} { return &corev1.TopologySpreadConstraint{} } - knownTypes["core/v1/TypedLocalObjectReference"] = func() any { + knownTypes["core/v1/TypedLocalObjectReference"] = func() interface{} { return &corev1.TypedLocalObjectReference{} } - knownTypes["core/v1/TypedObjectReference"] = func() any { + knownTypes["core/v1/TypedObjectReference"] = func() interface{} { return &corev1.TypedObjectReference{} } - knownTypes["core/v1/Volume"] = func() any { + knownTypes["core/v1/Volume"] = func() interface{} { return &corev1.Volume{} } - knownTypes["core/v1/VolumeDevice"] = func() any { + knownTypes["core/v1/VolumeDevice"] = func() interface{} { return &corev1.VolumeDevice{} } - knownTypes["core/v1/VolumeMount"] = func() any { + knownTypes["core/v1/VolumeMount"] = func() interface{} { return &corev1.VolumeMount{} } - knownTypes["core/v1/VolumeMountStatus"] = func() any { + knownTypes["core/v1/VolumeMountStatus"] = func() interface{} { return &corev1.VolumeMountStatus{} } - knownTypes["core/v1/VolumeNodeAffinity"] = func() any { + knownTypes["core/v1/VolumeNodeAffinity"] = func() interface{} { return &corev1.VolumeNodeAffinity{} } - knownTypes["core/v1/VolumeProjection"] = func() any { + knownTypes["core/v1/VolumeProjection"] = func() interface{} { return &corev1.VolumeProjection{} } - knownTypes["core/v1/VolumeResourceRequirements"] = func() any { + knownTypes["core/v1/VolumeResourceRequirements"] = func() interface{} { return &corev1.VolumeResourceRequirements{} } - knownTypes["core/v1/VolumeSource"] = func() any { + knownTypes["core/v1/VolumeSource"] = func() interface{} { return &corev1.VolumeSource{} } - knownTypes["core/v1/VsphereVirtualDiskVolumeSource"] = func() any { + knownTypes["core/v1/VsphereVirtualDiskVolumeSource"] = func() interface{} { return &corev1.VsphereVirtualDiskVolumeSource{} } - knownTypes["core/v1/WeightedPodAffinityTerm"] = func() any { + knownTypes["core/v1/WeightedPodAffinityTerm"] = func() interface{} { return &corev1.WeightedPodAffinityTerm{} } - knownTypes["core/v1/WindowsSecurityContextOptions"] = func() any { + knownTypes["core/v1/WindowsSecurityContextOptions"] = func() interface{} { return &corev1.WindowsSecurityContextOptions{} } } diff --git a/util/argo/normalizers/diff_normalizer.go b/util/argo/normalizers/diff_normalizer.go index 5fccbe8e03..ec2982dbf9 100644 --- a/util/argo/normalizers/diff_normalizer.go +++ b/util/argo/normalizers/diff_normalizer.go @@ -15,8 +15,8 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/glob" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/glob" ) const ( @@ -70,8 +70,8 @@ type jqNormalizerPatch struct { } func (np *jqNormalizerPatch) Apply(data []byte) ([]byte, error) { - dataJSON := make(map[string]any) - err := json.Unmarshal(data, &dataJSON) + dataJson := make(map[string]interface{}) + err := json.Unmarshal(data, &dataJson) if err != nil { return nil, err } @@ -79,10 +79,10 @@ func (np *jqNormalizerPatch) Apply(data []byte) ([]byte, error) { ctx, cancel := context.WithTimeout(context.Background(), np.jqExecutionTimeout) defer cancel() - iter := np.code.RunWithContext(ctx, dataJSON) + iter := np.code.RunWithContext(ctx, dataJson) first, ok := iter.Next() if !ok { - return nil, errors.New("JQ patch did not return any data") + return nil, fmt.Errorf("JQ patch did not return any data") } if err, ok = first.(error); ok { if errors.Is(err, context.DeadlineExceeded) { @@ -92,7 +92,7 @@ func (np *jqNormalizerPatch) Apply(data []byte) ([]byte, error) { } _, ok = iter.Next() if ok { - return nil, errors.New("JQ patch returned multiple objects") + return nil, fmt.Errorf("JQ patch returned multiple objects") } patchedData, err := json.Marshal(first) @@ -184,7 +184,7 @@ func NewIgnoreNormalizer(ignore []v1alpha1.ResourceIgnoreDifferences, overrides // Normalize removes fields from supplied resource using json paths from matching items of specified resources ignored differences list func (n *ignoreNormalizer) Normalize(un *unstructured.Unstructured) error { if un == nil { - return errors.New("invalid argument: unstructured is nil") + return fmt.Errorf("invalid argument: unstructured is nil") } matched := make([]normalizerPatch, 0) for _, patch := range n.patches { diff --git a/util/argo/normalizers/diff_normalizer_test.go b/util/argo/normalizers/diff_normalizer_test.go index 3871a35d56..8feb8b3467 100644 --- a/util/argo/normalizers/diff_normalizer_test.go +++ b/util/argo/normalizers/diff_normalizer_test.go @@ -2,7 +2,7 @@ package normalizers import ( "encoding/json" - "errors" + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -10,8 +10,8 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test" ) func TestNormalizeObjectWithMatchedGroupKind(t *testing.T) { @@ -167,9 +167,9 @@ func TestNormalizeJQPathExpression(t *testing.T) { deployment := test.NewDeployment() - var initContainers []any - initContainers = append(initContainers, map[string]any{"name": "init-container-0"}) - initContainers = append(initContainers, map[string]any{"name": "init-container-1"}) + var initContainers []interface{} + initContainers = append(initContainers, map[string]interface{}{"name": "init-container-0"}) + initContainers = append(initContainers, map[string]interface{}{"name": "init-container-1"}) err = unstructured.SetNestedSlice(deployment.Object, initContainers, "spec", "template", "spec", "initContainers") require.NoError(t, err) @@ -185,7 +185,7 @@ func TestNormalizeJQPathExpression(t *testing.T) { assert.True(t, has) assert.Len(t, actualInitContainers, 1) - actualInitContainerName, has, err := unstructured.NestedString(actualInitContainers[0].(map[string]any), "name") + actualInitContainerName, has, err := unstructured.NestedString(actualInitContainers[0].(map[string]interface{}), "name") require.NoError(t, err) assert.True(t, has) assert.Equal(t, "init-container-1", actualInitContainerName) @@ -250,7 +250,7 @@ func TestNormalizeExpectedErrorAreSilenced(t *testing.T) { _, err = jqPatch.Apply(deploymentData) assert.False(t, shouldLogError(err)) - assert.True(t, shouldLogError(errors.New("An error that should not be ignored"))) + assert.True(t, shouldLogError(fmt.Errorf("An error that should not be ignored"))) } func TestJqPathExpressionFailWithTimeout(t *testing.T) { diff --git a/util/argo/normalizers/knowntypes_normalizer.go b/util/argo/normalizers/knowntypes_normalizer.go index 97a5362c6b..f96a366a75 100644 --- a/util/argo/normalizers/knowntypes_normalizer.go +++ b/util/argo/normalizers/knowntypes_normalizer.go @@ -6,22 +6,22 @@ import ( "strings" log "github.com/sirupsen/logrus" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "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" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) -//go:generate go run github.com/argoproj/argo-cd/v3/hack/known_types corev1 k8s.io/api/core/v1 corev1_known_types.go --docs diffing_known_types.txt -var knownTypes = map[string]func() any{} +//go:generate go run github.com/argoproj/argo-cd/v2/hack/known_types corev1 k8s.io/api/core/v1 corev1_known_types.go --docs diffing_known_types.txt +var knownTypes = map[string]func() interface{}{} type knownTypeField struct { fieldPath []string - newFieldFn func() any + newFieldFn func() interface{} } type knownTypesNormalizer struct { @@ -30,10 +30,10 @@ type knownTypesNormalizer struct { // Register some non-code-generated types here. The bulk of them are in corev1_known_types.go func init() { - knownTypes["core/Quantity"] = func() any { + knownTypes["core/Quantity"] = func() interface{} { return &resource.Quantity{} } - knownTypes["meta/v1/Duration"] = func() any { + knownTypes["meta/v1/Duration"] = func() interface{} { return &metav1.Duration{} } } @@ -62,8 +62,8 @@ func (n *knownTypesNormalizer) ensureDefaultCRDsConfigured() { if _, ok := n.typeFields[rolloutGK]; !ok { n.typeFields[rolloutGK] = []knownTypeField{{ fieldPath: []string{"spec", "template", "spec"}, - newFieldFn: func() any { - return &corev1.PodSpec{} + newFieldFn: func() interface{} { + return &v1.PodSpec{} }, }} } @@ -81,15 +81,15 @@ func (n *knownTypesNormalizer) addKnownField(gk schema.GroupKind, fieldPath stri return nil } -func normalize(obj map[string]any, field knownTypeField, fieldPath []string) error { +func normalize(obj map[string]interface{}, field knownTypeField, fieldPath []string) error { for i := range fieldPath { if nestedField, ok, err := unstructured.NestedFieldNoCopy(obj, fieldPath[:i+1]...); err == nil && ok { - items, ok := nestedField.([]any) + items, ok := nestedField.([]interface{}) if !ok { continue } for j := range items { - item, ok := items[j].(map[string]any) + item, ok := items[j].(map[string]interface{}) if !ok { continue } @@ -125,7 +125,7 @@ func normalize(obj map[string]any, field knownTypeField, fieldPath []string) err return nil } -func remarshal(fieldVal any, field knownTypeField) (any, error) { +func remarshal(fieldVal interface{}, field knownTypeField) (interface{}, error) { data, err := json.Marshal(fieldVal) if err != nil { return nil, err @@ -139,7 +139,7 @@ func remarshal(fieldVal any, field knownTypeField) (any, error) { if err != nil { return nil, err } - var newFieldVal any + var newFieldVal interface{} err = json.Unmarshal(data, &newFieldVal) if err != nil { return nil, err diff --git a/util/argo/normalizers/knowntypes_normalizer_test.go b/util/argo/normalizers/knowntypes_normalizer_test.go index d91cdef50a..ea2a66ab9d 100644 --- a/util/argo/normalizers/knowntypes_normalizer_test.go +++ b/util/argo/normalizers/knowntypes_normalizer_test.go @@ -6,10 +6,10 @@ import ( "strings" "testing" - "github.com/argoproj/argo-cd/v3/pkg/apis/application" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -49,7 +49,8 @@ func mustUnmarshalYAML(yamlStr string) *unstructured.Unstructured { return un } -func nestedSliceMap(obj map[string]any, i int, path ...string) (map[string]any, error) { +// nolint:unparam +func nestedSliceMap(obj map[string]interface{}, i int, path ...string) (map[string]interface{}, error) { items, ok, err := unstructured.NestedSlice(obj, path...) if err != nil { return nil, err @@ -60,11 +61,11 @@ func nestedSliceMap(obj map[string]any, i int, path ...string) (map[string]any, if len(items) < i { return nil, fmt.Errorf("field %s has less than %d items", strings.Join(path, "."), i) } - item, ok := items[i].(map[string]any) - if !ok { + if item, ok := items[i].(map[string]interface{}); !ok { return nil, fmt.Errorf("field %s[%d] is not map", strings.Join(path, "."), i) + } else { + return item, nil } - return item, nil } func TestNormalize_MapField(t *testing.T) { diff --git a/util/argo/normalizers/util.go b/util/argo/normalizers/util.go index 91af12d6a4..289c8bcccd 100644 --- a/util/argo/normalizers/util.go +++ b/util/argo/normalizers/util.go @@ -9,13 +9,12 @@ func getGroupKindForOverrideKey(key string) (string, string, error) { var group, kind string parts := strings.Split(key, "/") - switch len(parts) { - case 2: + if len(parts) == 2 { group = parts[0] kind = parts[1] - case 1: + } else if len(parts) == 1 { kind = parts[0] - default: + } else { return "", "", fmt.Errorf("override key must be / or , got: '%s' ", key) } return group, kind, nil diff --git a/util/argo/resource_tracking.go b/util/argo/resource_tracking.go index ac1535d52d..5079a355be 100644 --- a/util/argo/resource_tracking.go +++ b/util/argo/resource_tracking.go @@ -9,21 +9,29 @@ import ( kubeutil "github.com/argoproj/gitops-engine/pkg/utils/kube" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/kube" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/kube" + argokube "github.com/argoproj/argo-cd/v2/util/kube" + "github.com/argoproj/argo-cd/v2/util/settings" +) + +const ( + TrackingMethodAnnotation v1alpha1.TrackingMethod = "annotation" + TrackingMethodLabel v1alpha1.TrackingMethod = "label" + TrackingMethodAnnotationAndLabel v1alpha1.TrackingMethod = "annotation+label" ) var ( - ErrWrongResourceTrackingFormat = errors.New("wrong resource tracking format, should be :/:/") - LabelMaxLength = 63 - OkEndPattern = regexp.MustCompile("[a-zA-Z0-9]$") + WrongResourceTrackingFormat = fmt.Errorf("wrong resource tracking format, should be :/:/") + LabelMaxLength = 63 + OkEndPattern = regexp.MustCompile("[a-zA-Z0-9]$") ) // ResourceTracking defines methods which allow setup and retrieve tracking information to resource type ResourceTracking interface { GetAppName(un *unstructured.Unstructured, key string, trackingMethod v1alpha1.TrackingMethod, installationID string) string - GetAppInstance(un *unstructured.Unstructured, trackingMethod v1alpha1.TrackingMethod, installationID string) *AppInstanceValue + 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) @@ -45,15 +53,24 @@ func NewResourceTracking() ResourceTracking { return &resourceTracking{} } +// GetTrackingMethod retrieve tracking method from settings +func GetTrackingMethod(settingsMgr *settings.SettingsManager) v1alpha1.TrackingMethod { + tm, err := settingsMgr.GetTrackingMethod() + if err != nil || tm == "" { + return TrackingMethodLabel + } + return v1alpha1.TrackingMethod(tm) +} + func IsOldTrackingMethod(trackingMethod string) bool { - return trackingMethod == "" || trackingMethod == string(v1alpha1.TrackingMethodLabel) + return trackingMethod == "" || trackingMethod == string(TrackingMethodLabel) } func (rt *resourceTracking) getAppInstanceValue(un *unstructured.Unstructured, installationID string) *AppInstanceValue { if installationID != "" && un.GetAnnotations() == nil || un.GetAnnotations()[common.AnnotationInstallationID] != installationID { return nil } - appInstanceAnnotation, err := kube.GetAppInstanceAnnotation(un, common.AnnotationKeyAppInstance) + appInstanceAnnotation, err := argokube.GetAppInstanceAnnotation(un, common.AnnotationKeyAppInstance) if err != nil { return nil } @@ -74,27 +91,31 @@ func (rt *resourceTracking) GetAppName(un *unstructured.Unstructured, key string return "" } switch trackingMethod { - case v1alpha1.TrackingMethodLabel: - label, err := kube.GetAppInstanceLabel(un, key) + case TrackingMethodLabel: + label, err := argokube.GetAppInstanceLabel(un, key) if err != nil { return "" } return label - case v1alpha1.TrackingMethodAnnotationAndLabel: + case TrackingMethodAnnotationAndLabel: return retrieveAppInstanceValue() - case v1alpha1.TrackingMethodAnnotation: + case TrackingMethodAnnotation: return retrieveAppInstanceValue() default: - return retrieveAppInstanceValue() + label, err := argokube.GetAppInstanceLabel(un, key) + if err != nil { + return "" + } + return label } } // 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, trackingMethod v1alpha1.TrackingMethod, instanceID string) *AppInstanceValue { +func (rt *resourceTracking) GetAppInstance(un *unstructured.Unstructured, key string, trackingMethod v1alpha1.TrackingMethod, instanceID string) *AppInstanceValue { switch trackingMethod { - case v1alpha1.TrackingMethodAnnotation, v1alpha1.TrackingMethodAnnotationAndLabel: + case TrackingMethodAnnotation, TrackingMethodAnnotationAndLabel: return rt.getAppInstanceValue(un, instanceID) default: return nil @@ -125,26 +146,26 @@ func (rt *resourceTracking) SetAppInstance(un *unstructured.Unstructured, key, v setAppInstanceAnnotation := func() error { appInstanceValue := UnstructuredToAppInstanceValue(un, val, namespace) if instanceID != "" { - if err := kube.SetAppInstanceAnnotation(un, common.AnnotationInstallationID, instanceID); err != nil { + if err := argokube.SetAppInstanceAnnotation(un, common.AnnotationInstallationID, instanceID); err != nil { return err } } else { - if err := kube.RemoveAnnotation(un, common.AnnotationInstallationID); err != nil { + if err := argokube.RemoveAnnotation(un, common.AnnotationInstallationID); err != nil { return err } } - return kube.SetAppInstanceAnnotation(un, common.AnnotationKeyAppInstance, rt.BuildAppInstanceValue(appInstanceValue)) + return argokube.SetAppInstanceAnnotation(un, common.AnnotationKeyAppInstance, rt.BuildAppInstanceValue(appInstanceValue)) } switch trackingMethod { - case v1alpha1.TrackingMethodLabel: - err := kube.SetAppInstanceLabel(un, key, val) + case TrackingMethodLabel: + err := argokube.SetAppInstanceLabel(un, key, val) if err != nil { return fmt.Errorf("failed to set app instance label: %w", err) } return nil - case v1alpha1.TrackingMethodAnnotation: + case TrackingMethodAnnotation: return setAppInstanceAnnotation() - case v1alpha1.TrackingMethodAnnotationAndLabel: + case TrackingMethodAnnotationAndLabel: err := setAppInstanceAnnotation() if err != nil { return err @@ -160,13 +181,17 @@ func (rt *resourceTracking) SetAppInstance(un *unstructured.Unstructured, key, v val = val[:len(val)-1] } } - err = kube.SetAppInstanceLabel(un, key, val) + err = argokube.SetAppInstanceLabel(un, key, val) if err != nil { return fmt.Errorf("failed to set app instance label: %w", err) } return nil default: - return setAppInstanceAnnotation() + err := argokube.SetAppInstanceLabel(un, key, val) + if err != nil { + return fmt.Errorf("failed to set app instance label: %w", err) + } + return nil } } @@ -181,15 +206,15 @@ func (rt *resourceTracking) ParseAppInstanceValue(value string) (*AppInstanceVal parts := strings.SplitN(value, ":", 3) appInstanceValue.ApplicationName = parts[0] if len(parts) != 3 { - return nil, ErrWrongResourceTrackingFormat + return nil, WrongResourceTrackingFormat } groupParts := strings.Split(parts[1], "/") if len(groupParts) != 2 { - return nil, ErrWrongResourceTrackingFormat + return nil, WrongResourceTrackingFormat } nsParts := strings.Split(parts[2], "/") if len(nsParts) != 2 { - return nil, ErrWrongResourceTrackingFormat + return nil, WrongResourceTrackingFormat } appInstanceValue.Group = groupParts[0] appInstanceValue.Kind = groupParts[1] @@ -222,21 +247,21 @@ func (rt *resourceTracking) Normalize(config, live *unstructured.Unstructured, l return nil } - annotation, err := kube.GetAppInstanceAnnotation(config, common.AnnotationKeyAppInstance) + annotation, err := argokube.GetAppInstanceAnnotation(config, common.AnnotationKeyAppInstance) if err != nil { return err } - err = kube.SetAppInstanceAnnotation(live, common.AnnotationKeyAppInstance, annotation) + err = argokube.SetAppInstanceAnnotation(live, common.AnnotationKeyAppInstance, annotation) if err != nil { return err } - label, err = kube.GetAppInstanceLabel(config, labelKey) + label, err = argokube.GetAppInstanceLabel(config, labelKey) if err != nil { return fmt.Errorf("failed to get app instance label: %w", err) } if label == "" { - err = kube.RemoveLabel(live, labelKey) + err = argokube.RemoveLabel(live, labelKey) if err != nil { return fmt.Errorf("failed to remove app instance label: %w", err) } diff --git a/util/argo/resource_tracking_test.go b/util/argo/resource_tracking_test.go index 582d610e2b..0b613f31c5 100644 --- a/util/argo/resource_tracking_test.go +++ b/util/argo/resource_tracking_test.go @@ -4,15 +4,14 @@ import ( "os" "testing" - "github.com/argoproj/argo-cd/v3/util/kube" + "github.com/argoproj/argo-cd/v2/util/kube" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/yaml.v2" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/common" ) func TestSetAppInstanceLabel(t *testing.T) { @@ -25,9 +24,9 @@ func TestSetAppInstanceLabel(t *testing.T) { resourceTracking := NewResourceTracking() - err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app", "", v1alpha1.TrackingMethodLabel, "") + err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel, "") require.NoError(t, err) - app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, v1alpha1.TrackingMethodLabel, "") + app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodLabel, "") assert.Equal(t, "my-app", app) } @@ -41,10 +40,10 @@ func TestSetAppInstanceAnnotation(t *testing.T) { resourceTracking := NewResourceTracking() - err = resourceTracking.SetAppInstance(&obj, common.AnnotationKeyAppInstance, "my-app", "", v1alpha1.TrackingMethodAnnotation, "") + err = resourceTracking.SetAppInstance(&obj, common.AnnotationKeyAppInstance, "my-app", "", TrackingMethodAnnotation, "") require.NoError(t, err) - app := resourceTracking.GetAppName(&obj, common.AnnotationKeyAppInstance, v1alpha1.TrackingMethodAnnotation, "") + app := resourceTracking.GetAppName(&obj, common.AnnotationKeyAppInstance, TrackingMethodAnnotation, "") assert.Equal(t, "my-app", app) } @@ -57,10 +56,10 @@ func TestSetAppInstanceAnnotationAndLabel(t *testing.T) { resourceTracking := NewResourceTracking() - err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app", "", v1alpha1.TrackingMethodAnnotationAndLabel, "") + err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodAnnotationAndLabel, "") require.NoError(t, err) - app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, v1alpha1.TrackingMethodAnnotationAndLabel, "") + app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotationAndLabel, "") assert.Equal(t, "my-app", app) } @@ -73,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", "", v1alpha1.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, v1alpha1.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 @@ -93,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", "", v1alpha1.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, v1alpha1.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 @@ -113,7 +112,7 @@ func TestSetAppInstanceAnnotationAndLabelOutOfBounds(t *testing.T) { resourceTracking := NewResourceTracking() - err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "----------------------------------------------------------------", "", v1alpha1.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") } @@ -128,8 +127,8 @@ func TestSetAppInstanceAnnotationNotFound(t *testing.T) { resourceTracking := NewResourceTracking() - app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, v1alpha1.TrackingMethodAnnotation, "") - assert.Empty(t, app) + app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotation, "") + assert.Equal(t, "", app) } func TestParseAppInstanceValue(t *testing.T) { @@ -157,13 +156,13 @@ func TestParseAppInstanceValueColon(t *testing.T) { func TestParseAppInstanceValueWrongFormat1(t *testing.T) { resourceTracking := NewResourceTracking() _, err := resourceTracking.ParseAppInstanceValue("app") - require.ErrorIs(t, err, ErrWrongResourceTrackingFormat) + require.ErrorIs(t, err, WrongResourceTrackingFormat) } func TestParseAppInstanceValueWrongFormat2(t *testing.T) { resourceTracking := NewResourceTracking() _, err := resourceTracking.ParseAppInstanceValue("app;group/kind/ns") - require.ErrorIs(t, err, ErrWrongResourceTrackingFormat) + require.ErrorIs(t, err, WrongResourceTrackingFormat) } func TestParseAppInstanceValueCorrectFormat(t *testing.T) { @@ -187,15 +186,15 @@ 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", "", v1alpha1.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", "", v1alpha1.TrackingMethodAnnotation, "") + err = rt.SetAppInstance(configObj, common.AnnotationKeyAppInstance, "my-app2", "", TrackingMethodAnnotation, "") require.NoError(t, err) - _ = rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(v1alpha1.TrackingMethodAnnotation)) + _ = rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(TrackingMethodAnnotation)) // the normalization should affect add the new style annotation and drop old tracking label from live object annotation, err := kube.GetAppInstanceAnnotation(configObj, common.AnnotationKeyAppInstance) @@ -244,7 +243,7 @@ func TestResourceIdNormalizer_NormalizeCRD(t *testing.T) { }, } - require.NoError(t, rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(v1alpha1.TrackingMethodAnnotation))) + require.NoError(t, rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(TrackingMethodAnnotation))) // the normalization should not apply any changes to the live object require.NotContains(t, liveObj.GetAnnotations(), common.AnnotationKeyAppInstance) } @@ -254,17 +253,17 @@ 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", "", v1alpha1.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", "", v1alpha1.TrackingMethodAnnotation, "") + err = rt.SetAppInstance(configObj, common.AnnotationKeyAppInstance, "my-app2", "", TrackingMethodAnnotation, "") require.NoError(t, err) - err = rt.SetAppInstance(configObj, common.LabelKeyAppInstance, "my-app", "", v1alpha1.TrackingMethodLabel, "") + err = rt.SetAppInstance(configObj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel, "") require.NoError(t, err) - _ = rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(v1alpha1.TrackingMethodAnnotation)) + _ = rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(TrackingMethodAnnotation)) // the normalization should affect add the new style annotation and drop old tracking label from live object annotation, err := kube.GetAppInstanceAnnotation(configObj, common.AnnotationKeyAppInstance) @@ -275,5 +274,5 @@ func TestResourceIdNormalizer_Normalize_ConfigHasOldLabel(t *testing.T) { } func TestIsOldTrackingMethod(t *testing.T) { - assert.True(t, IsOldTrackingMethod(string(v1alpha1.TrackingMethodLabel))) + assert.True(t, IsOldTrackingMethod(string(TrackingMethodLabel))) } diff --git a/util/argo/testdata/desired_deployment.yaml b/util/argo/testdata/desired_deployment.yaml index 657af3344c..c945ea7bc4 100644 --- a/util/argo/testdata/desired_deployment.yaml +++ b/util/argo/testdata/desired_deployment.yaml @@ -17,7 +17,7 @@ spec: app: guestbook-ui spec: containers: - - image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1' + - image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1' name: guestbook-ui ports: - containerPort: 80 diff --git a/util/argo/testdata/live_deployment_with_managed_replica.yaml b/util/argo/testdata/live_deployment_with_managed_replica.yaml index df4afb2beb..15de5345e2 100644 --- a/util/argo/testdata/live_deployment_with_managed_replica.yaml +++ b/util/argo/testdata/live_deployment_with_managed_replica.yaml @@ -4,7 +4,7 @@ metadata: annotations: deployment.kubernetes.io/revision: "1" kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook"},"name":"kustomize-guestbook-ui","namespace":"default"},"spec":{"replicas":1,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui"}},"spec":{"containers":[{"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook-ui","ports":[{"containerPort":80}]}]}}}} + {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook"},"name":"kustomize-guestbook-ui","namespace":"default"},"spec":{"replicas":1,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-ui","ports":[{"containerPort":80}]}]}}}} creationTimestamp: "2021-12-01T20:36:10Z" generation: 4 labels: @@ -126,7 +126,7 @@ spec: app: guestbook-ui spec: containers: - - image: quay.io/argoprojlabs/argocd-e2e-container:0.1 + - image: gcr.io/heptio-images/ks-guestbook-demo:0.1 imagePullPolicy: IfNotPresent name: guestbook-ui ports: diff --git a/util/askpass/askpass.pb.go b/util/askpass/askpass.pb.go index 948b3e4099..c41b7336e7 100644 --- a/util/askpass/askpass.pb.go +++ b/util/askpass/askpass.pb.go @@ -149,8 +149,8 @@ var fileDescriptor_1c7c1d31cf056104 = []byte{ 0x49, 0xeb, 0xc1, 0xdc, 0x8d, 0xe9, 0x4a, 0x29, 0x19, 0xec, 0x92, 0x10, 0x67, 0x29, 0x31, 0x38, 0x59, 0x9e, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x51, 0xda, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x89, 0x45, 0xe9, 0xf9, 0x05, - 0x45, 0xf9, 0x59, 0x60, 0x86, 0x6e, 0x72, 0x8a, 0x7e, 0x99, 0xb1, 0x3e, 0x72, 0x68, 0x25, 0xb1, - 0x81, 0x83, 0xc9, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x68, 0xa8, 0xbe, 0x90, 0x44, 0x01, 0x00, + 0x45, 0xf9, 0x59, 0x60, 0x86, 0x6e, 0x72, 0x8a, 0x7e, 0x99, 0x91, 0x3e, 0x72, 0x68, 0x25, 0xb1, + 0x81, 0x83, 0xc9, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xa8, 0xcc, 0x96, 0x87, 0x44, 0x01, 0x00, 0x00, } diff --git a/util/askpass/askpass.proto b/util/askpass/askpass.proto index b10adb5925..f4c3788185 100644 --- a/util/askpass/askpass.proto +++ b/util/askpass/askpass.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v3/util/askpass"; +option go_package = "github.com/argoproj/argo-cd/v2/util/askpass"; package askpass; diff --git a/util/askpass/common.go b/util/askpass/common.go index d0df03c3ca..2a34cca52c 100644 --- a/util/askpass/common.go +++ b/util/askpass/common.go @@ -1,7 +1,7 @@ package askpass import ( - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/util/env" ) var SocketPath = "/tmp/reposerver-ask-pass.sock" diff --git a/util/askpass/server.go b/util/askpass/server.go index 65204a1651..b6a1bbfc48 100644 --- a/util/askpass/server.go +++ b/util/askpass/server.go @@ -12,8 +12,8 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/argoproj/argo-cd/v3/util/git" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/io" ) type Server interface { @@ -61,7 +61,7 @@ func (s *server) GetCredentials(_ context.Context, q *CredentialsRequest) (*Cred return &CredentialsResponse{Username: creds.Username, Password: creds.Password}, nil } -func (s *server) Start(path string) (utilio.Closer, error) { +func (s *server) Start(path string) (io.Closer, error) { _ = os.Remove(path) listener, err := net.Listen("unix", path) if err != nil { @@ -72,7 +72,7 @@ func (s *server) Start(path string) (utilio.Closer, error) { go func() { _ = server.Serve(listener) }() - return utilio.NewCloser(listener.Close), nil + return io.NewCloser(listener.Close), nil } func (s *server) Run() error { diff --git a/util/assets/assets.go b/util/assets/assets.go index fd5a73a0a2..3b53b226e0 100644 --- a/util/assets/assets.go +++ b/util/assets/assets.go @@ -1,7 +1,7 @@ package assets import ( - "github.com/argoproj/argo-cd/v3/assets" + "github.com/argoproj/argo-cd/v2/assets" ) var ( diff --git a/util/buffered_context/buffered_context_test.go b/util/buffered_context/buffered_context_test.go index a0933e3d93..ed8ff849b4 100644 --- a/util/buffered_context/buffered_context_test.go +++ b/util/buffered_context/buffered_context_test.go @@ -7,11 +7,11 @@ import ( "github.com/stretchr/testify/assert" - "github.com/argoproj/argo-cd/v3/util/buffered_context" + "github.com/argoproj/argo-cd/v2/util/buffered_context" ) func TestWithEarlierDeadline_NoDeadline(t *testing.T) { - ctx := t.Context() + ctx := context.Background() bufferedCtx, cancel := buffered_context.WithEarlierDeadline(ctx, 100*time.Millisecond) defer cancel() @@ -23,7 +23,7 @@ func TestWithEarlierDeadline_NoDeadline(t *testing.T) { } func TestWithEarlierDeadline_WithDeadline(t *testing.T) { - ctx, cancel := context.WithDeadline(t.Context(), time.Now()) + ctx, cancel := context.WithDeadline(context.Background(), time.Now()) defer cancel() buffer := 100 * time.Millisecond diff --git a/util/cache/appstate/cache.go b/util/cache/appstate/cache.go index 33eded8004..5ad5b2154a 100644 --- a/util/cache/appstate/cache.go +++ b/util/cache/appstate/cache.go @@ -8,9 +8,9 @@ import ( "github.com/spf13/cobra" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - "github.com/argoproj/argo-cd/v3/util/env" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/argoproj/argo-cd/v2/util/env" ) var ( @@ -47,16 +47,16 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...cacheutil.Options) func() (* } } -func (c *Cache) GetItem(key string, item any) error { +func (c *Cache) GetItem(key string, item interface{}) error { return c.Cache.GetItem(key, item) } -func (c *Cache) SetItem(key string, item any, expiration time.Duration, delete bool) error { +func (c *Cache) SetItem(key string, item interface{}, expiration time.Duration, delete bool) error { return c.Cache.SetItem(key, item, &cacheutil.CacheActionOpts{Expiration: expiration, Delete: delete}) } func appManagedResourcesKey(appName string) string { - return "app|managed-resources|" + appName + return fmt.Sprintf("app|managed-resources|%s", appName) } func (c *Cache) GetAppManagedResources(appName string, res *[]*appv1.ResourceDiff) error { @@ -72,7 +72,7 @@ func (c *Cache) SetAppManagedResources(appName string, managedResources []*appv1 } func appResourcesTreeKey(appName string, shard int64) string { - key := "app|resources-tree|" + appName + key := fmt.Sprintf("app|resources-tree|%s", appName) if shard > 0 { key = fmt.Sprintf("%s|%d", key, shard) } @@ -80,7 +80,7 @@ func appResourcesTreeKey(appName string, shard int64) string { } func clusterInfoKey(server string) string { - return "cluster|info|" + server + return fmt.Sprintf("cluster|info|%s", server) } func (c *Cache) GetAppResourcesTree(appName string, res *appv1.ApplicationTree) error { diff --git a/util/cache/appstate/cache_test.go b/util/cache/appstate/cache_test.go index e3baa96a60..f10e982d93 100644 --- a/util/cache/appstate/cache_test.go +++ b/util/cache/appstate/cache_test.go @@ -8,8 +8,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" ) type fixtures struct { @@ -59,24 +59,6 @@ func TestCache_GetAppResourcesTree(t *testing.T) { assert.Equal(t, &ApplicationTree{Nodes: []ResourceNode{{}}}, value) } -func TestCache_GetClusterInfo(t *testing.T) { - cache := newFixtures().Cache - // cache miss - res := &ClusterInfo{} - err := cache.GetClusterInfo("http://minikube", res) - assert.Equal(t, ErrCacheMiss, err) - // populate cache - err = cache.SetClusterInfo("http://kind-cluster", &ClusterInfo{ServerVersion: "0.24.0"}) - require.NoError(t, err) - // cache miss - err = cache.GetClusterInfo("http://kind-clusterss", res) - assert.Equal(t, ErrCacheMiss, err) - // cache hit - err = cache.GetClusterInfo("http://kind-cluster", res) - require.NoError(t, err) - assert.Equal(t, &ClusterInfo{ServerVersion: "0.24.0"}, res) -} - func TestAddCacheFlagsToCmd(t *testing.T) { cache, err := AddCacheFlagsToCmd(&cobra.Command{})() require.NoError(t, err) diff --git a/util/cache/cache.go b/util/cache/cache.go index a4fb5ff153..fb1d20c5b7 100644 --- a/util/cache/cache.go +++ b/util/cache/cache.go @@ -4,7 +4,6 @@ import ( "context" "crypto/tls" "crypto/x509" - "errors" "fmt" "math" "os" @@ -15,9 +14,9 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/common" - certutil "github.com/argoproj/argo-cd/v3/util/cert" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/common" + certutil "github.com/argoproj/argo-cd/v2/util/cert" + "github.com/argoproj/argo-cd/v2/util/env" ) const ( @@ -179,7 +178,7 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...Options) func() (*Cache, err redisCACertificate := redisCACertificateSrc() compressionStr := compressionStrSrc() - var tlsConfig *tls.Config + var tlsConfig *tls.Config = nil if redisUseTLS { tlsConfig = &tls.Config{} if redisClientCertificate != "" { @@ -189,16 +188,15 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...Options) func() (*Cache, err } tlsConfig.Certificates = []tls.Certificate{clientCert} } - switch { - case insecureRedis: + if insecureRedis { tlsConfig.InsecureSkipVerify = true - case redisCACertificate != "": + } else if redisCACertificate != "" { redisCA, err := certutil.ParseTLSCertificatesFromPath(redisCACertificate) if err != nil { return nil, err } tlsConfig.RootCAs = certutil.GetCertPoolFromPEMData(redisCA) - default: + } else { var err error tlsConfig.RootCAs, err = x509.SystemCertPool() if err != nil { @@ -270,9 +268,9 @@ func (c *Cache) generateFullKey(key string) string { } // Sets or deletes an item in cache -func (c *Cache) SetItem(key string, item any, opts *CacheActionOpts) error { +func (c *Cache) SetItem(key string, item interface{}, opts *CacheActionOpts) error { if item == nil { - return errors.New("cannot set nil item in cache") + return fmt.Errorf("cannot set nil item in cache") } if opts == nil { opts = &CacheActionOpts{} @@ -281,11 +279,12 @@ func (c *Cache) SetItem(key string, item any, opts *CacheActionOpts) error { client := c.GetClient() if opts.Delete { return client.Delete(fullKey) + } else { + return client.Set(&Item{Key: fullKey, Object: item, CacheActionOpts: *opts}) } - return client.Set(&Item{Key: fullKey, Object: item, CacheActionOpts: *opts}) } -func (c *Cache) GetItem(key string, item any) error { +func (c *Cache) GetItem(key string, item interface{}) error { key = c.generateFullKey(key) if item == nil { return fmt.Errorf("cannot get item into a nil for key %s", key) diff --git a/util/cache/cache_test.go b/util/cache/cache_test.go index bcd6d5136c..921b2b1dc1 100644 --- a/util/cache/cache_test.go +++ b/util/cache/cache_test.go @@ -1,6 +1,7 @@ package cache import ( + "fmt" "testing" "time" @@ -10,7 +11,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) func TestAddCacheFlagsToCmd(t *testing.T) { @@ -85,5 +86,5 @@ func TestGenerateCacheKey(t *testing.T) { client := NewInMemoryCache(60 * time.Second) cache := NewCache(client) testKey := cache.generateFullKey("testkey") - assert.Equal(t, "testkey|"+common.CacheVersion, testKey) + assert.Equal(t, fmt.Sprintf("testkey|%s", common.CacheVersion), testKey) } diff --git a/util/cache/client.go b/util/cache/client.go index 3ef73dd9ff..f5bb7b9427 100644 --- a/util/cache/client.go +++ b/util/cache/client.go @@ -14,7 +14,7 @@ var ( type Item struct { Key string - Object any + Object interface{} CacheActionOpts CacheActionOpts } @@ -30,7 +30,7 @@ type CacheActionOpts struct { type CacheClient interface { Set(item *Item) error Rename(oldKey string, newKey string, expiration time.Duration) error - Get(key string, obj any) error + Get(key string, obj interface{}) error Delete(key string) error OnUpdated(ctx context.Context, key string, callback func() error) error NotifyUpdated(key string) error diff --git a/util/cache/client_test.go b/util/cache/client_test.go index 76e3310277..2b16245b81 100644 --- a/util/cache/client_test.go +++ b/util/cache/client_test.go @@ -29,8 +29,8 @@ func TestCache(t *testing.T) { cacheObj.Foo = "baz" err = c.Get("key", &obj) require.NoError(t, err) - assert.Equal(t, "foo", obj.Foo) - assert.Equal(t, "bar", string(obj.Bar)) + assert.EqualValues(t, "foo", obj.Foo) + assert.EqualValues(t, "bar", string(obj.Bar)) err = c.Delete("key") require.NoError(t, err) diff --git a/util/cache/inmemory.go b/util/cache/inmemory.go index f42a6bf537..c46b02b942 100644 --- a/util/cache/inmemory.go +++ b/util/cache/inmemory.go @@ -17,7 +17,7 @@ func NewInMemoryCache(expiration time.Duration) *InMemoryCache { } func init() { - gob.Register([]any{}) + gob.Register([]interface{}{}) } // compile-time validation of adherence of the CacheClient contract @@ -53,7 +53,7 @@ func (i *InMemoryCache) Rename(oldKey string, newKey string, expiration time.Dur } // HasSame returns true if key with the same value already present in cache -func (i *InMemoryCache) HasSame(key string, obj any) (bool, error) { +func (i *InMemoryCache) HasSame(key string, obj interface{}) (bool, error) { var buf bytes.Buffer err := gob.NewEncoder(&buf).Encode(obj) if err != nil { @@ -71,7 +71,7 @@ func (i *InMemoryCache) HasSame(key string, obj any) (bool, error) { return bytes.Equal(buf.Bytes(), existingBuf.Bytes()), nil } -func (i *InMemoryCache) Get(key string, obj any) error { +func (i *InMemoryCache) Get(key string, obj interface{}) error { bufIf, found := i.memCache.Get(key) if !found { return ErrCacheMiss @@ -89,18 +89,18 @@ func (i *InMemoryCache) Flush() { i.memCache.Flush() } -func (i *InMemoryCache) OnUpdated(_ context.Context, _ string, _ func() error) error { +func (i *InMemoryCache) OnUpdated(ctx context.Context, key string, callback func() error) error { return nil } -func (i *InMemoryCache) NotifyUpdated(_ string) error { +func (i *InMemoryCache) NotifyUpdated(key string) error { return nil } // Items return a list of items in the cache; requires passing a constructor function // so that the items can be decoded from gob format. -func (i *InMemoryCache) Items(createNewObject func() any) (map[string]any, error) { - result := map[string]any{} +func (i *InMemoryCache) Items(createNewObject func() interface{}) (map[string]interface{}, error) { + result := map[string]interface{}{} for key, value := range i.memCache.Items() { buf := value.Object.(bytes.Buffer) diff --git a/util/cache/mocks/cacheclient.go b/util/cache/mocks/cacheclient.go index 401da714e2..2fdd9fc37f 100644 --- a/util/cache/mocks/cacheclient.go +++ b/util/cache/mocks/cacheclient.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/mock" - "github.com/argoproj/argo-cd/v3/util/cache" + "github.com/argoproj/argo-cd/v2/util/cache" ) type MockCacheClient struct { @@ -35,7 +35,7 @@ func (c *MockCacheClient) Set(item *cache.Item) error { return c.BaseCache.Set(item) } -func (c *MockCacheClient) Get(key string, obj any) error { +func (c *MockCacheClient) Get(key string, obj interface{}) error { args := c.Called(key, obj) if len(args) > 0 && args.Get(0) != nil { return args.Get(0).(error) diff --git a/util/cache/redis.go b/util/cache/redis.go index c60bdcbc2f..2c938b6998 100644 --- a/util/cache/redis.go +++ b/util/cache/redis.go @@ -12,7 +12,7 @@ import ( "sync" "time" - utilio "github.com/argoproj/argo-cd/v3/util/io" + ioutil "github.com/argoproj/argo-cd/v2/util/io" rediscache "github.com/go-redis/cache/v9" "github.com/redis/go-redis/v9" @@ -63,7 +63,7 @@ func (r *redisCache) getKey(key string) string { } } -func (r *redisCache) marshal(obj any) ([]byte, error) { +func (r *redisCache) marshal(obj interface{}) ([]byte, error) { buf := bytes.NewBuffer([]byte{}) var w io.Writer = buf if r.redisCompressionType == RedisCompressionGZip { @@ -87,15 +87,15 @@ func (r *redisCache) marshal(obj any) ([]byte, error) { return buf.Bytes(), nil } -func (r *redisCache) unmarshal(data []byte, obj any) error { +func (r *redisCache) unmarshal(data []byte, obj interface{}) error { buf := bytes.NewReader(data) var reader io.Reader = buf if r.redisCompressionType == RedisCompressionGZip { - gzipReader, err := gzip.NewReader(buf) - if err != nil { + if gzipReader, err := gzip.NewReader(buf); err != nil { return err + } else { + reader = gzipReader } - reader = gzipReader } if err := json.NewDecoder(reader).Decode(obj); err != nil { return fmt.Errorf("failed to decode cached data: %w", err) @@ -131,7 +131,7 @@ func (r *redisCache) Set(item *Item) error { }) } -func (r *redisCache) Get(key string, obj any) error { +func (r *redisCache) Get(key string, obj interface{}) error { var data []byte err := r.cache.Get(context.TODO(), r.getKey(key), &data) if errors.Is(err, rediscache.ErrCacheMiss) { @@ -149,7 +149,7 @@ func (r *redisCache) Delete(key string) error { func (r *redisCache) OnUpdated(ctx context.Context, key string, callback func() error) error { pubsub := r.client.Subscribe(ctx, key) - defer utilio.Close(pubsub) + defer ioutil.Close(pubsub) ch := pubsub.Channel() for { @@ -196,7 +196,7 @@ func (rh *redisHook) ProcessHook(next redis.ProcessHook) redis.ProcessHook { } } -func (redisHook) ProcessPipelineHook(_ redis.ProcessPipelineHook) redis.ProcessPipelineHook { +func (redisHook) ProcessPipelineHook(next redis.ProcessPipelineHook) redis.ProcessPipelineHook { return nil } diff --git a/util/cache/redis_hook.go b/util/cache/redis_hook.go index 5d30337e2d..e7cc3f4bcc 100644 --- a/util/cache/redis_hook.go +++ b/util/cache/redis_hook.go @@ -36,6 +36,6 @@ func (hook *argoRedisHooks) ProcessHook(next redis.ProcessHook) redis.ProcessHoo } } -func (hook *argoRedisHooks) ProcessPipelineHook(_ redis.ProcessPipelineHook) redis.ProcessPipelineHook { +func (hook *argoRedisHooks) ProcessPipelineHook(next redis.ProcessPipelineHook) redis.ProcessPipelineHook { return nil } diff --git a/util/cache/redis_test.go b/util/cache/redis_test.go index f6933430b8..8cda6d8086 100644 --- a/util/cache/redis_test.go +++ b/util/cache/redis_test.go @@ -3,6 +3,7 @@ package cache import ( "bytes" "compress/gzip" + "context" "io" "strconv" "testing" @@ -107,7 +108,7 @@ func TestRedisSetCacheCompressed(t *testing.T) { testValue := "my-value" require.NoError(t, client.Set(&Item{Key: "my-key", Object: testValue})) - compressedData, err := redisClient.Get(t.Context(), "my-key.gz").Bytes() + compressedData, err := redisClient.Get(context.Background(), "my-key.gz").Bytes() require.NoError(t, err) assert.Greater(t, len(compressedData), len([]byte(testValue)), "compressed data is bigger than uncompressed") diff --git a/util/cache/twolevelclient.go b/util/cache/twolevelclient.go index 87d7100381..f221099844 100644 --- a/util/cache/twolevelclient.go +++ b/util/cache/twolevelclient.go @@ -45,7 +45,7 @@ func (c *twoLevelClient) Set(item *Item) error { // Get returns cache value from in-memory cache if it present. Otherwise loads it from external cache and persists // in memory to avoid future requests to external cache. -func (c *twoLevelClient) Get(key string, obj any) error { +func (c *twoLevelClient) Get(key string, obj interface{}) error { err := c.inMemoryCache.Get(key, obj) if err == nil { return nil diff --git a/util/cert/cert.go b/util/cert/cert.go index b8d6ae575b..4fe3929966 100644 --- a/util/cert/cert.go +++ b/util/cert/cert.go @@ -19,7 +19,7 @@ import ( log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) // A struct representing an entry in the list of SSH known hosts. @@ -80,8 +80,9 @@ var validFQDNRegexp = regexp.MustCompile(`^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{ func IsValidHostname(hostname string, fqdn bool) bool { if !fqdn { return validHostNameRegexp.Match([]byte(hostname)) || validIPv6Regexp.Match([]byte(hostname)) + } else { + return validFQDNRegexp.Match([]byte(hostname)) } - return validFQDNRegexp.Match([]byte(hostname)) } // Get the configured path to where TLS certificates are stored on the local @@ -90,8 +91,9 @@ func IsValidHostname(hostname string, fqdn bool) bool { func GetTLSCertificateDataPath() string { if envPath := os.Getenv(common.EnvVarTLSDataPath); envPath != "" { return envPath + } else { + return common.DefaultPathTLSConfig } - return common.DefaultPathTLSConfig } // Get the configured path to where SSH certificates are stored on the local @@ -100,8 +102,9 @@ func GetTLSCertificateDataPath() string { func GetSSHKnownHostsDataPath() string { if envPath := os.Getenv(common.EnvVarSSHDataPath); envPath != "" { return filepath.Join(envPath, common.DefaultSSHKnownHostsName) + } else { + return filepath.Join(common.DefaultPathSSHConfig, common.DefaultSSHKnownHostsName) } - return filepath.Join(common.DefaultPathSSHConfig, common.DefaultSSHKnownHostsName) } // Decode a certificate in PEM format to X509 data structure @@ -156,7 +159,7 @@ func ParseTLSCertificatesFromStream(stream io.Reader) ([]string, error) { // TODO: Implement error heuristics for scanner.Scan() { - curLine++ + curLine += 1 if !inCertData { if strings.HasPrefix(scanner.Text(), CertificateBeginMarker) { certLine = 1 @@ -164,7 +167,7 @@ func ParseTLSCertificatesFromStream(stream io.Reader) ([]string, error) { pemData += scanner.Text() + "\n" } } else { - certLine++ + certLine += 1 pemData += scanner.Text() + "\n" if strings.HasPrefix(scanner.Text(), CertificateEndMarker) { inCertData = false @@ -212,10 +215,10 @@ func ParseSSHKnownHostsFromStream(stream io.Reader) ([]string, error) { numEntries := 0 for scanner.Scan() { - curLine++ + curLine += 1 lineData := scanner.Text() if IsValidSSHKnownHostsEntry(lineData) { - numEntries++ + numEntries += 1 knownHostsLists = append(knownHostsLists, lineData) } } @@ -243,7 +246,7 @@ func IsValidSSHKnownHostsEntry(line string) bool { func TokenizeSSHKnownHostsEntry(knownHostsEntry string) (string, string, []byte, error) { knownHostsToken := strings.SplitN(knownHostsEntry, " ", 3) if len(knownHostsToken) != 3 { - return "", "", nil, errors.New("error while tokenizing input data") + return "", "", nil, fmt.Errorf("error while tokenizing input data") } return knownHostsToken[0], knownHostsToken[1], []byte(knownHostsToken[2]), nil } @@ -323,12 +326,13 @@ func GetCertificateForConnect(serverName string) ([]string, error) { if err != nil { if os.IsNotExist(err) { return nil, nil + } else { + return nil, err } - return nil, err } if len(certificates) == 0 { - return nil, errors.New("no certificates found in existing file") + return nil, fmt.Errorf("no certificates found in existing file") } return certificates, nil diff --git a/util/cert/cert_test.go b/util/cert/cert_test.go index 3645bf0f0e..cfc4b4385d 100644 --- a/util/cert/cert_test.go +++ b/util/cert/cert_test.go @@ -1,6 +1,7 @@ package cert import ( + "fmt" "os" "path" "testing" @@ -8,13 +9,13 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) const ( - TestCert1CN = "CN=foo.example.com,OU=SpecOps,O=Capone\\, Inc,L=Chicago,ST=IL,C=US" - TestCert2CN = "CN=bar.example.com,OU=Testsuite,O=Testing Corp,L=Hanover,ST=Lower Saxony,C=DE" - TestTLSValidSingleCert = ` + Test_Cert1CN = "CN=foo.example.com,OU=SpecOps,O=Capone\\, Inc,L=Chicago,ST=IL,C=US" + Test_Cert2CN = "CN=bar.example.com,OU=Testsuite,O=Testing Corp,L=Hanover,ST=Lower Saxony,C=DE" + Test_TLSValidSingleCert = ` -----BEGIN CERTIFICATE----- MIIFvTCCA6WgAwIBAgIUGrTmW3qc39zqnE08e3qNDhUkeWswDQYJKoZIhvcNAQEL BQAwbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv @@ -51,7 +52,7 @@ xO7Tr5lAo74vNUkF2EHNaI28/RGnJPm2TIxZqy4rNH6L ` ) -const TestTLSInvalidPEMData = ` +const Test_TLSInvalidPEMData = ` MIIF1zCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL BQAwezELMAkGA1UEBhMCREUxFTATBgNVBAgMDExvd2VyIFNheG9ueTEQMA4GA1UE BwwHSGFub3ZlcjEVMBMGA1UECgwMVGVzdGluZyBDb3JwMRIwEAYDVQQLDAlUZXN0 @@ -68,7 +69,7 @@ YilqCPFX+az09EqqK/iHXnkdZ/Z2fCuU+9M/Zhrnlwlygl3RuVBI6xhm/ZsXtL2E Gxa61lNy6pyx5+hSxHEFEJshXLtioRd702VdLKxEOuYSXKeJDs1x9o6cJ75S6hko ` -const TestTLSInvalidSingleCert = ` +const Test_TLSInvalidSingleCert = ` -----BEGIN CERTIFICATE----- MIIF1zCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL BQAwezELMAkGA1UEBhMCREUxFTATBgNVBAgMDExvd2VyIFNheG9ueTEQMA4GA1UE @@ -105,7 +106,7 @@ XWyb96wrUlv+E8I= -----END CERTIFICATE----- ` -const TestTLSValidMultiCert = ` +const Test_TLSValidMultiCert = ` -----BEGIN CERTIFICATE----- MIIFvTCCA6WgAwIBAgIUGrTmW3qc39zqnE08e3qNDhUkeWswDQYJKoZIhvcNAQEL BQAwbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv @@ -176,7 +177,7 @@ XWyb96wrUlv+E8I= ` // Taken from hack/ssh_known_hosts -const TestValidSSHKnownHostsData = ` +const Test_ValidSSHKnownHostsData = ` # BitBucket bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M= # GitHub @@ -190,7 +191,7 @@ ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4Nak vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H ` -const TestInvalidSSHKnownHostsData = ` +const Test_InvalidSSHKnownHostsData = ` bitbucket.org AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M= # GitHub github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= @@ -203,20 +204,20 @@ ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4Nak vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H ` -func TestTLSCertificateValidPEMValidCert(t *testing.T) { +func Test_TLSCertificate_ValidPEM_ValidCert(t *testing.T) { // Valid PEM data, single certificate, expect array of length 1 - certificates, err := ParseTLSCertificatesFromData(TestTLSValidSingleCert) + certificates, err := ParseTLSCertificatesFromData(Test_TLSValidSingleCert) require.NoError(t, err) assert.Len(t, certificates, 1) // Expect good decode x509Cert, err := DecodePEMCertificateToX509(certificates[0]) require.NoError(t, err) - assert.Equal(t, TestCert1CN, x509Cert.Subject.String()) + assert.Equal(t, Test_Cert1CN, x509Cert.Subject.String()) } -func TestTLSCertificateValidPEMInvalidCert(t *testing.T) { +func Test_TLSCertificate_ValidPEM_InvalidCert(t *testing.T) { // Valid PEM data, but invalid certificate - certificates, err := ParseTLSCertificatesFromData(TestTLSInvalidSingleCert) + certificates, err := ParseTLSCertificatesFromData(Test_TLSInvalidSingleCert) require.NoError(t, err) assert.Len(t, certificates, 1) // Expect bad decode @@ -224,28 +225,28 @@ func TestTLSCertificateValidPEMInvalidCert(t *testing.T) { require.Error(t, err) } -func TestTLSCertificateInvalidPEM(t *testing.T) { +func Test_TLSCertificate_InvalidPEM(t *testing.T) { // Invalid PEM data, expect array of length 0 - certificates, err := ParseTLSCertificatesFromData(TestTLSInvalidPEMData) + certificates, err := ParseTLSCertificatesFromData(Test_TLSInvalidPEMData) require.NoError(t, err) assert.Empty(t, certificates) } -func TestTLSCertificateValidPEMValidCertMulti(t *testing.T) { +func Test_TLSCertificate_ValidPEM_ValidCert_Multi(t *testing.T) { // Valid PEM data, two certificates, expect array of length 2 - certificates, err := ParseTLSCertificatesFromData(TestTLSValidMultiCert) + certificates, err := ParseTLSCertificatesFromData(Test_TLSValidMultiCert) require.NoError(t, err) assert.Len(t, certificates, 2) // Expect good decode x509Cert, err := DecodePEMCertificateToX509(certificates[0]) require.NoError(t, err) - assert.Equal(t, TestCert1CN, x509Cert.Subject.String()) + assert.Equal(t, Test_Cert1CN, x509Cert.Subject.String()) x509Cert, err = DecodePEMCertificateToX509(certificates[1]) require.NoError(t, err) - assert.Equal(t, TestCert2CN, x509Cert.Subject.String()) + assert.Equal(t, Test_Cert2CN, x509Cert.Subject.String()) } -func TestTLSCertificateValidPEMValidCertFromFile(t *testing.T) { +func Test_TLSCertificate_ValidPEM_ValidCert_FromFile(t *testing.T) { // Valid PEM data, single certificate from file, expect array of length 1 certificates, err := ParseTLSCertificatesFromPath("../../test/certificates/cert1.pem") require.NoError(t, err) @@ -253,48 +254,48 @@ func TestTLSCertificateValidPEMValidCertFromFile(t *testing.T) { // Expect good decode x509Cert, err := DecodePEMCertificateToX509(certificates[0]) require.NoError(t, err) - assert.Equal(t, TestCert1CN, x509Cert.Subject.String()) + assert.Equal(t, Test_Cert1CN, x509Cert.Subject.String()) } -func TestTLSCertPool(t *testing.T) { - certificates, err := ParseTLSCertificatesFromData(TestTLSValidMultiCert) +func Test_TLSCertPool(t *testing.T) { + certificates, err := ParseTLSCertificatesFromData(Test_TLSValidMultiCert) require.NoError(t, err) assert.Len(t, certificates, 2) certPool := GetCertPoolFromPEMData(certificates) assert.NotNil(t, certPool) } -func TestTLSCertificateCertFromNonExistingFile(t *testing.T) { +func Test_TLSCertificate_CertFromNonExistingFile(t *testing.T) { // Non-existing file, expect err _, err := ParseTLSCertificatesFromPath("../../test/certificates/cert_nonexisting.pem") require.Error(t, err) } -func TestSSHKnownHostsDataParseData(t *testing.T) { +func Test_SSHKnownHostsData_ParseData(t *testing.T) { // Expect valid data with 7 known host entries - entries, err := ParseSSHKnownHostsFromData(TestValidSSHKnownHostsData) + entries, err := ParseSSHKnownHostsFromData(Test_ValidSSHKnownHostsData) require.NoError(t, err) assert.Len(t, entries, 7) } -func TestSSHKnownHostsDataParseFile(t *testing.T) { +func Test_SSHKnownHostsData_ParseFile(t *testing.T) { // Expect valid data with 7 known host entries entries, err := ParseSSHKnownHostsFromPath("../../test/certificates/ssh_known_hosts") require.NoError(t, err) assert.Len(t, entries, 7) } -func TestSSHKnownHostsDataParseNonExistingFile(t *testing.T) { +func Test_SSHKnownHostsData_ParseNonExistingFile(t *testing.T) { // Expect valid data with 7 known host entries entries, err := ParseSSHKnownHostsFromPath("../../test/certificates/ssh_known_hosts_invalid") require.Error(t, err) assert.Nil(t, entries) } -func TestSSHKnownHostsDataTokenize(t *testing.T) { +func Test_SSHKnownHostsData_Tokenize(t *testing.T) { // All entries should parse to valid SSH public keys // All entries should be tokenizable, and tokens should be feedable to decoder - entries, err := ParseSSHKnownHostsFromData(TestValidSSHKnownHostsData) + entries, err := ParseSSHKnownHostsFromData(Test_ValidSSHKnownHostsData) require.NoError(t, err) for _, entry := range entries { hosts, _, err := KnownHostsLineToPublicKey(entry) @@ -308,7 +309,7 @@ func TestSSHKnownHostsDataTokenize(t *testing.T) { } } -func TestMatchHostName(t *testing.T) { +func Test_MatchHostName(t *testing.T) { matchHostName := "foo.example.com" assert.True(t, MatchHostName(matchHostName, "*")) assert.True(t, MatchHostName(matchHostName, "*.example.com")) @@ -321,7 +322,7 @@ func TestMatchHostName(t *testing.T) { assert.False(t, MatchHostName(matchHostName, "foo.otherexample.*")) } -func TestSSHFingerprintSHA256(t *testing.T) { +func Test_SSHFingerprintSHA256(t *testing.T) { // actual SHA256 fingerprints for keys defined above fingerprints := [...]string{ "46OSHA1Rmj8E8ERTC6xkNcmGOw9oFxYr0WF6zWW8l1E", @@ -332,7 +333,7 @@ func TestSSHFingerprintSHA256(t *testing.T) { "ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og", "ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og", } - entries, err := ParseSSHKnownHostsFromData(TestValidSSHKnownHostsData) + entries, err := ParseSSHKnownHostsFromData(Test_ValidSSHKnownHostsData) require.NoError(t, err) assert.Len(t, entries, 7) for idx, entry := range entries { @@ -343,7 +344,7 @@ func TestSSHFingerprintSHA256(t *testing.T) { } } -func TestSSHFingerPrintSHA256FromString(t *testing.T) { +func Test_SSHFingerPrintSHA256FromString(t *testing.T) { // actual SHA256 fingerprints for keys defined above fingerprints := [...]string{ "46OSHA1Rmj8E8ERTC6xkNcmGOw9oFxYr0WF6zWW8l1E", @@ -354,7 +355,7 @@ func TestSSHFingerPrintSHA256FromString(t *testing.T) { "ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og", "ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og", } - entries, err := ParseSSHKnownHostsFromData(TestValidSSHKnownHostsData) + entries, err := ParseSSHKnownHostsFromData(Test_ValidSSHKnownHostsData) require.NoError(t, err) assert.Len(t, entries, 7) for idx, entry := range entries { @@ -363,7 +364,7 @@ func TestSSHFingerPrintSHA256FromString(t *testing.T) { } } -func TestServerNameWithoutPort(t *testing.T) { +func Test_ServerNameWithoutPort(t *testing.T) { hostNames := map[string]string{ "localhost": "localhost", "localhost:9443": "localhost", @@ -378,7 +379,7 @@ func TestServerNameWithoutPort(t *testing.T) { } } -func TestValidHostnames(t *testing.T) { +func Test_ValidHostnames(t *testing.T) { hostNames := map[string]bool{ "localhost": true, "localhost.localdomain": true, @@ -398,13 +399,13 @@ func TestValidHostnames(t *testing.T) { } for hostName, valid := range hostNames { - t.Run("Test validity for hostname "+hostName, func(t *testing.T) { + t.Run(fmt.Sprintf("Test validity for hostname %s", hostName), func(t *testing.T) { assert.Equal(t, valid, IsValidHostname(hostName, false)) }) } } -func TestValidFQDNs(t *testing.T) { +func Test_ValidFQDNs(t *testing.T) { hostNames := map[string]bool{ "localhost": false, "localhost.localdomain": false, @@ -426,7 +427,7 @@ func TestValidFQDNs(t *testing.T) { } } -func TestEscapeBracketPattern(t *testing.T) { +func Test_EscapeBracketPattern(t *testing.T) { // input: expected output patternList := map[string]string{ "foo.bar": "foo.bar", diff --git a/util/claims/claims.go b/util/claims/claims.go deleted file mode 100644 index 2b77e53b5b..0000000000 --- a/util/claims/claims.go +++ /dev/null @@ -1,56 +0,0 @@ -package claims - -import ( - "encoding/json" - - "github.com/golang-jwt/jwt/v5" -) - -// ArgoClaims defines the claims structure based on Dex's documented claims -type ArgoClaims struct { - jwt.RegisteredClaims - Email string `json:"email,omitempty"` - EmailVerified bool `json:"email_verified,omitempty"` - Name string `json:"name,omitempty"` - Groups []string `json:"groups,omitempty"` - // As per Dex docs, federated_claims has a specific structure - FederatedClaims *FederatedClaims `json:"federated_claims,omitempty"` -} - -// FederatedClaims represents the structure documented by Dex -type FederatedClaims struct { - ConnectorID string `json:"connector_id"` - UserID string `json:"user_id"` -} - -// MapClaimsToArgoClaims converts a jwt.MapClaims to a ArgoClaims -func MapClaimsToArgoClaims(claims jwt.MapClaims) (*ArgoClaims, error) { - if claims == nil { - return &ArgoClaims{}, nil - } - - claimsBytes, err := json.Marshal(claims) - if err != nil { - return nil, err - } - - var argoClaims ArgoClaims - err = json.Unmarshal(claimsBytes, &argoClaims) - if err != nil { - return nil, err - } - return &argoClaims, nil -} - -// GetUserIdentifier returns a consistent user identifier, checking federated_claims.user_id when Dex is in use -func (c *ArgoClaims) GetUserIdentifier() string { - // Check federated claims first - if c.FederatedClaims != nil && c.FederatedClaims.UserID != "" { - return c.FederatedClaims.UserID - } - // Fallback to sub - if c.Subject != "" { - return c.Subject - } - return "" -} diff --git a/util/claims/claims_test.go b/util/claims/claims_test.go deleted file mode 100644 index 6b9a3fc8a5..0000000000 --- a/util/claims/claims_test.go +++ /dev/null @@ -1,159 +0,0 @@ -package claims - -import ( - "reflect" - "testing" - "time" - - "github.com/golang-jwt/jwt/v5" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestGetUserIdentifier(t *testing.T) { - tests := []struct { - name string - claims *ArgoClaims - want string - }{ - { - name: "when both dex and sub defined - prefer dex user_id", - claims: &ArgoClaims{ - RegisteredClaims: jwt.RegisteredClaims{ - Subject: "ignored:login", - }, - FederatedClaims: &FederatedClaims{ - UserID: "dex-user", - }, - }, - want: "dex-user", - }, - { - name: "when both dex and sub defined but dex user_id empty - fallback to sub", - claims: &ArgoClaims{ - RegisteredClaims: jwt.RegisteredClaims{ - Subject: "test:apiKey", - }, - FederatedClaims: &FederatedClaims{ - UserID: "", - }, - }, - want: "test:apiKey", - }, - { - name: "when only sub is defined (no dex) - use sub", - claims: &ArgoClaims{ - RegisteredClaims: jwt.RegisteredClaims{ - Subject: "admin:login", - }, - }, - want: "admin:login", - }, - { - name: "when neither dex nor sub defined - return empty", - claims: &ArgoClaims{}, - want: "", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := tt.claims.GetUserIdentifier() - assert.Equal(t, tt.want, got) - }) - } -} - -func TestMapClaimsToArgoClaims(t *testing.T) { - expectedExpiredAt := jwt.NewNumericDate(time.Now().Add(time.Hour)) - expectedIssuedAt := jwt.NewNumericDate(time.Now().Add(time.Hour * -2)) - expectedNotBefore := jwt.NewNumericDate(time.Now().Add(time.Hour * -3)) - - tests := []struct { - name string - claims jwt.MapClaims - want *ArgoClaims - wantErr bool - }{ - { - name: "nil claims", - claims: nil, - want: &ArgoClaims{}, - }, - { - name: "empty claims", - claims: jwt.MapClaims{}, - want: &ArgoClaims{}, - }, - { - name: "invalid claims", - claims: jwt.MapClaims{ - "email_verified": "not-a-bool", - }, - wantErr: true, - }, - { - name: "all registered known claims", - claims: jwt.MapClaims{ - "jti": "jti", - "iss": "iss", - "sub": "sub", - "aud": "aud", - "iat": expectedIssuedAt.Unix(), - "exp": expectedExpiredAt.Unix(), - "nbf": expectedNotBefore.Unix(), - }, - want: &ArgoClaims{ - RegisteredClaims: jwt.RegisteredClaims{ - ID: "jti", - Issuer: "iss", - Subject: "sub", - Audience: jwt.ClaimStrings{"aud"}, - ExpiresAt: expectedExpiredAt, - IssuedAt: expectedIssuedAt, - NotBefore: expectedNotBefore, - }, - }, - }, - { - name: "all argo claims", - claims: jwt.MapClaims{ - "email": "email@test.com", - "email_verified": true, - "name": "the-name", - "groups": []string{ - "my-org:my-team2", - "my-org:my-team1", - }, - "federated_claims": map[string]any{ - "connector_id": "my-connector", - "user_id": "user-id", - }, - }, - want: &ArgoClaims{ - Email: "email@test.com", - EmailVerified: true, - Name: "the-name", - Groups: []string{ - "my-org:my-team2", - "my-org:my-team1", - }, - FederatedClaims: &FederatedClaims{ - ConnectorID: "my-connector", - UserID: "user-id", - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := MapClaimsToArgoClaims(tt.claims) - if tt.wantErr { - assert.Error(t, err, "MapClaimsToArgoClaims()") - } else { - require.NoError(t, err, "MapClaimsToArgoClaims()") - assert.Truef(t, reflect.DeepEqual(got, tt.want), "MapClaimsToArgoClaims() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/util/cli/cli.go b/util/cli/cli.go index 3c6b0cfa6f..a84e031f6d 100644 --- a/util/cli/cli.go +++ b/util/cli/cli.go @@ -5,7 +5,6 @@ package cli import ( "bufio" "bytes" - stderrors "errors" "flag" "fmt" "os" @@ -26,10 +25,10 @@ import ( "k8s.io/kubectl/pkg/util/term" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/errors" - utilio "github.com/argoproj/argo-cd/v3/util/io" - utillog "github.com/argoproj/argo-cd/v3/util/log" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/io" + utillog "github.com/argoproj/argo-cd/v2/util/log" ) // NewVersionCmd returns a new `version` command to be used as a sub-command to root @@ -38,7 +37,7 @@ func NewVersionCmd(cliName string) *cobra.Command { versionCmd := cobra.Command{ Use: "version", Short: "Print version information", - Run: func(_ *cobra.Command, _ []string) { + Run: func(cmd *cobra.Command, args []string) { version := common.GetVersion() fmt.Printf("%s: %s\n", cliName, version) if short { @@ -204,7 +203,7 @@ func SetGLogLevel(glogLevel int) { func writeToTempFile(pattern string, data []byte) string { f, err := os.CreateTemp("", pattern) errors.CheckError(err) - defer utilio.Close(f) + defer io.Close(f) _, err = f.Write(data) errors.CheckError(err) return f.Name() @@ -277,10 +276,11 @@ func InteractiveEdit(filePattern string, data []byte, save func(input []byte) er updated, err := os.ReadFile(tempFile) errors.CheckError(err) if string(updated) == "" || string(updated) == string(data) { - errors.CheckError(stderrors.New("edit cancelled, no valid changes were saved")) + errors.CheckError(fmt.Errorf("edit cancelled, no valid changes were saved")) break + } else { + data = stripComments(updated) } - data = stripComments(updated) err = save(data) if err == nil { @@ -309,7 +309,7 @@ func PrintDiff(name string, live *unstructured.Unstructured, target *unstructure if err != nil { return err } - liveFile := path.Join(tempDir, name+"-live.yaml") + liveFile := path.Join(tempDir, fmt.Sprintf("%s-live.yaml", name)) liveData := []byte("") if live != nil { liveData, err = yaml.Marshal(live) diff --git a/util/clusterauth/clusterauth.go b/util/clusterauth/clusterauth.go index 26ee329644..d57e27792e 100644 --- a/util/clusterauth/clusterauth.go +++ b/util/clusterauth/clusterauth.go @@ -2,20 +2,22 @@ package clusterauth import ( "context" + "encoding/json" "fmt" "strings" "time" - "github.com/golang-jwt/jwt/v5" + jwt "github.com/golang-jwt/jwt/v4" log "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) // ArgoCDManagerServiceAccount is the name of the service account for managing a cluster @@ -23,7 +25,6 @@ const ( ArgoCDManagerServiceAccount = "argocd-manager" ArgoCDManagerClusterRole = "argocd-manager-role" ArgoCDManagerClusterRoleBinding = "argocd-manager-role-binding" - SATokenSecretSuffix = "-long-lived-token" ) // ArgoCDManagerPolicyRules are the policies to give argocd-manager @@ -66,8 +67,8 @@ func CreateServiceAccount( } _, err := clientset.CoreV1().ServiceAccounts(namespace).Create(context.Background(), &serviceAccount, metav1.CreateOptions{}) if err != nil { - if !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("failed to create service account %q in namespace %q: %w", serviceAccountName, namespace, err) + if !apierr.IsAlreadyExists(err) { + return fmt.Errorf("Failed to create service account %q in namespace %q: %w", serviceAccountName, namespace, err) } log.Infof("ServiceAccount %q already exists in namespace %q", serviceAccountName, namespace) return nil @@ -76,15 +77,15 @@ func CreateServiceAccount( return nil } -func upsert(kind string, name string, create func() (any, error), update func() (any, error)) error { +func upsert(kind string, name string, create func() (interface{}, error), update func() (interface{}, error)) error { _, err := create() if err != nil { - if !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("failed to create %s %q: %w", kind, name, err) + if !apierr.IsAlreadyExists(err) { + return fmt.Errorf("Failed to create %s %q: %w", kind, name, err) } _, err = update() if err != nil { - return fmt.Errorf("failed to update %s %q: %w", kind, name, err) + return fmt.Errorf("Failed to update %s %q: %w", kind, name, err) } log.Infof("%s %q updated", kind, name) } else { @@ -104,9 +105,9 @@ func upsertClusterRole(clientset kubernetes.Interface, name string, rules []rbac }, Rules: rules, } - return upsert("ClusterRole", name, func() (any, error) { + return upsert("ClusterRole", name, func() (interface{}, error) { return clientset.RbacV1().ClusterRoles().Create(context.Background(), &clusterRole, metav1.CreateOptions{}) - }, func() (any, error) { + }, func() (interface{}, error) { return clientset.RbacV1().ClusterRoles().Update(context.Background(), &clusterRole, metav1.UpdateOptions{}) }) } @@ -122,9 +123,9 @@ func upsertRole(clientset kubernetes.Interface, name string, namespace string, r }, Rules: rules, } - return upsert("Role", fmt.Sprintf("%s/%s", namespace, name), func() (any, error) { + return upsert("Role", fmt.Sprintf("%s/%s", namespace, name), func() (interface{}, error) { return clientset.RbacV1().Roles(namespace).Create(context.Background(), &role, metav1.CreateOptions{}) - }, func() (any, error) { + }, func() (interface{}, error) { return clientset.RbacV1().Roles(namespace).Update(context.Background(), &role, metav1.UpdateOptions{}) }) } @@ -145,9 +146,9 @@ func upsertClusterRoleBinding(clientset kubernetes.Interface, name string, clust }, Subjects: []rbacv1.Subject{subject}, } - return upsert("ClusterRoleBinding", name, func() (any, error) { + return upsert("ClusterRoleBinding", name, func() (interface{}, error) { return clientset.RbacV1().ClusterRoleBindings().Create(context.Background(), &roleBinding, metav1.CreateOptions{}) - }, func() (any, error) { + }, func() (interface{}, error) { return clientset.RbacV1().ClusterRoleBindings().Update(context.Background(), &roleBinding, metav1.UpdateOptions{}) }) } @@ -168,9 +169,9 @@ func upsertRoleBinding(clientset kubernetes.Interface, name string, roleName str }, Subjects: []rbacv1.Subject{subject}, } - return upsert("RoleBinding", fmt.Sprintf("%s/%s", namespace, name), func() (any, error) { + return upsert("RoleBinding", fmt.Sprintf("%s/%s", namespace, name), func() (interface{}, error) { return clientset.RbacV1().RoleBindings(namespace).Create(context.Background(), &roleBinding, metav1.CreateOptions{}) - }, func() (any, error) { + }, func() (interface{}, error) { return clientset.RbacV1().RoleBindings(namespace).Update(context.Background(), &roleBinding, metav1.UpdateOptions{}) }) } @@ -236,7 +237,7 @@ func GetServiceAccountBearerToken(clientset kubernetes.Interface, ns string, sa return false, fmt.Errorf("failed to get secret %q for serviceaccount %q: %w", secretName, sa, err) } - _, ok := secret.Data[corev1.ServiceAccountTokenKey] + _, ok := secret.Data["token"] if !ok { return false, nil } @@ -247,21 +248,59 @@ func GetServiceAccountBearerToken(clientset kubernetes.Interface, ns string, sa return "", fmt.Errorf("failed to get token for serviceaccount %q: %w", sa, err) } - return string(secret.Data[corev1.ServiceAccountTokenKey]), nil + return string(secret.Data["token"]), nil } -// getOrCreateServiceAccountTokenSecret will create a -// kubernetes.io/service-account-token secret associated with a -// ServiceAccount named '-long-lived-token', or -// use the existing one with that name. -// This was added to help add k8s v1.24+ clusters. -func getOrCreateServiceAccountTokenSecret(clientset kubernetes.Interface, serviceaccount, namespace string) (string, error) { +// getOrCreateServiceAccountTokenSecret will check if a ServiceAccount +// already has a kubernetes.io/service-account-token secret associated +// with it or creates one if the ServiceAccount doesn't have one. This +// was added to help add k8s v1.24+ clusters. +func getOrCreateServiceAccountTokenSecret(clientset kubernetes.Interface, sa, ns string) (string, error) { + // Wait for sa to have secret, but don't wait too + // long for 1.24+ clusters + var serviceAccount *corev1.ServiceAccount + err := wait.PollUntilContextTimeout(context.Background(), 500*time.Millisecond, 30*time.Second, true, func(ctx context.Context) (bool, error) { + ctx, cancel := context.WithTimeout(ctx, common.ClusterAuthRequestTimeout) + defer cancel() + var getErr error + serviceAccount, getErr = clientset.CoreV1().ServiceAccounts(ns).Get(ctx, sa, metav1.GetOptions{}) + if getErr != nil { + return false, fmt.Errorf("failed to get serviceaccount %q: %w", sa, getErr) + } + return true, nil + }) + if err != nil && !wait.Interrupted(err) { + return "", fmt.Errorf("failed to get serviceaccount token secret: %w", err) + } + if serviceAccount == nil { + log.Errorf("Unexpected nil serviceaccount '%s/%s' with no error returned", ns, sa) + return "", fmt.Errorf("failed to create serviceaccount token secret: nil serviceaccount returned for '%s/%s' with no error", ns, sa) + } + + outerCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + for _, s := range serviceAccount.Secrets { + innerCtx, cancel := context.WithTimeout(outerCtx, common.ClusterAuthRequestTimeout) + defer cancel() + existingSecret, err := clientset.CoreV1().Secrets(ns).Get(innerCtx, s.Name, metav1.GetOptions{}) + if err != nil { + return "", fmt.Errorf("failed to retrieve secret %q: %w", s.Name, err) + } + if existingSecret.Type == corev1.SecretTypeServiceAccountToken { + return existingSecret.Name, nil + } + } + + return createServiceAccountToken(clientset, serviceAccount) +} + +func createServiceAccountToken(clientset kubernetes.Interface, serviceAccount *corev1.ServiceAccount) (string, error) { secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: serviceaccount + SATokenSecretSuffix, - Namespace: namespace, + GenerateName: serviceAccount.Name + "-token-", + Namespace: serviceAccount.Namespace, Annotations: map[string]string{ - corev1.ServiceAccountNameKey: serviceaccount, + corev1.ServiceAccountNameKey: serviceAccount.Name, }, }, Type: corev1.SecretTypeServiceAccountToken, @@ -269,15 +308,24 @@ func getOrCreateServiceAccountTokenSecret(clientset kubernetes.Interface, servic ctx, cancel := context.WithTimeout(context.Background(), common.ClusterAuthRequestTimeout) defer cancel() - _, err := clientset.CoreV1().Secrets(namespace).Create(ctx, secret, metav1.CreateOptions{}) + secret, err := clientset.CoreV1().Secrets(serviceAccount.Namespace).Create(ctx, secret, metav1.CreateOptions{}) + if err != nil { + return "", fmt.Errorf("failed to create secret for serviceaccount %q: %w", serviceAccount.Name, err) + } - switch { - case apierrors.IsAlreadyExists(err): - log.Infof("Using existing bearer token secret %q for ServiceAccount %q", secret.Name, serviceaccount) - case err != nil: - return "", fmt.Errorf("failed to create secret %q for serviceaccount %q: %w", secret.Name, serviceaccount, err) - default: - log.Infof("Created bearer token secret %q for ServiceAccount %q", secret.Name, serviceaccount) + log.Infof("Created bearer token secret for ServiceAccount %q", serviceAccount.Name) + serviceAccount.Secrets = []corev1.ObjectReference{{ + Name: secret.Name, + Namespace: secret.Namespace, + }} + patch, err := json.Marshal(serviceAccount) + if err != nil { + return "", fmt.Errorf("failed marshaling patch for serviceaccount %q: %w", serviceAccount.Name, err) + } + + _, err = clientset.CoreV1().ServiceAccounts(serviceAccount.Namespace).Patch(ctx, serviceAccount.Name, types.StrategicMergePatchType, patch, metav1.PatchOptions{}) + if err != nil { + return "", fmt.Errorf("failed to patch serviceaccount %q with bearer token secret: %w", serviceAccount.Name, err) } return secret.Name, nil @@ -291,8 +339,8 @@ func UninstallClusterManagerRBAC(clientset kubernetes.Interface) error { // UninstallRBAC uninstalls RBAC related resources for a binding, role, and service account func UninstallRBAC(clientset kubernetes.Interface, namespace, bindingName, roleName, serviceAccount string) error { if err := clientset.RbacV1().ClusterRoleBindings().Delete(context.Background(), bindingName, metav1.DeleteOptions{}); err != nil { - if !apierrors.IsNotFound(err) { - return fmt.Errorf("failed to delete ClusterRoleBinding: %w", err) + if !apierr.IsNotFound(err) { + return fmt.Errorf("Failed to delete ClusterRoleBinding: %w", err) } log.Infof("ClusterRoleBinding %q not found", bindingName) } else { @@ -300,8 +348,8 @@ func UninstallRBAC(clientset kubernetes.Interface, namespace, bindingName, roleN } if err := clientset.RbacV1().ClusterRoles().Delete(context.Background(), roleName, metav1.DeleteOptions{}); err != nil { - if !apierrors.IsNotFound(err) { - return fmt.Errorf("failed to delete ClusterRole: %w", err) + if !apierr.IsNotFound(err) { + return fmt.Errorf("Failed to delete ClusterRole: %w", err) } log.Infof("ClusterRole %q not found", roleName) } else { @@ -309,8 +357,8 @@ func UninstallRBAC(clientset kubernetes.Interface, namespace, bindingName, roleN } if err := clientset.CoreV1().ServiceAccounts(namespace).Delete(context.Background(), serviceAccount, metav1.DeleteOptions{}); err != nil { - if !apierrors.IsNotFound(err) { - return fmt.Errorf("failed to delete ServiceAccount: %w", err) + if !apierr.IsNotFound(err) { + return fmt.Errorf("Failed to delete ServiceAccount: %w", err) } log.Infof("ServiceAccount %q in namespace %q not found", serviceAccount, namespace) } else { @@ -320,11 +368,17 @@ func UninstallRBAC(clientset kubernetes.Interface, namespace, bindingName, roleN } type ServiceAccountClaims struct { + Sub string `json:"sub"` + Iss string `json:"iss"` Namespace string `json:"kubernetes.io/serviceaccount/namespace"` SecretName string `json:"kubernetes.io/serviceaccount/secret.name"` ServiceAccountName string `json:"kubernetes.io/serviceaccount/service-account.name"` ServiceAccountUID string `json:"kubernetes.io/serviceaccount/service-account.uid"` - jwt.RegisteredClaims +} + +// Valid satisfies the jwt.Claims interface to enable JWT parsing +func (sac *ServiceAccountClaims) Valid() error { + return nil } // ParseServiceAccountToken parses a Kubernetes service account token @@ -333,7 +387,7 @@ func ParseServiceAccountToken(token string) (*ServiceAccountClaims, error) { var claims ServiceAccountClaims _, _, err := parser.ParseUnverified(token, &claims) if err != nil { - return nil, fmt.Errorf("failed to parse service account token: %w", err) + return nil, fmt.Errorf("Failed to parse service account token: %w", err) } return &claims, nil } @@ -373,7 +427,7 @@ func GenerateNewClusterManagerSecret(clientset kubernetes.Interface, claims *Ser return true, nil }) if err != nil { - return nil, fmt.Errorf("timed out waiting for secret to generate new token: %w", err) + return nil, fmt.Errorf("Timed out waiting for secret to generate new token: %w", err) } return created, nil } @@ -408,7 +462,7 @@ func RotateServiceAccountSecrets(clientset kubernetes.Interface, claims *Service // 2. delete existing secret object secretsClient := clientset.CoreV1().Secrets(claims.Namespace) err = secretsClient.Delete(context.Background(), claims.SecretName, metav1.DeleteOptions{}) - if !apierrors.IsNotFound(err) { + if !apierr.IsNotFound(err) { return err } return nil diff --git a/util/clusterauth/clusterauth_test.go b/util/clusterauth/clusterauth_test.go index 5aedf45d84..73a99d58d7 100644 --- a/util/clusterauth/clusterauth_test.go +++ b/util/clusterauth/clusterauth_test.go @@ -1,22 +1,24 @@ package clusterauth import ( - "errors" + "context" "os" "testing" "time" - "github.com/golang-jwt/jwt/v5" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/storage/names" "k8s.io/client-go/kubernetes/fake" kubetesting "k8s.io/client-go/testing" "sigs.k8s.io/yaml" + + "github.com/argoproj/argo-cd/v2/util/errors" ) const ( @@ -25,33 +27,29 @@ const ( ) var testClaims = ServiceAccountClaims{ - "kube-system", - "argocd-manager-token-tj79r", - "argocd-manager", - "91dd37cf-8d92-11e9-a091-d65f2ae7fa8d", - jwt.RegisteredClaims{ - Subject: "system:serviceaccount:kube-system:argocd-manager", - Issuer: "kubernetes/serviceaccount", - }, + Sub: "system:serviceaccount:kube-system:argocd-manager", + Iss: "kubernetes/serviceaccount", + Namespace: "kube-system", + SecretName: "argocd-manager-token-tj79r", + ServiceAccountName: "argocd-manager", + ServiceAccountUID: "91dd37cf-8d92-11e9-a091-d65f2ae7fa8d", } -func newServiceAccount(t *testing.T) *corev1.ServiceAccount { - t.Helper() +func newServiceAccount() *corev1.ServiceAccount { saBytes, err := os.ReadFile("./testdata/argocd-manager-sa.yaml") - require.NoError(t, err) + errors.CheckError(err) var sa corev1.ServiceAccount err = yaml.Unmarshal(saBytes, &sa) - require.NoError(t, err) + errors.CheckError(err) return &sa } -func newServiceAccountSecret(t *testing.T) *corev1.Secret { - t.Helper() +func newServiceAccountSecret() *corev1.Secret { secretBytes, err := os.ReadFile("./testdata/argocd-manager-sa-token.yaml") - require.NoError(t, err) + errors.CheckError(err) var secret corev1.Secret err = yaml.Unmarshal(secretBytes, &secret) - require.NoError(t, err) + errors.CheckError(err) return &secret } @@ -82,7 +80,7 @@ func TestCreateServiceAccount(t *testing.T) { cs := fake.NewClientset(ns) err := CreateServiceAccount(cs, "argocd-manager", "kube-system") require.NoError(t, err) - rsa, err := cs.CoreV1().ServiceAccounts("kube-system").Get(t.Context(), "argocd-manager", metav1.GetOptions{}) + rsa, err := cs.CoreV1().ServiceAccounts("kube-system").Get(context.Background(), "argocd-manager", metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, rsa) }) @@ -91,7 +89,7 @@ func TestCreateServiceAccount(t *testing.T) { cs := fake.NewClientset(ns, sa) err := CreateServiceAccount(cs, "argocd-manager", "kube-system") require.NoError(t, err) - rsa, err := cs.CoreV1().ServiceAccounts("kube-system").Get(t.Context(), "argocd-manager", metav1.GetOptions{}) + rsa, err := cs.CoreV1().ServiceAccounts("kube-system").Get(context.Background(), "argocd-manager", metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, rsa) }) @@ -100,42 +98,19 @@ func TestCreateServiceAccount(t *testing.T) { cs := fake.NewClientset() err := CreateServiceAccount(cs, "argocd-manager", "invalid") require.NoError(t, err) - rsa, err := cs.CoreV1().ServiceAccounts("invalid").Get(t.Context(), "argocd-manager", metav1.GetOptions{}) + rsa, err := cs.CoreV1().ServiceAccounts("invalid").Get(context.Background(), "argocd-manager", metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, rsa) }) } -func _MockK8STokenController(objects kubetesting.ObjectTracker) kubetesting.ReactionFunc { - return (func(action kubetesting.Action) (bool, runtime.Object, error) { - secret, ok := action.(kubetesting.CreateAction).GetObject().(*corev1.Secret) - if !ok { - return false, nil, nil - } - _, err := objects.Get(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, - secret.Namespace, - secret.Annotations[corev1.ServiceAccountNameKey], - metav1.GetOptions{}) - if err != nil { - return false, nil, nil - } - if secret.Data == nil { - secret.Data = map[string][]byte{} - } - if secret.Data[corev1.ServiceAccountTokenKey] == nil { - secret.Data[corev1.ServiceAccountTokenKey] = []byte(testToken) - } - return false, secret, nil - }) -} - func TestInstallClusterManagerRBAC(t *testing.T) { ns := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "test", }, } - legacyAutoSecret := &corev1.Secret{ + secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "sa-secret", Namespace: "test", @@ -152,39 +127,25 @@ func TestInstallClusterManagerRBAC(t *testing.T) { }, Secrets: []corev1.ObjectReference{ { - Kind: legacyAutoSecret.GetObjectKind().GroupVersionKind().Kind, - APIVersion: legacyAutoSecret.APIVersion, - Name: legacyAutoSecret.GetName(), - Namespace: legacyAutoSecret.GetNamespace(), - UID: legacyAutoSecret.GetUID(), - ResourceVersion: legacyAutoSecret.GetResourceVersion(), + Kind: secret.GetObjectKind().GroupVersionKind().Kind, + APIVersion: secret.APIVersion, + Name: secret.GetName(), + Namespace: secret.GetNamespace(), + UID: secret.GetUID(), + ResourceVersion: secret.GetResourceVersion(), }, }, } - longLivedSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: sa.Name + SATokenSecretSuffix, - Namespace: "test", - Annotations: map[string]string{ - corev1.ServiceAccountNameKey: sa.Name, - }, - }, - Type: corev1.SecretTypeServiceAccountToken, - Data: map[string][]byte{ - "token": []byte("barfoo"), - }, - } t.Run("Cluster Scope - Success", func(t *testing.T) { - cs := fake.NewClientset(ns, legacyAutoSecret, sa) - cs.PrependReactor("create", "secrets", _MockK8STokenController(cs.Tracker())) + cs := fake.NewClientset(ns, secret, sa) token, err := InstallClusterManagerRBAC(cs, "test", nil, testBearerTokenTimeout) require.NoError(t, err) - assert.Equal(t, testToken, token) + assert.Equal(t, "foobar", token) }) t.Run("Cluster Scope - Missing data in secret", func(t *testing.T) { - nsecret := legacyAutoSecret.DeepCopy() + nsecret := secret.DeepCopy() nsecret.Data = make(map[string][]byte) cs := fake.NewClientset(ns, nsecret, sa) token, err := InstallClusterManagerRBAC(cs, "test", nil, testBearerTokenTimeout) @@ -193,15 +154,14 @@ func TestInstallClusterManagerRBAC(t *testing.T) { }) t.Run("Namespace Scope - Success", func(t *testing.T) { - cs := fake.NewClientset(ns, sa, longLivedSecret) - cs.PrependReactor("create", "secrets", _MockK8STokenController(cs.Tracker())) + cs := fake.NewClientset(ns, secret, sa) token, err := InstallClusterManagerRBAC(cs, "test", []string{"nsa"}, testBearerTokenTimeout) require.NoError(t, err) - assert.Equal(t, "barfoo", token) + assert.Equal(t, "foobar", token) }) t.Run("Namespace Scope - Missing data in secret", func(t *testing.T) { - nsecret := legacyAutoSecret.DeepCopy() + nsecret := secret.DeepCopy() nsecret.Data = make(map[string][]byte) cs := fake.NewClientset(ns, nsecret, sa) token, err := InstallClusterManagerRBAC(cs, "test", []string{"nsa"}, testBearerTokenTimeout) @@ -212,23 +172,23 @@ func TestInstallClusterManagerRBAC(t *testing.T) { func TestUninstallClusterManagerRBAC(t *testing.T) { t.Run("Success", func(t *testing.T) { - cs := fake.NewClientset(newServiceAccountSecret(t)) + cs := fake.NewClientset(newServiceAccountSecret()) err := UninstallClusterManagerRBAC(cs) require.NoError(t, err) }) } func TestGenerateNewClusterManagerSecret(t *testing.T) { - kubeclientset := fake.NewClientset(newServiceAccountSecret(t)) + kubeclientset := fake.NewClientset(newServiceAccountSecret()) kubeclientset.ReactionChain = nil - generatedSecret := newServiceAccountSecret(t) + generatedSecret := newServiceAccountSecret() generatedSecret.Name = "argocd-manager-token-abc123" generatedSecret.Data = map[string][]byte{ "token": []byte("fake-token"), } - kubeclientset.AddReactor("*", "secrets", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) { + kubeclientset.AddReactor("*", "secrets", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { return true, generatedSecret, nil }) @@ -239,20 +199,20 @@ func TestGenerateNewClusterManagerSecret(t *testing.T) { } func TestRotateServiceAccountSecrets(t *testing.T) { - generatedSecret := newServiceAccountSecret(t) + generatedSecret := newServiceAccountSecret() generatedSecret.Name = "argocd-manager-token-abc123" generatedSecret.Data = map[string][]byte{ "token": []byte("fake-token"), } - kubeclientset := fake.NewClientset(newServiceAccount(t), newServiceAccountSecret(t), generatedSecret) + kubeclientset := fake.NewClientset(newServiceAccount(), newServiceAccountSecret(), generatedSecret) err := RotateServiceAccountSecrets(kubeclientset, &testClaims, generatedSecret) require.NoError(t, err) // Verify service account references new secret and old secret is deleted saClient := kubeclientset.CoreV1().ServiceAccounts(testClaims.Namespace) - sa, err := saClient.Get(t.Context(), testClaims.ServiceAccountName, metav1.GetOptions{}) + sa, err := saClient.Get(context.Background(), testClaims.ServiceAccountName, metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, []corev1.ObjectReference{ { @@ -260,13 +220,13 @@ func TestRotateServiceAccountSecrets(t *testing.T) { }, }, sa.Secrets) secretsClient := kubeclientset.CoreV1().Secrets(testClaims.Namespace) - _, err = secretsClient.Get(t.Context(), testClaims.SecretName, metav1.GetOptions{}) - assert.True(t, apierrors.IsNotFound(err)) + _, err = secretsClient.Get(context.Background(), testClaims.SecretName, metav1.GetOptions{}) + assert.True(t, apierr.IsNotFound(err)) } func TestGetServiceAccountBearerToken(t *testing.T) { - sa := newServiceAccount(t) - tokenSecret := newServiceAccountSecret(t) + sa := newServiceAccount() + tokenSecret := newServiceAccountSecret() dockercfgSecret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-manager-dockercfg-d8j66", @@ -280,6 +240,10 @@ func TestGetServiceAccountBearerToken(t *testing.T) { Name: dockercfgSecret.Name, Namespace: dockercfgSecret.Namespace, }, + { + Name: tokenSecret.Name, + Namespace: tokenSecret.Namespace, + }, } kubeclientset := fake.NewClientset(sa, dockercfgSecret, tokenSecret) @@ -294,60 +258,42 @@ func Test_getOrCreateServiceAccountTokenSecret_NoSecretForSA(t *testing.T) { Name: "kube-system", }, } - sa := &corev1.ServiceAccount{ + saWithoutSecret := &corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: ArgoCDManagerServiceAccount, Namespace: ns.Name, }, } - manualSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: ArgoCDManagerServiceAccount + SATokenSecretSuffix, - Namespace: ns.Name, - Annotations: map[string]string{ - corev1.ServiceAccountNameKey: sa.Name, - }, - }, - Type: corev1.SecretTypeServiceAccountToken, - } + cs := fake.NewClientset(ns, saWithoutSecret) + cs.PrependReactor("create", "secrets", + func(a kubetesting.Action) (handled bool, ret runtime.Object, err error) { + s, ok := a.(kubetesting.CreateAction).GetObject().(*corev1.Secret) + if !ok { + return + } - assertOnlyOneTokenExists := func(t *testing.T, cs *fake.Clientset) { - t.Helper() - got, err := getOrCreateServiceAccountTokenSecret(cs, ArgoCDManagerServiceAccount, ns.Name) - require.NoError(t, err) - assert.Equal(t, ArgoCDManagerServiceAccount+SATokenSecretSuffix, got) + if s.Name == "" && s.GenerateName != "" { + s.SetName(names.SimpleNameGenerator.GenerateName(s.GenerateName)) + } - list, err := cs.Tracker().List(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, - schema.GroupVersionKind{Version: "v1", Kind: "Secret"}, ns.Name, metav1.ListOptions{}) - require.NoError(t, err) - secretList, ok := list.(*corev1.SecretList) - require.True(t, ok) - assert.Len(t, secretList.Items, 1) - obj, err := cs.Tracker().Get(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, - ns.Name, ArgoCDManagerServiceAccount) - require.NoError(t, err, "ServiceAccount %s not found but was expected to be found", ArgoCDManagerServiceAccount) + s.Data = make(map[string][]byte) + s.Data["token"] = []byte("fake-token") - assert.Empty(t, obj.(*corev1.ServiceAccount).Secrets, 0) - } - t.Run("Token secret exists", func(t *testing.T) { - cs := fake.NewClientset(ns, sa, manualSecret) - assertOnlyOneTokenExists(t, cs) - }) - - t.Run("Token secret does not exist", func(t *testing.T) { - cs := fake.NewClientset(ns, sa) - assertOnlyOneTokenExists(t, cs) - }) - - t.Run("Error on secret creation", func(t *testing.T) { - cs := fake.NewClientset(ns, sa) - cs.PrependReactor("create", "secrets", func(kubetesting.Action) (handled bool, ret runtime.Object, err error) { - return true, &corev1.Secret{}, errors.New("testing error case") + return }) - got, err := getOrCreateServiceAccountTokenSecret(cs, ArgoCDManagerServiceAccount, ns.Name) - require.Error(t, err) - assert.Empty(t, got) - }) + + got, err := getOrCreateServiceAccountTokenSecret(cs, ArgoCDManagerServiceAccount, ns.Name) + require.NoError(t, err) + assert.Contains(t, got, "argocd-manager-token-") + + obj, err := cs.Tracker().Get(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, + ns.Name, ArgoCDManagerServiceAccount) + if err != nil { + t.Errorf("ServiceAccount %s not found but was expected to be found: %s", ArgoCDManagerServiceAccount, err.Error()) + } + + sa := obj.(*corev1.ServiceAccount) + assert.Len(t, sa.Secrets, 1) } func Test_getOrCreateServiceAccountTokenSecret_SAHasSecret(t *testing.T) { @@ -389,11 +335,13 @@ func Test_getOrCreateServiceAccountTokenSecret_SAHasSecret(t *testing.T) { got, err := getOrCreateServiceAccountTokenSecret(cs, ArgoCDManagerServiceAccount, ns.Name) require.NoError(t, err) - assert.Equal(t, ArgoCDManagerServiceAccount+SATokenSecretSuffix, got) + assert.Equal(t, "sa-secret", got) obj, err := cs.Tracker().Get(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, ns.Name, ArgoCDManagerServiceAccount) - require.NoError(t, err, "ServiceAccount %s not found but was expected to be found", ArgoCDManagerServiceAccount) + if err != nil { + t.Errorf("ServiceAccount %s not found but was expected to be found: %s", ArgoCDManagerServiceAccount, err.Error()) + } sa := obj.(*corev1.ServiceAccount) assert.Len(t, sa.Secrets, 1) diff --git a/util/clusterauth/testdata/argocd-manager-sa-token.yaml b/util/clusterauth/testdata/argocd-manager-sa-token.yaml index 0dbf4c5c8f..7faccf58b4 100644 --- a/util/clusterauth/testdata/argocd-manager-sa-token.yaml +++ b/util/clusterauth/testdata/argocd-manager-sa-token.yaml @@ -9,9 +9,10 @@ metadata: kubernetes.io/service-account.name: argocd-manager kubernetes.io/service-account.uid: 91dd37cf-8d92-11e9-a091-d65f2ae7fa8d creationTimestamp: "2019-06-13T04:30:24Z" - name: argocd-manager-long-lived-token + generateName: argocd-manager-token- + name: argocd-manager-token-tj79r namespace: kube-system resourceVersion: "133010" selfLink: /api/v1/namespaces/kube-system/secrets/argocd-manager-token-tj79r uid: f657d67e-8d93-11e9-a091-d65f2ae7fa8d -type: kubernetes.io/service-account-token +type: kubernetes.io/service-account-token \ No newline at end of file diff --git a/util/clusterauth/testdata/argocd-manager-sa.yaml b/util/clusterauth/testdata/argocd-manager-sa.yaml index 12edc44436..c02eceaa31 100644 --- a/util/clusterauth/testdata/argocd-manager-sa.yaml +++ b/util/clusterauth/testdata/argocd-manager-sa.yaml @@ -7,3 +7,5 @@ metadata: resourceVersion: "133015" selfLink: /api/v1/namespaces/kube-system/serviceaccounts/argocd-manager uid: 91dd37cf-8d92-11e9-a091-d65f2ae7fa8d +secrets: +- name: argocd-manager-token-tj79r \ No newline at end of file diff --git a/util/cmp/stream.go b/util/cmp/stream.go index c6c2195987..d7f080004d 100644 --- a/util/cmp/stream.go +++ b/util/cmp/stream.go @@ -15,10 +15,10 @@ import ( log "github.com/sirupsen/logrus" - pluginclient "github.com/argoproj/argo-cd/v3/cmpserver/apiclient" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/io/files" - "github.com/argoproj/argo-cd/v3/util/tgzstream" + pluginclient "github.com/argoproj/argo-cd/v2/cmpserver/apiclient" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/io/files" + "github.com/argoproj/argo-cd/v2/util/tgzstream" ) // StreamSender defines the contract to send App files over stream @@ -41,7 +41,7 @@ func ReceiveRepoStream(ctx context.Context, receiver StreamReceiver, destDir str return nil, fmt.Errorf("error receiving stream header: %w", err) } if header == nil || header.GetMetadata() == nil { - return nil, errors.New("error getting stream metadata: metadata is nil") + return nil, fmt.Errorf("error getting stream metadata: metadata is nil") } metadata := header.GetMetadata() @@ -186,7 +186,7 @@ func receiveFile(ctx context.Context, receiver StreamReceiver, checksum, dst str } f := req.GetFile() if f == nil { - return nil, errors.New("stream request file is nil") + return nil, fmt.Errorf("stream request file is nil") } _, err = file.Write(f.Chunk) if err != nil { @@ -198,7 +198,7 @@ func receiveFile(ctx context.Context, receiver StreamReceiver, checksum, dst str } } if hex.EncodeToString(hasher.Sum(nil)) != checksum { - return nil, errors.New("file checksum validation error") + return nil, fmt.Errorf("file checksum validation error") } _, err = file.Seek(0, io.SeekStart) diff --git a/util/cmp/stream_test.go b/util/cmp/stream_test.go index eeefd4c403..393cf5d167 100644 --- a/util/cmp/stream_test.go +++ b/util/cmp/stream_test.go @@ -2,7 +2,7 @@ package cmp_test import ( "context" - "errors" + "fmt" "io" "os" "path/filepath" @@ -12,10 +12,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - pluginclient "github.com/argoproj/argo-cd/v3/cmpserver/apiclient" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/cmp" - "github.com/argoproj/argo-cd/v3/util/io/files" + pluginclient "github.com/argoproj/argo-cd/v2/cmpserver/apiclient" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/cmp" + "github.com/argoproj/argo-cd/v2/util/io/files" ) type streamMock struct { @@ -30,7 +30,7 @@ func (m *streamMock) Recv() (*pluginclient.AppStreamRequest, error) { case <-m.done: return nil, io.EOF case <-time.After(500 * time.Millisecond): - return nil, errors.New("timeout receiving message mock") + return nil, fmt.Errorf("timeout receiving message mock") } } @@ -59,10 +59,10 @@ func TestReceiveApplicationStream(t *testing.T) { close(streamMock.messages) os.RemoveAll(workdir) }() - go streamMock.sendFile(t.Context(), t, appDir, streamMock, []string{"env1", "env2"}, []string{"DUMMY.md", "dum*"}) + go streamMock.sendFile(context.Background(), t, appDir, streamMock, []string{"env1", "env2"}, []string{"DUMMY.md", "dum*"}) // when - env, err := cmp.ReceiveRepoStream(t.Context(), streamMock, workdir, false) + env, err := cmp.ReceiveRepoStream(context.Background(), streamMock, workdir, false) // then require.NoError(t, err) diff --git a/util/config/env.go b/util/config/env.go index 4f2b8cf475..f5576e649e 100644 --- a/util/config/env.go +++ b/util/config/env.go @@ -30,16 +30,15 @@ func LoadFlags() error { var key string for _, opt := range opts { - switch { - case strings.HasPrefix(opt, "--"): + if strings.HasPrefix(opt, "--") { if key != "" { flags[key] = "true" } key = strings.TrimPrefix(opt, "--") - case key != "": + } else if key != "" { flags[key] = opt key = "" - default: + } else { return errors.New("ARGOCD_OPTS invalid at '" + opt + "'") } } diff --git a/util/config/reader.go b/util/config/reader.go index 35b33b9d8a..9674a2ef5b 100644 --- a/util/config/reader.go +++ b/util/config/reader.go @@ -10,7 +10,7 @@ import ( ) // UnmarshalReader is used to read manifests from stdin -func UnmarshalReader(reader io.Reader, obj any) error { +func UnmarshalReader(reader io.Reader, obj interface{}) error { data, err := io.ReadAll(reader) if err != nil { return err @@ -19,7 +19,7 @@ func UnmarshalReader(reader io.Reader, obj any) error { } // unmarshalObject tries to convert a YAML or JSON byte array into the provided type. -func unmarshalObject(data []byte, obj any) error { +func unmarshalObject(data []byte, obj interface{}) error { // first, try unmarshaling as JSON // Based on technique from Kubectl, which supports both YAML and JSON: // https://mlafeldt.github.io/blog/teaching-go-programs-to-love-json-and-yaml/ @@ -35,7 +35,7 @@ func unmarshalObject(data []byte, obj any) error { // MarshalLocalYAMLFile writes JSON or YAML to a file on disk. // The caller is responsible for checking error return values. -func MarshalLocalYAMLFile(path string, obj any) error { +func MarshalLocalYAMLFile(path string, obj interface{}) error { yamlData, err := yaml.Marshal(obj) if err == nil { err = os.WriteFile(path, yamlData, 0o600) @@ -45,7 +45,7 @@ func MarshalLocalYAMLFile(path string, obj any) error { // UnmarshalLocalFile retrieves JSON or YAML from a file on disk. // The caller is responsible for checking error return values. -func UnmarshalLocalFile(path string, obj any) error { +func UnmarshalLocalFile(path string, obj interface{}) error { data, err := os.ReadFile(path) if err == nil { err = unmarshalObject(data, obj) @@ -53,13 +53,13 @@ func UnmarshalLocalFile(path string, obj any) error { return err } -func Unmarshal(data []byte, obj any) error { +func Unmarshal(data []byte, obj interface{}) error { return unmarshalObject(data, obj) } // UnmarshalRemoteFile retrieves JSON or YAML through a GET request. // The caller is responsible for checking error return values. -func UnmarshalRemoteFile(url string, obj any) error { +func UnmarshalRemoteFile(url string, obj interface{}) error { data, err := ReadRemoteFile(url) if err == nil { err = unmarshalObject(data, obj) diff --git a/util/config/reader_test.go b/util/config/reader_test.go index 31e515bcc6..7265aefb68 100644 --- a/util/config/reader_test.go +++ b/util/config/reader_test.go @@ -37,7 +37,9 @@ func TestUnmarshalLocalFile(t *testing.T) { Field2 int } err = UnmarshalLocalFile(file.Name(), &testStruct) - require.NoError(t, err, "Could not unmarshal test data") + if err != nil { + t.Errorf("Could not unmarshal test data: %s", err) + } if testStruct.Field1 != field1 || testStruct.Field2 != field2 { t.Errorf("Test data did not match! Expected {%s %d} but got: %v", field1, field2, testStruct) @@ -56,7 +58,9 @@ func TestUnmarshal(t *testing.T) { Field2 int } err := Unmarshal([]byte(sentinel), &testStruct) - require.NoError(t, err, "Could not unmarshal test data") + if err != nil { + t.Errorf("Could not unmarshal test data: %s", err) + } if testStruct.Field1 != field1 || testStruct.Field2 != field2 { t.Errorf("Test data did not match! Expected {%s %d} but got: %v", field1, field2, testStruct) @@ -80,7 +84,7 @@ func TestUnmarshalRemoteFile(t *testing.T) { // send back the address so that it can be used c <- listener.Addr().String() - http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // return the sentinel text at root URL fmt.Fprint(w, sentinel) }) @@ -97,14 +101,18 @@ func TestUnmarshalRemoteFile(t *testing.T) { t.Logf("Listening at address: %s", address) data, err := ReadRemoteFile("http://" + address) - assert.Equal(t, string(data), sentinel, "Test data did not match (err = %v)! Expected %q and received %q", err, sentinel, string(data)) + if string(data) != sentinel { + t.Errorf("Test data did not match (err = %v)! Expected %q and received %q", err, sentinel, string(data)) + } var testStruct struct { Field1 string Field2 int } err = UnmarshalRemoteFile("http://"+address, &testStruct) - require.NoError(t, err, "Could not unmarshal test data") + if err != nil { + t.Errorf("Could not unmarshal test data: %s", err) + } if testStruct.Field1 != field1 || testStruct.Field2 != field2 { t.Errorf("Test data did not match! Expected {%s %d} but got: %v", field1, field2, testStruct) diff --git a/util/db/certificate.go b/util/db/certificate.go index 7c14f48299..3bedbc5e6f 100644 --- a/util/db/certificate.go +++ b/util/db/certificate.go @@ -2,7 +2,6 @@ package db import ( "context" - "errors" "fmt" "regexp" "strings" @@ -11,9 +10,9 @@ import ( log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/common" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - certutil "github.com/argoproj/argo-cd/v3/util/cert" + "github.com/argoproj/argo-cd/v2/common" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + certutil "github.com/argoproj/argo-cd/v2/util/cert" ) // A struct representing an entry in the list of SSH known hosts. @@ -56,7 +55,7 @@ type CertificateListSelector struct { // - For SSH keys, the SHA256 fingerprint of the key as string, prepended by // the string "SHA256:" // - For TLS certs, the Subject of the X509 cert as a string in DN notation -func (db *db) ListRepoCertificates(_ context.Context, selector *CertificateListSelector) (*appsv1.RepositoryCertificateList, error) { +func (db *db) ListRepoCertificates(ctx context.Context, selector *CertificateListSelector) (*appsv1.RepositoryCertificateList, error) { // selector may be given as nil, but we need at least an empty data structure // so we create it if necessary. if selector == nil { @@ -123,7 +122,7 @@ func (db *db) ListRepoCertificates(_ context.Context, selector *CertificateListS } // Get a single certificate from the datastore -func (db *db) GetRepoCertificate(_ context.Context, serverType string, serverName string) (*appsv1.RepositoryCertificate, error) { +func (db *db) GetRepoCertificate(ctx context.Context, serverType string, serverName string) (*appsv1.RepositoryCertificate, error) { if serverType == "ssh" { sshKnownHostsList, err := db.getSSHKnownHostsData() if err != nil { @@ -151,8 +150,8 @@ func (db *db) GetRepoCertificate(_ context.Context, serverType string, serverNam // actually created. func (db *db) CreateRepoCertificate(ctx context.Context, certificates *appsv1.RepositoryCertificateList, upsert bool) (*appsv1.RepositoryCertificateList, error) { var ( - saveSSHData = false - saveTLSData = false + saveSSHData bool = false + saveTLSData bool = false ) sshKnownHostsList, err := db.getSSHKnownHostsData() @@ -175,7 +174,7 @@ func (db *db) CreateRepoCertificate(ctx context.Context, certificates *appsv1.Re // For SSH known host entries, we let Go's ssh library do the validation // later on. if certificate.CertType == "https" && !certutil.IsValidHostname(certificate.ServerName, false) { - return nil, fmt.Errorf("invalid hostname in request: %s", certificate.ServerName) + return nil, fmt.Errorf("Invalid hostname in request: %s", certificate.ServerName) } else if certificate.CertType == "ssh" { // Matches "[hostname]:port" format reExtract := regexp.MustCompile(`^\[(.*)\]\:[0-9]+$`) @@ -187,12 +186,11 @@ func (db *db) CreateRepoCertificate(ctx context.Context, certificates *appsv1.Re hostnameToCheck = matches[1] } if !certutil.IsValidHostname(hostnameToCheck, false) { - return nil, fmt.Errorf("invalid hostname in request: %s", hostnameToCheck) + return nil, fmt.Errorf("Invalid hostname in request: %s", hostnameToCheck) } } - switch certificate.CertType { - case "ssh": + if certificate.CertType == "ssh" { // Whether we have a new certificate entry newEntry := true // Whether we have upserted an existing certificate entry @@ -204,16 +202,17 @@ func (db *db) CreateRepoCertificate(ctx context.Context, certificates *appsv1.Re for _, entry := range sshKnownHostsList { if entry.Host == certificate.ServerName && entry.SubType == certificate.CertSubType { if !upsert && entry.Data != string(certificate.CertData) { - return nil, fmt.Errorf("key for '%s' (subtype: '%s') already exists, and upsert was not specified", entry.Host, entry.SubType) + return nil, fmt.Errorf("Key for '%s' (subtype: '%s') already exist and upsert was not specified.", entry.Host, entry.SubType) + } else { + // Do not add an entry on upsert, but remember if we actual did an + // upsert. + newEntry = false + if entry.Data != string(certificate.CertData) { + entry.Data = string(certificate.CertData) + upserted = true + } + break } - // Do not add an entry on upsert, but remember if we actual did an - // upsert. - newEntry = false - if entry.Data != string(certificate.CertData) { - entry.Data = string(certificate.CertData) - upserted = true - } - break } } @@ -242,8 +241,8 @@ func (db *db) CreateRepoCertificate(ctx context.Context, certificates *appsv1.Re created = append(created, certificate) saveSSHData = true } - case "https": - var tlsCertificate *TLSCertificate + } else if certificate.CertType == "https" { + var tlsCertificate *TLSCertificate = nil newEntry := true upserted := false pemCreated := make([]string, 0) @@ -254,7 +253,7 @@ func (db *db) CreateRepoCertificate(ctx context.Context, certificates *appsv1.Re newEntry = false if entry.Data != string(certificate.CertData) { if !upsert { - return nil, fmt.Errorf("TLS certificate for server '%s' already exists, and upsert was not specified", entry.Subject) + return nil, fmt.Errorf("TLS certificate for server '%s' already exist and upsert was not specified.", entry.Subject) } } // Store pointer to this entry for later use. @@ -271,7 +270,7 @@ func (db *db) CreateRepoCertificate(ctx context.Context, certificates *appsv1.Re // We should have at least one valid PEM entry if len(pemData) == 0 { - return nil, errors.New("no valid PEM data received") + return nil, fmt.Errorf("No valid PEM data received.") } // Make sure we have valid X509 certificates in the data @@ -309,9 +308,9 @@ func (db *db) CreateRepoCertificate(ctx context.Context, certificates *appsv1.Re } saveTLSData = true } - default: + } else { // Invalid/unknown certificate type - return nil, fmt.Errorf("unknown certificate type: %s", certificate.CertType) + return nil, fmt.Errorf("Unknown certificate type: %s", certificate.CertType) } } diff --git a/util/db/certificate_test.go b/util/db/certificate_test.go index fadc100d45..62358bcd15 100644 --- a/util/db/certificate_test.go +++ b/util/db/certificate_test.go @@ -1,30 +1,31 @@ package db import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( - TestCert1CN = "CN=foo.example.com,OU=SpecOps,O=Capone\\, Inc,L=Chicago,ST=IL,C=US" - TestCert2CN = "CN=bar.example.com,OU=Testsuite,O=Testing Corp,L=Hanover,ST=Lower Saxony,C=DE" + Test_Cert1CN = "CN=foo.example.com,OU=SpecOps,O=Capone\\, Inc,L=Chicago,ST=IL,C=US" + Test_Cert2CN = "CN=bar.example.com,OU=Testsuite,O=Testing Corp,L=Hanover,ST=Lower Saxony,C=DE" ) -var TestTLSSubjects = []string{ +var Test_TLS_Subjects []string = []string{ "CN=foo.example.com,OU=SpecOps,O=Capone\\, Inc,L=Chicago,ST=IL,C=US", "CN=bar.example.com,OU=Testsuite,O=Testing Corp,L=Hanover,ST=Lower Saxony,C=DE", } -const TestTLSValidSingleCert = ` +const Test_TLSValidSingleCert = ` -----BEGIN CERTIFICATE----- MIIFvTCCA6WgAwIBAgIUGrTmW3qc39zqnE08e3qNDhUkeWswDQYJKoZIhvcNAQEL BQAwbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv @@ -60,7 +61,7 @@ xO7Tr5lAo74vNUkF2EHNaI28/RGnJPm2TIxZqy4rNH6L -----END CERTIFICATE----- ` -const TestTLSInvalidPEMData = ` +const Test_TLSInvalidPEMData = ` MIIF1zCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL BQAwezELMAkGA1UEBhMCREUxFTATBgNVBAgMDExvd2VyIFNheG9ueTEQMA4GA1UE BwwHSGFub3ZlcjEVMBMGA1UECgwMVGVzdGluZyBDb3JwMRIwEAYDVQQLDAlUZXN0 @@ -77,7 +78,7 @@ YilqCPFX+az09EqqK/iHXnkdZ/Z2fCuU+9M/Zhrnlwlygl3RuVBI6xhm/ZsXtL2E Gxa61lNy6pyx5+hSxHEFEJshXLtioRd702VdLKxEOuYSXKeJDs1x9o6cJ75S6hko ` -const TestTLSInvalidSingleCert = ` +const Test_TLSInvalidSingleCert = ` -----BEGIN CERTIFICATE----- MIIF1zCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL BQAwezELMAkGA1UEBhMCREUxFTATBgNVBAgMDExvd2VyIFNheG9ueTEQMA4GA1UE @@ -114,7 +115,7 @@ XWyb96wrUlv+E8I= -----END CERTIFICATE----- ` -const TestTLSValidMultiCert = ` +const Test_TLSValidMultiCert = ` -----BEGIN CERTIFICATE----- MIIFvTCCA6WgAwIBAgIUGrTmW3qc39zqnE08e3qNDhUkeWswDQYJKoZIhvcNAQEL BQAwbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv @@ -185,7 +186,7 @@ XWyb96wrUlv+E8I= ` // Taken from hack/ssh_known_hosts -const TestValidSSHKnownHostsData = ` +const Test_ValidSSHKnownHostsData = ` # BitBucket bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M= # GitHub @@ -199,7 +200,7 @@ ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4Nak vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H ` -const TestInvalidSSHKnownHostsData = ` +const Test_InvalidSSHKnownHostsData = ` bitbucket.org AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M= # GitHub github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= @@ -212,7 +213,7 @@ ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4Nak vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H ` -var TestSSHHostnameEntries = []string{ +var Test_SSH_Hostname_Entries []string = []string{ "bitbucket.org", "github.com", "gitlab.com", @@ -222,7 +223,7 @@ var TestSSHHostnameEntries = []string{ "vs-ssh.visualstudio.com", } -var TestSSHSubtypes = []string{ +var Test_SSH_Subtypes []string = []string{ "ssh-rsa", "ssh-rsa", "ecdsa-sha2-nistp256", @@ -232,19 +233,19 @@ var TestSSHSubtypes = []string{ "ssh-rsa", } -var TestTLSHostnames = []string{ +var Test_TLS_Hostnames []string = []string{ "test.example.com", "test.example.com", "github.com", } const ( - TestNumSSHKnownHostsExpected = 7 - TestNumTLSCertificatesExpected = 3 + Test_NumSSHKnownHostsExpected = 7 + Test_NumTLSCertificatesExpected = 3 ) func getCertClientset() *fake.Clientset { - cm := corev1.ConfigMap{ + cm := v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-cm", Namespace: testNamespace, @@ -255,7 +256,7 @@ func getCertClientset() *fake.Clientset { Data: nil, } - sshCM := corev1.ConfigMap{ + sshCM := v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-ssh-known-hosts-cm", Namespace: testNamespace, @@ -264,11 +265,11 @@ func getCertClientset() *fake.Clientset { }, }, Data: map[string]string{ - "ssh_known_hosts": TestValidSSHKnownHostsData, + "ssh_known_hosts": Test_ValidSSHKnownHostsData, }, } - tlsCM := corev1.ConfigMap{ + tlsCM := v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-tls-certs-cm", Namespace: testNamespace, @@ -277,63 +278,63 @@ func getCertClientset() *fake.Clientset { }, }, Data: map[string]string{ - "test.example.com": TestTLSValidMultiCert, - "gitlab.com": TestTLSValidSingleCert, + "test.example.com": Test_TLSValidMultiCert, + "gitlab.com": Test_TLSValidSingleCert, }, } return fake.NewClientset([]runtime.Object{&cm, &sshCM, &tlsCM}...) } -func TestListCertificate(t *testing.T) { +func Test_ListCertificate(t *testing.T) { clientset := getCertClientset() - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) assert.NotNil(t, db) // List all SSH known host entries from configuration. // Expected: List of 7 entries - certList, err := db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err := db.ListRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "*", CertType: "ssh", }) require.NoError(t, err) assert.NotNil(t, certList) - assert.Len(t, certList.Items, TestNumSSHKnownHostsExpected) + assert.Len(t, certList.Items, Test_NumSSHKnownHostsExpected) for idx, entry := range certList.Items { - assert.Equal(t, entry.ServerName, TestSSHHostnameEntries[idx]) - assert.Equal(t, entry.CertSubType, TestSSHSubtypes[idx]) + assert.Equal(t, entry.ServerName, Test_SSH_Hostname_Entries[idx]) + assert.Equal(t, entry.CertSubType, Test_SSH_Subtypes[idx]) } // List all TLS certificates from configuration. // Expected: List of 3 entries - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "*", CertType: "https", }) require.NoError(t, err) assert.NotNil(t, certList) - assert.Len(t, certList.Items, TestNumTLSCertificatesExpected) + assert.Len(t, certList.Items, Test_NumTLSCertificatesExpected) // List all certificates using selector // Expected: List of 10 entries - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "*", CertType: "*", }) require.NoError(t, err) assert.NotNil(t, certList) - assert.Len(t, certList.Items, TestNumTLSCertificatesExpected+TestNumSSHKnownHostsExpected) + assert.Len(t, certList.Items, Test_NumTLSCertificatesExpected+Test_NumSSHKnownHostsExpected) // List all certificates using nil selector // Expected: List of 10 entries - certList, err = db.ListRepoCertificates(t.Context(), nil) + certList, err = db.ListRepoCertificates(context.Background(), nil) require.NoError(t, err) assert.NotNil(t, certList) - assert.Len(t, certList.Items, TestNumTLSCertificatesExpected+TestNumSSHKnownHostsExpected) + assert.Len(t, certList.Items, Test_NumTLSCertificatesExpected+Test_NumSSHKnownHostsExpected) // List all certificates matching a host name pattern // Expected: List of 4 entries, all with servername gitlab.com - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "gitlab.com", CertType: "*", }) @@ -345,7 +346,7 @@ func TestListCertificate(t *testing.T) { } // List all TLS certificates matching a host name pattern - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "gitlab.com", CertType: "https", }) @@ -356,13 +357,13 @@ func TestListCertificate(t *testing.T) { assert.Equal(t, "https", certList.Items[0].CertType) } -func TestCreateSSHKnownHostEntries(t *testing.T) { +func Test_CreateSSHKnownHostEntries(t *testing.T) { clientset := getCertClientset() - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) assert.NotNil(t, db) // Valid known hosts entry - certList, err := db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err := db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "foo.example.com", @@ -376,7 +377,7 @@ func TestCreateSSHKnownHostEntries(t *testing.T) { assert.Len(t, certList.Items, 1) // Valid known hosts entry - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "[foo.example.com]:2222", @@ -391,7 +392,7 @@ func TestCreateSSHKnownHostEntries(t *testing.T) { // Invalid hostname // Result: Error - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "foo..example.com", @@ -405,7 +406,7 @@ func TestCreateSSHKnownHostEntries(t *testing.T) { // Check if it really was added // Result: List of 1 entry - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "foo.example.com", CertType: "ssh", }) @@ -415,7 +416,7 @@ func TestCreateSSHKnownHostEntries(t *testing.T) { // Existing cert, same data, no upsert // Result: no error, should return 0 added certificates - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "foo.example.com", @@ -430,7 +431,7 @@ func TestCreateSSHKnownHostEntries(t *testing.T) { // Existing cert, different data, no upsert // Result: Error - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "foo.example.com", @@ -443,7 +444,7 @@ func TestCreateSSHKnownHostEntries(t *testing.T) { assert.Nil(t, certList) // Existing cert, different data, upsert - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "foo.example.com", @@ -458,7 +459,7 @@ func TestCreateSSHKnownHostEntries(t *testing.T) { // Invalid known hosts entry, case 1: key sub type missing // Result: Error - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "bar.example.com", @@ -472,7 +473,7 @@ func TestCreateSSHKnownHostEntries(t *testing.T) { // Invalid known hosts entry, case 2: invalid base64 data // Result: Error - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "bar.example.com", @@ -485,19 +486,19 @@ func TestCreateSSHKnownHostEntries(t *testing.T) { assert.Nil(t, certList) } -func TestCreateTLSCertificates(t *testing.T) { +func Test_CreateTLSCertificates(t *testing.T) { clientset := getCertClientset() - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) assert.NotNil(t, db) // Valid TLS certificate // Expected: List of 1 entry - certList, err := db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err := db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "foo.example.com", CertType: "https", - CertData: []byte(TestTLSValidSingleCert), + CertData: []byte(Test_TLSValidSingleCert), }, }, }, false) @@ -507,12 +508,12 @@ func TestCreateTLSCertificates(t *testing.T) { // Invalid hostname // Result: Error - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "foo..example", CertType: "https", - CertData: []byte(TestTLSValidSingleCert), + CertData: []byte(Test_TLSValidSingleCert), }, }, }, false) @@ -521,7 +522,7 @@ func TestCreateTLSCertificates(t *testing.T) { // Check if it really was added // Result: Return new certificate - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "foo.example.com", CertType: "https", }) @@ -531,12 +532,12 @@ func TestCreateTLSCertificates(t *testing.T) { // Valid TLS certificates, multiple PEMs in data // Expected: List of 2 entry - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "bar.example.com", CertType: "https", - CertData: []byte(TestTLSValidMultiCert), + CertData: []byte(Test_TLSValidMultiCert), }, }, }, false) @@ -546,7 +547,7 @@ func TestCreateTLSCertificates(t *testing.T) { // Check if it really was added // Result: Return new certificate - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "bar.example.com", CertType: "https", }) @@ -556,12 +557,12 @@ func TestCreateTLSCertificates(t *testing.T) { // Valid TLS certificate, existing cert, same data, no upsert // Expected: List of 0 entry - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "foo.example.com", CertType: "https", - CertData: []byte(TestTLSValidSingleCert), + CertData: []byte(Test_TLSValidSingleCert), }, }, }, false) @@ -571,12 +572,12 @@ func TestCreateTLSCertificates(t *testing.T) { // Valid TLS certificate, existing cert, different data, no upsert // Expected: Error - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "foo.example.com", CertType: "https", - CertData: []byte(TestTLSValidMultiCert), + CertData: []byte(Test_TLSValidMultiCert), }, }, }, false) @@ -585,12 +586,12 @@ func TestCreateTLSCertificates(t *testing.T) { // Valid TLS certificate, existing cert, different data, upsert // Expected: List of 2 entries - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "foo.example.com", CertType: "https", - CertData: []byte(TestTLSValidMultiCert), + CertData: []byte(Test_TLSValidMultiCert), }, }, }, true) @@ -600,7 +601,7 @@ func TestCreateTLSCertificates(t *testing.T) { // Check if upsert was successful // Expected: List of 2 entries, matching hostnames & cert types - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "foo.example.com", CertType: "https", }) @@ -614,12 +615,12 @@ func TestCreateTLSCertificates(t *testing.T) { // Invalid PEM data, new cert // Expected: Error - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "baz.example.com", CertType: "https", - CertData: []byte(TestTLSInvalidPEMData), + CertData: []byte(Test_TLSInvalidPEMData), }, }, }, false) @@ -628,12 +629,12 @@ func TestCreateTLSCertificates(t *testing.T) { // Valid PEM data, new cert, but invalid certificate // Expected: Error - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "baz.example.com", CertType: "https", - CertData: []byte(TestTLSInvalidSingleCert), + CertData: []byte(Test_TLSInvalidSingleCert), }, }, }, false) @@ -642,12 +643,12 @@ func TestCreateTLSCertificates(t *testing.T) { // Invalid PEM data, existing cert, upsert // Expected: Error - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "baz.example.com", CertType: "https", - CertData: []byte(TestTLSInvalidPEMData), + CertData: []byte(Test_TLSInvalidPEMData), }, }, }, true) @@ -656,12 +657,12 @@ func TestCreateTLSCertificates(t *testing.T) { // Valid PEM data, existing cert, but invalid certificate, upsert // Expected: Error - certList, err = db.CreateRepoCertificate(t.Context(), &v1alpha1.RepositoryCertificateList{ + certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{ Items: []v1alpha1.RepositoryCertificate{ { ServerName: "baz.example.com", CertType: "https", - CertData: []byte(TestTLSInvalidSingleCert), + CertData: []byte(Test_TLSInvalidSingleCert), }, }, }, true) @@ -669,14 +670,14 @@ func TestCreateTLSCertificates(t *testing.T) { assert.Nil(t, certList) } -func TestRemoveSSHKnownHosts(t *testing.T) { +func Test_RemoveSSHKnownHosts(t *testing.T) { clientset := getCertClientset() - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) assert.NotNil(t, db) // Remove single SSH known hosts entry by hostname // Expected: List of 1 entry - certList, err := db.RemoveRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err := db.RemoveRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "github.com", CertType: "ssh", }) @@ -686,7 +687,7 @@ func TestRemoveSSHKnownHosts(t *testing.T) { // Check whether entry was really removed // Expected: List of 0 entries - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "github.com", CertType: "ssh", }) @@ -696,7 +697,7 @@ func TestRemoveSSHKnownHosts(t *testing.T) { // Remove single SSH known hosts entry by sub type // Expected: List of 1 entry - certList, err = db.RemoveRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.RemoveRepoCertificates(context.Background(), &CertificateListSelector{ CertType: "ssh", CertSubType: "ssh-ed25519", }) @@ -706,7 +707,7 @@ func TestRemoveSSHKnownHosts(t *testing.T) { // Check whether entry was really removed // Expected: List of 0 entries - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ CertType: "ssh", CertSubType: "ssh-ed25519", }) @@ -716,7 +717,7 @@ func TestRemoveSSHKnownHosts(t *testing.T) { // Remove all remaining SSH known hosts entries // Expected: List of 5 entry - certList, err = db.RemoveRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.RemoveRepoCertificates(context.Background(), &CertificateListSelector{ CertType: "ssh", }) require.NoError(t, err) @@ -725,7 +726,7 @@ func TestRemoveSSHKnownHosts(t *testing.T) { // Check whether the entries were really removed // Expected: List of 0 entries - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ CertType: "ssh", }) require.NoError(t, err) @@ -733,14 +734,14 @@ func TestRemoveSSHKnownHosts(t *testing.T) { assert.Empty(t, certList.Items) } -func TestRemoveTLSCertificates(t *testing.T) { +func Test_RemoveTLSCertificates(t *testing.T) { clientset := getCertClientset() - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) assert.NotNil(t, db) // Remove single TLS certificate entry by hostname // Expected: List of 1 entry - certList, err := db.RemoveRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err := db.RemoveRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "gitlab.com", CertType: "https", }) @@ -750,7 +751,7 @@ func TestRemoveTLSCertificates(t *testing.T) { // Check whether entry was really removed // Expected: List of 0 entries - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "gitlab.com", CertType: "https", }) @@ -760,7 +761,7 @@ func TestRemoveTLSCertificates(t *testing.T) { // Remove all TLS certificate entry for hostname // Expected: List of 2 entry - certList, err = db.RemoveRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.RemoveRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "test.example.com", CertType: "https", }) @@ -770,7 +771,7 @@ func TestRemoveTLSCertificates(t *testing.T) { // Check whether entries were really removed // Expected: List of 0 entries - certList, err = db.ListRepoCertificates(t.Context(), &CertificateListSelector{ + certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{ HostNamePattern: "test.example.com", CertType: "https", }) diff --git a/util/db/cluster.go b/util/db/cluster.go index a0259d98ac..4ce9bdbd37 100644 --- a/util/db/cluster.go +++ b/util/db/cluster.go @@ -13,15 +13,15 @@ import ( log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + apiv1 "k8s.io/api/core/v1" + apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/watch" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/common" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/settings" + "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/settings" ) var ( @@ -37,12 +37,12 @@ func (db *db) getLocalCluster() *appv1.Cluster { initLocalCluster.Do(func() { info, err := db.kubeclientset.Discovery().ServerVersion() if err == nil { - //nolint:staticcheck + // nolint:staticcheck localCluster.ServerVersion = fmt.Sprintf("%s.%s", info.Major, info.Minor) - //nolint:staticcheck + // nolint:staticcheck localCluster.ConnectionState = appv1.ConnectionState{Status: appv1.ConnectionStatusSuccessful} } else { - //nolint:staticcheck + // nolint:staticcheck localCluster.ConnectionState = appv1.ConnectionState{ Status: appv1.ConnectionStatusFailed, Message: err.Error(), @@ -51,13 +51,13 @@ func (db *db) getLocalCluster() *appv1.Cluster { }) cluster := localCluster.DeepCopy() now := metav1.Now() - //nolint:staticcheck + // nolint:staticcheck cluster.ConnectionState.ModifiedAt = &now return cluster } // ListClusters returns list of clusters -func (db *db) ListClusters(_ context.Context) (*appv1.ClusterList, error) { +func (db *db) ListClusters(ctx context.Context) (*appv1.ClusterList, error) { clusterSecrets, err := db.listSecretsByType(common.LabelValueSecretTypeCluster) if err != nil { return nil, err @@ -106,7 +106,7 @@ func (db *db) CreateCluster(ctx context.Context, c *appv1.Cluster) (*appv1.Clust return nil, err } - clusterSecret := &corev1.Secret{ + clusterSecret := &apiv1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: secName, }, @@ -118,7 +118,7 @@ func (db *db) CreateCluster(ctx context.Context, c *appv1.Cluster) (*appv1.Clust clusterSecret, err = db.createSecret(ctx, clusterSecret) if err != nil { - if apierrors.IsAlreadyExists(err) { + if apierr.IsAlreadyExists(err) { return nil, status.Errorf(codes.AlreadyExists, "cluster %q already exists", c.Server) } return nil, err @@ -142,42 +142,32 @@ func (db *db) WatchClusters(ctx context.Context, handleModEvent func(oldCluster *appv1.Cluster, newCluster *appv1.Cluster), handleDeleteEvent func(clusterServer string), ) error { - argoSettings, err := db.settingsMgr.GetSettings() + localCls, err := db.GetCluster(ctx, appv1.KubernetesInternalAPIServerAddr) if err != nil { return err } - - localCls := db.getLocalCluster() - if argoSettings.InClusterEnabled { - localCls, err = db.GetCluster(ctx, appv1.KubernetesInternalAPIServerAddr) - if err != nil { - return fmt.Errorf("could not get local cluster: %w", err) - } - handleAddEvent(localCls) - } + handleAddEvent(localCls) db.watchSecrets( ctx, common.LabelValueSecretTypeCluster, - func(secret *corev1.Secret) { + func(secret *apiv1.Secret) { cluster, err := SecretToCluster(secret) if err != nil { log.Errorf("could not unmarshal cluster secret %s", secret.Name) return } if cluster.Server == appv1.KubernetesInternalAPIServerAddr { - if argoSettings.InClusterEnabled { - // change local cluster event to modified, since it cannot be added at runtime - handleModEvent(localCls, cluster) - localCls = cluster - } + // change local cluster event to modified or deleted, since it cannot be re-added or deleted + handleModEvent(localCls, cluster) + localCls = cluster return } handleAddEvent(cluster) }, - func(oldSecret *corev1.Secret, newSecret *corev1.Secret) { + func(oldSecret *apiv1.Secret, newSecret *apiv1.Secret) { oldCluster, err := SecretToCluster(oldSecret) if err != nil { log.Errorf("could not unmarshal cluster secret %s", oldSecret.Name) @@ -194,12 +184,11 @@ func (db *db) WatchClusters(ctx context.Context, handleModEvent(oldCluster, newCluster) }, - func(secret *corev1.Secret) { - if string(secret.Data["server"]) == appv1.KubernetesInternalAPIServerAddr && argoSettings.InClusterEnabled { - // change local cluster event to modified, since it cannot be deleted at runtime, unless disabled. - newLocalCls := db.getLocalCluster() - handleModEvent(localCls, newLocalCls) - localCls = newLocalCls + func(secret *apiv1.Secret) { + if string(secret.Data["server"]) == appv1.KubernetesInternalAPIServerAddr { + // change local cluster event to modified or deleted, since it cannot be re-added or deleted + handleModEvent(localCls, db.getLocalCluster()) + localCls = db.getLocalCluster() } else { handleDeleteEvent(string(secret.Data["server"])) } @@ -209,7 +198,7 @@ func (db *db) WatchClusters(ctx context.Context, return err } -func (db *db) getClusterSecret(server string) (*corev1.Secret, error) { +func (db *db) getClusterSecret(server string) (*apiv1.Secret, error) { clusterSecrets, err := db.listSecretsByType(common.LabelValueSecretTypeCluster) if err != nil { return nil, err @@ -225,14 +214,6 @@ func (db *db) getClusterSecret(server string) (*corev1.Secret, error) { // GetCluster returns a cluster from a query func (db *db) GetCluster(_ context.Context, server string) (*appv1.Cluster, error) { - argoSettings, err := db.settingsMgr.GetSettings() - if err != nil { - return nil, err - } - if server == appv1.KubernetesInternalAPIServerAddr && !argoSettings.InClusterEnabled { - return nil, status.Errorf(codes.NotFound, "cluster %q is disabled", server) - } - informer, err := db.settingsMgr.GetSecretsInformer() if err != nil { return nil, err @@ -241,9 +222,8 @@ func (db *db) GetCluster(_ context.Context, server string) (*appv1.Cluster, erro if err != nil { return nil, err } - if len(res) > 0 { - return SecretToCluster(res[0].(*corev1.Secret)) + return SecretToCluster(res[0].(*apiv1.Secret)) } if server == appv1.KubernetesInternalAPIServerAddr { return db.getLocalCluster(), nil @@ -253,7 +233,7 @@ func (db *db) GetCluster(_ context.Context, server string) (*appv1.Cluster, erro } // GetProjectClusters return project scoped clusters by given project name -func (db *db) GetProjectClusters(_ context.Context, project string) ([]*appv1.Cluster, error) { +func (db *db) GetProjectClusters(ctx context.Context, project string) ([]*appv1.Cluster, error) { informer, err := db.settingsMgr.GetSecretsInformer() if err != nil { return nil, fmt.Errorf("failed to get secrets informer: %w", err) @@ -264,7 +244,7 @@ func (db *db) GetProjectClusters(_ context.Context, project string) ([]*appv1.Cl } var res []*appv1.Cluster for i := range secrets { - cluster, err := SecretToCluster(secrets[i].(*corev1.Secret)) + cluster, err := SecretToCluster(secrets[i].(*apiv1.Secret)) if err != nil { return nil, fmt.Errorf("failed to convert secret to cluster: %w", err) } @@ -273,11 +253,7 @@ func (db *db) GetProjectClusters(_ context.Context, project string) ([]*appv1.Cl return res, nil } -func (db *db) GetClusterServersByName(_ context.Context, name string) ([]string, error) { - argoSettings, err := db.settingsMgr.GetSettings() - if err != nil { - return nil, err - } +func (db *db) GetClusterServersByName(ctx context.Context, name string) ([]string, error) { informer, err := db.settingsMgr.GetSecretsInformer() if err != nil { return nil, err @@ -289,7 +265,7 @@ func (db *db) GetClusterServersByName(_ context.Context, name string) ([]string, return nil, err } - if len(localClusterSecrets) == 0 && db.getLocalCluster().Name == name && argoSettings.InClusterEnabled { + if len(localClusterSecrets) == 0 && db.getLocalCluster().Name == name { return []string{appv1.KubernetesInternalAPIServerAddr}, nil } @@ -299,12 +275,8 @@ func (db *db) GetClusterServersByName(_ context.Context, name string) ([]string, } var res []string for i := range secrets { - s := secrets[i].(*corev1.Secret) - server := strings.TrimRight(string(s.Data["server"]), "/") - if !argoSettings.InClusterEnabled && server == appv1.KubernetesInternalAPIServerAddr { - continue - } - res = append(res, server) + s := secrets[i].(*apiv1.Secret) + res = append(res, strings.TrimRight(string(s.Data["server"]), "/")) } return res, nil } @@ -350,7 +322,7 @@ func (db *db) DeleteCluster(ctx context.Context, server string) error { } // clusterToSecret converts a cluster object to string data for serialization to a secret -func clusterToSecret(c *appv1.Cluster, secret *corev1.Secret) error { +func clusterToSecret(c *appv1.Cluster, secret *apiv1.Secret) error { data := make(map[string][]byte) data["server"] = []byte(strings.TrimRight(c.Server, "/")) if c.Name == "" { @@ -378,8 +350,8 @@ func clusterToSecret(c *appv1.Cluster, secret *corev1.Secret) error { secret.Data = data secret.Labels = c.Labels - if c.Annotations != nil && c.Annotations[corev1.LastAppliedConfigAnnotation] != "" { - return status.Errorf(codes.InvalidArgument, "annotation %s cannot be set", corev1.LastAppliedConfigAnnotation) + if c.Annotations != nil && c.Annotations[apiv1.LastAppliedConfigAnnotation] != "" { + return status.Errorf(codes.InvalidArgument, "annotation %s cannot be set", apiv1.LastAppliedConfigAnnotation) } secret.Annotations = c.Annotations @@ -397,7 +369,7 @@ func clusterToSecret(c *appv1.Cluster, secret *corev1.Secret) error { } // SecretToCluster converts a secret into a Cluster object -func SecretToCluster(s *corev1.Secret) (*appv1.Cluster, error) { +func SecretToCluster(s *apiv1.Secret) (*appv1.Cluster, error) { var config appv1.ClusterConfig if len(s.Data["config"]) > 0 { err := json.Unmarshal(s.Data["config"], &config) @@ -440,7 +412,7 @@ func SecretToCluster(s *corev1.Secret) (*appv1.Cluster, error) { if s.Annotations != nil { annotations = maps.Clone(s.Annotations) // delete system annotations - delete(annotations, corev1.LastAppliedConfigAnnotation) + delete(annotations, apiv1.LastAppliedConfigAnnotation) delete(annotations, common.AnnotationKeyManagedBy) } diff --git a/util/db/cluster_norace_test.go b/util/db/cluster_norace_test.go index b55b03db41..c26cfbf8b4 100644 --- a/util/db/cluster_norace_test.go +++ b/util/db/cluster_norace_test.go @@ -4,25 +4,26 @@ package db import ( + "context" "testing" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" "github.com/stretchr/testify/assert" "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/settings" ) func TestWatchClusters_CreateRemoveCluster(t *testing.T) { // !race: // Intermittent failure when running TestWatchClusters_LocalClusterModifications with -race, likely due to race condition // https://github.com/argoproj/argo-cd/issues/4755 - emptyArgoCDConfigMap := &corev1.ConfigMap{ + emptyArgoCDConfigMap := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: fakeNamespace, @@ -32,7 +33,7 @@ func TestWatchClusters_CreateRemoveCluster(t *testing.T) { }, Data: map[string]string{}, } - argoCDSecret := &corev1.Secret{ + argoCDSecret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: fakeNamespace, @@ -46,14 +47,14 @@ func TestWatchClusters_CreateRemoveCluster(t *testing.T) { }, } kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) + settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) - completed := runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){ + runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){ func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) { assert.Nil(t, old) assert.Equal(t, v1alpha1.KubernetesInternalAPIServerAddr, new.Server) - _, err := db.CreateCluster(t.Context(), &v1alpha1.Cluster{ + _, err := db.CreateCluster(context.Background(), &v1alpha1.Cluster{ Server: "https://minikube", Name: "minikube", }) @@ -64,21 +65,20 @@ func TestWatchClusters_CreateRemoveCluster(t *testing.T) { assert.Equal(t, "https://minikube", new.Server) assert.Equal(t, "minikube", new.Name) - assert.NoError(t, db.DeleteCluster(t.Context(), "https://minikube")) + assert.NoError(t, db.DeleteCluster(context.Background(), "https://minikube")) }, func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) { assert.Nil(t, new) assert.Equal(t, "https://minikube", old.Server) }, }) - assert.True(t, completed, "Failed due to timeout") } func TestWatchClusters_LocalClusterModifications(t *testing.T) { // !race: // Intermittent failure when running TestWatchClusters_LocalClusterModifications with -race, likely due to race condition // https://github.com/argoproj/argo-cd/issues/4755 - emptyArgoCDConfigMap := &corev1.ConfigMap{ + emptyArgoCDConfigMap := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: fakeNamespace, @@ -88,7 +88,7 @@ func TestWatchClusters_LocalClusterModifications(t *testing.T) { }, Data: map[string]string{}, } - argoCDSecret := &corev1.Secret{ + argoCDSecret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: fakeNamespace, @@ -102,14 +102,14 @@ func TestWatchClusters_LocalClusterModifications(t *testing.T) { }, } kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) + settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) - completed := runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){ + runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){ func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) { assert.Nil(t, old) assert.Equal(t, v1alpha1.KubernetesInternalAPIServerAddr, new.Server) - _, err := db.CreateCluster(t.Context(), &v1alpha1.Cluster{ + _, err := db.CreateCluster(context.Background(), &v1alpha1.Cluster{ Server: v1alpha1.KubernetesInternalAPIServerAddr, Name: "some name", }) @@ -120,50 +120,11 @@ func TestWatchClusters_LocalClusterModifications(t *testing.T) { assert.Equal(t, v1alpha1.KubernetesInternalAPIServerAddr, new.Server) assert.Equal(t, "some name", new.Name) - assert.NoError(t, db.DeleteCluster(t.Context(), v1alpha1.KubernetesInternalAPIServerAddr)) + assert.NoError(t, db.DeleteCluster(context.Background(), v1alpha1.KubernetesInternalAPIServerAddr)) }, - func(_ *v1alpha1.Cluster, new *v1alpha1.Cluster) { + func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) { assert.Equal(t, v1alpha1.KubernetesInternalAPIServerAddr, new.Server) assert.Equal(t, "in-cluster", new.Name) }, }) - assert.True(t, completed, "Failed due to timeout") -} - -func TestWatchClusters_LocalClusterModificationsWhenDisabled(t *testing.T) { - // !race: - // Intermittent failure when running TestWatchClusters_LocalClusterModifications with -race, likely due to race condition - // https://github.com/argoproj/argo-cd/issues/4755 - argoCDConfigMapWithInClusterServerAddressDisabled := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.ArgoCDConfigMapName, - Namespace: fakeNamespace, - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string]string{"cluster.inClusterEnabled": "false"}, - } - argoCDSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.ArgoCDSecretName, - Namespace: fakeNamespace, - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string][]byte{ - "admin.password": nil, - "server.secretkey": nil, - }, - } - kubeclientset := fake.NewClientset(argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) - db := NewDB(fakeNamespace, settingsManager, kubeclientset) - completed := runWatchTest(t, db, []func(_ *v1alpha1.Cluster, _ *v1alpha1.Cluster){ - func(_ *v1alpha1.Cluster, _ *v1alpha1.Cluster) { - assert.Fail(t, "The in-cluster should not be added when disabled") - }, - }) - assert.False(t, completed, "Expecting the method to never complete because no cluster is ever added") } diff --git a/util/db/cluster_test.go b/util/db/cluster_test.go index b564081143..fc3da404e8 100644 --- a/util/db/cluster_test.go +++ b/util/db/cluster_test.go @@ -9,13 +9,14 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( @@ -51,7 +52,7 @@ func Test_URIToSecretName(t *testing.T) { func Test_secretToCluster(t *testing.T) { labels := map[string]string{"key1": "val1"} annotations := map[string]string{"key2": "val2"} - secret := &corev1.Secret{ + secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster", Namespace: fakeNamespace, @@ -78,11 +79,11 @@ func Test_secretToCluster(t *testing.T) { } func Test_secretToCluster_LastAppliedConfigurationDropped(t *testing.T) { - secret := &corev1.Secret{ + secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster", Namespace: fakeNamespace, - Annotations: map[string]string{corev1.LastAppliedConfigAnnotation: "val2"}, + Annotations: map[string]string{v1.LastAppliedConfigAnnotation: "val2"}, }, Data: map[string][]byte{ "name": []byte("test"), @@ -96,7 +97,7 @@ func Test_secretToCluster_LastAppliedConfigurationDropped(t *testing.T) { } func TestClusterToSecret(t *testing.T) { - cluster := &v1alpha1.Cluster{ + cluster := &appv1.Cluster{ Server: "server", Labels: map[string]string{"test": "label"}, Annotations: map[string]string{"test": "annotation"}, @@ -105,7 +106,7 @@ func TestClusterToSecret(t *testing.T) { Project: "project", Namespaces: []string{"default"}, } - s := &corev1.Secret{} + s := &v1.Secret{} err := clusterToSecret(cluster, s) require.NoError(t, err) @@ -118,22 +119,22 @@ func TestClusterToSecret(t *testing.T) { } func TestClusterToSecret_LastAppliedConfigurationRejected(t *testing.T) { - cluster := &v1alpha1.Cluster{ + cluster := &appv1.Cluster{ Server: "server", - Annotations: map[string]string{corev1.LastAppliedConfigAnnotation: "val2"}, + Annotations: map[string]string{v1.LastAppliedConfigAnnotation: "val2"}, Name: "test", Config: v1alpha1.ClusterConfig{}, Project: "project", Namespaces: []string{"default"}, } - s := &corev1.Secret{} + s := &v1.Secret{} err := clusterToSecret(cluster, s) require.Error(t, err) require.Equal(t, codes.InvalidArgument, status.Code(err)) } func Test_secretToCluster_NoConfig(t *testing.T) { - secret := &corev1.Secret{ + secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster", Namespace: fakeNamespace, @@ -154,7 +155,7 @@ func Test_secretToCluster_NoConfig(t *testing.T) { } func Test_secretToCluster_InvalidConfig(t *testing.T) { - secret := &corev1.Secret{ + secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster", Namespace: fakeNamespace, @@ -171,7 +172,7 @@ func Test_secretToCluster_InvalidConfig(t *testing.T) { } func TestUpdateCluster(t *testing.T) { - kubeclientset := fake.NewClientset(&corev1.Secret{ + kubeclientset := fake.NewClientset(&v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster", Namespace: fakeNamespace, @@ -184,24 +185,24 @@ func TestUpdateCluster(t *testing.T) { "config": []byte("{}"), }, }) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) + settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) requestedAt := metav1.Now() - _, err := db.UpdateCluster(t.Context(), &v1alpha1.Cluster{ + _, err := db.UpdateCluster(context.Background(), &v1alpha1.Cluster{ Name: "test", Server: "http://mycluster", RefreshRequestedAt: &requestedAt, }) require.NoError(t, err) - secret, err := kubeclientset.CoreV1().Secrets(fakeNamespace).Get(t.Context(), "mycluster", metav1.GetOptions{}) + secret, err := kubeclientset.CoreV1().Secrets(fakeNamespace).Get(context.Background(), "mycluster", metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, secret.Annotations[v1alpha1.AnnotationKeyRefresh], requestedAt.Format(time.RFC3339)) } func TestDeleteUnknownCluster(t *testing.T) { - kubeclientset := fake.NewClientset(&corev1.Secret{ + kubeclientset := fake.NewClientset(&v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster", Namespace: fakeNamespace, @@ -214,13 +215,13 @@ func TestDeleteUnknownCluster(t *testing.T) { "name": []byte("mycluster"), }, }) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) + settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) - assert.EqualError(t, db.DeleteCluster(t.Context(), "http://unknown"), `rpc error: code = NotFound desc = cluster "http://unknown" not found`) + assert.EqualError(t, db.DeleteCluster(context.Background(), "http://unknown"), `rpc error: code = NotFound desc = cluster "http://unknown" not found`) } func TestRejectCreationForInClusterWhenDisabled(t *testing.T) { - argoCDConfigMapWithInClusterServerAddressDisabled := &corev1.ConfigMap{ + argoCDConfigMapWithInClusterServerAddressDisabled := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: fakeNamespace, @@ -230,7 +231,7 @@ func TestRejectCreationForInClusterWhenDisabled(t *testing.T) { }, Data: map[string]string{"cluster.inClusterEnabled": "false"}, } - argoCDSecret := &corev1.Secret{ + argoCDSecret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: fakeNamespace, @@ -244,18 +245,18 @@ func TestRejectCreationForInClusterWhenDisabled(t *testing.T) { }, } kubeclientset := fake.NewClientset(argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) + settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) - _, err := db.CreateCluster(t.Context(), &v1alpha1.Cluster{ - Server: v1alpha1.KubernetesInternalAPIServerAddr, + _, err := db.CreateCluster(context.Background(), &appv1.Cluster{ + Server: appv1.KubernetesInternalAPIServerAddr, Name: "incluster-name", }) require.Error(t, err) } -func runWatchTest(t *testing.T, db ArgoDB, actions []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster)) (completed bool) { +func runWatchTest(t *testing.T, db ArgoDB, actions []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster)) { t.Helper() - ctx, cancel := context.WithCancel(t.Context()) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() timeout := time.Second * 5 @@ -290,146 +291,13 @@ func runWatchTest(t *testing.T, db ArgoDB, actions []func(old *v1alpha1.Cluster, select { case <-allDone: - return true case <-time.After(timeout): - return false + assert.Fail(t, "Failed due to timeout") } } -func TestGetCluster(t *testing.T) { - emptyArgoCDConfigMap := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.ArgoCDConfigMapName, - Namespace: fakeNamespace, - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string]string{}, - } - argoCDConfigMapWithInClusterServerAddressDisabled := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.ArgoCDConfigMapName, - Namespace: fakeNamespace, - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string]string{"cluster.inClusterEnabled": "false"}, - } - argoCDSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.ArgoCDSecretName, - Namespace: fakeNamespace, - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string][]byte{ - "admin.password": nil, - "server.secretkey": nil, - }, - } - secretForServerWithInClusterAddr := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "mycluster1", - Namespace: fakeNamespace, - Labels: map[string]string{ - common.LabelKeySecretType: common.LabelValueSecretTypeCluster, - }, - }, - Data: map[string][]byte{ - "server": []byte(v1alpha1.KubernetesInternalAPIServerAddr), - "name": []byte("in-cluster-renamed"), - }, - } - - secretForServerWithExternalClusterAddr := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "mycluster2", - Namespace: fakeNamespace, - Labels: map[string]string{ - common.LabelKeySecretType: common.LabelValueSecretTypeCluster, - }, - }, - Data: map[string][]byte{ - "server": []byte("http://mycluster2"), - "name": []byte("mycluster2"), - }, - } - - t.Run("Valid external cluster", func(t *testing.T) { - kubeclientset := fake.NewClientset(secretForServerWithExternalClusterAddr, emptyArgoCDConfigMap, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) - db := NewDB(fakeNamespace, settingsManager, kubeclientset) - - cluster, err := db.GetCluster(t.Context(), string(secretForServerWithExternalClusterAddr.Data["server"])) - require.NoError(t, err) - assert.Equal(t, string(secretForServerWithExternalClusterAddr.Data["server"]), cluster.Server) - assert.Equal(t, string(secretForServerWithExternalClusterAddr.Data["name"]), cluster.Name) - }) - - t.Run("invalid cluster", func(t *testing.T) { - kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) - db := NewDB(fakeNamespace, settingsManager, kubeclientset) - - _, err := db.GetCluster(t.Context(), "https://mycluster-does-not-exist") - require.Error(t, err) - status, ok := status.FromError(err) - assert.True(t, ok) - assert.Equal(t, codes.NotFound, status.Code()) - }) - - t.Run("in-cluster not configured", func(t *testing.T) { - kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) - db := NewDB(fakeNamespace, settingsManager, kubeclientset) - - cluster, err := db.GetCluster(t.Context(), v1alpha1.KubernetesInternalAPIServerAddr) - require.NoError(t, err) - assert.Equal(t, v1alpha1.KubernetesInternalAPIServerAddr, cluster.Server) - assert.Equal(t, "in-cluster", cluster.Name) - }) - - t.Run("in-cluster disabled", func(t *testing.T) { - kubeclientset := fake.NewClientset(argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) - db := NewDB(fakeNamespace, settingsManager, kubeclientset) - - _, err := db.GetCluster(t.Context(), v1alpha1.KubernetesInternalAPIServerAddr) - require.Error(t, err) - status, ok := status.FromError(err) - assert.True(t, ok) - assert.Equal(t, codes.NotFound, status.Code()) - }) - - t.Run("in-cluster configured", func(t *testing.T) { - kubeclientset := fake.NewClientset(secretForServerWithInClusterAddr, emptyArgoCDConfigMap, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) - db := NewDB(fakeNamespace, settingsManager, kubeclientset) - - cluster, err := db.GetCluster(t.Context(), v1alpha1.KubernetesInternalAPIServerAddr) - require.NoError(t, err) - assert.Equal(t, v1alpha1.KubernetesInternalAPIServerAddr, cluster.Server) - assert.Equal(t, "in-cluster-renamed", cluster.Name) - }) - - t.Run("in-cluster configured and disabled", func(t *testing.T) { - kubeclientset := fake.NewClientset(secretForServerWithInClusterAddr, argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) - db := NewDB(fakeNamespace, settingsManager, kubeclientset) - - _, err := db.GetCluster(t.Context(), v1alpha1.KubernetesInternalAPIServerAddr) - require.Error(t, err) - status, ok := status.FromError(err) - assert.True(t, ok) - assert.Equal(t, codes.NotFound, status.Code()) - }) -} - func TestListClusters(t *testing.T) { - emptyArgoCDConfigMap := &corev1.ConfigMap{ + emptyArgoCDConfigMap := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: fakeNamespace, @@ -439,7 +307,7 @@ func TestListClusters(t *testing.T) { }, Data: map[string]string{}, } - argoCDConfigMapWithInClusterServerAddressDisabled := &corev1.ConfigMap{ + argoCDConfigMapWithInClusterServerAddressDisabled := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: fakeNamespace, @@ -449,7 +317,7 @@ func TestListClusters(t *testing.T) { }, Data: map[string]string{"cluster.inClusterEnabled": "false"}, } - argoCDSecret := &corev1.Secret{ + argoCDSecret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: fakeNamespace, @@ -462,7 +330,7 @@ func TestListClusters(t *testing.T) { "server.secretkey": nil, }, } - secretForServerWithInClusterAddr := &corev1.Secret{ + secretForServerWithInClusterAddr := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster1", Namespace: fakeNamespace, @@ -471,12 +339,12 @@ func TestListClusters(t *testing.T) { }, }, Data: map[string][]byte{ - "server": []byte(v1alpha1.KubernetesInternalAPIServerAddr), + "server": []byte(appv1.KubernetesInternalAPIServerAddr), "name": []byte("in-cluster"), }, } - secretForServerWithExternalClusterAddr := &corev1.Secret{ + secretForServerWithExternalClusterAddr := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster2", Namespace: fakeNamespace, @@ -490,7 +358,7 @@ func TestListClusters(t *testing.T) { }, } - invalidSecret := &corev1.Secret{ + invalidSecret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster3", Namespace: fakeNamespace, @@ -504,30 +372,30 @@ func TestListClusters(t *testing.T) { t.Run("Valid clusters", func(t *testing.T) { kubeclientset := fake.NewClientset(secretForServerWithInClusterAddr, secretForServerWithExternalClusterAddr, emptyArgoCDConfigMap, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) + settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) - clusters, err := db.ListClusters(t.Context()) + clusters, err := db.ListClusters(context.TODO()) require.NoError(t, err) assert.Len(t, clusters.Items, 2) }) t.Run("Cluster list with invalid cluster", func(t *testing.T) { kubeclientset := fake.NewClientset(secretForServerWithInClusterAddr, secretForServerWithExternalClusterAddr, invalidSecret, emptyArgoCDConfigMap, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) + settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) - clusters, err := db.ListClusters(t.Context()) + clusters, err := db.ListClusters(context.TODO()) require.NoError(t, err) assert.Len(t, clusters.Items, 2) }) t.Run("Implicit in-cluster secret", func(t *testing.T) { kubeclientset := fake.NewClientset(secretForServerWithExternalClusterAddr, emptyArgoCDConfigMap, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) + settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) - clusters, err := db.ListClusters(t.Context()) + clusters, err := db.ListClusters(context.TODO()) require.NoError(t, err) // ListClusters() should have added an implicit in-cluster secret to the list assert.Len(t, clusters.Items, 2) @@ -535,137 +403,30 @@ func TestListClusters(t *testing.T) { t.Run("ListClusters() should not add the cluster with in-cluster server address since in-cluster is disabled", func(t *testing.T) { kubeclientset := fake.NewClientset(secretForServerWithInClusterAddr, argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) + settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) - clusters, err := db.ListClusters(t.Context()) + clusters, err := db.ListClusters(context.TODO()) require.NoError(t, err) assert.Empty(t, clusters.Items) }) t.Run("ListClusters() should add this cluster since it does not contain in-cluster server address even though in-cluster is disabled", func(t *testing.T) { kubeclientset := fake.NewClientset(secretForServerWithExternalClusterAddr, argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) - settingsManager := settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace) + settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) - clusters, err := db.ListClusters(t.Context()) + clusters, err := db.ListClusters(context.TODO()) require.NoError(t, err) assert.Len(t, clusters.Items, 1) }) } -func TestGetClusterServersByName(t *testing.T) { - emptyArgoCDConfigMap := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.ArgoCDConfigMapName, - Namespace: fakeNamespace, - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string]string{}, - } - argoCDSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.ArgoCDSecretName, - Namespace: fakeNamespace, - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string][]byte{ - "admin.password": nil, - "server.secretkey": nil, - }, - } - argoCDConfigMapWithInClusterServerAddressDisabled := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.ArgoCDConfigMapName, - Namespace: fakeNamespace, - Labels: map[string]string{ - "app.kubernetes.io/part-of": "argocd", - }, - }, - Data: map[string]string{"cluster.inClusterEnabled": "false"}, - } - argoCDSecretInClusterConfigured := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "my-cluster-secret", - Namespace: fakeNamespace, - Labels: map[string]string{ - common.LabelKeySecretType: common.LabelValueSecretTypeCluster, - }, - Annotations: map[string]string{ - common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD, - }, - }, - Data: map[string][]byte{ - "name": []byte("in-cluster-renamed"), - "server": []byte(v1alpha1.KubernetesInternalAPIServerAddr), - "config": []byte("{}"), - }, - } - - t.Run("returns the server name", func(t *testing.T) { - argoCDClusterSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "my-cluster-secret", - Namespace: fakeNamespace, - Labels: map[string]string{ - common.LabelKeySecretType: common.LabelValueSecretTypeCluster, - }, - Annotations: map[string]string{ - common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD, - }, - }, - Data: map[string][]byte{ - "name": []byte("my-cluster-name"), - "server": []byte("https://my-cluster-server"), - "config": []byte("{}"), - }, - } - - kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDClusterSecret, argoCDSecret) - db := NewDB(fakeNamespace, settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace), kubeclientset) - servers, err := db.GetClusterServersByName(t.Context(), "my-cluster-name") - require.NoError(t, err) - assert.ElementsMatch(t, []string{"https://my-cluster-server"}, servers) - }) - t.Run("returns in-cluster", func(t *testing.T) { - kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret) - db := NewDB(fakeNamespace, settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace), kubeclientset) - servers, err := db.GetClusterServersByName(t.Context(), "in-cluster") - require.NoError(t, err) - assert.ElementsMatch(t, []string{v1alpha1.KubernetesInternalAPIServerAddr}, servers) - }) - t.Run("does not return in-cluster when disabled", func(t *testing.T) { - kubeclientset := fake.NewClientset(argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) - db := NewDB(fakeNamespace, settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace), kubeclientset) - servers, err := db.GetClusterServersByName(t.Context(), "in-cluster") - require.NoError(t, err) - assert.Empty(t, servers) - }) - t.Run("returns in-cluster when configured", func(t *testing.T) { - kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecretInClusterConfigured, argoCDSecret) - db := NewDB(fakeNamespace, settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace), kubeclientset) - servers, err := db.GetClusterServersByName(t.Context(), "in-cluster-renamed") - require.NoError(t, err) - assert.ElementsMatch(t, []string{v1alpha1.KubernetesInternalAPIServerAddr}, servers) - }) - t.Run("does not return in-cluster when configured and disabled", func(t *testing.T) { - kubeclientset := fake.NewClientset(argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecretInClusterConfigured, argoCDSecret) - db := NewDB(fakeNamespace, settings.NewSettingsManager(t.Context(), kubeclientset, fakeNamespace), kubeclientset) - servers, err := db.GetClusterServersByName(t.Context(), "in-cluster-renamed") - require.NoError(t, err) - assert.Empty(t, servers) - }) -} - // TestClusterRaceConditionClusterSecrets reproduces a race condition // on the cluster secrets. The test isn't asserting anything because // before the fix it would cause a panic from concurrent map iteration and map write func TestClusterRaceConditionClusterSecrets(t *testing.T) { - clusterSecret := &corev1.Secret{ + clusterSecret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster", Namespace: "default", @@ -679,7 +440,7 @@ func TestClusterRaceConditionClusterSecrets(t *testing.T) { }, } kubeClient := fake.NewClientset( - &corev1.ConfigMap{ + &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -689,7 +450,7 @@ func TestClusterRaceConditionClusterSecrets(t *testing.T) { }, Data: map[string]string{}, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -704,15 +465,14 @@ func TestClusterRaceConditionClusterSecrets(t *testing.T) { }, clusterSecret, ) - ctx := t.Context() - settingsManager := settings.NewSettingsManager(ctx, kubeClient, "default") + settingsManager := settings.NewSettingsManager(context.Background(), kubeClient, "default") db := NewDB("default", settingsManager, kubeClient) cluster, _ := SecretToCluster(clusterSecret) go func() { for { // create a copy so we dont act on the same argo cluster clusterCopy := cluster.DeepCopy() - _, _ = db.UpdateCluster(ctx, clusterCopy) + _, _ = db.UpdateCluster(context.Background(), clusterCopy) } }() // yes, we will take 15 seconds to run this test @@ -720,7 +480,7 @@ func TestClusterRaceConditionClusterSecrets(t *testing.T) { for i := 0; i < 30; i++ { // create a copy so we dont act on the same argo cluster clusterCopy := cluster.DeepCopy() - _, _ = db.UpdateCluster(ctx, clusterCopy) + _, _ = db.UpdateCluster(context.Background(), clusterCopy) time.Sleep(time.Millisecond * 500) } } diff --git a/util/db/db.go b/util/db/db.go index f4e1bb3fc8..f0f88d44d3 100644 --- a/util/db/db.go +++ b/util/db/db.go @@ -5,17 +5,17 @@ import ( "math" "strings" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/api/core/v1" + kubeerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/common" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/settings" + "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/env" + "github.com/argoproj/argo-cd/v2/util/settings" ) // SecretMaperValidation determine whether the secret should be transformed(i.e. trailing CRLF characters trimmed) @@ -55,7 +55,7 @@ type ArgoDB interface { // GetRepository returns a repository by URL GetRepository(ctx context.Context, url, project string) (*appv1.Repository, error) // GetProjectRepositories returns project scoped repositories by given project name - GetProjectRepositories(project string) ([]*appv1.Repository, error) + GetProjectRepositories(ctx context.Context, project string) ([]*appv1.Repository, error) // RepositoryExists returns whether a repository is configured for the given URL RepositoryExists(ctx context.Context, repoURL, project string) (bool, error) // UpdateRepository updates a repository @@ -68,7 +68,7 @@ type ArgoDB interface { // GetWriteRepository returns a repository by URL with write credentials GetWriteRepository(ctx context.Context, url, project string) (*appv1.Repository, error) // GetProjectWriteRepositories returns project scoped repositories from write credentials by given project name - GetProjectWriteRepositories(project string) ([]*appv1.Repository, error) + GetProjectWriteRepositories(ctx context.Context, project string) ([]*appv1.Repository, error) // WriteRepositoryExists returns whether a repository is configured for the given URL with write credentials WriteRepositoryExists(ctx context.Context, repoURL, project string) (bool, error) // UpdateWriteRepository updates a repository with write credentials @@ -107,6 +107,9 @@ type ArgoDB interface { // GetAllHelmRepositoryCredentials gets all repo credentials GetAllHelmRepositoryCredentials(ctx context.Context) ([]*appv1.RepoCreds, error) + // GetWriteCredentials gets repo credentials specific to the hydrator for given URL + GetWriteCredentials(ctx context.Context, repoURL string) (*appv1.Repository, error) + // ListHelmRepositories lists repositories ListHelmRepositories(ctx context.Context) ([]*appv1.Repository, error) @@ -136,15 +139,40 @@ func NewDB(namespace string, settingsMgr *settings.SettingsManager, kubeclientse } } -func (db *db) getSecret(name string, cache map[string]*corev1.Secret) (*corev1.Secret, error) { - if _, ok := cache[name]; !ok { - secret, err := db.settingsMgr.GetSecretByName(name) +func (db *db) getSecret(name string, cache map[string]*v1.Secret) (*v1.Secret, error) { + secret, ok := cache[name] + if !ok { + secretsLister, err := db.settingsMgr.GetSecretsLister() if err != nil { return nil, err } + secret, err = secretsLister.Secrets(db.ns).Get(name) + if err != nil { + return nil, err + } + if secret.Data == nil { + secret.Data = make(map[string][]byte) + } cache[name] = secret } - return cache[name], nil + return secret, nil +} + +func (db *db) unmarshalFromSecretsStr(secrets map[*SecretMaperValidation]*v1.SecretKeySelector, cache map[string]*v1.Secret) error { + for dst, src := range secrets { + if src != nil { + secret, err := db.getSecret(src.Name, cache) + if err != nil { + return err + } + if dst.Transform != nil { + *dst.Dest = dst.Transform(string(secret.Data[src.Key])) + } else { + *dst.Dest = string(secret.Data[src.Key]) + } + } + } + return nil } // StripCRLFCharacter strips the trailing CRLF characters @@ -159,7 +187,7 @@ func (db *db) GetApplicationControllerReplicas() int { appControllerDeployment, err := db.kubeclientset.AppsV1().Deployments(db.settingsMgr.GetNamespace()).Get(context.Background(), applicationControllerName, metav1.GetOptions{}) if err != nil { appControllerDeployment = nil - if !apierrors.IsNotFound(err) { + if !kubeerrors.IsNotFound(err) { log.Warnf("error retrieveing Argo CD controller deployment: %s", err) } } diff --git a/util/db/db_test.go b/util/db/db_test.go index 2c8c67bd92..8227f86964 100644 --- a/util/db/db_test.go +++ b/util/db/db_test.go @@ -1,6 +1,8 @@ package db import ( + "context" + "strings" "testing" "time" @@ -8,24 +10,24 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" + appv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( testNamespace = "default" ) -func getClientset(objects ...runtime.Object) *fake.Clientset { - secret := corev1.Secret{ +func getClientset(config map[string]string, objects ...runtime.Object) *fake.Clientset { + secret := v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", Namespace: testNamespace, @@ -35,7 +37,7 @@ func getClientset(objects ...runtime.Object) *fake.Clientset { "server.secretkey": []byte("test"), }, } - cm := corev1.ConfigMap{ + cm := v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-cm", Namespace: testNamespace, @@ -43,15 +45,16 @@ func getClientset(objects ...runtime.Object) *fake.Clientset { "app.kubernetes.io/part-of": "argocd", }, }, + Data: config, } return fake.NewClientset(append(objects, &cm, &secret)...) } func TestCreateRepository(t *testing.T) { - clientset := getClientset() - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + clientset := getClientset(nil) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) - repo, err := db.CreateRepository(t.Context(), &v1alpha1.Repository{ + repo, err := db.CreateRepository(context.Background(), &v1alpha1.Repository{ Repo: "https://github.com/argoproj/argocd-example-apps", Username: "test-username", Password: "test-password", @@ -59,7 +62,7 @@ func TestCreateRepository(t *testing.T) { require.NoError(t, err) assert.Equal(t, "https://github.com/argoproj/argocd-example-apps", repo.Repo) - secret, err := clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), RepoURLToSecretName(repoSecretPrefix, repo.Repo, ""), metav1.GetOptions{}) + secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.Background(), RepoURLToSecretName(repoSecretPrefix, repo.Repo, ""), metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, common.AnnotationValueManagedByArgoCD, secret.Annotations[common.AnnotationKeyManagedBy]) @@ -69,10 +72,10 @@ func TestCreateRepository(t *testing.T) { } func TestCreateProjectScopedRepository(t *testing.T) { - clientset := getClientset() - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + clientset := getClientset(nil) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) - repo, err := db.CreateRepository(t.Context(), &v1alpha1.Repository{ + repo, err := db.CreateRepository(context.Background(), &v1alpha1.Repository{ Repo: "https://github.com/argoproj/argocd-example-apps", Username: "test-username", Password: "test-password", @@ -80,7 +83,7 @@ func TestCreateProjectScopedRepository(t *testing.T) { }) require.NoError(t, err) - otherRepo, err := db.CreateRepository(t.Context(), &v1alpha1.Repository{ + otherRepo, err := db.CreateRepository(context.Background(), &v1alpha1.Repository{ Repo: "https://github.com/argoproj/argocd-example-apps", Username: "other-username", Password: "other-password", @@ -88,7 +91,7 @@ func TestCreateProjectScopedRepository(t *testing.T) { }) require.NoError(t, err) - _, err = db.CreateRepository(t.Context(), &v1alpha1.Repository{ + _, err = db.CreateRepository(context.Background(), &v1alpha1.Repository{ Repo: "https://github.com/argoproj/argocd-example-apps", Username: "wrong-username", Password: "wrong-password", @@ -97,7 +100,7 @@ func TestCreateProjectScopedRepository(t *testing.T) { assert.Equal(t, "https://github.com/argoproj/argocd-example-apps", repo.Repo) - secret, err := clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), RepoURLToSecretName(repoSecretPrefix, repo.Repo, "test-project"), metav1.GetOptions{}) + secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.Background(), RepoURLToSecretName(repoSecretPrefix, repo.Repo, "test-project"), metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, common.AnnotationValueManagedByArgoCD, secret.Annotations[common.AnnotationKeyManagedBy]) @@ -106,7 +109,7 @@ func TestCreateProjectScopedRepository(t *testing.T) { assert.Equal(t, "test-project", string(secret.Data[project])) assert.Empty(t, secret.Data[sshPrivateKey]) - secret, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), RepoURLToSecretName(repoSecretPrefix, otherRepo.Repo, "other-project"), metav1.GetOptions{}) + secret, err = clientset.CoreV1().Secrets(testNamespace).Get(context.Background(), RepoURLToSecretName(repoSecretPrefix, otherRepo.Repo, "other-project"), metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, common.AnnotationValueManagedByArgoCD, secret.Annotations[common.AnnotationKeyManagedBy]) assert.Equal(t, "other-username", string(secret.Data[username])) @@ -116,10 +119,10 @@ func TestCreateProjectScopedRepository(t *testing.T) { } func TestCreateRepoCredentials(t *testing.T) { - clientset := getClientset() - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + clientset := getClientset(nil) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) - creds, err := db.CreateRepositoryCredentials(t.Context(), &v1alpha1.RepoCreds{ + creds, err := db.CreateRepositoryCredentials(context.Background(), &v1alpha1.RepoCreds{ URL: "https://github.com/argoproj/", Username: "test-username", Password: "test-password", @@ -127,7 +130,7 @@ func TestCreateRepoCredentials(t *testing.T) { require.NoError(t, err) assert.Equal(t, "https://github.com/argoproj/", creds.URL) - secret, err := clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), RepoURLToSecretName(credSecretPrefix, creds.URL, ""), metav1.GetOptions{}) + secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.Background(), RepoURLToSecretName(credSecretPrefix, creds.URL, ""), metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, common.AnnotationValueManagedByArgoCD, secret.Annotations[common.AnnotationKeyManagedBy]) @@ -135,7 +138,7 @@ func TestCreateRepoCredentials(t *testing.T) { assert.Equal(t, "test-password", string(secret.Data[password])) assert.Empty(t, secret.Data[sshPrivateKey]) - created, err := db.CreateRepository(t.Context(), &v1alpha1.Repository{ + created, err := db.CreateRepository(context.Background(), &v1alpha1.Repository{ Repo: "https://github.com/argoproj/argo-cd", }) require.NoError(t, err) @@ -145,70 +148,93 @@ func TestCreateRepoCredentials(t *testing.T) { // Just give it a little time to settle. time.Sleep(1 * time.Second) - repo, err := db.GetRepository(t.Context(), created.Repo, "") + repo, err := db.GetRepository(context.Background(), created.Repo, "") require.NoError(t, err) assert.Equal(t, "test-username", repo.Username) assert.Equal(t, "test-password", repo.Password) } func TestGetRepositoryCredentials(t *testing.T) { - clientset := getClientset() - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) - _, err := db.CreateRepositoryCredentials(t.Context(), &v1alpha1.RepoCreds{ - URL: "https://secured", - Username: "test-username", - Password: "test-password", - }) - require.NoError(t, err) + config := map[string]string{ + "repositories": ` +- url: https://known/repo +- url: https://secured/repo +- url: https://missing/repo +`, + "repository.credentials": ` +- url: https://secured + usernameSecret: + name: managed-secret + key: username + passwordSecret: + name: managed-secret + key: password +- url: https://missing + usernameSecret: + name: managed-secret + key: username + passwordSecret: + name: missing-managed-secret + key: password +`, + } + clientset := getClientset(config, newManagedSecret()) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) tests := []struct { name string repoURL string want *v1alpha1.RepoCreds + wantErr bool }{ { name: "TestUnknownRepo", repoURL: "https://unknown/repo", want: nil, + wantErr: false, }, { name: "TestKnownRepo", repoURL: "https://known/repo", want: nil, + wantErr: false, }, { name: "TestSecuredRepo", repoURL: "https://secured/repo", want: &v1alpha1.RepoCreds{URL: "https://secured", Username: "test-username", Password: "test-password"}, + wantErr: false, }, { name: "TestMissingRepo", repoURL: "https://missing/repo", want: nil, + wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := db.GetRepositoryCredentials(t.Context(), tt.repoURL) + got, err := db.GetRepositoryCredentials(context.TODO(), tt.repoURL) + + if tt.wantErr { + require.Error(t, err) + assert.True(t, errors.IsNotFound(err)) + } else { + require.NoError(t, err) + } - require.NoError(t, err) assert.Equal(t, tt.want, got) }) } } func TestCreateExistingRepository(t *testing.T) { - clientset := getClientset() - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) - - _, err := db.CreateRepository(t.Context(), &v1alpha1.Repository{ - Repo: "https://github.com/argoproj/argocd-example-apps", - Username: "test-username", - Password: "test-password", + clientset := getClientset(map[string]string{ + "repositories": `- url: https://github.com/argoproj/argocd-example-apps`, }) - require.NoError(t, err) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) - _, err = db.CreateRepository(t.Context(), &v1alpha1.Repository{ + _, err := db.CreateRepository(context.Background(), &v1alpha1.Repository{ Repo: "https://github.com/argoproj/argocd-example-apps", Username: "test-username", Password: "test-password", @@ -218,52 +244,23 @@ func TestCreateExistingRepository(t *testing.T) { } func TestGetRepository(t *testing.T) { - clientset := getClientset(&corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: testNamespace, - Name: "known-repo-secret", - Annotations: map[string]string{ - common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD, - }, - Labels: map[string]string{ - common.LabelKeySecretType: common.LabelValueSecretTypeRepository, - }, - }, - Data: map[string][]byte{ - "url": []byte("https://known/repo"), - }, - }, &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: testNamespace, - Name: "secured-repo-secret", - Annotations: map[string]string{ - common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD, - }, - Labels: map[string]string{ - common.LabelKeySecretType: common.LabelValueSecretTypeRepository, - }, - }, - Data: map[string][]byte{ - "url": []byte("https://secured/repo"), - }, - }, &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: testNamespace, - Name: "secured-repo-creds-secret", - Annotations: map[string]string{ - common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD, - }, - Labels: map[string]string{ - common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds, - }, - }, - Data: map[string][]byte{ - "url": []byte("https://secured"), - "username": []byte("test-username"), - "password": []byte("test-password"), - }, - }) - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + config := map[string]string{ + "repositories": ` +- url: https://known/repo +- url: https://secured/repo +`, + "repository.credentials": ` +- url: https://secured + usernameSecret: + name: managed-secret + key: username + passwordSecret: + name: managed-secret + key: password +`, + } + clientset := getClientset(config, newManagedSecret()) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) tests := []struct { name string @@ -288,24 +285,270 @@ func TestGetRepository(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := db.GetRepository(t.Context(), tt.repoURL, "") + got, err := db.GetRepository(context.TODO(), tt.repoURL, "") require.NoError(t, err) assert.Equal(t, tt.want, got) }) } } +func newManagedSecret() *v1.Secret { + return &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "managed-secret", + Namespace: testNamespace, + Annotations: map[string]string{ + common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD, + }, + }, + Data: map[string][]byte{ + username: []byte("test-username"), + password: []byte("test-password"), + }, + } +} + +func TestDeleteRepositoryManagedSecrets(t *testing.T) { + config := map[string]string{ + "repositories": ` +- url: https://github.com/argoproj/argocd-example-apps + usernameSecret: + name: managed-secret + key: username + passwordSecret: + name: managed-secret + key: password +`, + } + clientset := getClientset(config, newManagedSecret()) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + + err := db.DeleteRepository(context.Background(), "https://github.com/argoproj/argocd-example-apps", "") + require.NoError(t, err) + + _, err = clientset.CoreV1().Secrets(testNamespace).Get(context.Background(), "managed-secret", metav1.GetOptions{}) + require.Error(t, err) + assert.True(t, errors.IsNotFound(err)) + + cm, err := clientset.CoreV1().ConfigMaps(testNamespace).Get(context.Background(), "argocd-cm", metav1.GetOptions{}) + require.NoError(t, err) + assert.Equal(t, "", cm.Data["repositories"]) +} + +func TestDeleteRepositoryUnmanagedSecrets(t *testing.T) { + config := map[string]string{ + "repositories": ` +- url: https://github.com/argoproj/argocd-example-apps + usernameSecret: + name: unmanaged-secret + key: username + passwordSecret: + name: unmanaged-secret + key: password +`, + } + clientset := getClientset(config, &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "unmanaged-secret", + Namespace: testNamespace, + }, + Data: map[string][]byte{ + username: []byte("test-username"), + password: []byte("test-password"), + }, + }) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + + err := db.DeleteRepository(context.Background(), "https://github.com/argoproj/argocd-example-apps", "") + require.NoError(t, err) + + s, err := clientset.CoreV1().Secrets(testNamespace).Get(context.Background(), "unmanaged-secret", metav1.GetOptions{}) + require.NoError(t, err) + assert.Equal(t, "test-username", string(s.Data[username])) + assert.Equal(t, "test-password", string(s.Data[password])) + + cm, err := clientset.CoreV1().ConfigMaps(testNamespace).Get(context.Background(), "argocd-cm", metav1.GetOptions{}) + require.NoError(t, err) + assert.Equal(t, "", cm.Data["repositories"]) +} + +func TestUpdateRepositoryWithManagedSecrets(t *testing.T) { + config := map[string]string{ + "repositories": ` +- url: https://github.com/argoproj/argocd-example-apps + usernameSecret: + name: managed-secret + key: username + passwordSecret: + name: managed-secret + key: password + sshPrivateKeySecret: + name: managed-secret + key: sshPrivateKey +`, + } + clientset := getClientset(config, &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "managed-secret", + Namespace: testNamespace, + Annotations: map[string]string{ + common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD, + }, + }, + Data: map[string][]byte{ + username: []byte("test-username"), + password: []byte("test-password"), + sshPrivateKey: []byte("test-ssh-private-key"), + }, + }) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + + repo, err := db.GetRepository(context.Background(), "https://github.com/argoproj/argocd-example-apps", "") + require.NoError(t, err) + assert.Equal(t, "test-username", repo.Username) + assert.Equal(t, "test-password", repo.Password) + assert.Equal(t, "test-ssh-private-key", repo.SSHPrivateKey) + + _, err = db.UpdateRepository(context.Background(), &v1alpha1.Repository{ + Repo: "https://github.com/argoproj/argocd-example-apps", Password: "", Username: "", SSHPrivateKey: "", + }) + require.NoError(t, err) + + _, err = clientset.CoreV1().Secrets(testNamespace).Get(context.Background(), "managed-secret", metav1.GetOptions{}) + require.Error(t, err) + assert.True(t, errors.IsNotFound(err)) + + cm, err := clientset.CoreV1().ConfigMaps(testNamespace).Get(context.Background(), "argocd-cm", metav1.GetOptions{}) + require.NoError(t, err) + assert.Equal(t, "- url: https://github.com/argoproj/argocd-example-apps", strings.Trim(cm.Data["repositories"], "\n")) +} + +func TestRepositorySecretsTrim(t *testing.T) { + config := map[string]string{ + "repositories": ` +- url: https://github.com/argoproj/argocd-example-apps + usernameSecret: + name: managed-secret + key: username + passwordSecret: + name: managed-secret + key: password + sshPrivateKeySecret: + name: managed-secret + key: sshPrivateKey + tlsClientCertDataSecret: + name: managed-secret + key: tlsClientCertData + tlsClientCertKeySecret: + name: managed-secret + key: tlsClientCertKey + githubAppPrivateKeySecret: + name: managed-secret + key: githubAppPrivateKey +`, + } + clientset := getClientset(config, &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "managed-secret", + Namespace: testNamespace, + Annotations: map[string]string{ + common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD, + }, + }, + Data: map[string][]byte{ + username: []byte("test-username\n\n"), + password: []byte("test-password\r\r"), + sshPrivateKey: []byte("test-ssh-private-key\n\r"), + tlsClientCertData: []byte("test-tls-client-cert-data\n\r"), + tlsClientCertKey: []byte("test-tls-client-cert-key\n\r"), + githubAppPrivateKey: []byte("test-github-app-private-key\n\r"), + }, + }) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + + repo, err := db.GetRepository(context.Background(), "https://github.com/argoproj/argocd-example-apps", "") + require.NoError(t, err) + teststruct := []struct { + expectedSecret string + retrievedSecret string + }{ + { + "test-username", + repo.Username, + }, + { + "test-password", + repo.Password, + }, + { + "test-ssh-private-key", + repo.SSHPrivateKey, + }, + { + "test-tls-client-cert-data", + repo.TLSClientCertData, + }, + { + "test-tls-client-cert-key", + repo.TLSClientCertKey, + }, + { + "test-github-app-private-key", + repo.GithubAppPrivateKey, + }, + } + for _, tt := range teststruct { + assert.Equal(t, tt.expectedSecret, tt.retrievedSecret) + } +} + +func TestGetClusterSuccessful(t *testing.T) { + server := "my-cluster" + name := "my-name" + clientset := getClientset(nil, &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: testNamespace, + Labels: map[string]string{ + common.LabelKeySecretType: common.LabelValueSecretTypeCluster, + }, + }, + Data: map[string][]byte{ + "server": []byte(server), + "name": []byte(name), + "config": []byte("{}"), + }, + }) + + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + cluster, err := db.GetCluster(context.Background(), server) + require.NoError(t, err) + assert.Equal(t, server, cluster.Server) + assert.Equal(t, name, cluster.Name) +} + +func TestGetNonExistingCluster(t *testing.T) { + server := "https://mycluster" + clientset := getClientset(nil) + + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + _, err := db.GetCluster(context.Background(), server) + require.Error(t, err) + status, ok := status.FromError(err) + assert.True(t, ok) + assert.Equal(t, codes.NotFound, status.Code()) +} + func TestCreateClusterSuccessful(t *testing.T) { server := "https://mycluster" - clientset := getClientset() - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + clientset := getClientset(nil) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) - _, err := db.CreateCluster(t.Context(), &v1alpha1.Cluster{ + _, err := db.CreateCluster(context.Background(), &v1alpha1.Cluster{ Server: server, }) require.NoError(t, err) - secret, err := clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), "cluster-mycluster-3274446258", metav1.GetOptions{}) + secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.Background(), "cluster-mycluster-3274446258", metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, server, string(secret.Data["server"])) @@ -316,7 +559,7 @@ func TestDeleteClusterWithManagedSecret(t *testing.T) { clusterURL := "https://mycluster" clusterName := "cluster-mycluster-3274446258" - clientset := getClientset(&corev1.Secret{ + clientset := getClientset(nil, &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: clusterName, Namespace: testNamespace, @@ -333,11 +576,11 @@ func TestDeleteClusterWithManagedSecret(t *testing.T) { }, }) - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) - err := db.DeleteCluster(t.Context(), clusterURL) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + err := db.DeleteCluster(context.Background(), clusterURL) require.NoError(t, err) - _, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), clusterName, metav1.GetOptions{}) + _, err = clientset.CoreV1().Secrets(testNamespace).Get(context.Background(), clusterName, metav1.GetOptions{}) require.Error(t, err) assert.True(t, errors.IsNotFound(err)) @@ -347,7 +590,7 @@ func TestDeleteClusterWithUnmanagedSecret(t *testing.T) { clusterURL := "https://mycluster" clusterName := "mycluster-443" - clientset := getClientset(&corev1.Secret{ + clientset := getClientset(nil, &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: clusterName, Namespace: testNamespace, @@ -361,20 +604,20 @@ func TestDeleteClusterWithUnmanagedSecret(t *testing.T) { }, }) - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) - err := db.DeleteCluster(t.Context(), clusterURL) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + err := db.DeleteCluster(context.Background(), clusterURL) require.NoError(t, err) - secret, err := clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), clusterName, metav1.GetOptions{}) + secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.Background(), clusterName, metav1.GetOptions{}) require.NoError(t, err) assert.Empty(t, secret.Labels) } func TestFuzzyEquivalence(t *testing.T) { - clientset := getClientset() - ctx := t.Context() - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + clientset := getClientset(nil) + ctx := context.Background() + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) repo, err := db.CreateRepository(ctx, &v1alpha1.Repository{ Repo: "https://github.com/argoproj/argocd-example-apps", @@ -399,26 +642,192 @@ func TestFuzzyEquivalence(t *testing.T) { assert.Equal(t, "https://github.com/argoproj/argocd-example-apps", repo.Repo) } +func TestListHelmRepositories(t *testing.T) { + config := map[string]string{ + "repositories": ` +- url: https://argoproj.github.io/argo-helm + name: argo + type: helm + usernameSecret: + name: test-secret + key: username + passwordSecret: + name: test-secret + key: password + tlsClientCertDataSecret: + name: test-secret + key: cert + tlsClientCertKeySecret: + name: test-secret + key: key +`, + } + clientset := getClientset(config, &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-secret", + Namespace: testNamespace, + }, + Data: map[string][]byte{ + "username": []byte("test-username"), + "password": []byte("test-password"), + "ca": []byte("test-ca"), + "cert": []byte("test-cert"), + "key": []byte("test-key"), + }, + }) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + + repos, err := db.ListRepositories(context.Background()) + require.NoError(t, err) + assert.Len(t, repos, 1) + repo := repos[0] + assert.Equal(t, "https://argoproj.github.io/argo-helm", repo.Repo) + assert.Equal(t, "helm", repo.Type) + assert.Equal(t, "argo", repo.Name) + assert.Equal(t, "test-username", repo.Username) + assert.Equal(t, "test-password", repo.Password) + assert.Equal(t, "test-cert", repo.TLSClientCertData) + assert.Equal(t, "test-key", repo.TLSClientCertKey) +} + +func TestHelmRepositorySecretsTrim(t *testing.T) { + config := map[string]string{ + "repositories": ` +- url: https://argoproj.github.io/argo-helm + name: argo + type: helm + usernameSecret: + name: test-secret + key: username + passwordSecret: + name: test-secret + key: password + tlsClientCertDataSecret: + name: test-secret + key: cert + tlsClientCertKeySecret: + name: test-secret + key: key +`, + } + clientset := getClientset(config, &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-secret", + Namespace: testNamespace, + }, + Data: map[string][]byte{ + "username": []byte("test-username\r\n"), + "password": []byte("test-password\r\n"), + "cert": []byte("test-cert\n\r"), + "key": []byte("test-key\n\r"), + }, + }) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + repo, err := db.GetRepository(context.Background(), "https://argoproj.github.io/argo-helm", "") + + require.NoError(t, err) + teststruct := []struct { + expectedSecret string + retrievedSecret string + }{ + { + "test-username", + repo.Username, + }, + { + "test-password", + repo.Password, + }, + { + "test-cert", + repo.TLSClientCertData, + }, + { + "test-key", + repo.TLSClientCertKey, + }, + } + for _, tt := range teststruct { + assert.Equal(t, tt.expectedSecret, tt.retrievedSecret) + } +} + +func TestGetClusterServersByName(t *testing.T) { + clientset := getClientset(nil, &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-secret", + Namespace: testNamespace, + Labels: map[string]string{ + common.LabelKeySecretType: common.LabelValueSecretTypeCluster, + }, + Annotations: map[string]string{ + common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD, + }, + }, + Data: map[string][]byte{ + "name": []byte("my-cluster-name"), + "server": []byte("https://my-cluster-server"), + "config": []byte("{}"), + }, + }) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + servers, err := db.GetClusterServersByName(context.Background(), "my-cluster-name") + require.NoError(t, err) + assert.ElementsMatch(t, []string{"https://my-cluster-server"}, servers) +} + +func TestGetClusterServersByName_InClusterNotConfigured(t *testing.T) { + clientset := getClientset(nil) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + servers, err := db.GetClusterServersByName(context.Background(), "in-cluster") + require.NoError(t, err) + assert.ElementsMatch(t, []string{v1alpha1.KubernetesInternalAPIServerAddr}, servers) +} + +func TestGetClusterServersByName_InClusterConfigured(t *testing.T) { + clientset := getClientset(nil, &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-secret", + Namespace: testNamespace, + Labels: map[string]string{ + common.LabelKeySecretType: common.LabelValueSecretTypeCluster, + }, + Annotations: map[string]string{ + common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD, + }, + }, + Data: map[string][]byte{ + "name": []byte("in-cluster-renamed"), + "server": []byte(v1alpha1.KubernetesInternalAPIServerAddr), + "config": []byte("{}"), + }, + }) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + servers, err := db.GetClusterServersByName(context.Background(), "in-cluster-renamed") + require.NoError(t, err) + assert.ElementsMatch(t, []string{v1alpha1.KubernetesInternalAPIServerAddr}, servers) +} + func TestGetApplicationControllerReplicas(t *testing.T) { - clientset := getClientset() + clientset := getClientset(nil) expectedReplicas := int32(2) t.Setenv(common.EnvControllerReplicas, "2") - db := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) replicas := db.GetApplicationControllerReplicas() assert.Equal(t, int(expectedReplicas), replicas) expectedReplicas = int32(3) - clientset = getClientset(&appsv1.Deployment{ + clientset = getClientset(nil, &appv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: common.ApplicationController, Namespace: testNamespace, }, - Spec: appsv1.DeploymentSpec{ + Spec: appv1.DeploymentSpec{ Replicas: &expectedReplicas, }, }) t.Setenv(common.EnvControllerReplicas, "2") - db = NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + db = NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) replicas = db.GetApplicationControllerReplicas() assert.Equal(t, int(expectedReplicas), replicas) } diff --git a/util/db/gpgkeys.go b/util/db/gpgkeys.go index 92e63c46ed..8024571852 100644 --- a/util/db/gpgkeys.go +++ b/util/db/gpgkeys.go @@ -2,15 +2,14 @@ package db import ( "context" - "errors" "fmt" "os" log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/common" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/gpg" + "github.com/argoproj/argo-cd/v2/common" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/gpg" ) // Validates a single GnuPG key and returns the key's ID @@ -39,10 +38,10 @@ func validatePGPKey(keyData string) (*appsv1.GnuPGPublicKey, error) { // Each key/value pair in the config map must exactly contain one public key, with the (short) GPG key ID as key if len(parsed) != 1 { - return nil, errors.New("more than one key found in input data") + return nil, fmt.Errorf("More than one key found in input data") } - var retKey *appsv1.GnuPGPublicKey + var retKey *appsv1.GnuPGPublicKey = nil // Is there a better way to get the first element from a map without knowing its key? for _, k := range parsed { retKey = k @@ -51,12 +50,13 @@ func validatePGPKey(keyData string) (*appsv1.GnuPGPublicKey, error) { if retKey != nil { retKey.KeyData = keyData return retKey, nil + } else { + return nil, fmt.Errorf("Could not find the GPG key") } - return nil, errors.New("could not find the GPG key") } // ListConfiguredGPGPublicKeys returns a list of all configured GPG public keys from the ConfigMap -func (db *db) ListConfiguredGPGPublicKeys(_ context.Context) (map[string]*appsv1.GnuPGPublicKey, error) { +func (db *db) ListConfiguredGPGPublicKeys(ctx context.Context) (map[string]*appsv1.GnuPGPublicKey, error) { log.Debugf("Loading PGP public keys from config map") result := make(map[string]*appsv1.GnuPGPublicKey) keysCM, err := db.settingsMgr.GetConfigMapByName(common.ArgoCDGPGKeysConfigMapName) @@ -69,18 +69,18 @@ func (db *db) ListConfiguredGPGPublicKeys(_ context.Context) (map[string]*appsv1 // This is not optimal, but the executil from argo-pkg does not support writing to // stdin of the forked process. So for now, we must live with that. for k, p := range keysCM.Data { - expectedKeyID := gpg.KeyID(k) - if expectedKeyID == "" { - return nil, fmt.Errorf("found entry with key '%s' in ConfigMap, but this is not a valid PGP key ID", k) + if expectedKeyID := gpg.KeyID(k); expectedKeyID != "" { + parsedKey, err := validatePGPKey(p) + if err != nil { + return nil, fmt.Errorf("Could not parse GPG key for entry '%s': %s", expectedKeyID, err.Error()) + } + if expectedKeyID != parsedKey.KeyID { + return nil, fmt.Errorf("Key parsed for entry with key ID '%s' had different key ID '%s'", expectedKeyID, parsedKey.KeyID) + } + result[parsedKey.KeyID] = parsedKey + } else { + return nil, fmt.Errorf("Found entry with key '%s' in ConfigMap, but this is not a valid PGP key ID", k) } - parsedKey, err := validatePGPKey(p) - if err != nil { - return nil, fmt.Errorf("could not parse GPG key for entry '%s': %s", expectedKeyID, err.Error()) - } - if expectedKeyID != parsedKey.KeyID { - return nil, fmt.Errorf("key parsed for entry with key ID '%s' had different key ID '%s'", expectedKeyID, parsedKey.KeyID) - } - result[parsedKey.KeyID] = parsedKey } return result, nil @@ -101,6 +101,10 @@ func (db *db) AddGPGPublicKey(ctx context.Context, keyData string) (map[string]* return nil, nil, err } + if keysCM.Data == nil { + keysCM.Data = make(map[string]string) + } + for kid, key := range keys { if _, ok := keysCM.Data[kid]; ok { skipped = append(skipped, kid) @@ -127,8 +131,12 @@ func (db *db) DeleteGPGPublicKey(ctx context.Context, keyID string) error { return err } + if keysCM.Data == nil { + return fmt.Errorf("No such key configured: %s", keyID) + } + if _, ok := keysCM.Data[keyID]; !ok { - return fmt.Errorf("no such key configured: %s", keyID) + return fmt.Errorf("No such key configured: %s", keyID) } delete(keysCM.Data, keyID) diff --git a/util/db/gpgkeys_test.go b/util/db/gpgkeys_test.go index a5e8435ecf..731293b5b2 100644 --- a/util/db/gpgkeys_test.go +++ b/util/db/gpgkeys_test.go @@ -1,22 +1,24 @@ package db import ( + "context" + "os" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/gpg/testdata" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/gpg/testdata" + "github.com/argoproj/argo-cd/v2/util/settings" ) // GPG config map with a single key and good mapping -var gpgCMEmpty = corev1.ConfigMap{ +var gpgCMEmpty = v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDGPGKeysConfigMapName, Namespace: testNamespace, @@ -27,7 +29,7 @@ var gpgCMEmpty = corev1.ConfigMap{ } // GPG config map with a single key and good mapping -var gpgCMSingleGoodPubkey = corev1.ConfigMap{ +var gpgCMSingleGoodPubkey = v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDGPGKeysConfigMapName, Namespace: testNamespace, @@ -41,7 +43,7 @@ var gpgCMSingleGoodPubkey = corev1.ConfigMap{ } // GPG config map with two keys and good mapping -var gpgCMMultiGoodPubkey = corev1.ConfigMap{ +var gpgCMMultiGoodPubkey = v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDGPGKeysConfigMapName, Namespace: testNamespace, @@ -56,7 +58,7 @@ var gpgCMMultiGoodPubkey = corev1.ConfigMap{ } // GPG config map with a single key and bad mapping -var gpgCMSingleKeyWrongId = corev1.ConfigMap{ +var gpgCMSingleKeyWrongId = v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDGPGKeysConfigMapName, Namespace: testNamespace, @@ -70,7 +72,7 @@ var gpgCMSingleKeyWrongId = corev1.ConfigMap{ } // GPG config map with a garbage pub key -var gpgCMGarbagePubkey = corev1.ConfigMap{ +var gpgCMGarbagePubkey = v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDGPGKeysConfigMapName, Namespace: testNamespace, @@ -84,7 +86,7 @@ var gpgCMGarbagePubkey = corev1.ConfigMap{ } // GPG config map with a wrong key -var gpgCMGarbageCMKey = corev1.ConfigMap{ +var gpgCMGarbageCMKey = v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDGPGKeysConfigMapName, Namespace: testNamespace, @@ -98,8 +100,8 @@ var gpgCMGarbageCMKey = corev1.ConfigMap{ } // Returns a fake client set for use in tests -func getGPGKeysClientset(gpgCM corev1.ConfigMap) *fake.Clientset { - cm := corev1.ConfigMap{ +func getGPGKeysClientset(gpgCM v1.ConfigMap) *fake.Clientset { + cm := v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-cm", Namespace: testNamespace, @@ -142,60 +144,60 @@ func Test_ListConfiguredGPGPublicKeys(t *testing.T) { // Good case. Single key in input, right mapping to Key ID in CM { clientset := getGPGKeysClientset(gpgCMSingleGoodPubkey) - settings := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + settings := settings.NewSettingsManager(context.Background(), clientset, testNamespace) db := NewDB(testNamespace, settings, clientset) if db == nil { panic("could not get database") } - keys, err := db.ListConfiguredGPGPublicKeys(t.Context()) + keys, err := db.ListConfiguredGPGPublicKeys(context.Background()) require.NoError(t, err) assert.Len(t, keys, 1) } // Good case. No certificates in ConfigMap { clientset := getGPGKeysClientset(gpgCMEmpty) - settings := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + settings := settings.NewSettingsManager(context.Background(), clientset, testNamespace) db := NewDB(testNamespace, settings, clientset) if db == nil { panic("could not get database") } - keys, err := db.ListConfiguredGPGPublicKeys(t.Context()) + keys, err := db.ListConfiguredGPGPublicKeys(context.Background()) require.NoError(t, err) assert.Empty(t, keys) } // Bad case. Single key in input, wrong mapping to Key ID in CM { clientset := getGPGKeysClientset(gpgCMSingleKeyWrongId) - settings := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + settings := settings.NewSettingsManager(context.Background(), clientset, testNamespace) db := NewDB(testNamespace, settings, clientset) if db == nil { panic("could not get database") } - keys, err := db.ListConfiguredGPGPublicKeys(t.Context()) + keys, err := db.ListConfiguredGPGPublicKeys(context.Background()) require.Error(t, err) assert.Empty(t, keys) } // Bad case. Garbage public key { clientset := getGPGKeysClientset(gpgCMGarbagePubkey) - settings := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + settings := settings.NewSettingsManager(context.Background(), clientset, testNamespace) db := NewDB(testNamespace, settings, clientset) if db == nil { panic("could not get database") } - keys, err := db.ListConfiguredGPGPublicKeys(t.Context()) + keys, err := db.ListConfiguredGPGPublicKeys(context.Background()) require.Error(t, err) assert.Empty(t, keys) } // Bad case. Garbage ConfigMap key in data { clientset := getGPGKeysClientset(gpgCMGarbageCMKey) - settings := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + settings := settings.NewSettingsManager(context.Background(), clientset, testNamespace) db := NewDB(testNamespace, settings, clientset) if db == nil { panic("could not get database") } - keys, err := db.ListConfiguredGPGPublicKeys(t.Context()) + keys, err := db.ListConfiguredGPGPublicKeys(context.Background()) require.Error(t, err) assert.Empty(t, keys) } @@ -205,11 +207,11 @@ func Test_AddGPGPublicKey(t *testing.T) { // Good case { clientset := getGPGKeysClientset(gpgCMEmpty) - settings := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + settings := settings.NewSettingsManager(context.Background(), clientset, testNamespace) db := NewDB(testNamespace, settings, clientset) // Key should be added - new, skipped, err := db.AddGPGPublicKey(t.Context(), testdata.Github_asc) + new, skipped, err := db.AddGPGPublicKey(context.Background(), testdata.Github_asc) require.NoError(t, err) assert.Len(t, new, 1) assert.Empty(t, skipped) @@ -218,7 +220,7 @@ func Test_AddGPGPublicKey(t *testing.T) { assert.Len(t, cm.Data, 1) // Same key should not be added, but skipped - new, skipped, err = db.AddGPGPublicKey(t.Context(), testdata.Github_asc) + new, skipped, err = db.AddGPGPublicKey(context.Background(), testdata.Github_asc) require.NoError(t, err) assert.Empty(t, new) assert.Len(t, skipped, 1) @@ -227,7 +229,7 @@ func Test_AddGPGPublicKey(t *testing.T) { assert.Len(t, cm.Data, 1) // New keys should be added - new, skipped, err = db.AddGPGPublicKey(t.Context(), testdata.Multi_asc) + new, skipped, err = db.AddGPGPublicKey(context.Background(), testdata.Multi_asc) require.NoError(t, err) assert.Len(t, new, 2) assert.Empty(t, skipped) @@ -236,7 +238,7 @@ func Test_AddGPGPublicKey(t *testing.T) { assert.Len(t, cm.Data, 3) // Same new keys should be skipped - new, skipped, err = db.AddGPGPublicKey(t.Context(), testdata.Multi_asc) + new, skipped, err = db.AddGPGPublicKey(context.Background(), testdata.Multi_asc) require.NoError(t, err) assert.Empty(t, new) assert.Len(t, skipped, 2) @@ -245,7 +247,7 @@ func Test_AddGPGPublicKey(t *testing.T) { assert.Len(t, cm.Data, 3) // Garbage input should result in error - new, skipped, err = db.AddGPGPublicKey(t.Context(), testdata.Garbage_asc) + new, skipped, err = db.AddGPGPublicKey(context.Background(), testdata.Garbage_asc) require.Error(t, err) assert.Nil(t, new) assert.Nil(t, skipped) @@ -256,47 +258,47 @@ func Test_AddGPGPublicKey(t *testing.T) { } func Test_DeleteGPGPublicKey(t *testing.T) { - defer t.Setenv("GNUPGHOME", "") + defer os.Setenv("GNUPGHOME", "") t.Run("good case", func(t *testing.T) { clientset := getGPGKeysClientset(gpgCMMultiGoodPubkey) - settings := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + settings := settings.NewSettingsManager(context.Background(), clientset, testNamespace) db := NewDB(testNamespace, settings, clientset) // Key should be removed - err := db.DeleteGPGPublicKey(t.Context(), "FDC79815400D88A9") + err := db.DeleteGPGPublicKey(context.Background(), "FDC79815400D88A9") require.NoError(t, err) // Key should not exist anymore, therefore can't be deleted again - err = db.DeleteGPGPublicKey(t.Context(), "FDC79815400D88A9") + err = db.DeleteGPGPublicKey(context.Background(), "FDC79815400D88A9") require.Error(t, err) // One key left in configuration - n, err := db.ListConfiguredGPGPublicKeys(t.Context()) + n, err := db.ListConfiguredGPGPublicKeys(context.Background()) require.NoError(t, err) assert.Len(t, n, 1) // Key should be removed - err = db.DeleteGPGPublicKey(t.Context(), "F7842A5CEAA9C0B1") + err = db.DeleteGPGPublicKey(context.Background(), "F7842A5CEAA9C0B1") require.NoError(t, err) // Key should not exist anymore, therefore can't be deleted again - err = db.DeleteGPGPublicKey(t.Context(), "F7842A5CEAA9C0B1") + err = db.DeleteGPGPublicKey(context.Background(), "F7842A5CEAA9C0B1") require.Error(t, err) // No key left in configuration - n, err = db.ListConfiguredGPGPublicKeys(t.Context()) + n, err = db.ListConfiguredGPGPublicKeys(context.Background()) require.NoError(t, err) assert.Empty(t, n) }) t.Run("bad case - empty ConfigMap", func(t *testing.T) { clientset := getGPGKeysClientset(gpgCMEmpty) - settings := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + settings := settings.NewSettingsManager(context.Background(), clientset, testNamespace) db := NewDB(testNamespace, settings, clientset) // Key should be removed - err := db.DeleteGPGPublicKey(t.Context(), "F7842A5CEAA9C0B1") + err := db.DeleteGPGPublicKey(context.Background(), "F7842A5CEAA9C0B1") require.Error(t, err) }) } diff --git a/util/db/helmrepository.go b/util/db/helmrepository.go index d88db9e818..0cc6bb2742 100644 --- a/util/db/helmrepository.go +++ b/util/db/helmrepository.go @@ -3,15 +3,62 @@ package db import ( "context" "fmt" + "strings" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + v1 "k8s.io/api/core/v1" "k8s.io/utils/ptr" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/settings" ) +func getHelmRepoCredIndex(helmRepositories []settings.HelmRepoCredentials, repoURL string) int { + for i, cred := range helmRepositories { + if strings.EqualFold(cred.URL, repoURL) { + return i + } + } + return -1 +} + +func (db *db) getHelmRepo(repoURL string, helmRepositories []settings.HelmRepoCredentials) (*v1alpha1.Repository, error) { + index := getHelmRepoCredIndex(helmRepositories, repoURL) + if index < 0 { + return nil, status.Errorf(codes.NotFound, "repo '%s' not found", repoURL) + } + repoInfo := helmRepositories[index] + + repo := &v1alpha1.Repository{ + Repo: repoInfo.URL, + Type: "helm", + Name: repoInfo.Name, + } + err := db.unmarshalFromSecretsStr(map[*SecretMaperValidation]*v1.SecretKeySelector{ + {Dest: &repo.Username, Transform: StripCRLFCharacter}: repoInfo.UsernameSecret, + {Dest: &repo.Password, Transform: StripCRLFCharacter}: repoInfo.PasswordSecret, + {Dest: &repo.TLSClientCertData, Transform: StripCRLFCharacter}: repoInfo.CertSecret, + {Dest: &repo.TLSClientCertKey, Transform: StripCRLFCharacter}: repoInfo.KeySecret, + }, make(map[string]*v1.Secret)) + return repo, err +} + // ListHelmRepositories lists configured helm repositories func (db *db) ListHelmRepositories(ctx context.Context) ([]*v1alpha1.Repository, error) { - var result []*v1alpha1.Repository + helmRepositories, err := db.settingsMgr.GetHelmRepositories() + if err != nil { + return nil, fmt.Errorf("failed to get list of Helm repositories from settings manager: %w", err) + } + + result := make([]*v1alpha1.Repository, len(helmRepositories)) + for i, helmRepoInfo := range helmRepositories { + repo, err := db.getHelmRepo(helmRepoInfo.URL, helmRepositories) + if err != nil { + return nil, fmt.Errorf("failed to get Helm repository %q: %w", helmRepoInfo.URL, err) + } + result[i] = repo + } repos, err := db.listRepositories(ctx, ptr.To("helm"), false) if err != nil { return nil, fmt.Errorf("failed to list Helm repositories: %w", err) diff --git a/util/db/mocks/ArgoDB.go b/util/db/mocks/ArgoDB.go index e9e7c3f932..86539666c3 100644 --- a/util/db/mocks/ArgoDB.go +++ b/util/db/mocks/ArgoDB.go @@ -1,17 +1,1190 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" + context "context" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/db" + db "github.com/argoproj/argo-cd/v2/util/db" mock "github.com/stretchr/testify/mock" + + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) +// ArgoDB is an autogenerated mock type for the ArgoDB type +type ArgoDB struct { + mock.Mock +} + +// AddGPGPublicKey provides a mock function with given fields: ctx, keyData +func (_m *ArgoDB) AddGPGPublicKey(ctx context.Context, keyData string) (map[string]*v1alpha1.GnuPGPublicKey, []string, error) { + ret := _m.Called(ctx, keyData) + + if len(ret) == 0 { + panic("no return value specified for AddGPGPublicKey") + } + + var r0 map[string]*v1alpha1.GnuPGPublicKey + var r1 []string + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, string) (map[string]*v1alpha1.GnuPGPublicKey, []string, error)); ok { + return rf(ctx, keyData) + } + if rf, ok := ret.Get(0).(func(context.Context, string) map[string]*v1alpha1.GnuPGPublicKey); ok { + r0 = rf(ctx, keyData) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]*v1alpha1.GnuPGPublicKey) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) []string); ok { + r1 = rf(ctx, keyData) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).([]string) + } + } + + if rf, ok := ret.Get(2).(func(context.Context, string) error); ok { + r2 = rf(ctx, keyData) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// CreateCluster provides a mock function with given fields: ctx, c +func (_m *ArgoDB) CreateCluster(ctx context.Context, c *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { + ret := _m.Called(ctx, c) + + if len(ret) == 0 { + panic("no return value specified for CreateCluster") + } + + var r0 *v1alpha1.Cluster + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Cluster) (*v1alpha1.Cluster, error)); ok { + return rf(ctx, c) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Cluster) *v1alpha1.Cluster); ok { + r0 = rf(ctx, c) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Cluster) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Cluster) error); ok { + r1 = rf(ctx, c) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateRepoCertificate provides a mock function with given fields: ctx, certificate, upsert +func (_m *ArgoDB) CreateRepoCertificate(ctx context.Context, certificate *v1alpha1.RepositoryCertificateList, upsert bool) (*v1alpha1.RepositoryCertificateList, error) { + ret := _m.Called(ctx, certificate, upsert) + + if len(ret) == 0 { + panic("no return value specified for CreateRepoCertificate") + } + + var r0 *v1alpha1.RepositoryCertificateList + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepositoryCertificateList, bool) (*v1alpha1.RepositoryCertificateList, error)); ok { + return rf(ctx, certificate, upsert) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepositoryCertificateList, bool) *v1alpha1.RepositoryCertificateList); ok { + r0 = rf(ctx, certificate, upsert) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RepositoryCertificateList) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.RepositoryCertificateList, bool) error); ok { + r1 = rf(ctx, certificate, upsert) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateRepository provides a mock function with given fields: ctx, r +func (_m *ArgoDB) CreateRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for CreateRepository") + } + + var r0 *v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) (*v1alpha1.Repository, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) *v1alpha1.Repository); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Repository) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateRepositoryCredentials provides a mock function with given fields: ctx, r +func (_m *ArgoDB) CreateRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for CreateRepositoryCredentials") + } + + var r0 *v1alpha1.RepoCreds + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) *v1alpha1.RepoCreds); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RepoCreds) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.RepoCreds) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateWriteRepository provides a mock function with given fields: ctx, r +func (_m *ArgoDB) CreateWriteRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for CreateWriteRepository") + } + + var r0 *v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) (*v1alpha1.Repository, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) *v1alpha1.Repository); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Repository) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateWriteRepositoryCredentials provides a mock function with given fields: ctx, r +func (_m *ArgoDB) CreateWriteRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for CreateWriteRepositoryCredentials") + } + + var r0 *v1alpha1.RepoCreds + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) *v1alpha1.RepoCreds); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RepoCreds) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.RepoCreds) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteCluster provides a mock function with given fields: ctx, server +func (_m *ArgoDB) DeleteCluster(ctx context.Context, server string) error { + ret := _m.Called(ctx, server) + + if len(ret) == 0 { + panic("no return value specified for DeleteCluster") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, server) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteGPGPublicKey provides a mock function with given fields: ctx, keyID +func (_m *ArgoDB) DeleteGPGPublicKey(ctx context.Context, keyID string) error { + ret := _m.Called(ctx, keyID) + + if len(ret) == 0 { + panic("no return value specified for DeleteGPGPublicKey") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, keyID) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteRepository provides a mock function with given fields: ctx, name, project +func (_m *ArgoDB) DeleteRepository(ctx context.Context, name string, project string) error { + ret := _m.Called(ctx, name, project) + + if len(ret) == 0 { + panic("no return value specified for DeleteRepository") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { + r0 = rf(ctx, name, project) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteRepositoryCredentials provides a mock function with given fields: ctx, name +func (_m *ArgoDB) DeleteRepositoryCredentials(ctx context.Context, name string) error { + ret := _m.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for DeleteRepositoryCredentials") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, name) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteWriteRepository provides a mock function with given fields: ctx, name, project +func (_m *ArgoDB) DeleteWriteRepository(ctx context.Context, name string, project string) error { + ret := _m.Called(ctx, name, project) + + if len(ret) == 0 { + panic("no return value specified for DeleteWriteRepository") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { + r0 = rf(ctx, name, project) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteWriteRepositoryCredentials provides a mock function with given fields: ctx, name +func (_m *ArgoDB) DeleteWriteRepositoryCredentials(ctx context.Context, name string) error { + ret := _m.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for DeleteWriteRepositoryCredentials") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, name) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GetAllHelmRepositoryCredentials provides a mock function with given fields: ctx +func (_m *ArgoDB) GetAllHelmRepositoryCredentials(ctx context.Context) ([]*v1alpha1.RepoCreds, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetAllHelmRepositoryCredentials") + } + + var r0 []*v1alpha1.RepoCreds + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]*v1alpha1.RepoCreds, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []*v1alpha1.RepoCreds); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1alpha1.RepoCreds) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetApplicationControllerReplicas provides a mock function with no fields +func (_m *ArgoDB) GetApplicationControllerReplicas() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetApplicationControllerReplicas") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// GetCluster provides a mock function with given fields: ctx, server +func (_m *ArgoDB) GetCluster(ctx context.Context, server string) (*v1alpha1.Cluster, error) { + ret := _m.Called(ctx, server) + + if len(ret) == 0 { + panic("no return value specified for GetCluster") + } + + var r0 *v1alpha1.Cluster + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*v1alpha1.Cluster, error)); ok { + return rf(ctx, server) + } + if rf, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.Cluster); ok { + r0 = rf(ctx, server) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Cluster) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, server) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetClusterServersByName provides a mock function with given fields: ctx, name +func (_m *ArgoDB) GetClusterServersByName(ctx context.Context, name string) ([]string, error) { + ret := _m.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for GetClusterServersByName") + } + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) ([]string, error)); ok { + return rf(ctx, name) + } + if rf, ok := ret.Get(0).(func(context.Context, string) []string); ok { + r0 = rf(ctx, name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetProjectClusters provides a mock function with given fields: ctx, project +func (_m *ArgoDB) GetProjectClusters(ctx context.Context, project string) ([]*v1alpha1.Cluster, error) { + ret := _m.Called(ctx, project) + + if len(ret) == 0 { + panic("no return value specified for GetProjectClusters") + } + + var r0 []*v1alpha1.Cluster + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) ([]*v1alpha1.Cluster, error)); ok { + return rf(ctx, project) + } + if rf, ok := ret.Get(0).(func(context.Context, string) []*v1alpha1.Cluster); ok { + r0 = rf(ctx, project) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1alpha1.Cluster) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, project) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetProjectRepositories provides a mock function with given fields: ctx, project +func (_m *ArgoDB) GetProjectRepositories(ctx context.Context, project string) ([]*v1alpha1.Repository, error) { + ret := _m.Called(ctx, project) + + if len(ret) == 0 { + panic("no return value specified for GetProjectRepositories") + } + + var r0 []*v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) ([]*v1alpha1.Repository, error)); ok { + return rf(ctx, project) + } + if rf, ok := ret.Get(0).(func(context.Context, string) []*v1alpha1.Repository); ok { + r0 = rf(ctx, project) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, project) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetProjectWriteRepositories provides a mock function with given fields: ctx, project +func (_m *ArgoDB) GetProjectWriteRepositories(ctx context.Context, project string) ([]*v1alpha1.Repository, error) { + ret := _m.Called(ctx, project) + + if len(ret) == 0 { + panic("no return value specified for GetProjectWriteRepositories") + } + + var r0 []*v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) ([]*v1alpha1.Repository, error)); ok { + return rf(ctx, project) + } + if rf, ok := ret.Get(0).(func(context.Context, string) []*v1alpha1.Repository); ok { + r0 = rf(ctx, project) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, project) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRepository provides a mock function with given fields: ctx, url, project +func (_m *ArgoDB) GetRepository(ctx context.Context, url string, project string) (*v1alpha1.Repository, error) { + ret := _m.Called(ctx, url, project) + + if len(ret) == 0 { + panic("no return value specified for GetRepository") + } + + var r0 *v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) (*v1alpha1.Repository, error)); ok { + return rf(ctx, url, project) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string) *v1alpha1.Repository); ok { + r0 = rf(ctx, url, project) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { + r1 = rf(ctx, url, project) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRepositoryCredentials provides a mock function with given fields: ctx, name +func (_m *ArgoDB) GetRepositoryCredentials(ctx context.Context, name string) (*v1alpha1.RepoCreds, error) { + ret := _m.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for GetRepositoryCredentials") + } + + var r0 *v1alpha1.RepoCreds + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*v1alpha1.RepoCreds, error)); ok { + return rf(ctx, name) + } + if rf, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.RepoCreds); ok { + r0 = rf(ctx, name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RepoCreds) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetWriteCredentials provides a mock function with given fields: ctx, repoURL +func (_m *ArgoDB) GetWriteCredentials(ctx context.Context, repoURL string) (*v1alpha1.Repository, error) { + ret := _m.Called(ctx, repoURL) + + if len(ret) == 0 { + panic("no return value specified for GetWriteCredentials") + } + + var r0 *v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*v1alpha1.Repository, error)); ok { + return rf(ctx, repoURL) + } + if rf, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.Repository); ok { + r0 = rf(ctx, repoURL) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, repoURL) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetWriteRepository provides a mock function with given fields: ctx, url, project +func (_m *ArgoDB) GetWriteRepository(ctx context.Context, url string, project string) (*v1alpha1.Repository, error) { + ret := _m.Called(ctx, url, project) + + if len(ret) == 0 { + panic("no return value specified for GetWriteRepository") + } + + var r0 *v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) (*v1alpha1.Repository, error)); ok { + return rf(ctx, url, project) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string) *v1alpha1.Repository); ok { + r0 = rf(ctx, url, project) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { + r1 = rf(ctx, url, project) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetWriteRepositoryCredentials provides a mock function with given fields: ctx, name +func (_m *ArgoDB) GetWriteRepositoryCredentials(ctx context.Context, name string) (*v1alpha1.RepoCreds, error) { + ret := _m.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for GetWriteRepositoryCredentials") + } + + var r0 *v1alpha1.RepoCreds + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*v1alpha1.RepoCreds, error)); ok { + return rf(ctx, name) + } + if rf, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.RepoCreds); ok { + r0 = rf(ctx, name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RepoCreds) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListClusters provides a mock function with given fields: ctx +func (_m *ArgoDB) ListClusters(ctx context.Context) (*v1alpha1.ClusterList, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ListClusters") + } + + var r0 *v1alpha1.ClusterList + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*v1alpha1.ClusterList, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *v1alpha1.ClusterList); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.ClusterList) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListConfiguredGPGPublicKeys provides a mock function with given fields: ctx +func (_m *ArgoDB) ListConfiguredGPGPublicKeys(ctx context.Context) (map[string]*v1alpha1.GnuPGPublicKey, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ListConfiguredGPGPublicKeys") + } + + var r0 map[string]*v1alpha1.GnuPGPublicKey + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (map[string]*v1alpha1.GnuPGPublicKey, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) map[string]*v1alpha1.GnuPGPublicKey); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]*v1alpha1.GnuPGPublicKey) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListHelmRepositories provides a mock function with given fields: ctx +func (_m *ArgoDB) ListHelmRepositories(ctx context.Context) ([]*v1alpha1.Repository, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ListHelmRepositories") + } + + var r0 []*v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]*v1alpha1.Repository, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []*v1alpha1.Repository); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListRepoCertificates provides a mock function with given fields: ctx, selector +func (_m *ArgoDB) ListRepoCertificates(ctx context.Context, selector *db.CertificateListSelector) (*v1alpha1.RepositoryCertificateList, error) { + ret := _m.Called(ctx, selector) + + if len(ret) == 0 { + panic("no return value specified for ListRepoCertificates") + } + + var r0 *v1alpha1.RepositoryCertificateList + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *db.CertificateListSelector) (*v1alpha1.RepositoryCertificateList, error)); ok { + return rf(ctx, selector) + } + if rf, ok := ret.Get(0).(func(context.Context, *db.CertificateListSelector) *v1alpha1.RepositoryCertificateList); ok { + r0 = rf(ctx, selector) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RepositoryCertificateList) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *db.CertificateListSelector) error); ok { + r1 = rf(ctx, selector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListRepositories provides a mock function with given fields: ctx +func (_m *ArgoDB) ListRepositories(ctx context.Context) ([]*v1alpha1.Repository, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ListRepositories") + } + + var r0 []*v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]*v1alpha1.Repository, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []*v1alpha1.Repository); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListRepositoryCredentials provides a mock function with given fields: ctx +func (_m *ArgoDB) ListRepositoryCredentials(ctx context.Context) ([]string, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ListRepositoryCredentials") + } + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]string, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []string); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListWriteRepositories provides a mock function with given fields: ctx +func (_m *ArgoDB) ListWriteRepositories(ctx context.Context) ([]*v1alpha1.Repository, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ListWriteRepositories") + } + + var r0 []*v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]*v1alpha1.Repository, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []*v1alpha1.Repository); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListWriteRepositoryCredentials provides a mock function with given fields: ctx +func (_m *ArgoDB) ListWriteRepositoryCredentials(ctx context.Context) ([]string, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ListWriteRepositoryCredentials") + } + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]string, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []string); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RemoveRepoCertificates provides a mock function with given fields: ctx, selector +func (_m *ArgoDB) RemoveRepoCertificates(ctx context.Context, selector *db.CertificateListSelector) (*v1alpha1.RepositoryCertificateList, error) { + ret := _m.Called(ctx, selector) + + if len(ret) == 0 { + panic("no return value specified for RemoveRepoCertificates") + } + + var r0 *v1alpha1.RepositoryCertificateList + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *db.CertificateListSelector) (*v1alpha1.RepositoryCertificateList, error)); ok { + return rf(ctx, selector) + } + if rf, ok := ret.Get(0).(func(context.Context, *db.CertificateListSelector) *v1alpha1.RepositoryCertificateList); ok { + r0 = rf(ctx, selector) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RepositoryCertificateList) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *db.CertificateListSelector) error); ok { + r1 = rf(ctx, selector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RepositoryExists provides a mock function with given fields: ctx, repoURL, project +func (_m *ArgoDB) RepositoryExists(ctx context.Context, repoURL string, project string) (bool, error) { + ret := _m.Called(ctx, repoURL, project) + + if len(ret) == 0 { + panic("no return value specified for RepositoryExists") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) (bool, error)); ok { + return rf(ctx, repoURL, project) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string) bool); ok { + r0 = rf(ctx, repoURL, project) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { + r1 = rf(ctx, repoURL, project) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateCluster provides a mock function with given fields: ctx, c +func (_m *ArgoDB) UpdateCluster(ctx context.Context, c *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { + ret := _m.Called(ctx, c) + + if len(ret) == 0 { + panic("no return value specified for UpdateCluster") + } + + var r0 *v1alpha1.Cluster + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Cluster) (*v1alpha1.Cluster, error)); ok { + return rf(ctx, c) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Cluster) *v1alpha1.Cluster); ok { + r0 = rf(ctx, c) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Cluster) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Cluster) error); ok { + r1 = rf(ctx, c) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateRepository provides a mock function with given fields: ctx, r +func (_m *ArgoDB) UpdateRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for UpdateRepository") + } + + var r0 *v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) (*v1alpha1.Repository, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) *v1alpha1.Repository); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Repository) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateRepositoryCredentials provides a mock function with given fields: ctx, r +func (_m *ArgoDB) UpdateRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for UpdateRepositoryCredentials") + } + + var r0 *v1alpha1.RepoCreds + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) *v1alpha1.RepoCreds); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RepoCreds) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.RepoCreds) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateWriteRepository provides a mock function with given fields: ctx, r +func (_m *ArgoDB) UpdateWriteRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for UpdateWriteRepository") + } + + var r0 *v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) (*v1alpha1.Repository, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) *v1alpha1.Repository); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Repository) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateWriteRepositoryCredentials provides a mock function with given fields: ctx, r +func (_m *ArgoDB) UpdateWriteRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for UpdateWriteRepositoryCredentials") + } + + var r0 *v1alpha1.RepoCreds + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) *v1alpha1.RepoCreds); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RepoCreds) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.RepoCreds) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// WatchClusters provides a mock function with given fields: ctx, handleAddEvent, handleModEvent, handleDeleteEvent +func (_m *ArgoDB) WatchClusters(ctx context.Context, handleAddEvent func(*v1alpha1.Cluster), handleModEvent func(*v1alpha1.Cluster, *v1alpha1.Cluster), handleDeleteEvent func(string)) error { + ret := _m.Called(ctx, handleAddEvent, handleModEvent, handleDeleteEvent) + + if len(ret) == 0 { + panic("no return value specified for WatchClusters") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, func(*v1alpha1.Cluster), func(*v1alpha1.Cluster, *v1alpha1.Cluster), func(string)) error); ok { + r0 = rf(ctx, handleAddEvent, handleModEvent, handleDeleteEvent) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// WriteRepositoryExists provides a mock function with given fields: ctx, repoURL, project +func (_m *ArgoDB) WriteRepositoryExists(ctx context.Context, repoURL string, project string) (bool, error) { + ret := _m.Called(ctx, repoURL, project) + + if len(ret) == 0 { + panic("no return value specified for WriteRepositoryExists") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) (bool, error)); ok { + return rf(ctx, repoURL, project) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string) bool); ok { + r0 = rf(ctx, repoURL, project) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { + r1 = rf(ctx, repoURL, project) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewArgoDB creates a new instance of ArgoDB. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewArgoDB(t interface { @@ -25,2266 +1198,3 @@ func NewArgoDB(t interface { return mock } - -// ArgoDB is an autogenerated mock type for the ArgoDB type -type ArgoDB struct { - mock.Mock -} - -type ArgoDB_Expecter struct { - mock *mock.Mock -} - -func (_m *ArgoDB) EXPECT() *ArgoDB_Expecter { - return &ArgoDB_Expecter{mock: &_m.Mock} -} - -// AddGPGPublicKey provides a mock function for the type ArgoDB -func (_mock *ArgoDB) AddGPGPublicKey(ctx context.Context, keyData string) (map[string]*v1alpha1.GnuPGPublicKey, []string, error) { - ret := _mock.Called(ctx, keyData) - - if len(ret) == 0 { - panic("no return value specified for AddGPGPublicKey") - } - - var r0 map[string]*v1alpha1.GnuPGPublicKey - var r1 []string - var r2 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string) (map[string]*v1alpha1.GnuPGPublicKey, []string, error)); ok { - return returnFunc(ctx, keyData) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string) map[string]*v1alpha1.GnuPGPublicKey); ok { - r0 = returnFunc(ctx, keyData) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[string]*v1alpha1.GnuPGPublicKey) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string) []string); ok { - r1 = returnFunc(ctx, keyData) - } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).([]string) - } - } - if returnFunc, ok := ret.Get(2).(func(context.Context, string) error); ok { - r2 = returnFunc(ctx, keyData) - } else { - r2 = ret.Error(2) - } - return r0, r1, r2 -} - -// ArgoDB_AddGPGPublicKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddGPGPublicKey' -type ArgoDB_AddGPGPublicKey_Call struct { - *mock.Call -} - -// AddGPGPublicKey is a helper method to define mock.On call -// - ctx -// - keyData -func (_e *ArgoDB_Expecter) AddGPGPublicKey(ctx interface{}, keyData interface{}) *ArgoDB_AddGPGPublicKey_Call { - return &ArgoDB_AddGPGPublicKey_Call{Call: _e.mock.On("AddGPGPublicKey", ctx, keyData)} -} - -func (_c *ArgoDB_AddGPGPublicKey_Call) Run(run func(ctx context.Context, keyData string)) *ArgoDB_AddGPGPublicKey_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) - }) - return _c -} - -func (_c *ArgoDB_AddGPGPublicKey_Call) Return(stringToGnuPGPublicKey map[string]*v1alpha1.GnuPGPublicKey, strings []string, err error) *ArgoDB_AddGPGPublicKey_Call { - _c.Call.Return(stringToGnuPGPublicKey, strings, err) - return _c -} - -func (_c *ArgoDB_AddGPGPublicKey_Call) RunAndReturn(run func(ctx context.Context, keyData string) (map[string]*v1alpha1.GnuPGPublicKey, []string, error)) *ArgoDB_AddGPGPublicKey_Call { - _c.Call.Return(run) - return _c -} - -// CreateCluster provides a mock function for the type ArgoDB -func (_mock *ArgoDB) CreateCluster(ctx context.Context, c *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { - ret := _mock.Called(ctx, c) - - if len(ret) == 0 { - panic("no return value specified for CreateCluster") - } - - var r0 *v1alpha1.Cluster - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Cluster) (*v1alpha1.Cluster, error)); ok { - return returnFunc(ctx, c) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Cluster) *v1alpha1.Cluster); ok { - r0 = returnFunc(ctx, c) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Cluster) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.Cluster) error); ok { - r1 = returnFunc(ctx, c) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_CreateCluster_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateCluster' -type ArgoDB_CreateCluster_Call struct { - *mock.Call -} - -// CreateCluster is a helper method to define mock.On call -// - ctx -// - c -func (_e *ArgoDB_Expecter) CreateCluster(ctx interface{}, c interface{}) *ArgoDB_CreateCluster_Call { - return &ArgoDB_CreateCluster_Call{Call: _e.mock.On("CreateCluster", ctx, c)} -} - -func (_c *ArgoDB_CreateCluster_Call) Run(run func(ctx context.Context, c *v1alpha1.Cluster)) *ArgoDB_CreateCluster_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.Cluster)) - }) - return _c -} - -func (_c *ArgoDB_CreateCluster_Call) Return(cluster *v1alpha1.Cluster, err error) *ArgoDB_CreateCluster_Call { - _c.Call.Return(cluster, err) - return _c -} - -func (_c *ArgoDB_CreateCluster_Call) RunAndReturn(run func(ctx context.Context, c *v1alpha1.Cluster) (*v1alpha1.Cluster, error)) *ArgoDB_CreateCluster_Call { - _c.Call.Return(run) - return _c -} - -// CreateRepoCertificate provides a mock function for the type ArgoDB -func (_mock *ArgoDB) CreateRepoCertificate(ctx context.Context, certificate *v1alpha1.RepositoryCertificateList, upsert bool) (*v1alpha1.RepositoryCertificateList, error) { - ret := _mock.Called(ctx, certificate, upsert) - - if len(ret) == 0 { - panic("no return value specified for CreateRepoCertificate") - } - - var r0 *v1alpha1.RepositoryCertificateList - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepositoryCertificateList, bool) (*v1alpha1.RepositoryCertificateList, error)); ok { - return returnFunc(ctx, certificate, upsert) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepositoryCertificateList, bool) *v1alpha1.RepositoryCertificateList); ok { - r0 = returnFunc(ctx, certificate, upsert) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.RepositoryCertificateList) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.RepositoryCertificateList, bool) error); ok { - r1 = returnFunc(ctx, certificate, upsert) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_CreateRepoCertificate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateRepoCertificate' -type ArgoDB_CreateRepoCertificate_Call struct { - *mock.Call -} - -// CreateRepoCertificate is a helper method to define mock.On call -// - ctx -// - certificate -// - upsert -func (_e *ArgoDB_Expecter) CreateRepoCertificate(ctx interface{}, certificate interface{}, upsert interface{}) *ArgoDB_CreateRepoCertificate_Call { - return &ArgoDB_CreateRepoCertificate_Call{Call: _e.mock.On("CreateRepoCertificate", ctx, certificate, upsert)} -} - -func (_c *ArgoDB_CreateRepoCertificate_Call) Run(run func(ctx context.Context, certificate *v1alpha1.RepositoryCertificateList, upsert bool)) *ArgoDB_CreateRepoCertificate_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.RepositoryCertificateList), args[2].(bool)) - }) - return _c -} - -func (_c *ArgoDB_CreateRepoCertificate_Call) Return(repositoryCertificateList *v1alpha1.RepositoryCertificateList, err error) *ArgoDB_CreateRepoCertificate_Call { - _c.Call.Return(repositoryCertificateList, err) - return _c -} - -func (_c *ArgoDB_CreateRepoCertificate_Call) RunAndReturn(run func(ctx context.Context, certificate *v1alpha1.RepositoryCertificateList, upsert bool) (*v1alpha1.RepositoryCertificateList, error)) *ArgoDB_CreateRepoCertificate_Call { - _c.Call.Return(run) - return _c -} - -// CreateRepository provides a mock function for the type ArgoDB -func (_mock *ArgoDB) CreateRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { - ret := _mock.Called(ctx, r) - - if len(ret) == 0 { - panic("no return value specified for CreateRepository") - } - - var r0 *v1alpha1.Repository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) (*v1alpha1.Repository, error)); ok { - return returnFunc(ctx, r) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) *v1alpha1.Repository); ok { - r0 = returnFunc(ctx, r) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Repository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.Repository) error); ok { - r1 = returnFunc(ctx, r) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_CreateRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateRepository' -type ArgoDB_CreateRepository_Call struct { - *mock.Call -} - -// CreateRepository is a helper method to define mock.On call -// - ctx -// - r -func (_e *ArgoDB_Expecter) CreateRepository(ctx interface{}, r interface{}) *ArgoDB_CreateRepository_Call { - return &ArgoDB_CreateRepository_Call{Call: _e.mock.On("CreateRepository", ctx, r)} -} - -func (_c *ArgoDB_CreateRepository_Call) Run(run func(ctx context.Context, r *v1alpha1.Repository)) *ArgoDB_CreateRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.Repository)) - }) - return _c -} - -func (_c *ArgoDB_CreateRepository_Call) Return(repository *v1alpha1.Repository, err error) *ArgoDB_CreateRepository_Call { - _c.Call.Return(repository, err) - return _c -} - -func (_c *ArgoDB_CreateRepository_Call) RunAndReturn(run func(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error)) *ArgoDB_CreateRepository_Call { - _c.Call.Return(run) - return _c -} - -// CreateRepositoryCredentials provides a mock function for the type ArgoDB -func (_mock *ArgoDB) CreateRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { - ret := _mock.Called(ctx, r) - - if len(ret) == 0 { - panic("no return value specified for CreateRepositoryCredentials") - } - - var r0 *v1alpha1.RepoCreds - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)); ok { - return returnFunc(ctx, r) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) *v1alpha1.RepoCreds); ok { - r0 = returnFunc(ctx, r) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.RepoCreds) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.RepoCreds) error); ok { - r1 = returnFunc(ctx, r) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_CreateRepositoryCredentials_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateRepositoryCredentials' -type ArgoDB_CreateRepositoryCredentials_Call struct { - *mock.Call -} - -// CreateRepositoryCredentials is a helper method to define mock.On call -// - ctx -// - r -func (_e *ArgoDB_Expecter) CreateRepositoryCredentials(ctx interface{}, r interface{}) *ArgoDB_CreateRepositoryCredentials_Call { - return &ArgoDB_CreateRepositoryCredentials_Call{Call: _e.mock.On("CreateRepositoryCredentials", ctx, r)} -} - -func (_c *ArgoDB_CreateRepositoryCredentials_Call) Run(run func(ctx context.Context, r *v1alpha1.RepoCreds)) *ArgoDB_CreateRepositoryCredentials_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.RepoCreds)) - }) - return _c -} - -func (_c *ArgoDB_CreateRepositoryCredentials_Call) Return(repoCreds *v1alpha1.RepoCreds, err error) *ArgoDB_CreateRepositoryCredentials_Call { - _c.Call.Return(repoCreds, err) - return _c -} - -func (_c *ArgoDB_CreateRepositoryCredentials_Call) RunAndReturn(run func(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)) *ArgoDB_CreateRepositoryCredentials_Call { - _c.Call.Return(run) - return _c -} - -// CreateWriteRepository provides a mock function for the type ArgoDB -func (_mock *ArgoDB) CreateWriteRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { - ret := _mock.Called(ctx, r) - - if len(ret) == 0 { - panic("no return value specified for CreateWriteRepository") - } - - var r0 *v1alpha1.Repository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) (*v1alpha1.Repository, error)); ok { - return returnFunc(ctx, r) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) *v1alpha1.Repository); ok { - r0 = returnFunc(ctx, r) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Repository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.Repository) error); ok { - r1 = returnFunc(ctx, r) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_CreateWriteRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateWriteRepository' -type ArgoDB_CreateWriteRepository_Call struct { - *mock.Call -} - -// CreateWriteRepository is a helper method to define mock.On call -// - ctx -// - r -func (_e *ArgoDB_Expecter) CreateWriteRepository(ctx interface{}, r interface{}) *ArgoDB_CreateWriteRepository_Call { - return &ArgoDB_CreateWriteRepository_Call{Call: _e.mock.On("CreateWriteRepository", ctx, r)} -} - -func (_c *ArgoDB_CreateWriteRepository_Call) Run(run func(ctx context.Context, r *v1alpha1.Repository)) *ArgoDB_CreateWriteRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.Repository)) - }) - return _c -} - -func (_c *ArgoDB_CreateWriteRepository_Call) Return(repository *v1alpha1.Repository, err error) *ArgoDB_CreateWriteRepository_Call { - _c.Call.Return(repository, err) - return _c -} - -func (_c *ArgoDB_CreateWriteRepository_Call) RunAndReturn(run func(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error)) *ArgoDB_CreateWriteRepository_Call { - _c.Call.Return(run) - return _c -} - -// CreateWriteRepositoryCredentials provides a mock function for the type ArgoDB -func (_mock *ArgoDB) CreateWriteRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { - ret := _mock.Called(ctx, r) - - if len(ret) == 0 { - panic("no return value specified for CreateWriteRepositoryCredentials") - } - - var r0 *v1alpha1.RepoCreds - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)); ok { - return returnFunc(ctx, r) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) *v1alpha1.RepoCreds); ok { - r0 = returnFunc(ctx, r) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.RepoCreds) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.RepoCreds) error); ok { - r1 = returnFunc(ctx, r) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_CreateWriteRepositoryCredentials_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateWriteRepositoryCredentials' -type ArgoDB_CreateWriteRepositoryCredentials_Call struct { - *mock.Call -} - -// CreateWriteRepositoryCredentials is a helper method to define mock.On call -// - ctx -// - r -func (_e *ArgoDB_Expecter) CreateWriteRepositoryCredentials(ctx interface{}, r interface{}) *ArgoDB_CreateWriteRepositoryCredentials_Call { - return &ArgoDB_CreateWriteRepositoryCredentials_Call{Call: _e.mock.On("CreateWriteRepositoryCredentials", ctx, r)} -} - -func (_c *ArgoDB_CreateWriteRepositoryCredentials_Call) Run(run func(ctx context.Context, r *v1alpha1.RepoCreds)) *ArgoDB_CreateWriteRepositoryCredentials_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.RepoCreds)) - }) - return _c -} - -func (_c *ArgoDB_CreateWriteRepositoryCredentials_Call) Return(repoCreds *v1alpha1.RepoCreds, err error) *ArgoDB_CreateWriteRepositoryCredentials_Call { - _c.Call.Return(repoCreds, err) - return _c -} - -func (_c *ArgoDB_CreateWriteRepositoryCredentials_Call) RunAndReturn(run func(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)) *ArgoDB_CreateWriteRepositoryCredentials_Call { - _c.Call.Return(run) - return _c -} - -// DeleteCluster provides a mock function for the type ArgoDB -func (_mock *ArgoDB) DeleteCluster(ctx context.Context, server string) error { - ret := _mock.Called(ctx, server) - - if len(ret) == 0 { - panic("no return value specified for DeleteCluster") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string) error); ok { - r0 = returnFunc(ctx, server) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// ArgoDB_DeleteCluster_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteCluster' -type ArgoDB_DeleteCluster_Call struct { - *mock.Call -} - -// DeleteCluster is a helper method to define mock.On call -// - ctx -// - server -func (_e *ArgoDB_Expecter) DeleteCluster(ctx interface{}, server interface{}) *ArgoDB_DeleteCluster_Call { - return &ArgoDB_DeleteCluster_Call{Call: _e.mock.On("DeleteCluster", ctx, server)} -} - -func (_c *ArgoDB_DeleteCluster_Call) Run(run func(ctx context.Context, server string)) *ArgoDB_DeleteCluster_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) - }) - return _c -} - -func (_c *ArgoDB_DeleteCluster_Call) Return(err error) *ArgoDB_DeleteCluster_Call { - _c.Call.Return(err) - return _c -} - -func (_c *ArgoDB_DeleteCluster_Call) RunAndReturn(run func(ctx context.Context, server string) error) *ArgoDB_DeleteCluster_Call { - _c.Call.Return(run) - return _c -} - -// DeleteGPGPublicKey provides a mock function for the type ArgoDB -func (_mock *ArgoDB) DeleteGPGPublicKey(ctx context.Context, keyID string) error { - ret := _mock.Called(ctx, keyID) - - if len(ret) == 0 { - panic("no return value specified for DeleteGPGPublicKey") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string) error); ok { - r0 = returnFunc(ctx, keyID) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// ArgoDB_DeleteGPGPublicKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteGPGPublicKey' -type ArgoDB_DeleteGPGPublicKey_Call struct { - *mock.Call -} - -// DeleteGPGPublicKey is a helper method to define mock.On call -// - ctx -// - keyID -func (_e *ArgoDB_Expecter) DeleteGPGPublicKey(ctx interface{}, keyID interface{}) *ArgoDB_DeleteGPGPublicKey_Call { - return &ArgoDB_DeleteGPGPublicKey_Call{Call: _e.mock.On("DeleteGPGPublicKey", ctx, keyID)} -} - -func (_c *ArgoDB_DeleteGPGPublicKey_Call) Run(run func(ctx context.Context, keyID string)) *ArgoDB_DeleteGPGPublicKey_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) - }) - return _c -} - -func (_c *ArgoDB_DeleteGPGPublicKey_Call) Return(err error) *ArgoDB_DeleteGPGPublicKey_Call { - _c.Call.Return(err) - return _c -} - -func (_c *ArgoDB_DeleteGPGPublicKey_Call) RunAndReturn(run func(ctx context.Context, keyID string) error) *ArgoDB_DeleteGPGPublicKey_Call { - _c.Call.Return(run) - return _c -} - -// DeleteRepository provides a mock function for the type ArgoDB -func (_mock *ArgoDB) DeleteRepository(ctx context.Context, name string, project string) error { - ret := _mock.Called(ctx, name, project) - - if len(ret) == 0 { - panic("no return value specified for DeleteRepository") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) error); ok { - r0 = returnFunc(ctx, name, project) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// ArgoDB_DeleteRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteRepository' -type ArgoDB_DeleteRepository_Call struct { - *mock.Call -} - -// DeleteRepository is a helper method to define mock.On call -// - ctx -// - name -// - project -func (_e *ArgoDB_Expecter) DeleteRepository(ctx interface{}, name interface{}, project interface{}) *ArgoDB_DeleteRepository_Call { - return &ArgoDB_DeleteRepository_Call{Call: _e.mock.On("DeleteRepository", ctx, name, project)} -} - -func (_c *ArgoDB_DeleteRepository_Call) Run(run func(ctx context.Context, name string, project string)) *ArgoDB_DeleteRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(string)) - }) - return _c -} - -func (_c *ArgoDB_DeleteRepository_Call) Return(err error) *ArgoDB_DeleteRepository_Call { - _c.Call.Return(err) - return _c -} - -func (_c *ArgoDB_DeleteRepository_Call) RunAndReturn(run func(ctx context.Context, name string, project string) error) *ArgoDB_DeleteRepository_Call { - _c.Call.Return(run) - return _c -} - -// DeleteRepositoryCredentials provides a mock function for the type ArgoDB -func (_mock *ArgoDB) DeleteRepositoryCredentials(ctx context.Context, name string) error { - ret := _mock.Called(ctx, name) - - if len(ret) == 0 { - panic("no return value specified for DeleteRepositoryCredentials") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string) error); ok { - r0 = returnFunc(ctx, name) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// ArgoDB_DeleteRepositoryCredentials_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteRepositoryCredentials' -type ArgoDB_DeleteRepositoryCredentials_Call struct { - *mock.Call -} - -// DeleteRepositoryCredentials is a helper method to define mock.On call -// - ctx -// - name -func (_e *ArgoDB_Expecter) DeleteRepositoryCredentials(ctx interface{}, name interface{}) *ArgoDB_DeleteRepositoryCredentials_Call { - return &ArgoDB_DeleteRepositoryCredentials_Call{Call: _e.mock.On("DeleteRepositoryCredentials", ctx, name)} -} - -func (_c *ArgoDB_DeleteRepositoryCredentials_Call) Run(run func(ctx context.Context, name string)) *ArgoDB_DeleteRepositoryCredentials_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) - }) - return _c -} - -func (_c *ArgoDB_DeleteRepositoryCredentials_Call) Return(err error) *ArgoDB_DeleteRepositoryCredentials_Call { - _c.Call.Return(err) - return _c -} - -func (_c *ArgoDB_DeleteRepositoryCredentials_Call) RunAndReturn(run func(ctx context.Context, name string) error) *ArgoDB_DeleteRepositoryCredentials_Call { - _c.Call.Return(run) - return _c -} - -// DeleteWriteRepository provides a mock function for the type ArgoDB -func (_mock *ArgoDB) DeleteWriteRepository(ctx context.Context, name string, project string) error { - ret := _mock.Called(ctx, name, project) - - if len(ret) == 0 { - panic("no return value specified for DeleteWriteRepository") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) error); ok { - r0 = returnFunc(ctx, name, project) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// ArgoDB_DeleteWriteRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteWriteRepository' -type ArgoDB_DeleteWriteRepository_Call struct { - *mock.Call -} - -// DeleteWriteRepository is a helper method to define mock.On call -// - ctx -// - name -// - project -func (_e *ArgoDB_Expecter) DeleteWriteRepository(ctx interface{}, name interface{}, project interface{}) *ArgoDB_DeleteWriteRepository_Call { - return &ArgoDB_DeleteWriteRepository_Call{Call: _e.mock.On("DeleteWriteRepository", ctx, name, project)} -} - -func (_c *ArgoDB_DeleteWriteRepository_Call) Run(run func(ctx context.Context, name string, project string)) *ArgoDB_DeleteWriteRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(string)) - }) - return _c -} - -func (_c *ArgoDB_DeleteWriteRepository_Call) Return(err error) *ArgoDB_DeleteWriteRepository_Call { - _c.Call.Return(err) - return _c -} - -func (_c *ArgoDB_DeleteWriteRepository_Call) RunAndReturn(run func(ctx context.Context, name string, project string) error) *ArgoDB_DeleteWriteRepository_Call { - _c.Call.Return(run) - return _c -} - -// DeleteWriteRepositoryCredentials provides a mock function for the type ArgoDB -func (_mock *ArgoDB) DeleteWriteRepositoryCredentials(ctx context.Context, name string) error { - ret := _mock.Called(ctx, name) - - if len(ret) == 0 { - panic("no return value specified for DeleteWriteRepositoryCredentials") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string) error); ok { - r0 = returnFunc(ctx, name) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// ArgoDB_DeleteWriteRepositoryCredentials_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteWriteRepositoryCredentials' -type ArgoDB_DeleteWriteRepositoryCredentials_Call struct { - *mock.Call -} - -// DeleteWriteRepositoryCredentials is a helper method to define mock.On call -// - ctx -// - name -func (_e *ArgoDB_Expecter) DeleteWriteRepositoryCredentials(ctx interface{}, name interface{}) *ArgoDB_DeleteWriteRepositoryCredentials_Call { - return &ArgoDB_DeleteWriteRepositoryCredentials_Call{Call: _e.mock.On("DeleteWriteRepositoryCredentials", ctx, name)} -} - -func (_c *ArgoDB_DeleteWriteRepositoryCredentials_Call) Run(run func(ctx context.Context, name string)) *ArgoDB_DeleteWriteRepositoryCredentials_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) - }) - return _c -} - -func (_c *ArgoDB_DeleteWriteRepositoryCredentials_Call) Return(err error) *ArgoDB_DeleteWriteRepositoryCredentials_Call { - _c.Call.Return(err) - return _c -} - -func (_c *ArgoDB_DeleteWriteRepositoryCredentials_Call) RunAndReturn(run func(ctx context.Context, name string) error) *ArgoDB_DeleteWriteRepositoryCredentials_Call { - _c.Call.Return(run) - return _c -} - -// GetAllHelmRepositoryCredentials provides a mock function for the type ArgoDB -func (_mock *ArgoDB) GetAllHelmRepositoryCredentials(ctx context.Context) ([]*v1alpha1.RepoCreds, error) { - ret := _mock.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for GetAllHelmRepositoryCredentials") - } - - var r0 []*v1alpha1.RepoCreds - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context) ([]*v1alpha1.RepoCreds, error)); ok { - return returnFunc(ctx) - } - if returnFunc, ok := ret.Get(0).(func(context.Context) []*v1alpha1.RepoCreds); ok { - r0 = returnFunc(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*v1alpha1.RepoCreds) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = returnFunc(ctx) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_GetAllHelmRepositoryCredentials_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAllHelmRepositoryCredentials' -type ArgoDB_GetAllHelmRepositoryCredentials_Call struct { - *mock.Call -} - -// GetAllHelmRepositoryCredentials is a helper method to define mock.On call -// - ctx -func (_e *ArgoDB_Expecter) GetAllHelmRepositoryCredentials(ctx interface{}) *ArgoDB_GetAllHelmRepositoryCredentials_Call { - return &ArgoDB_GetAllHelmRepositoryCredentials_Call{Call: _e.mock.On("GetAllHelmRepositoryCredentials", ctx)} -} - -func (_c *ArgoDB_GetAllHelmRepositoryCredentials_Call) Run(run func(ctx context.Context)) *ArgoDB_GetAllHelmRepositoryCredentials_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *ArgoDB_GetAllHelmRepositoryCredentials_Call) Return(repoCredss []*v1alpha1.RepoCreds, err error) *ArgoDB_GetAllHelmRepositoryCredentials_Call { - _c.Call.Return(repoCredss, err) - return _c -} - -func (_c *ArgoDB_GetAllHelmRepositoryCredentials_Call) RunAndReturn(run func(ctx context.Context) ([]*v1alpha1.RepoCreds, error)) *ArgoDB_GetAllHelmRepositoryCredentials_Call { - _c.Call.Return(run) - return _c -} - -// GetApplicationControllerReplicas provides a mock function for the type ArgoDB -func (_mock *ArgoDB) GetApplicationControllerReplicas() int { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for GetApplicationControllerReplicas") - } - - var r0 int - if returnFunc, ok := ret.Get(0).(func() int); ok { - r0 = returnFunc() - } else { - r0 = ret.Get(0).(int) - } - return r0 -} - -// ArgoDB_GetApplicationControllerReplicas_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetApplicationControllerReplicas' -type ArgoDB_GetApplicationControllerReplicas_Call struct { - *mock.Call -} - -// GetApplicationControllerReplicas is a helper method to define mock.On call -func (_e *ArgoDB_Expecter) GetApplicationControllerReplicas() *ArgoDB_GetApplicationControllerReplicas_Call { - return &ArgoDB_GetApplicationControllerReplicas_Call{Call: _e.mock.On("GetApplicationControllerReplicas")} -} - -func (_c *ArgoDB_GetApplicationControllerReplicas_Call) Run(run func()) *ArgoDB_GetApplicationControllerReplicas_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *ArgoDB_GetApplicationControllerReplicas_Call) Return(n int) *ArgoDB_GetApplicationControllerReplicas_Call { - _c.Call.Return(n) - return _c -} - -func (_c *ArgoDB_GetApplicationControllerReplicas_Call) RunAndReturn(run func() int) *ArgoDB_GetApplicationControllerReplicas_Call { - _c.Call.Return(run) - return _c -} - -// GetCluster provides a mock function for the type ArgoDB -func (_mock *ArgoDB) GetCluster(ctx context.Context, server string) (*v1alpha1.Cluster, error) { - ret := _mock.Called(ctx, server) - - if len(ret) == 0 { - panic("no return value specified for GetCluster") - } - - var r0 *v1alpha1.Cluster - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*v1alpha1.Cluster, error)); ok { - return returnFunc(ctx, server) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.Cluster); ok { - r0 = returnFunc(ctx, server) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Cluster) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = returnFunc(ctx, server) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_GetCluster_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCluster' -type ArgoDB_GetCluster_Call struct { - *mock.Call -} - -// GetCluster is a helper method to define mock.On call -// - ctx -// - server -func (_e *ArgoDB_Expecter) GetCluster(ctx interface{}, server interface{}) *ArgoDB_GetCluster_Call { - return &ArgoDB_GetCluster_Call{Call: _e.mock.On("GetCluster", ctx, server)} -} - -func (_c *ArgoDB_GetCluster_Call) Run(run func(ctx context.Context, server string)) *ArgoDB_GetCluster_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) - }) - return _c -} - -func (_c *ArgoDB_GetCluster_Call) Return(cluster *v1alpha1.Cluster, err error) *ArgoDB_GetCluster_Call { - _c.Call.Return(cluster, err) - return _c -} - -func (_c *ArgoDB_GetCluster_Call) RunAndReturn(run func(ctx context.Context, server string) (*v1alpha1.Cluster, error)) *ArgoDB_GetCluster_Call { - _c.Call.Return(run) - return _c -} - -// GetClusterServersByName provides a mock function for the type ArgoDB -func (_mock *ArgoDB) GetClusterServersByName(ctx context.Context, name string) ([]string, error) { - ret := _mock.Called(ctx, name) - - if len(ret) == 0 { - panic("no return value specified for GetClusterServersByName") - } - - var r0 []string - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string) ([]string, error)); ok { - return returnFunc(ctx, name) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string) []string); ok { - r0 = returnFunc(ctx, name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = returnFunc(ctx, name) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_GetClusterServersByName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetClusterServersByName' -type ArgoDB_GetClusterServersByName_Call struct { - *mock.Call -} - -// GetClusterServersByName is a helper method to define mock.On call -// - ctx -// - name -func (_e *ArgoDB_Expecter) GetClusterServersByName(ctx interface{}, name interface{}) *ArgoDB_GetClusterServersByName_Call { - return &ArgoDB_GetClusterServersByName_Call{Call: _e.mock.On("GetClusterServersByName", ctx, name)} -} - -func (_c *ArgoDB_GetClusterServersByName_Call) Run(run func(ctx context.Context, name string)) *ArgoDB_GetClusterServersByName_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) - }) - return _c -} - -func (_c *ArgoDB_GetClusterServersByName_Call) Return(strings []string, err error) *ArgoDB_GetClusterServersByName_Call { - _c.Call.Return(strings, err) - return _c -} - -func (_c *ArgoDB_GetClusterServersByName_Call) RunAndReturn(run func(ctx context.Context, name string) ([]string, error)) *ArgoDB_GetClusterServersByName_Call { - _c.Call.Return(run) - return _c -} - -// GetProjectClusters provides a mock function for the type ArgoDB -func (_mock *ArgoDB) GetProjectClusters(ctx context.Context, project string) ([]*v1alpha1.Cluster, error) { - ret := _mock.Called(ctx, project) - - if len(ret) == 0 { - panic("no return value specified for GetProjectClusters") - } - - var r0 []*v1alpha1.Cluster - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string) ([]*v1alpha1.Cluster, error)); ok { - return returnFunc(ctx, project) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string) []*v1alpha1.Cluster); ok { - r0 = returnFunc(ctx, project) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*v1alpha1.Cluster) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = returnFunc(ctx, project) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_GetProjectClusters_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetProjectClusters' -type ArgoDB_GetProjectClusters_Call struct { - *mock.Call -} - -// GetProjectClusters is a helper method to define mock.On call -// - ctx -// - project -func (_e *ArgoDB_Expecter) GetProjectClusters(ctx interface{}, project interface{}) *ArgoDB_GetProjectClusters_Call { - return &ArgoDB_GetProjectClusters_Call{Call: _e.mock.On("GetProjectClusters", ctx, project)} -} - -func (_c *ArgoDB_GetProjectClusters_Call) Run(run func(ctx context.Context, project string)) *ArgoDB_GetProjectClusters_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) - }) - return _c -} - -func (_c *ArgoDB_GetProjectClusters_Call) Return(clusters []*v1alpha1.Cluster, err error) *ArgoDB_GetProjectClusters_Call { - _c.Call.Return(clusters, err) - return _c -} - -func (_c *ArgoDB_GetProjectClusters_Call) RunAndReturn(run func(ctx context.Context, project string) ([]*v1alpha1.Cluster, error)) *ArgoDB_GetProjectClusters_Call { - _c.Call.Return(run) - return _c -} - -// GetProjectRepositories provides a mock function for the type ArgoDB -func (_mock *ArgoDB) GetProjectRepositories(project string) ([]*v1alpha1.Repository, error) { - ret := _mock.Called(project) - - if len(ret) == 0 { - panic("no return value specified for GetProjectRepositories") - } - - var r0 []*v1alpha1.Repository - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) ([]*v1alpha1.Repository, error)); ok { - return returnFunc(project) - } - if returnFunc, ok := ret.Get(0).(func(string) []*v1alpha1.Repository); ok { - r0 = returnFunc(project) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*v1alpha1.Repository) - } - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(project) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_GetProjectRepositories_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetProjectRepositories' -type ArgoDB_GetProjectRepositories_Call struct { - *mock.Call -} - -// GetProjectRepositories is a helper method to define mock.On call -// - project -func (_e *ArgoDB_Expecter) GetProjectRepositories(project interface{}) *ArgoDB_GetProjectRepositories_Call { - return &ArgoDB_GetProjectRepositories_Call{Call: _e.mock.On("GetProjectRepositories", project)} -} - -func (_c *ArgoDB_GetProjectRepositories_Call) Run(run func(project string)) *ArgoDB_GetProjectRepositories_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *ArgoDB_GetProjectRepositories_Call) Return(repositorys []*v1alpha1.Repository, err error) *ArgoDB_GetProjectRepositories_Call { - _c.Call.Return(repositorys, err) - return _c -} - -func (_c *ArgoDB_GetProjectRepositories_Call) RunAndReturn(run func(project string) ([]*v1alpha1.Repository, error)) *ArgoDB_GetProjectRepositories_Call { - _c.Call.Return(run) - return _c -} - -// GetProjectWriteRepositories provides a mock function for the type ArgoDB -func (_mock *ArgoDB) GetProjectWriteRepositories(project string) ([]*v1alpha1.Repository, error) { - ret := _mock.Called(project) - - if len(ret) == 0 { - panic("no return value specified for GetProjectWriteRepositories") - } - - var r0 []*v1alpha1.Repository - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) ([]*v1alpha1.Repository, error)); ok { - return returnFunc(project) - } - if returnFunc, ok := ret.Get(0).(func(string) []*v1alpha1.Repository); ok { - r0 = returnFunc(project) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*v1alpha1.Repository) - } - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(project) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_GetProjectWriteRepositories_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetProjectWriteRepositories' -type ArgoDB_GetProjectWriteRepositories_Call struct { - *mock.Call -} - -// GetProjectWriteRepositories is a helper method to define mock.On call -// - project -func (_e *ArgoDB_Expecter) GetProjectWriteRepositories(project interface{}) *ArgoDB_GetProjectWriteRepositories_Call { - return &ArgoDB_GetProjectWriteRepositories_Call{Call: _e.mock.On("GetProjectWriteRepositories", project)} -} - -func (_c *ArgoDB_GetProjectWriteRepositories_Call) Run(run func(project string)) *ArgoDB_GetProjectWriteRepositories_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *ArgoDB_GetProjectWriteRepositories_Call) Return(repositorys []*v1alpha1.Repository, err error) *ArgoDB_GetProjectWriteRepositories_Call { - _c.Call.Return(repositorys, err) - return _c -} - -func (_c *ArgoDB_GetProjectWriteRepositories_Call) RunAndReturn(run func(project string) ([]*v1alpha1.Repository, error)) *ArgoDB_GetProjectWriteRepositories_Call { - _c.Call.Return(run) - return _c -} - -// GetRepository provides a mock function for the type ArgoDB -func (_mock *ArgoDB) GetRepository(ctx context.Context, url string, project string) (*v1alpha1.Repository, error) { - ret := _mock.Called(ctx, url, project) - - if len(ret) == 0 { - panic("no return value specified for GetRepository") - } - - var r0 *v1alpha1.Repository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) (*v1alpha1.Repository, error)); ok { - return returnFunc(ctx, url, project) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) *v1alpha1.Repository); ok { - r0 = returnFunc(ctx, url, project) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Repository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string, string) error); ok { - r1 = returnFunc(ctx, url, project) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_GetRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRepository' -type ArgoDB_GetRepository_Call struct { - *mock.Call -} - -// GetRepository is a helper method to define mock.On call -// - ctx -// - url -// - project -func (_e *ArgoDB_Expecter) GetRepository(ctx interface{}, url interface{}, project interface{}) *ArgoDB_GetRepository_Call { - return &ArgoDB_GetRepository_Call{Call: _e.mock.On("GetRepository", ctx, url, project)} -} - -func (_c *ArgoDB_GetRepository_Call) Run(run func(ctx context.Context, url string, project string)) *ArgoDB_GetRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(string)) - }) - return _c -} - -func (_c *ArgoDB_GetRepository_Call) Return(repository *v1alpha1.Repository, err error) *ArgoDB_GetRepository_Call { - _c.Call.Return(repository, err) - return _c -} - -func (_c *ArgoDB_GetRepository_Call) RunAndReturn(run func(ctx context.Context, url string, project string) (*v1alpha1.Repository, error)) *ArgoDB_GetRepository_Call { - _c.Call.Return(run) - return _c -} - -// GetRepositoryCredentials provides a mock function for the type ArgoDB -func (_mock *ArgoDB) GetRepositoryCredentials(ctx context.Context, name string) (*v1alpha1.RepoCreds, error) { - ret := _mock.Called(ctx, name) - - if len(ret) == 0 { - panic("no return value specified for GetRepositoryCredentials") - } - - var r0 *v1alpha1.RepoCreds - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*v1alpha1.RepoCreds, error)); ok { - return returnFunc(ctx, name) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.RepoCreds); ok { - r0 = returnFunc(ctx, name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.RepoCreds) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = returnFunc(ctx, name) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_GetRepositoryCredentials_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRepositoryCredentials' -type ArgoDB_GetRepositoryCredentials_Call struct { - *mock.Call -} - -// GetRepositoryCredentials is a helper method to define mock.On call -// - ctx -// - name -func (_e *ArgoDB_Expecter) GetRepositoryCredentials(ctx interface{}, name interface{}) *ArgoDB_GetRepositoryCredentials_Call { - return &ArgoDB_GetRepositoryCredentials_Call{Call: _e.mock.On("GetRepositoryCredentials", ctx, name)} -} - -func (_c *ArgoDB_GetRepositoryCredentials_Call) Run(run func(ctx context.Context, name string)) *ArgoDB_GetRepositoryCredentials_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) - }) - return _c -} - -func (_c *ArgoDB_GetRepositoryCredentials_Call) Return(repoCreds *v1alpha1.RepoCreds, err error) *ArgoDB_GetRepositoryCredentials_Call { - _c.Call.Return(repoCreds, err) - return _c -} - -func (_c *ArgoDB_GetRepositoryCredentials_Call) RunAndReturn(run func(ctx context.Context, name string) (*v1alpha1.RepoCreds, error)) *ArgoDB_GetRepositoryCredentials_Call { - _c.Call.Return(run) - return _c -} - -// GetWriteRepository provides a mock function for the type ArgoDB -func (_mock *ArgoDB) GetWriteRepository(ctx context.Context, url string, project string) (*v1alpha1.Repository, error) { - ret := _mock.Called(ctx, url, project) - - if len(ret) == 0 { - panic("no return value specified for GetWriteRepository") - } - - var r0 *v1alpha1.Repository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) (*v1alpha1.Repository, error)); ok { - return returnFunc(ctx, url, project) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) *v1alpha1.Repository); ok { - r0 = returnFunc(ctx, url, project) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Repository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string, string) error); ok { - r1 = returnFunc(ctx, url, project) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_GetWriteRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetWriteRepository' -type ArgoDB_GetWriteRepository_Call struct { - *mock.Call -} - -// GetWriteRepository is a helper method to define mock.On call -// - ctx -// - url -// - project -func (_e *ArgoDB_Expecter) GetWriteRepository(ctx interface{}, url interface{}, project interface{}) *ArgoDB_GetWriteRepository_Call { - return &ArgoDB_GetWriteRepository_Call{Call: _e.mock.On("GetWriteRepository", ctx, url, project)} -} - -func (_c *ArgoDB_GetWriteRepository_Call) Run(run func(ctx context.Context, url string, project string)) *ArgoDB_GetWriteRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(string)) - }) - return _c -} - -func (_c *ArgoDB_GetWriteRepository_Call) Return(repository *v1alpha1.Repository, err error) *ArgoDB_GetWriteRepository_Call { - _c.Call.Return(repository, err) - return _c -} - -func (_c *ArgoDB_GetWriteRepository_Call) RunAndReturn(run func(ctx context.Context, url string, project string) (*v1alpha1.Repository, error)) *ArgoDB_GetWriteRepository_Call { - _c.Call.Return(run) - return _c -} - -// GetWriteRepositoryCredentials provides a mock function for the type ArgoDB -func (_mock *ArgoDB) GetWriteRepositoryCredentials(ctx context.Context, name string) (*v1alpha1.RepoCreds, error) { - ret := _mock.Called(ctx, name) - - if len(ret) == 0 { - panic("no return value specified for GetWriteRepositoryCredentials") - } - - var r0 *v1alpha1.RepoCreds - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*v1alpha1.RepoCreds, error)); ok { - return returnFunc(ctx, name) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.RepoCreds); ok { - r0 = returnFunc(ctx, name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.RepoCreds) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = returnFunc(ctx, name) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_GetWriteRepositoryCredentials_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetWriteRepositoryCredentials' -type ArgoDB_GetWriteRepositoryCredentials_Call struct { - *mock.Call -} - -// GetWriteRepositoryCredentials is a helper method to define mock.On call -// - ctx -// - name -func (_e *ArgoDB_Expecter) GetWriteRepositoryCredentials(ctx interface{}, name interface{}) *ArgoDB_GetWriteRepositoryCredentials_Call { - return &ArgoDB_GetWriteRepositoryCredentials_Call{Call: _e.mock.On("GetWriteRepositoryCredentials", ctx, name)} -} - -func (_c *ArgoDB_GetWriteRepositoryCredentials_Call) Run(run func(ctx context.Context, name string)) *ArgoDB_GetWriteRepositoryCredentials_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) - }) - return _c -} - -func (_c *ArgoDB_GetWriteRepositoryCredentials_Call) Return(repoCreds *v1alpha1.RepoCreds, err error) *ArgoDB_GetWriteRepositoryCredentials_Call { - _c.Call.Return(repoCreds, err) - return _c -} - -func (_c *ArgoDB_GetWriteRepositoryCredentials_Call) RunAndReturn(run func(ctx context.Context, name string) (*v1alpha1.RepoCreds, error)) *ArgoDB_GetWriteRepositoryCredentials_Call { - _c.Call.Return(run) - return _c -} - -// ListClusters provides a mock function for the type ArgoDB -func (_mock *ArgoDB) ListClusters(ctx context.Context) (*v1alpha1.ClusterList, error) { - ret := _mock.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for ListClusters") - } - - var r0 *v1alpha1.ClusterList - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context) (*v1alpha1.ClusterList, error)); ok { - return returnFunc(ctx) - } - if returnFunc, ok := ret.Get(0).(func(context.Context) *v1alpha1.ClusterList); ok { - r0 = returnFunc(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.ClusterList) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = returnFunc(ctx) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_ListClusters_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListClusters' -type ArgoDB_ListClusters_Call struct { - *mock.Call -} - -// ListClusters is a helper method to define mock.On call -// - ctx -func (_e *ArgoDB_Expecter) ListClusters(ctx interface{}) *ArgoDB_ListClusters_Call { - return &ArgoDB_ListClusters_Call{Call: _e.mock.On("ListClusters", ctx)} -} - -func (_c *ArgoDB_ListClusters_Call) Run(run func(ctx context.Context)) *ArgoDB_ListClusters_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *ArgoDB_ListClusters_Call) Return(clusterList *v1alpha1.ClusterList, err error) *ArgoDB_ListClusters_Call { - _c.Call.Return(clusterList, err) - return _c -} - -func (_c *ArgoDB_ListClusters_Call) RunAndReturn(run func(ctx context.Context) (*v1alpha1.ClusterList, error)) *ArgoDB_ListClusters_Call { - _c.Call.Return(run) - return _c -} - -// ListConfiguredGPGPublicKeys provides a mock function for the type ArgoDB -func (_mock *ArgoDB) ListConfiguredGPGPublicKeys(ctx context.Context) (map[string]*v1alpha1.GnuPGPublicKey, error) { - ret := _mock.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for ListConfiguredGPGPublicKeys") - } - - var r0 map[string]*v1alpha1.GnuPGPublicKey - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context) (map[string]*v1alpha1.GnuPGPublicKey, error)); ok { - return returnFunc(ctx) - } - if returnFunc, ok := ret.Get(0).(func(context.Context) map[string]*v1alpha1.GnuPGPublicKey); ok { - r0 = returnFunc(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[string]*v1alpha1.GnuPGPublicKey) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = returnFunc(ctx) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_ListConfiguredGPGPublicKeys_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListConfiguredGPGPublicKeys' -type ArgoDB_ListConfiguredGPGPublicKeys_Call struct { - *mock.Call -} - -// ListConfiguredGPGPublicKeys is a helper method to define mock.On call -// - ctx -func (_e *ArgoDB_Expecter) ListConfiguredGPGPublicKeys(ctx interface{}) *ArgoDB_ListConfiguredGPGPublicKeys_Call { - return &ArgoDB_ListConfiguredGPGPublicKeys_Call{Call: _e.mock.On("ListConfiguredGPGPublicKeys", ctx)} -} - -func (_c *ArgoDB_ListConfiguredGPGPublicKeys_Call) Run(run func(ctx context.Context)) *ArgoDB_ListConfiguredGPGPublicKeys_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *ArgoDB_ListConfiguredGPGPublicKeys_Call) Return(stringToGnuPGPublicKey map[string]*v1alpha1.GnuPGPublicKey, err error) *ArgoDB_ListConfiguredGPGPublicKeys_Call { - _c.Call.Return(stringToGnuPGPublicKey, err) - return _c -} - -func (_c *ArgoDB_ListConfiguredGPGPublicKeys_Call) RunAndReturn(run func(ctx context.Context) (map[string]*v1alpha1.GnuPGPublicKey, error)) *ArgoDB_ListConfiguredGPGPublicKeys_Call { - _c.Call.Return(run) - return _c -} - -// ListHelmRepositories provides a mock function for the type ArgoDB -func (_mock *ArgoDB) ListHelmRepositories(ctx context.Context) ([]*v1alpha1.Repository, error) { - ret := _mock.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for ListHelmRepositories") - } - - var r0 []*v1alpha1.Repository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context) ([]*v1alpha1.Repository, error)); ok { - return returnFunc(ctx) - } - if returnFunc, ok := ret.Get(0).(func(context.Context) []*v1alpha1.Repository); ok { - r0 = returnFunc(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*v1alpha1.Repository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = returnFunc(ctx) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_ListHelmRepositories_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListHelmRepositories' -type ArgoDB_ListHelmRepositories_Call struct { - *mock.Call -} - -// ListHelmRepositories is a helper method to define mock.On call -// - ctx -func (_e *ArgoDB_Expecter) ListHelmRepositories(ctx interface{}) *ArgoDB_ListHelmRepositories_Call { - return &ArgoDB_ListHelmRepositories_Call{Call: _e.mock.On("ListHelmRepositories", ctx)} -} - -func (_c *ArgoDB_ListHelmRepositories_Call) Run(run func(ctx context.Context)) *ArgoDB_ListHelmRepositories_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *ArgoDB_ListHelmRepositories_Call) Return(repositorys []*v1alpha1.Repository, err error) *ArgoDB_ListHelmRepositories_Call { - _c.Call.Return(repositorys, err) - return _c -} - -func (_c *ArgoDB_ListHelmRepositories_Call) RunAndReturn(run func(ctx context.Context) ([]*v1alpha1.Repository, error)) *ArgoDB_ListHelmRepositories_Call { - _c.Call.Return(run) - return _c -} - -// ListRepoCertificates provides a mock function for the type ArgoDB -func (_mock *ArgoDB) ListRepoCertificates(ctx context.Context, selector *db.CertificateListSelector) (*v1alpha1.RepositoryCertificateList, error) { - ret := _mock.Called(ctx, selector) - - if len(ret) == 0 { - panic("no return value specified for ListRepoCertificates") - } - - var r0 *v1alpha1.RepositoryCertificateList - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *db.CertificateListSelector) (*v1alpha1.RepositoryCertificateList, error)); ok { - return returnFunc(ctx, selector) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *db.CertificateListSelector) *v1alpha1.RepositoryCertificateList); ok { - r0 = returnFunc(ctx, selector) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.RepositoryCertificateList) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *db.CertificateListSelector) error); ok { - r1 = returnFunc(ctx, selector) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_ListRepoCertificates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListRepoCertificates' -type ArgoDB_ListRepoCertificates_Call struct { - *mock.Call -} - -// ListRepoCertificates is a helper method to define mock.On call -// - ctx -// - selector -func (_e *ArgoDB_Expecter) ListRepoCertificates(ctx interface{}, selector interface{}) *ArgoDB_ListRepoCertificates_Call { - return &ArgoDB_ListRepoCertificates_Call{Call: _e.mock.On("ListRepoCertificates", ctx, selector)} -} - -func (_c *ArgoDB_ListRepoCertificates_Call) Run(run func(ctx context.Context, selector *db.CertificateListSelector)) *ArgoDB_ListRepoCertificates_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*db.CertificateListSelector)) - }) - return _c -} - -func (_c *ArgoDB_ListRepoCertificates_Call) Return(repositoryCertificateList *v1alpha1.RepositoryCertificateList, err error) *ArgoDB_ListRepoCertificates_Call { - _c.Call.Return(repositoryCertificateList, err) - return _c -} - -func (_c *ArgoDB_ListRepoCertificates_Call) RunAndReturn(run func(ctx context.Context, selector *db.CertificateListSelector) (*v1alpha1.RepositoryCertificateList, error)) *ArgoDB_ListRepoCertificates_Call { - _c.Call.Return(run) - return _c -} - -// ListRepositories provides a mock function for the type ArgoDB -func (_mock *ArgoDB) ListRepositories(ctx context.Context) ([]*v1alpha1.Repository, error) { - ret := _mock.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for ListRepositories") - } - - var r0 []*v1alpha1.Repository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context) ([]*v1alpha1.Repository, error)); ok { - return returnFunc(ctx) - } - if returnFunc, ok := ret.Get(0).(func(context.Context) []*v1alpha1.Repository); ok { - r0 = returnFunc(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*v1alpha1.Repository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = returnFunc(ctx) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_ListRepositories_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListRepositories' -type ArgoDB_ListRepositories_Call struct { - *mock.Call -} - -// ListRepositories is a helper method to define mock.On call -// - ctx -func (_e *ArgoDB_Expecter) ListRepositories(ctx interface{}) *ArgoDB_ListRepositories_Call { - return &ArgoDB_ListRepositories_Call{Call: _e.mock.On("ListRepositories", ctx)} -} - -func (_c *ArgoDB_ListRepositories_Call) Run(run func(ctx context.Context)) *ArgoDB_ListRepositories_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *ArgoDB_ListRepositories_Call) Return(repositorys []*v1alpha1.Repository, err error) *ArgoDB_ListRepositories_Call { - _c.Call.Return(repositorys, err) - return _c -} - -func (_c *ArgoDB_ListRepositories_Call) RunAndReturn(run func(ctx context.Context) ([]*v1alpha1.Repository, error)) *ArgoDB_ListRepositories_Call { - _c.Call.Return(run) - return _c -} - -// ListRepositoryCredentials provides a mock function for the type ArgoDB -func (_mock *ArgoDB) ListRepositoryCredentials(ctx context.Context) ([]string, error) { - ret := _mock.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for ListRepositoryCredentials") - } - - var r0 []string - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context) ([]string, error)); ok { - return returnFunc(ctx) - } - if returnFunc, ok := ret.Get(0).(func(context.Context) []string); ok { - r0 = returnFunc(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = returnFunc(ctx) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_ListRepositoryCredentials_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListRepositoryCredentials' -type ArgoDB_ListRepositoryCredentials_Call struct { - *mock.Call -} - -// ListRepositoryCredentials is a helper method to define mock.On call -// - ctx -func (_e *ArgoDB_Expecter) ListRepositoryCredentials(ctx interface{}) *ArgoDB_ListRepositoryCredentials_Call { - return &ArgoDB_ListRepositoryCredentials_Call{Call: _e.mock.On("ListRepositoryCredentials", ctx)} -} - -func (_c *ArgoDB_ListRepositoryCredentials_Call) Run(run func(ctx context.Context)) *ArgoDB_ListRepositoryCredentials_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *ArgoDB_ListRepositoryCredentials_Call) Return(strings []string, err error) *ArgoDB_ListRepositoryCredentials_Call { - _c.Call.Return(strings, err) - return _c -} - -func (_c *ArgoDB_ListRepositoryCredentials_Call) RunAndReturn(run func(ctx context.Context) ([]string, error)) *ArgoDB_ListRepositoryCredentials_Call { - _c.Call.Return(run) - return _c -} - -// ListWriteRepositories provides a mock function for the type ArgoDB -func (_mock *ArgoDB) ListWriteRepositories(ctx context.Context) ([]*v1alpha1.Repository, error) { - ret := _mock.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for ListWriteRepositories") - } - - var r0 []*v1alpha1.Repository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context) ([]*v1alpha1.Repository, error)); ok { - return returnFunc(ctx) - } - if returnFunc, ok := ret.Get(0).(func(context.Context) []*v1alpha1.Repository); ok { - r0 = returnFunc(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*v1alpha1.Repository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = returnFunc(ctx) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_ListWriteRepositories_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListWriteRepositories' -type ArgoDB_ListWriteRepositories_Call struct { - *mock.Call -} - -// ListWriteRepositories is a helper method to define mock.On call -// - ctx -func (_e *ArgoDB_Expecter) ListWriteRepositories(ctx interface{}) *ArgoDB_ListWriteRepositories_Call { - return &ArgoDB_ListWriteRepositories_Call{Call: _e.mock.On("ListWriteRepositories", ctx)} -} - -func (_c *ArgoDB_ListWriteRepositories_Call) Run(run func(ctx context.Context)) *ArgoDB_ListWriteRepositories_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *ArgoDB_ListWriteRepositories_Call) Return(repositorys []*v1alpha1.Repository, err error) *ArgoDB_ListWriteRepositories_Call { - _c.Call.Return(repositorys, err) - return _c -} - -func (_c *ArgoDB_ListWriteRepositories_Call) RunAndReturn(run func(ctx context.Context) ([]*v1alpha1.Repository, error)) *ArgoDB_ListWriteRepositories_Call { - _c.Call.Return(run) - return _c -} - -// ListWriteRepositoryCredentials provides a mock function for the type ArgoDB -func (_mock *ArgoDB) ListWriteRepositoryCredentials(ctx context.Context) ([]string, error) { - ret := _mock.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for ListWriteRepositoryCredentials") - } - - var r0 []string - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context) ([]string, error)); ok { - return returnFunc(ctx) - } - if returnFunc, ok := ret.Get(0).(func(context.Context) []string); ok { - r0 = returnFunc(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = returnFunc(ctx) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_ListWriteRepositoryCredentials_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListWriteRepositoryCredentials' -type ArgoDB_ListWriteRepositoryCredentials_Call struct { - *mock.Call -} - -// ListWriteRepositoryCredentials is a helper method to define mock.On call -// - ctx -func (_e *ArgoDB_Expecter) ListWriteRepositoryCredentials(ctx interface{}) *ArgoDB_ListWriteRepositoryCredentials_Call { - return &ArgoDB_ListWriteRepositoryCredentials_Call{Call: _e.mock.On("ListWriteRepositoryCredentials", ctx)} -} - -func (_c *ArgoDB_ListWriteRepositoryCredentials_Call) Run(run func(ctx context.Context)) *ArgoDB_ListWriteRepositoryCredentials_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *ArgoDB_ListWriteRepositoryCredentials_Call) Return(strings []string, err error) *ArgoDB_ListWriteRepositoryCredentials_Call { - _c.Call.Return(strings, err) - return _c -} - -func (_c *ArgoDB_ListWriteRepositoryCredentials_Call) RunAndReturn(run func(ctx context.Context) ([]string, error)) *ArgoDB_ListWriteRepositoryCredentials_Call { - _c.Call.Return(run) - return _c -} - -// RemoveRepoCertificates provides a mock function for the type ArgoDB -func (_mock *ArgoDB) RemoveRepoCertificates(ctx context.Context, selector *db.CertificateListSelector) (*v1alpha1.RepositoryCertificateList, error) { - ret := _mock.Called(ctx, selector) - - if len(ret) == 0 { - panic("no return value specified for RemoveRepoCertificates") - } - - var r0 *v1alpha1.RepositoryCertificateList - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *db.CertificateListSelector) (*v1alpha1.RepositoryCertificateList, error)); ok { - return returnFunc(ctx, selector) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *db.CertificateListSelector) *v1alpha1.RepositoryCertificateList); ok { - r0 = returnFunc(ctx, selector) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.RepositoryCertificateList) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *db.CertificateListSelector) error); ok { - r1 = returnFunc(ctx, selector) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_RemoveRepoCertificates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveRepoCertificates' -type ArgoDB_RemoveRepoCertificates_Call struct { - *mock.Call -} - -// RemoveRepoCertificates is a helper method to define mock.On call -// - ctx -// - selector -func (_e *ArgoDB_Expecter) RemoveRepoCertificates(ctx interface{}, selector interface{}) *ArgoDB_RemoveRepoCertificates_Call { - return &ArgoDB_RemoveRepoCertificates_Call{Call: _e.mock.On("RemoveRepoCertificates", ctx, selector)} -} - -func (_c *ArgoDB_RemoveRepoCertificates_Call) Run(run func(ctx context.Context, selector *db.CertificateListSelector)) *ArgoDB_RemoveRepoCertificates_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*db.CertificateListSelector)) - }) - return _c -} - -func (_c *ArgoDB_RemoveRepoCertificates_Call) Return(repositoryCertificateList *v1alpha1.RepositoryCertificateList, err error) *ArgoDB_RemoveRepoCertificates_Call { - _c.Call.Return(repositoryCertificateList, err) - return _c -} - -func (_c *ArgoDB_RemoveRepoCertificates_Call) RunAndReturn(run func(ctx context.Context, selector *db.CertificateListSelector) (*v1alpha1.RepositoryCertificateList, error)) *ArgoDB_RemoveRepoCertificates_Call { - _c.Call.Return(run) - return _c -} - -// RepositoryExists provides a mock function for the type ArgoDB -func (_mock *ArgoDB) RepositoryExists(ctx context.Context, repoURL string, project string) (bool, error) { - ret := _mock.Called(ctx, repoURL, project) - - if len(ret) == 0 { - panic("no return value specified for RepositoryExists") - } - - var r0 bool - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) (bool, error)); ok { - return returnFunc(ctx, repoURL, project) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) bool); ok { - r0 = returnFunc(ctx, repoURL, project) - } else { - r0 = ret.Get(0).(bool) - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string, string) error); ok { - r1 = returnFunc(ctx, repoURL, project) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_RepositoryExists_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RepositoryExists' -type ArgoDB_RepositoryExists_Call struct { - *mock.Call -} - -// RepositoryExists is a helper method to define mock.On call -// - ctx -// - repoURL -// - project -func (_e *ArgoDB_Expecter) RepositoryExists(ctx interface{}, repoURL interface{}, project interface{}) *ArgoDB_RepositoryExists_Call { - return &ArgoDB_RepositoryExists_Call{Call: _e.mock.On("RepositoryExists", ctx, repoURL, project)} -} - -func (_c *ArgoDB_RepositoryExists_Call) Run(run func(ctx context.Context, repoURL string, project string)) *ArgoDB_RepositoryExists_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(string)) - }) - return _c -} - -func (_c *ArgoDB_RepositoryExists_Call) Return(b bool, err error) *ArgoDB_RepositoryExists_Call { - _c.Call.Return(b, err) - return _c -} - -func (_c *ArgoDB_RepositoryExists_Call) RunAndReturn(run func(ctx context.Context, repoURL string, project string) (bool, error)) *ArgoDB_RepositoryExists_Call { - _c.Call.Return(run) - return _c -} - -// UpdateCluster provides a mock function for the type ArgoDB -func (_mock *ArgoDB) UpdateCluster(ctx context.Context, c *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { - ret := _mock.Called(ctx, c) - - if len(ret) == 0 { - panic("no return value specified for UpdateCluster") - } - - var r0 *v1alpha1.Cluster - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Cluster) (*v1alpha1.Cluster, error)); ok { - return returnFunc(ctx, c) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Cluster) *v1alpha1.Cluster); ok { - r0 = returnFunc(ctx, c) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Cluster) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.Cluster) error); ok { - r1 = returnFunc(ctx, c) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_UpdateCluster_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateCluster' -type ArgoDB_UpdateCluster_Call struct { - *mock.Call -} - -// UpdateCluster is a helper method to define mock.On call -// - ctx -// - c -func (_e *ArgoDB_Expecter) UpdateCluster(ctx interface{}, c interface{}) *ArgoDB_UpdateCluster_Call { - return &ArgoDB_UpdateCluster_Call{Call: _e.mock.On("UpdateCluster", ctx, c)} -} - -func (_c *ArgoDB_UpdateCluster_Call) Run(run func(ctx context.Context, c *v1alpha1.Cluster)) *ArgoDB_UpdateCluster_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.Cluster)) - }) - return _c -} - -func (_c *ArgoDB_UpdateCluster_Call) Return(cluster *v1alpha1.Cluster, err error) *ArgoDB_UpdateCluster_Call { - _c.Call.Return(cluster, err) - return _c -} - -func (_c *ArgoDB_UpdateCluster_Call) RunAndReturn(run func(ctx context.Context, c *v1alpha1.Cluster) (*v1alpha1.Cluster, error)) *ArgoDB_UpdateCluster_Call { - _c.Call.Return(run) - return _c -} - -// UpdateRepository provides a mock function for the type ArgoDB -func (_mock *ArgoDB) UpdateRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { - ret := _mock.Called(ctx, r) - - if len(ret) == 0 { - panic("no return value specified for UpdateRepository") - } - - var r0 *v1alpha1.Repository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) (*v1alpha1.Repository, error)); ok { - return returnFunc(ctx, r) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) *v1alpha1.Repository); ok { - r0 = returnFunc(ctx, r) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Repository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.Repository) error); ok { - r1 = returnFunc(ctx, r) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_UpdateRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateRepository' -type ArgoDB_UpdateRepository_Call struct { - *mock.Call -} - -// UpdateRepository is a helper method to define mock.On call -// - ctx -// - r -func (_e *ArgoDB_Expecter) UpdateRepository(ctx interface{}, r interface{}) *ArgoDB_UpdateRepository_Call { - return &ArgoDB_UpdateRepository_Call{Call: _e.mock.On("UpdateRepository", ctx, r)} -} - -func (_c *ArgoDB_UpdateRepository_Call) Run(run func(ctx context.Context, r *v1alpha1.Repository)) *ArgoDB_UpdateRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.Repository)) - }) - return _c -} - -func (_c *ArgoDB_UpdateRepository_Call) Return(repository *v1alpha1.Repository, err error) *ArgoDB_UpdateRepository_Call { - _c.Call.Return(repository, err) - return _c -} - -func (_c *ArgoDB_UpdateRepository_Call) RunAndReturn(run func(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error)) *ArgoDB_UpdateRepository_Call { - _c.Call.Return(run) - return _c -} - -// UpdateRepositoryCredentials provides a mock function for the type ArgoDB -func (_mock *ArgoDB) UpdateRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { - ret := _mock.Called(ctx, r) - - if len(ret) == 0 { - panic("no return value specified for UpdateRepositoryCredentials") - } - - var r0 *v1alpha1.RepoCreds - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)); ok { - return returnFunc(ctx, r) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) *v1alpha1.RepoCreds); ok { - r0 = returnFunc(ctx, r) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.RepoCreds) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.RepoCreds) error); ok { - r1 = returnFunc(ctx, r) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_UpdateRepositoryCredentials_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateRepositoryCredentials' -type ArgoDB_UpdateRepositoryCredentials_Call struct { - *mock.Call -} - -// UpdateRepositoryCredentials is a helper method to define mock.On call -// - ctx -// - r -func (_e *ArgoDB_Expecter) UpdateRepositoryCredentials(ctx interface{}, r interface{}) *ArgoDB_UpdateRepositoryCredentials_Call { - return &ArgoDB_UpdateRepositoryCredentials_Call{Call: _e.mock.On("UpdateRepositoryCredentials", ctx, r)} -} - -func (_c *ArgoDB_UpdateRepositoryCredentials_Call) Run(run func(ctx context.Context, r *v1alpha1.RepoCreds)) *ArgoDB_UpdateRepositoryCredentials_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.RepoCreds)) - }) - return _c -} - -func (_c *ArgoDB_UpdateRepositoryCredentials_Call) Return(repoCreds *v1alpha1.RepoCreds, err error) *ArgoDB_UpdateRepositoryCredentials_Call { - _c.Call.Return(repoCreds, err) - return _c -} - -func (_c *ArgoDB_UpdateRepositoryCredentials_Call) RunAndReturn(run func(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)) *ArgoDB_UpdateRepositoryCredentials_Call { - _c.Call.Return(run) - return _c -} - -// UpdateWriteRepository provides a mock function for the type ArgoDB -func (_mock *ArgoDB) UpdateWriteRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { - ret := _mock.Called(ctx, r) - - if len(ret) == 0 { - panic("no return value specified for UpdateWriteRepository") - } - - var r0 *v1alpha1.Repository - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) (*v1alpha1.Repository, error)); ok { - return returnFunc(ctx, r) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) *v1alpha1.Repository); ok { - r0 = returnFunc(ctx, r) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Repository) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.Repository) error); ok { - r1 = returnFunc(ctx, r) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_UpdateWriteRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateWriteRepository' -type ArgoDB_UpdateWriteRepository_Call struct { - *mock.Call -} - -// UpdateWriteRepository is a helper method to define mock.On call -// - ctx -// - r -func (_e *ArgoDB_Expecter) UpdateWriteRepository(ctx interface{}, r interface{}) *ArgoDB_UpdateWriteRepository_Call { - return &ArgoDB_UpdateWriteRepository_Call{Call: _e.mock.On("UpdateWriteRepository", ctx, r)} -} - -func (_c *ArgoDB_UpdateWriteRepository_Call) Run(run func(ctx context.Context, r *v1alpha1.Repository)) *ArgoDB_UpdateWriteRepository_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.Repository)) - }) - return _c -} - -func (_c *ArgoDB_UpdateWriteRepository_Call) Return(repository *v1alpha1.Repository, err error) *ArgoDB_UpdateWriteRepository_Call { - _c.Call.Return(repository, err) - return _c -} - -func (_c *ArgoDB_UpdateWriteRepository_Call) RunAndReturn(run func(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error)) *ArgoDB_UpdateWriteRepository_Call { - _c.Call.Return(run) - return _c -} - -// UpdateWriteRepositoryCredentials provides a mock function for the type ArgoDB -func (_mock *ArgoDB) UpdateWriteRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { - ret := _mock.Called(ctx, r) - - if len(ret) == 0 { - panic("no return value specified for UpdateWriteRepositoryCredentials") - } - - var r0 *v1alpha1.RepoCreds - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)); ok { - return returnFunc(ctx, r) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) *v1alpha1.RepoCreds); ok { - r0 = returnFunc(ctx, r) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.RepoCreds) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.RepoCreds) error); ok { - r1 = returnFunc(ctx, r) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_UpdateWriteRepositoryCredentials_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateWriteRepositoryCredentials' -type ArgoDB_UpdateWriteRepositoryCredentials_Call struct { - *mock.Call -} - -// UpdateWriteRepositoryCredentials is a helper method to define mock.On call -// - ctx -// - r -func (_e *ArgoDB_Expecter) UpdateWriteRepositoryCredentials(ctx interface{}, r interface{}) *ArgoDB_UpdateWriteRepositoryCredentials_Call { - return &ArgoDB_UpdateWriteRepositoryCredentials_Call{Call: _e.mock.On("UpdateWriteRepositoryCredentials", ctx, r)} -} - -func (_c *ArgoDB_UpdateWriteRepositoryCredentials_Call) Run(run func(ctx context.Context, r *v1alpha1.RepoCreds)) *ArgoDB_UpdateWriteRepositoryCredentials_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.RepoCreds)) - }) - return _c -} - -func (_c *ArgoDB_UpdateWriteRepositoryCredentials_Call) Return(repoCreds *v1alpha1.RepoCreds, err error) *ArgoDB_UpdateWriteRepositoryCredentials_Call { - _c.Call.Return(repoCreds, err) - return _c -} - -func (_c *ArgoDB_UpdateWriteRepositoryCredentials_Call) RunAndReturn(run func(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)) *ArgoDB_UpdateWriteRepositoryCredentials_Call { - _c.Call.Return(run) - return _c -} - -// WatchClusters provides a mock function for the type ArgoDB -func (_mock *ArgoDB) WatchClusters(ctx context.Context, handleAddEvent func(cluster *v1alpha1.Cluster), handleModEvent func(oldCluster *v1alpha1.Cluster, newCluster *v1alpha1.Cluster), handleDeleteEvent func(clusterServer string)) error { - ret := _mock.Called(ctx, handleAddEvent, handleModEvent, handleDeleteEvent) - - if len(ret) == 0 { - panic("no return value specified for WatchClusters") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, func(cluster *v1alpha1.Cluster), func(oldCluster *v1alpha1.Cluster, newCluster *v1alpha1.Cluster), func(clusterServer string)) error); ok { - r0 = returnFunc(ctx, handleAddEvent, handleModEvent, handleDeleteEvent) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// ArgoDB_WatchClusters_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchClusters' -type ArgoDB_WatchClusters_Call struct { - *mock.Call -} - -// WatchClusters is a helper method to define mock.On call -// - ctx -// - handleAddEvent -// - handleModEvent -// - handleDeleteEvent -func (_e *ArgoDB_Expecter) WatchClusters(ctx interface{}, handleAddEvent interface{}, handleModEvent interface{}, handleDeleteEvent interface{}) *ArgoDB_WatchClusters_Call { - return &ArgoDB_WatchClusters_Call{Call: _e.mock.On("WatchClusters", ctx, handleAddEvent, handleModEvent, handleDeleteEvent)} -} - -func (_c *ArgoDB_WatchClusters_Call) Run(run func(ctx context.Context, handleAddEvent func(cluster *v1alpha1.Cluster), handleModEvent func(oldCluster *v1alpha1.Cluster, newCluster *v1alpha1.Cluster), handleDeleteEvent func(clusterServer string))) *ArgoDB_WatchClusters_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(func(cluster *v1alpha1.Cluster)), args[2].(func(oldCluster *v1alpha1.Cluster, newCluster *v1alpha1.Cluster)), args[3].(func(clusterServer string))) - }) - return _c -} - -func (_c *ArgoDB_WatchClusters_Call) Return(err error) *ArgoDB_WatchClusters_Call { - _c.Call.Return(err) - return _c -} - -func (_c *ArgoDB_WatchClusters_Call) RunAndReturn(run func(ctx context.Context, handleAddEvent func(cluster *v1alpha1.Cluster), handleModEvent func(oldCluster *v1alpha1.Cluster, newCluster *v1alpha1.Cluster), handleDeleteEvent func(clusterServer string)) error) *ArgoDB_WatchClusters_Call { - _c.Call.Return(run) - return _c -} - -// WriteRepositoryExists provides a mock function for the type ArgoDB -func (_mock *ArgoDB) WriteRepositoryExists(ctx context.Context, repoURL string, project string) (bool, error) { - ret := _mock.Called(ctx, repoURL, project) - - if len(ret) == 0 { - panic("no return value specified for WriteRepositoryExists") - } - - var r0 bool - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) (bool, error)); ok { - return returnFunc(ctx, repoURL, project) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) bool); ok { - r0 = returnFunc(ctx, repoURL, project) - } else { - r0 = ret.Get(0).(bool) - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string, string) error); ok { - r1 = returnFunc(ctx, repoURL, project) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// ArgoDB_WriteRepositoryExists_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteRepositoryExists' -type ArgoDB_WriteRepositoryExists_Call struct { - *mock.Call -} - -// WriteRepositoryExists is a helper method to define mock.On call -// - ctx -// - repoURL -// - project -func (_e *ArgoDB_Expecter) WriteRepositoryExists(ctx interface{}, repoURL interface{}, project interface{}) *ArgoDB_WriteRepositoryExists_Call { - return &ArgoDB_WriteRepositoryExists_Call{Call: _e.mock.On("WriteRepositoryExists", ctx, repoURL, project)} -} - -func (_c *ArgoDB_WriteRepositoryExists_Call) Run(run func(ctx context.Context, repoURL string, project string)) *ArgoDB_WriteRepositoryExists_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(string)) - }) - return _c -} - -func (_c *ArgoDB_WriteRepositoryExists_Call) Return(b bool, err error) *ArgoDB_WriteRepositoryExists_Call { - _c.Call.Return(b, err) - return _c -} - -func (_c *ArgoDB_WriteRepositoryExists_Call) RunAndReturn(run func(ctx context.Context, repoURL string, project string) (bool, error)) *ArgoDB_WriteRepositoryExists_Call { - _c.Call.Return(run) - return _c -} diff --git a/util/db/repo_creds.go b/util/db/repo_creds.go index bef4fb5836..b4abe4cf1f 100644 --- a/util/db/repo_creds.go +++ b/util/db/repo_creds.go @@ -3,7 +3,7 @@ package db import ( "context" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) type RepoCredsDB interface { diff --git a/util/db/repository.go b/util/db/repository.go index 9ff1d7eeef..f6e7a708d0 100644 --- a/util/db/repository.go +++ b/util/db/repository.go @@ -5,14 +5,15 @@ import ( "fmt" "hash/fnv" - corev1 "k8s.io/api/core/v1" + apiv1 "k8s.io/api/core/v1" log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/settings" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/settings" ) const ( @@ -28,43 +29,56 @@ const ( project = "project" // The name of the key storing the SSH private in the secret sshPrivateKey = "sshPrivateKey" + // The name of the key storing the TLS client cert data in the secret + tlsClientCertData = "tlsClientCertData" + // The name of the key storing the TLS client cert key in the secret + tlsClientCertKey = "tlsClientCertKey" + // The name of the key storing the GitHub App private key in the secret + githubAppPrivateKey = "githubAppPrivateKey" + // The name of the key storing the service account to access Google Cloud Source repositories + gcpServiceAccountKey = "gcpServiceAccountKey" ) // repositoryBackend defines the API for types that wish to provide interaction with repository storage type repositoryBackend interface { - CreateRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) - GetRepository(ctx context.Context, repoURL, project string) (*v1alpha1.Repository, error) - ListRepositories(ctx context.Context, repoType *string) ([]*v1alpha1.Repository, error) - UpdateRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) + CreateRepository(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) + GetRepository(ctx context.Context, repoURL, project string) (*appsv1.Repository, error) + ListRepositories(ctx context.Context, repoType *string) ([]*appsv1.Repository, error) + UpdateRepository(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) DeleteRepository(ctx context.Context, repoURL, project string) error RepositoryExists(ctx context.Context, repoURL, project string, allowFallback bool) (bool, error) - CreateRepoCreds(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) - GetRepoCreds(ctx context.Context, repoURL string) (*v1alpha1.RepoCreds, error) + CreateRepoCreds(ctx context.Context, r *appsv1.RepoCreds) (*appsv1.RepoCreds, error) + GetRepoCreds(ctx context.Context, repoURL string) (*appsv1.RepoCreds, error) ListRepoCreds(ctx context.Context) ([]string, error) - UpdateRepoCreds(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) + UpdateRepoCreds(ctx context.Context, r *appsv1.RepoCreds) (*appsv1.RepoCreds, error) DeleteRepoCreds(ctx context.Context, name string) error RepoCredsExists(ctx context.Context, repoURL string) (bool, error) - GetAllHelmRepoCreds(ctx context.Context) ([]*v1alpha1.RepoCreds, error) + GetAllHelmRepoCreds(ctx context.Context) ([]*appsv1.RepoCreds, error) } -func (db *db) CreateRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { +func (db *db) CreateRepository(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) { secretBackend := db.repoBackend() + legacyBackend := db.legacyRepoBackend() secretExists, err := secretBackend.RepositoryExists(ctx, r.Repo, r.Project, false) if err != nil { return nil, err } + legacyExists, err := legacyBackend.RepositoryExists(ctx, r.Repo, r.Project, false) + if err != nil { + return nil, err + } - if secretExists { + if secretExists || legacyExists { return nil, status.Errorf(codes.AlreadyExists, "repository %q already exists", r.Repo) } return secretBackend.CreateRepository(ctx, r) } -func (db *db) CreateWriteRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { +func (db *db) CreateWriteRepository(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) { secretBackend := db.repoWriteBackend() secretExists, err := secretBackend.RepositoryExists(ctx, r.Repo, r.Project, false) if err != nil { @@ -78,7 +92,7 @@ func (db *db) CreateWriteRepository(ctx context.Context, r *v1alpha1.Repository) return secretBackend.CreateRepository(ctx, r) } -func (db *db) GetRepository(ctx context.Context, repoURL, project string) (*v1alpha1.Repository, error) { +func (db *db) GetRepository(ctx context.Context, repoURL, project string) (*appsv1.Repository, error) { repository, err := db.getRepository(ctx, repoURL, project) if err != nil { return repository, fmt.Errorf("unable to get repository %q: %w", repoURL, err) @@ -91,29 +105,29 @@ func (db *db) GetRepository(ctx context.Context, repoURL, project string) (*v1al return repository, err } -func (db *db) GetWriteRepository(ctx context.Context, repoURL, project string) (*v1alpha1.Repository, error) { +func (db *db) GetWriteRepository(ctx context.Context, repoURL, project string) (*appsv1.Repository, error) { repository, err := db.repoWriteBackend().GetRepository(ctx, repoURL, project) if err != nil { return repository, fmt.Errorf("unable to get write repository %q: %w", repoURL, err) } // TODO: enrich with write credentials. - // if err := db.enrichCredsToRepo(ctx, repository); err != nil { - // return repository, fmt.Errorf("unable to enrich write repository %q info with credentials: %w", repoURL, err) - // } + //if err := db.enrichCredsToRepo(ctx, repository); err != nil { + // return repository, fmt.Errorf("unable to enrich write repository %q info with credentials: %w", repoURL, err) + //} return repository, err } -func (db *db) GetProjectRepositories(project string) ([]*v1alpha1.Repository, error) { +func (db *db) GetProjectRepositories(ctx context.Context, project string) ([]*appsv1.Repository, error) { return db.getRepositories(settings.ByProjectRepoIndexer, project) } -func (db *db) GetProjectWriteRepositories(project string) ([]*v1alpha1.Repository, error) { +func (db *db) GetProjectWriteRepositories(ctx context.Context, project string) ([]*appsv1.Repository, error) { return db.getRepositories(settings.ByProjectRepoWriteIndexer, project) } -func (db *db) getRepositories(indexer, project string) ([]*v1alpha1.Repository, error) { +func (db *db) getRepositories(indexer, project string) ([]*appv1.Repository, error) { informer, err := db.settingsMgr.GetSecretsInformer() if err != nil { return nil, err @@ -122,9 +136,9 @@ func (db *db) getRepositories(indexer, project string) ([]*v1alpha1.Repository, if err != nil { return nil, err } - var res []*v1alpha1.Repository + var res []*appv1.Repository for i := range secrets { - repo, err := secretToRepository(secrets[i].(*corev1.Secret)) + repo, err := secretToRepository(secrets[i].(*apiv1.Secret)) if err != nil { return nil, err } @@ -135,7 +149,13 @@ func (db *db) getRepositories(indexer, project string) ([]*v1alpha1.Repository, func (db *db) RepositoryExists(ctx context.Context, repoURL, project string) (bool, error) { secretsBackend := db.repoBackend() - return secretsBackend.RepositoryExists(ctx, repoURL, project, true) + exists, err := secretsBackend.RepositoryExists(ctx, repoURL, project, true) + if exists || err != nil { + return exists, err + } + + legacyBackend := db.legacyRepoBackend() + return legacyBackend.RepositoryExists(ctx, repoURL, project, true) } func (db *db) WriteRepositoryExists(ctx context.Context, repoURL, project string) (bool, error) { @@ -143,7 +163,7 @@ func (db *db) WriteRepositoryExists(ctx context.Context, repoURL, project string return secretsBackend.RepositoryExists(ctx, repoURL, project, true) } -func (db *db) getRepository(ctx context.Context, repoURL, project string) (*v1alpha1.Repository, error) { +func (db *db) getRepository(ctx context.Context, repoURL, project string) (*appsv1.Repository, error) { secretsBackend := db.repoBackend() exists, err := secretsBackend.RepositoryExists(ctx, repoURL, project, true) if err != nil { @@ -156,29 +176,54 @@ func (db *db) getRepository(ctx context.Context, repoURL, project string) (*v1al return repository, nil } - return &v1alpha1.Repository{Repo: repoURL}, nil + legacyBackend := db.legacyRepoBackend() + exists, err = legacyBackend.RepositoryExists(ctx, repoURL, project, true) + if err != nil { + return nil, fmt.Errorf("unable to check if repository %q exists from legacy backend: %w", repoURL, err) + } else if exists { + repository, err := legacyBackend.GetRepository(ctx, repoURL, project) + if err != nil { + return nil, fmt.Errorf("unable to get repository %q from legacy backend: %w", repoURL, err) + } + return repository, nil + } + + return &appsv1.Repository{Repo: repoURL}, nil } -func (db *db) ListRepositories(ctx context.Context) ([]*v1alpha1.Repository, error) { +func (db *db) ListRepositories(ctx context.Context) ([]*appsv1.Repository, error) { return db.listRepositories(ctx, nil, false) } -func (db *db) ListWriteRepositories(ctx context.Context) ([]*v1alpha1.Repository, error) { +func (db *db) ListWriteRepositories(ctx context.Context) ([]*appsv1.Repository, error) { return db.listRepositories(ctx, nil, true) } -func (db *db) listRepositories(ctx context.Context, repoType *string, writeCreds bool) ([]*v1alpha1.Repository, error) { - var backend repositoryBackend +func (db *db) listRepositories(ctx context.Context, repoType *string, writeCreds bool) ([]*appsv1.Repository, error) { + // TODO It would be nice to check for duplicates between secret and legacy repositories and make it so that + // repositories from secrets overlay repositories from legacys. + + var repositories []*appv1.Repository if writeCreds { - backend = db.repoWriteBackend() + var err error + repositories, err = db.repoWriteBackend().ListRepositories(ctx, repoType) + if err != nil { + return nil, err + } } else { - backend = db.repoBackend() + secretRepositories, err := db.repoBackend().ListRepositories(ctx, repoType) + if err != nil { + return nil, err + } + + legacyRepositories, err := db.legacyRepoBackend().ListRepositories(ctx, repoType) + if err != nil { + return nil, err + } + + repositories = append(secretRepositories, legacyRepositories...) } - repositories, err := backend.ListRepositories(ctx, repoType) - if err != nil { - return nil, err - } - if err = db.enrichCredsToRepos(ctx, repositories); err != nil { + if err := db.enrichCredsToRepos(ctx, repositories); err != nil { return nil, err } @@ -186,7 +231,7 @@ func (db *db) listRepositories(ctx context.Context, repoType *string, writeCreds } // UpdateRepository updates a repository -func (db *db) UpdateRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { +func (db *db) UpdateRepository(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) { secretsBackend := db.repoBackend() exists, err := secretsBackend.RepositoryExists(ctx, r.Repo, r.Project, false) if err != nil { @@ -195,10 +240,18 @@ func (db *db) UpdateRepository(ctx context.Context, r *v1alpha1.Repository) (*v1 return secretsBackend.UpdateRepository(ctx, r) } + legacyBackend := db.legacyRepoBackend() + exists, err = legacyBackend.RepositoryExists(ctx, r.Repo, r.Project, false) + if err != nil { + return nil, err + } else if exists { + return legacyBackend.UpdateRepository(ctx, r) + } + return nil, status.Errorf(codes.NotFound, "repo '%s' not found", r.Repo) } -func (db *db) UpdateWriteRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { +func (db *db) UpdateWriteRepository(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) { secretBackend := db.repoWriteBackend() exists, err := secretBackend.RepositoryExists(ctx, r.Repo, r.Project, false) if err != nil { @@ -221,6 +274,14 @@ func (db *db) DeleteRepository(ctx context.Context, repoURL, project string) err return secretsBackend.DeleteRepository(ctx, repoURL, project) } + legacyBackend := db.legacyRepoBackend() + exists, err = legacyBackend.RepositoryExists(ctx, repoURL, project, false) + if err != nil { + return err + } else if exists { + return legacyBackend.DeleteRepository(ctx, repoURL, project) + } + return status.Errorf(codes.NotFound, "repo '%s' not found", repoURL) } @@ -240,12 +301,20 @@ func (db *db) DeleteWriteRepository(ctx context.Context, repoURL, project string // ListRepositoryCredentials returns a list of URLs that contain repo credential sets func (db *db) ListRepositoryCredentials(ctx context.Context) ([]string, error) { + // TODO It would be nice to check for duplicates between secret and legacy repositories and make it so that + // repositories from secrets overlay repositories from legacys. + secretRepoCreds, err := db.repoBackend().ListRepoCreds(ctx) if err != nil { return nil, err } - return secretRepoCreds, nil + legacyRepoCreds, err := db.legacyRepoBackend().ListRepoCreds(ctx) + if err != nil { + return nil, err + } + + return append(secretRepoCreds, legacyRepoCreds...), nil } // ListWriteRepositoryCredentials returns a list of URLs that contain repo write credential sets @@ -258,7 +327,7 @@ func (db *db) ListWriteRepositoryCredentials(ctx context.Context) ([]string, err } // GetRepositoryCredentials retrieves a repository credential set -func (db *db) GetRepositoryCredentials(ctx context.Context, repoURL string) (*v1alpha1.RepoCreds, error) { +func (db *db) GetRepositoryCredentials(ctx context.Context, repoURL string) (*appsv1.RepoCreds, error) { secretsBackend := db.repoBackend() exists, err := secretsBackend.RepoCredsExists(ctx, repoURL) if err != nil { @@ -271,11 +340,23 @@ func (db *db) GetRepositoryCredentials(ctx context.Context, repoURL string) (*v1 return creds, nil } + legacyBackend := db.legacyRepoBackend() + exists, err = legacyBackend.RepoCredsExists(ctx, repoURL) + if err != nil { + return nil, fmt.Errorf("unable to check if repository credentials for %q exists from legacy backend: %w", repoURL, err) + } else if exists { + creds, err := legacyBackend.GetRepoCreds(ctx, repoURL) + if err != nil { + return nil, fmt.Errorf("unable to get repository credentials for %q from legacy backend: %w", repoURL, err) + } + return creds, nil + } + return nil, nil } // GetWriteRepositoryCredentials retrieves a repository write credential set -func (db *db) GetWriteRepositoryCredentials(ctx context.Context, repoURL string) (*v1alpha1.RepoCreds, error) { +func (db *db) GetWriteRepositoryCredentials(ctx context.Context, repoURL string) (*appsv1.RepoCreds, error) { secretBackend := db.repoWriteBackend() exists, err := secretBackend.RepoCredsExists(ctx, repoURL) if err != nil { @@ -287,9 +368,9 @@ func (db *db) GetWriteRepositoryCredentials(ctx context.Context, repoURL string) } // TODO: enrich with write credentials. - // if err := db.enrichCredsToRepo(ctx, repository); err != nil { - // return repository, fmt.Errorf("unable to enrich write repository %q info with credentials: %w", repoURL, err) - // } + //if err := db.enrichCredsToRepo(ctx, repository); err != nil { + // return repository, fmt.Errorf("unable to enrich write repository %q info with credentials: %w", repoURL, err) + //} creds, err := secretBackend.GetRepoCreds(ctx, repoURL) if err != nil { @@ -300,25 +381,38 @@ func (db *db) GetWriteRepositoryCredentials(ctx context.Context, repoURL string) } // GetAllHelmRepositoryCredentials retrieves all repository credentials -func (db *db) GetAllHelmRepositoryCredentials(ctx context.Context) ([]*v1alpha1.RepoCreds, error) { +func (db *db) GetAllHelmRepositoryCredentials(ctx context.Context) ([]*appsv1.RepoCreds, error) { + // TODO It would be nice to check for duplicates between secret and legacy repositories and make it so that + // repositories from secrets overlay repositories from legacys. + secretRepoCreds, err := db.repoBackend().GetAllHelmRepoCreds(ctx) if err != nil { return nil, fmt.Errorf("failed to get all Helm repo creds: %w", err) } - return secretRepoCreds, nil + legacyRepoCreds, err := db.legacyRepoBackend().GetAllHelmRepoCreds(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get all legacy Helm repo creds: %w", err) + } + + return append(secretRepoCreds, legacyRepoCreds...), nil } // CreateRepositoryCredentials creates a repository credential set -func (db *db) CreateRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { +func (db *db) CreateRepositoryCredentials(ctx context.Context, r *appsv1.RepoCreds) (*appsv1.RepoCreds, error) { + legacyBackend := db.legacyRepoBackend() secretBackend := db.repoBackend() secretExists, err := secretBackend.RepositoryExists(ctx, r.URL, "", false) if err != nil { return nil, err } + legacyExists, err := legacyBackend.RepositoryExists(ctx, r.URL, "", false) + if err != nil { + return nil, err + } - if secretExists { + if secretExists || legacyExists { return nil, status.Errorf(codes.AlreadyExists, "repository credentials %q already exists", r.URL) } @@ -326,7 +420,7 @@ func (db *db) CreateRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoC } // CreateWriteRepositoryCredentials creates a repository write credential set -func (db *db) CreateWriteRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { +func (db *db) CreateWriteRepositoryCredentials(ctx context.Context, r *appsv1.RepoCreds) (*appsv1.RepoCreds, error) { secretBackend := db.repoWriteBackend() secretExists, err := secretBackend.RepoCredsExists(ctx, r.URL) if err != nil { @@ -341,7 +435,7 @@ func (db *db) CreateWriteRepositoryCredentials(ctx context.Context, r *v1alpha1. } // UpdateRepositoryCredentials updates a repository credential set -func (db *db) UpdateRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { +func (db *db) UpdateRepositoryCredentials(ctx context.Context, r *appsv1.RepoCreds) (*appsv1.RepoCreds, error) { secretsBackend := db.repoBackend() exists, err := secretsBackend.RepoCredsExists(ctx, r.URL) if err != nil { @@ -350,11 +444,19 @@ func (db *db) UpdateRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoC return secretsBackend.UpdateRepoCreds(ctx, r) } + legacyBackend := db.legacyRepoBackend() + exists, err = legacyBackend.RepoCredsExists(ctx, r.URL) + if err != nil { + return nil, err + } else if exists { + return legacyBackend.UpdateRepoCreds(ctx, r) + } + return nil, status.Errorf(codes.NotFound, "repository credentials '%s' not found", r.URL) } // UpdateWriteRepositoryCredentials updates a repository write credential set -func (db *db) UpdateWriteRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { +func (db *db) UpdateWriteRepositoryCredentials(ctx context.Context, r *appsv1.RepoCreds) (*appsv1.RepoCreds, error) { secretBackend := db.repoWriteBackend() exists, err := secretBackend.RepoCredsExists(ctx, r.URL) if err != nil { @@ -379,6 +481,14 @@ func (db *db) DeleteRepositoryCredentials(ctx context.Context, name string) erro return secretsBackend.DeleteRepoCreds(ctx, name) } + legacyBackend := db.legacyRepoBackend() + exists, err = legacyBackend.RepoCredsExists(ctx, name) + if err != nil { + return err + } else if exists { + return legacyBackend.DeleteRepoCreds(ctx, name) + } + return status.Errorf(codes.NotFound, "repository credentials '%s' not found", name) } @@ -395,7 +505,7 @@ func (db *db) DeleteWriteRepositoryCredentials(ctx context.Context, name string) return status.Errorf(codes.NotFound, "write repository credentials '%s' not found", name) } -func (db *db) enrichCredsToRepos(ctx context.Context, repositories []*v1alpha1.Repository) error { +func (db *db) enrichCredsToRepos(ctx context.Context, repositories []*appsv1.Repository) error { for _, repository := range repositories { if err := db.enrichCredsToRepo(ctx, repository); err != nil { return err @@ -412,16 +522,21 @@ func (db *db) repoWriteBackend() repositoryBackend { return &secretsRepositoryBackend{db: db, writeCreds: true} } -func (db *db) enrichCredsToRepo(ctx context.Context, repository *v1alpha1.Repository) error { +func (db *db) legacyRepoBackend() repositoryBackend { + return &legacyRepositoryBackend{db: db} +} + +func (db *db) enrichCredsToRepo(ctx context.Context, repository *appsv1.Repository) error { if !repository.HasCredentials() { creds, err := db.GetRepositoryCredentials(ctx, repository.Repo) - if err != nil { + if err == nil { + if creds != nil { + repository.CopyCredentialsFrom(creds) + repository.InheritedCreds = true + } + } else { return fmt.Errorf("failed to get repository credentials for %q: %w", repository.Repo, err) } - if creds != nil { - repository.CopyCredentialsFrom(creds) - repository.InheritedCreds = true - } } else { log.Debugf("%s has credentials", repository.Repo) } diff --git a/util/db/repository_legacy.go b/util/db/repository_legacy.go new file mode 100644 index 0000000000..4f570c653e --- /dev/null +++ b/util/db/repository_legacy.go @@ -0,0 +1,475 @@ +package db + +import ( + "context" + "fmt" + "strings" + + log "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + apiv1 "k8s.io/api/core/v1" + apierr "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/argoproj/argo-cd/v2/common" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/settings" +) + +var _ repositoryBackend = &legacyRepositoryBackend{} + +// legacyRepositoryBackend is a repository backend strategy that maintains backward compatibility with previous versions. +// This can be removed in a future version, once the old "argocd-cm" storage for repositories is removed. +type legacyRepositoryBackend struct { + db *db +} + +func (l *legacyRepositoryBackend) CreateRepository(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) { + // This strategy only kept to preserve backward compatibility, but is deprecated. + // Therefore, no new repositories can be added with this backend. + panic("creating new repositories is not supported for the legacy repository backend") +} + +func (l *legacyRepositoryBackend) GetRepository(ctx context.Context, repoURL, project string) (*appsv1.Repository, error) { + repository, err := l.tryGetRepository(repoURL) + if err != nil { + return nil, fmt.Errorf("unable to get repository: %w", err) + } + return repository, nil +} + +func (l *legacyRepositoryBackend) ListRepositories(ctx context.Context, repoType *string) ([]*appsv1.Repository, error) { + inRepos, err := l.db.settingsMgr.GetRepositories() + if err != nil { + return nil, err + } + + var repos []*appsv1.Repository + for _, inRepo := range inRepos { + if repoType == nil || *repoType == inRepo.Type { + r, err := l.tryGetRepository(inRepo.URL) + if err != nil { + if r != nil && errors.IsCredentialsConfigurationError(err) { + modifiedTime := metav1.Now() + r.ConnectionState = appsv1.ConnectionState{ + Status: appsv1.ConnectionStatusFailed, + Message: "Configuration error - please check the server logs", + ModifiedAt: &modifiedTime, + } + + log.Warnf("could not retrieve repo: %s", err.Error()) + } else { + return nil, err + } + } + repos = append(repos, r) + } + } + return repos, nil +} + +func (l *legacyRepositoryBackend) UpdateRepository(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) { + repos, err := l.db.settingsMgr.GetRepositories() + if err != nil { + return nil, err + } + + index := l.getRepositoryIndex(repos, r.Repo) + if index < 0 { + return nil, status.Errorf(codes.NotFound, "repo '%s' not found", r.Repo) + } + + repoInfo := repos[index] + err = l.updateRepositorySecrets(&repoInfo, r) + if err != nil { + return nil, err + } + + // Update boolean settings + repoInfo.InsecureIgnoreHostKey = r.IsInsecure() + repoInfo.Insecure = r.IsInsecure() + repoInfo.EnableLFS = r.EnableLFS + repoInfo.Proxy = r.Proxy + + repos[index] = repoInfo + err = l.db.settingsMgr.SaveRepositories(repos) + if err != nil { + return nil, err + } + return r, nil +} + +func (l *legacyRepositoryBackend) DeleteRepository(ctx context.Context, repoURL, project string) error { + repos, err := l.db.settingsMgr.GetRepositories() + if err != nil { + return err + } + + index := l.getRepositoryIndex(repos, repoURL) + if index < 0 { + return status.Errorf(codes.NotFound, "repo '%s' not found", repoURL) + } + err = l.updateRepositorySecrets(&repos[index], &appsv1.Repository{ + SSHPrivateKey: "", + Password: "", + Username: "", + TLSClientCertData: "", + TLSClientCertKey: "", + GithubAppPrivateKey: "", + }) + if err != nil { + return err + } + repos = append(repos[:index], repos[index+1:]...) + return l.db.settingsMgr.SaveRepositories(repos) +} + +func (l *legacyRepositoryBackend) RepositoryExists(ctx context.Context, repoURL, project string, allowFallback bool) (bool, error) { + repos, err := l.db.settingsMgr.GetRepositories() + if err != nil { + return false, fmt.Errorf("unable to get repositories: %w", err) + } + + index := l.getRepositoryIndex(repos, repoURL) + return index >= 0, nil +} + +func (l *legacyRepositoryBackend) CreateRepoCreds(ctx context.Context, r *appsv1.RepoCreds) (*appsv1.RepoCreds, error) { + // This strategy only kept to preserve backward compatibility, but is deprecated. + // Therefore, no new repositories can be added with this backend. + panic("creating new repository credentials is not supported for the legacy repository backend") +} + +func (l *legacyRepositoryBackend) GetRepoCreds(ctx context.Context, repoURL string) (*appsv1.RepoCreds, error) { + var credential *appsv1.RepoCreds + + repoCredentials, err := l.db.settingsMgr.GetRepositoryCredentials() + if err != nil { + return nil, err + } + index := getRepositoryCredentialIndex(repoCredentials, repoURL) + if index >= 0 { + credential, err = l.credentialsToRepositoryCredentials(repoCredentials[index]) + if err != nil { + return nil, err + } + } + + return credential, err +} + +func (l *legacyRepositoryBackend) ListRepoCreds(ctx context.Context) ([]string, error) { + repos, err := l.db.settingsMgr.GetRepositoryCredentials() + if err != nil { + return nil, err + } + + urls := make([]string, len(repos)) + for i := range repos { + urls[i] = repos[i].URL + } + + return urls, nil +} + +func (l *legacyRepositoryBackend) UpdateRepoCreds(ctx context.Context, r *appsv1.RepoCreds) (*appsv1.RepoCreds, error) { + repos, err := l.db.settingsMgr.GetRepositoryCredentials() + if err != nil { + return nil, err + } + + index := getRepositoryCredentialIndex(repos, r.URL) + if index < 0 { + return nil, status.Errorf(codes.NotFound, "repository credentials '%s' not found", r.URL) + } + + repoInfo := repos[index] + err = l.updateCredentialsSecret(&repoInfo, r) + if err != nil { + return nil, err + } + + repos[index] = repoInfo + err = l.db.settingsMgr.SaveRepositoryCredentials(repos) + if err != nil { + return nil, err + } + return r, nil +} + +func (l *legacyRepositoryBackend) DeleteRepoCreds(ctx context.Context, name string) error { + repos, err := l.db.settingsMgr.GetRepositoryCredentials() + if err != nil { + return err + } + + index := getRepositoryCredentialIndex(repos, name) + if index < 0 { + return status.Errorf(codes.NotFound, "repository credentials '%s' not found", name) + } + err = l.updateCredentialsSecret(&repos[index], &appsv1.RepoCreds{ + SSHPrivateKey: "", + Password: "", + Username: "", + TLSClientCertData: "", + TLSClientCertKey: "", + GithubAppPrivateKey: "", + }) + if err != nil { + return err + } + repos = append(repos[:index], repos[index+1:]...) + return l.db.settingsMgr.SaveRepositoryCredentials(repos) +} + +func (l *legacyRepositoryBackend) RepoCredsExists(ctx context.Context, repoURL string) (bool, error) { + creds, err := l.db.settingsMgr.GetRepositoryCredentials() + if err != nil { + return false, err + } + + index := getRepositoryCredentialIndex(creds, repoURL) + return index >= 0, nil +} + +func (l *legacyRepositoryBackend) GetAllHelmRepoCreds(ctx context.Context) ([]*appsv1.RepoCreds, error) { + var allCredentials []*appsv1.RepoCreds + repoCredentials, err := l.db.settingsMgr.GetRepositoryCredentials() + if err != nil { + return nil, err + } + for _, v := range repoCredentials { + if strings.EqualFold(v.Type, "helm") { + credential, err := l.credentialsToRepositoryCredentials(v) + if err != nil { + return nil, err + } + allCredentials = append(allCredentials, credential) + } + } + return allCredentials, err +} + +func (l *legacyRepositoryBackend) updateRepositorySecrets(repoInfo *settings.Repository, r *appsv1.Repository) error { + secretsData := make(map[string]map[string][]byte) + + repoInfo.UsernameSecret = l.setSecretData(repoSecretPrefix, r.Repo, secretsData, repoInfo.UsernameSecret, r.Username, username) + repoInfo.PasswordSecret = l.setSecretData(repoSecretPrefix, r.Repo, secretsData, repoInfo.PasswordSecret, r.Password, password) + repoInfo.SSHPrivateKeySecret = l.setSecretData(repoSecretPrefix, r.Repo, secretsData, repoInfo.SSHPrivateKeySecret, r.SSHPrivateKey, sshPrivateKey) + repoInfo.TLSClientCertDataSecret = l.setSecretData(repoSecretPrefix, r.Repo, secretsData, repoInfo.TLSClientCertDataSecret, r.TLSClientCertData, tlsClientCertData) + repoInfo.TLSClientCertKeySecret = l.setSecretData(repoSecretPrefix, r.Repo, secretsData, repoInfo.TLSClientCertKeySecret, r.TLSClientCertKey, tlsClientCertKey) + repoInfo.GithubAppPrivateKeySecret = l.setSecretData(repoSecretPrefix, r.Repo, secretsData, repoInfo.GithubAppPrivateKeySecret, r.GithubAppPrivateKey, githubAppPrivateKey) + repoInfo.GCPServiceAccountKey = l.setSecretData(repoSecretPrefix, r.Repo, secretsData, repoInfo.GCPServiceAccountKey, r.GCPServiceAccountKey, gcpServiceAccountKey) + for k, v := range secretsData { + err := l.upsertSecret(k, v) + if err != nil { + return err + } + } + return nil +} + +func (l *legacyRepositoryBackend) updateCredentialsSecret(credsInfo *settings.RepositoryCredentials, c *appsv1.RepoCreds) error { + r := &appsv1.Repository{ + Repo: c.URL, + Username: c.Username, + Password: c.Password, + SSHPrivateKey: c.SSHPrivateKey, + TLSClientCertData: c.TLSClientCertData, + TLSClientCertKey: c.TLSClientCertKey, + GithubAppPrivateKey: c.GithubAppPrivateKey, + GithubAppId: c.GithubAppId, + GithubAppInstallationId: c.GithubAppInstallationId, + GitHubAppEnterpriseBaseURL: c.GitHubAppEnterpriseBaseURL, + GCPServiceAccountKey: c.GCPServiceAccountKey, + } + secretsData := make(map[string]map[string][]byte) + + credsInfo.UsernameSecret = l.setSecretData(credSecretPrefix, r.Repo, secretsData, credsInfo.UsernameSecret, r.Username, username) + credsInfo.PasswordSecret = l.setSecretData(credSecretPrefix, r.Repo, secretsData, credsInfo.PasswordSecret, r.Password, password) + credsInfo.SSHPrivateKeySecret = l.setSecretData(credSecretPrefix, r.Repo, secretsData, credsInfo.SSHPrivateKeySecret, r.SSHPrivateKey, sshPrivateKey) + credsInfo.TLSClientCertDataSecret = l.setSecretData(credSecretPrefix, r.Repo, secretsData, credsInfo.TLSClientCertDataSecret, r.TLSClientCertData, tlsClientCertData) + credsInfo.TLSClientCertKeySecret = l.setSecretData(credSecretPrefix, r.Repo, secretsData, credsInfo.TLSClientCertKeySecret, r.TLSClientCertKey, tlsClientCertKey) + credsInfo.GithubAppPrivateKeySecret = l.setSecretData(repoSecretPrefix, r.Repo, secretsData, credsInfo.GithubAppPrivateKeySecret, r.GithubAppPrivateKey, githubAppPrivateKey) + credsInfo.GCPServiceAccountKey = l.setSecretData(repoSecretPrefix, r.Repo, secretsData, credsInfo.GCPServiceAccountKey, r.GCPServiceAccountKey, gcpServiceAccountKey) + for k, v := range secretsData { + err := l.upsertSecret(k, v) + if err != nil { + return err + } + } + return nil +} + +func (l *legacyRepositoryBackend) upsertSecret(name string, data map[string][]byte) error { + secret, err := l.db.kubeclientset.CoreV1().Secrets(l.db.ns).Get(context.Background(), name, metav1.GetOptions{}) + if err != nil { + if apierr.IsNotFound(err) { + if len(data) == 0 { + return nil + } + _, err = l.db.kubeclientset.CoreV1().Secrets(l.db.ns).Create(context.Background(), &apiv1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Annotations: map[string]string{ + common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD, + }, + }, + Data: data, + }, metav1.CreateOptions{}) + if err != nil { + return err + } + } + } else { + for _, key := range []string{username, password, sshPrivateKey, tlsClientCertData, tlsClientCertKey, githubAppPrivateKey} { + if secret.Data == nil { + secret.Data = make(map[string][]byte) + } + if val, ok := data[key]; ok && len(val) > 0 { + secret.Data[key] = val + } else { + delete(secret.Data, key) + } + } + if len(secret.Data) == 0 { + isManagedByArgo := secret.Annotations != nil && secret.Annotations[common.AnnotationKeyManagedBy] == common.AnnotationValueManagedByArgoCD + if isManagedByArgo { + return l.db.kubeclientset.CoreV1().Secrets(l.db.ns).Delete(context.Background(), name, metav1.DeleteOptions{}) + } + return nil + } else { + _, err = l.db.kubeclientset.CoreV1().Secrets(l.db.ns).Update(context.Background(), secret, metav1.UpdateOptions{}) + if err != nil { + return err + } + } + } + return nil +} + +// tryGetRepository returns a repository by URL. +// It provides the same functionality as GetRepository, with the additional behaviour of still returning a repository, +// even if an error occurred during the resolving of credentials for the repository. Otherwise this function behaves +// just as one would expect. +func (l *legacyRepositoryBackend) tryGetRepository(repoURL string) (*appsv1.Repository, error) { + repos, err := l.db.settingsMgr.GetRepositories() + if err != nil { + return nil, err + } + + repo := &appsv1.Repository{Repo: repoURL} + index := l.getRepositoryIndex(repos, repoURL) + if index >= 0 { + repo, err = l.credentialsToRepository(repos[index]) + if err != nil { + return repo, errors.NewCredentialsConfigurationError(err) + } + } + + return repo, err +} + +func (l *legacyRepositoryBackend) credentialsToRepository(repoInfo settings.Repository) (*appsv1.Repository, error) { + repo := &appsv1.Repository{ + Repo: repoInfo.URL, + Type: repoInfo.Type, + Name: repoInfo.Name, + InsecureIgnoreHostKey: repoInfo.InsecureIgnoreHostKey, + Insecure: repoInfo.Insecure, + EnableLFS: repoInfo.EnableLFS, + EnableOCI: repoInfo.EnableOci, + GithubAppId: repoInfo.GithubAppId, + GithubAppInstallationId: repoInfo.GithubAppInstallationId, + GitHubAppEnterpriseBaseURL: repoInfo.GithubAppEnterpriseBaseURL, + Proxy: repoInfo.Proxy, + } + err := l.db.unmarshalFromSecretsStr(map[*SecretMaperValidation]*apiv1.SecretKeySelector{ + {Dest: &repo.Username, Transform: StripCRLFCharacter}: repoInfo.UsernameSecret, + {Dest: &repo.Password, Transform: StripCRLFCharacter}: repoInfo.PasswordSecret, + {Dest: &repo.SSHPrivateKey, Transform: StripCRLFCharacter}: repoInfo.SSHPrivateKeySecret, + {Dest: &repo.TLSClientCertData, Transform: StripCRLFCharacter}: repoInfo.TLSClientCertDataSecret, + {Dest: &repo.TLSClientCertKey, Transform: StripCRLFCharacter}: repoInfo.TLSClientCertKeySecret, + {Dest: &repo.GithubAppPrivateKey, Transform: StripCRLFCharacter}: repoInfo.GithubAppPrivateKeySecret, + {Dest: &repo.GCPServiceAccountKey, Transform: StripCRLFCharacter}: repoInfo.GCPServiceAccountKey, + }, make(map[string]*apiv1.Secret)) + return repo, err +} + +func (l *legacyRepositoryBackend) credentialsToRepositoryCredentials(repoInfo settings.RepositoryCredentials) (*appsv1.RepoCreds, error) { + creds := &appsv1.RepoCreds{ + URL: repoInfo.URL, + GithubAppId: repoInfo.GithubAppId, + GithubAppInstallationId: repoInfo.GithubAppInstallationId, + GitHubAppEnterpriseBaseURL: repoInfo.GithubAppEnterpriseBaseURL, + EnableOCI: repoInfo.EnableOCI, + } + err := l.db.unmarshalFromSecretsStr(map[*SecretMaperValidation]*apiv1.SecretKeySelector{ + {Dest: &creds.Username}: repoInfo.UsernameSecret, + {Dest: &creds.Password}: repoInfo.PasswordSecret, + {Dest: &creds.SSHPrivateKey}: repoInfo.SSHPrivateKeySecret, + {Dest: &creds.TLSClientCertData}: repoInfo.TLSClientCertDataSecret, + {Dest: &creds.TLSClientCertKey}: repoInfo.TLSClientCertKeySecret, + {Dest: &creds.GithubAppPrivateKey}: repoInfo.GithubAppPrivateKeySecret, + {Dest: &creds.GCPServiceAccountKey}: repoInfo.GCPServiceAccountKey, + }, make(map[string]*apiv1.Secret)) + return creds, err +} + +// Set data to be stored in a given secret used for repository credentials and templates. +// The name of the secret is a combination of the prefix given, and a calculated value +// from the repository or template URL. +func (l *legacyRepositoryBackend) setSecretData(prefix string, url string, secretsData map[string]map[string][]byte, secretKey *apiv1.SecretKeySelector, value string, defaultKeyName string) *apiv1.SecretKeySelector { + if secretKey == nil && value != "" { + secretKey = &apiv1.SecretKeySelector{ + LocalObjectReference: apiv1.LocalObjectReference{Name: RepoURLToSecretName(prefix, url, "")}, + Key: defaultKeyName, + } + } + + if secretKey != nil { + data, ok := secretsData[secretKey.Name] + if !ok { + data = map[string][]byte{} + } + if value != "" { + data[secretKey.Key] = []byte(value) + } + secretsData[secretKey.Name] = data + } + + if value == "" { + secretKey = nil + } + + return secretKey +} + +func (l *legacyRepositoryBackend) getRepositoryIndex(repos []settings.Repository, repoURL string) int { + for i, repo := range repos { + if git.SameURL(repo.URL, repoURL) { + return i + } + } + return -1 +} + +// getRepositoryCredentialIndex returns the index of the best matching repository credential +// configuration, i.e. the one with the longest match +func getRepositoryCredentialIndex(repoCredentials []settings.RepositoryCredentials, repoURL string) int { + var max, idx int = 0, -1 + repoURL = git.NormalizeGitURL(repoURL) + for i, cred := range repoCredentials { + credUrl := git.NormalizeGitURL(cred.URL) + if strings.HasPrefix(repoURL, credUrl) { + if len(credUrl) > max { + max = len(credUrl) + idx = i + } + } + } + return idx +} diff --git a/util/db/repository_legacy_test.go b/util/db/repository_legacy_test.go new file mode 100644 index 0000000000..b414ffa9cc --- /dev/null +++ b/util/db/repository_legacy_test.go @@ -0,0 +1,35 @@ +package db + +import ( + "testing" + + "github.com/argoproj/argo-cd/v2/util/settings" +) + +func Test_getRepositoryCredentialIndex(t *testing.T) { + repositoryCredentials := []settings.RepositoryCredentials{ + {URL: "http://known"}, + {URL: "http://known/repos"}, + {URL: "http://known/other"}, + {URL: "http://known/other/other"}, + } + tests := []struct { + name string + repoURL string + want int + }{ + {"TestNotFound", "", -1}, + {"TestNotFound", "http://unknown/repos", -1}, + {"TestNotFound", "http://unknown/repo/repo", -1}, + {"TestFoundFound", "http://known/repos/repo", 1}, + {"TestFoundFound", "http://known/other/repo/foo", 2}, + {"TestFoundFound", "http://known/other/other/repo", 3}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := getRepositoryCredentialIndex(repositoryCredentials, tt.repoURL); got != tt.want { + t.Errorf("getRepositoryCredentialIndex() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/util/db/repository_secrets.go b/util/db/repository_secrets.go index bc32d27835..1897e54d6d 100644 --- a/util/db/repository_secrets.go +++ b/util/db/repository_secrets.go @@ -9,12 +9,12 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/common" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/git" + "github.com/argoproj/argo-cd/v2/common" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/git" ) var _ repositoryBackend = &secretsRepositoryBackend{} @@ -38,7 +38,7 @@ func (s *secretsRepositoryBackend) CreateRepository(ctx context.Context, reposit _, err := s.db.createSecret(ctx, repositorySecret) if err != nil { - if apierrors.IsAlreadyExists(err) { + if apierr.IsAlreadyExists(err) { hasLabel, err := s.hasRepoTypeLabel(secName) if err != nil { return nil, status.Error(codes.Internal, err.Error()) @@ -63,7 +63,7 @@ func (s *secretsRepositoryBackend) hasRepoTypeLabel(secretName string) (bool, er noCache := make(map[string]*corev1.Secret) sec, err := s.db.getSecret(secretName, noCache) if err != nil { - if apierrors.IsNotFound(err) { + if apierr.IsNotFound(err) { return false, nil } return false, err @@ -83,7 +83,7 @@ func (s *secretsRepositoryBackend) GetRepoCredsBySecretName(_ context.Context, n return s.secretToRepoCred(secret) } -func (s *secretsRepositoryBackend) GetRepository(_ context.Context, repoURL, project string) (*appsv1.Repository, error) { +func (s *secretsRepositoryBackend) GetRepository(ctx context.Context, repoURL, project string) (*appsv1.Repository, error) { secret, err := s.getRepositorySecret(repoURL, project, true) if err != nil { if status.Code(err) == codes.NotFound { @@ -101,7 +101,7 @@ func (s *secretsRepositoryBackend) GetRepository(_ context.Context, repoURL, pro return repository, err } -func (s *secretsRepositoryBackend) ListRepositories(_ context.Context, repoType *string) ([]*appsv1.Repository, error) { +func (s *secretsRepositoryBackend) ListRepositories(ctx context.Context, repoType *string) ([]*appsv1.Repository, error) { var repos []*appsv1.Repository secrets, err := s.db.listSecretsByType(s.getSecretType()) @@ -112,17 +112,18 @@ func (s *secretsRepositoryBackend) ListRepositories(_ context.Context, repoType for _, secret := range secrets { r, err := secretToRepository(secret) if err != nil { - if r == nil { + if r != nil { + modifiedTime := metav1.Now() + r.ConnectionState = appsv1.ConnectionState{ + Status: appsv1.ConnectionStatusFailed, + Message: "Configuration error - please check the server logs", + ModifiedAt: &modifiedTime, + } + + log.Warnf("Error while parsing repository secret '%s': %v", secret.Name, err) + } else { return nil, err } - modifiedTime := metav1.Now() - r.ConnectionState = appsv1.ConnectionState{ - Status: appsv1.ConnectionStatusFailed, - Message: "Configuration error - please check the server logs", - ModifiedAt: &modifiedTime, - } - - log.Warnf("Error while parsing repository secret '%s': %v", secret.Name, err) } if repoType == nil || *repoType == r.Type { @@ -165,7 +166,7 @@ func (s *secretsRepositoryBackend) DeleteRepository(ctx context.Context, repoURL return s.db.settingsMgr.ResyncInformers() } -func (s *secretsRepositoryBackend) RepositoryExists(_ context.Context, repoURL, project string, allowFallback bool) (bool, error) { +func (s *secretsRepositoryBackend) RepositoryExists(ctx context.Context, repoURL, project string, allowFallback bool) (bool, error) { secret, err := s.getRepositorySecret(repoURL, project, allowFallback) if err != nil { if status.Code(err) == codes.NotFound { @@ -191,7 +192,7 @@ func (s *secretsRepositoryBackend) CreateRepoCreds(ctx context.Context, repoCred _, err := s.db.createSecret(ctx, repoCredsSecret) if err != nil { - if apierrors.IsAlreadyExists(err) { + if apierr.IsAlreadyExists(err) { return nil, status.Errorf(codes.AlreadyExists, "repository credentials %q already exists", repoCreds.URL) } return nil, err @@ -200,7 +201,7 @@ func (s *secretsRepositoryBackend) CreateRepoCreds(ctx context.Context, repoCred return repoCreds, s.db.settingsMgr.ResyncInformers() } -func (s *secretsRepositoryBackend) GetRepoCreds(_ context.Context, repoURL string) (*appsv1.RepoCreds, error) { +func (s *secretsRepositoryBackend) GetRepoCreds(ctx context.Context, repoURL string) (*appsv1.RepoCreds, error) { secret, err := s.getRepoCredsSecret(repoURL) if err != nil { if status.Code(err) == codes.NotFound { @@ -213,7 +214,7 @@ func (s *secretsRepositoryBackend) GetRepoCreds(_ context.Context, repoURL strin return s.secretToRepoCred(secret) } -func (s *secretsRepositoryBackend) ListRepoCreds(_ context.Context) ([]string, error) { +func (s *secretsRepositoryBackend) ListRepoCreds(ctx context.Context) ([]string, error) { var repoURLs []string secrets, err := s.db.listSecretsByType(common.LabelValueSecretTypeRepoCreds) @@ -265,7 +266,7 @@ func (s *secretsRepositoryBackend) DeleteRepoCreds(ctx context.Context, name str return s.db.settingsMgr.ResyncInformers() } -func (s *secretsRepositoryBackend) RepoCredsExists(_ context.Context, repoURL string) (bool, error) { +func (s *secretsRepositoryBackend) RepoCredsExists(ctx context.Context, repoURL string) (bool, error) { _, err := s.getRepoCredsSecret(repoURL) if err != nil { if status.Code(err) == codes.NotFound { @@ -278,7 +279,7 @@ func (s *secretsRepositoryBackend) RepoCredsExists(_ context.Context, repoURL st return true, nil } -func (s *secretsRepositoryBackend) GetAllHelmRepoCreds(_ context.Context) ([]*appsv1.RepoCreds, error) { +func (s *secretsRepositoryBackend) GetAllHelmRepoCreds(ctx context.Context) ([]*appsv1.RepoCreds, error) { var helmRepoCreds []*appsv1.RepoCreds secrets, err := s.db.listSecretsByType(common.LabelValueSecretTypeRepoCreds) @@ -306,7 +307,6 @@ func secretToRepository(secret *corev1.Secret) (*appsv1.Repository, error) { Repo: string(secret.Data["url"]), Username: string(secret.Data["username"]), Password: string(secret.Data["password"]), - BearerToken: string(secret.Data["bearerToken"]), SSHPrivateKey: string(secret.Data["sshPrivateKey"]), TLSClientCertData: string(secret.Data["tlsClientCertData"]), TLSClientCertKey: string(secret.Data["tlsClientCertKey"]), @@ -361,12 +361,6 @@ func secretToRepository(secret *corev1.Secret) (*appsv1.Repository, error) { } repository.ForceHttpBasicAuth = forceBasicAuth - useAzureWorkloadIdentity, err := boolOrFalse(secret, "useAzureWorkloadIdentity") - if err != nil { - return repository, err - } - repository.UseAzureWorkloadIdentity = useAzureWorkloadIdentity - return repository, nil } @@ -380,7 +374,6 @@ func (s *secretsRepositoryBackend) repositoryToSecret(repository *appsv1.Reposit updateSecretString(secret, "url", repository.Repo) updateSecretString(secret, "username", repository.Username) updateSecretString(secret, "password", repository.Password) - updateSecretString(secret, "bearerToken", repository.BearerToken) updateSecretString(secret, "sshPrivateKey", repository.SSHPrivateKey) updateSecretBool(secret, "enableOCI", repository.EnableOCI) updateSecretString(secret, "tlsClientCertData", repository.TLSClientCertData) @@ -397,7 +390,6 @@ func (s *secretsRepositoryBackend) repositoryToSecret(repository *appsv1.Reposit updateSecretString(secret, "noProxy", repository.NoProxy) updateSecretString(secret, "gcpServiceAccountKey", repository.GCPServiceAccountKey) updateSecretBool(secret, "forceHttpBasicAuth", repository.ForceHttpBasicAuth) - updateSecretBool(secret, "useAzureWorkloadIdentity", repository.UseAzureWorkloadIdentity) addSecretMetadata(secret, s.getSecretType()) } @@ -406,7 +398,6 @@ func (s *secretsRepositoryBackend) secretToRepoCred(secret *corev1.Secret) (*app URL: string(secret.Data["url"]), Username: string(secret.Data["username"]), Password: string(secret.Data["password"]), - BearerToken: string(secret.Data["bearerToken"]), SSHPrivateKey: string(secret.Data["sshPrivateKey"]), TLSClientCertData: string(secret.Data["tlsClientCertData"]), TLSClientCertKey: string(secret.Data["tlsClientCertKey"]), @@ -442,12 +433,6 @@ func (s *secretsRepositoryBackend) secretToRepoCred(secret *corev1.Secret) (*app } repository.ForceHttpBasicAuth = forceBasicAuth - useAzureWorkloadIdentity, err := boolOrFalse(secret, "useAzureWorkloadIdentity") - if err != nil { - return repository, err - } - repository.UseAzureWorkloadIdentity = useAzureWorkloadIdentity - return repository, nil } @@ -459,7 +444,6 @@ func repoCredsToSecret(repoCreds *appsv1.RepoCreds, secret *corev1.Secret) { updateSecretString(secret, "url", repoCreds.URL) updateSecretString(secret, "username", repoCreds.Username) updateSecretString(secret, "password", repoCreds.Password) - updateSecretString(secret, "bearerToken", repoCreds.BearerToken) updateSecretString(secret, "sshPrivateKey", repoCreds.SSHPrivateKey) updateSecretBool(secret, "enableOCI", repoCreds.EnableOCI) updateSecretString(secret, "tlsClientCertData", repoCreds.TLSClientCertData) @@ -473,7 +457,6 @@ func repoCredsToSecret(repoCreds *appsv1.RepoCreds, secret *corev1.Secret) { updateSecretString(secret, "proxy", repoCreds.Proxy) updateSecretString(secret, "noProxy", repoCreds.NoProxy) updateSecretBool(secret, "forceHttpBasicAuth", repoCreds.ForceHttpBasicAuth) - updateSecretBool(secret, "useAzureWorkloadIdentity", repoCreds.UseAzureWorkloadIdentity) addSecretMetadata(secret, common.LabelValueSecretTypeRepoCreds) } @@ -530,13 +513,13 @@ func (s *secretsRepositoryBackend) getRepositoryCredentialIndex(repoCredentials max, idx := 0, -1 repoURL = git.NormalizeGitURL(repoURL) for i, cred := range repoCredentials { - credURL := git.NormalizeGitURL(string(cred.Data["url"])) - if strings.HasPrefix(repoURL, credURL) { - if len(credURL) == max { + credUrl := git.NormalizeGitURL(string(cred.Data["url"])) + if strings.HasPrefix(repoURL, credUrl) { + if len(credUrl) == max { log.Warnf("Found multiple credentials for repoURL: %s", repoURL) } - if len(credURL) > max { - max = len(credURL) + if len(credUrl) > max { + max = len(credUrl) idx = i } } diff --git a/util/db/repository_secrets_test.go b/util/db/repository_secrets_test.go index d5f3e42a45..e484999f88 100644 --- a/util/db/repository_secrets_test.go +++ b/util/db/repository_secrets_test.go @@ -1,6 +1,7 @@ package db import ( + "context" "strconv" "testing" @@ -9,7 +10,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -17,9 +18,9 @@ import ( "k8s.io/client-go/kubernetes/fake" k8stesting "k8s.io/client-go/testing" - "github.com/argoproj/argo-cd/v3/common" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/settings" ) func TestSecretsRepositoryBackend_CreateRepository(t *testing.T) { @@ -36,8 +37,8 @@ func TestSecretsRepositoryBackend_CreateRepository(t *testing.T) { EnableLFS: true, } setupWithK8sObjects := func(objects ...runtime.Object) *fixture { - clientset := getClientset(objects...) - settingsMgr := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + clientset := getClientset(map[string]string{}, objects...) + settingsMgr := settings.NewSettingsManager(context.Background(), clientset, testNamespace) repoBackend := &secretsRepositoryBackend{db: &db{ ns: testNamespace, kubeclientset: clientset, @@ -54,14 +55,14 @@ func TestSecretsRepositoryBackend_CreateRepository(t *testing.T) { f := setupWithK8sObjects() // when - output, err := f.repoBackend.CreateRepository(t.Context(), repo) + output, err := f.repoBackend.CreateRepository(context.Background(), repo) // then require.NoError(t, err) assert.Same(t, repo, output) secret, err := f.clientSet.CoreV1().Secrets(testNamespace).Get( - t.Context(), + context.TODO(), RepoURLToSecretName(repoSecretPrefix, repo.Repo, ""), metav1.GetOptions{}, ) @@ -75,7 +76,7 @@ func TestSecretsRepositoryBackend_CreateRepository(t *testing.T) { assert.Equal(t, repo.Repo, string(secret.Data["url"])) assert.Equal(t, repo.Username, string(secret.Data["username"])) assert.Equal(t, repo.Password, string(secret.Data["password"])) - assert.Empty(t, string(secret.Data["insecureIgnoreHostKey"])) + assert.Equal(t, "", string(secret.Data["insecureIgnoreHostKey"])) assert.Equal(t, strconv.FormatBool(repo.EnableLFS), string(secret.Data["enableLfs"])) }) t.Run("will return proper error if secret does not have expected label", func(t *testing.T) { @@ -87,16 +88,16 @@ func TestSecretsRepositoryBackend_CreateRepository(t *testing.T) { delete(secret.Labels, common.LabelKeySecretType) f := setupWithK8sObjects(secret) f.clientSet.ReactionChain = nil - f.clientSet.AddReactor("create", "secrets", func(_ k8stesting.Action) (handled bool, ret runtime.Object, err error) { + f.clientSet.AddReactor("create", "secrets", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { gr := schema.GroupResource{ Group: "v1", Resource: "secrets", } - return true, nil, apierrors.NewAlreadyExists(gr, "already exists") + return true, nil, k8serrors.NewAlreadyExists(gr, "already exists") }) // when - output, err := f.repoBackend.CreateRepository(t.Context(), repo) + output, err := f.repoBackend.CreateRepository(context.Background(), repo) // then require.Error(t, err) @@ -124,21 +125,21 @@ func TestSecretsRepositoryBackend_CreateRepository(t *testing.T) { f := setupWithK8sObjects(secret) f.clientSet.ReactionChain = nil f.clientSet.WatchReactionChain = nil - f.clientSet.AddReactor("create", "secrets", func(_ k8stesting.Action) (handled bool, ret runtime.Object, err error) { + f.clientSet.AddReactor("create", "secrets", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { gr := schema.GroupResource{ Group: "v1", Resource: "secrets", } - return true, nil, apierrors.NewAlreadyExists(gr, "already exists") + return true, nil, k8serrors.NewAlreadyExists(gr, "already exists") }) watcher := watch.NewFakeWithChanSize(1, true) watcher.Add(secret) - f.clientSet.AddWatchReactor("secrets", func(_ k8stesting.Action) (handled bool, ret watch.Interface, err error) { + f.clientSet.AddWatchReactor("secrets", func(action k8stesting.Action) (handled bool, ret watch.Interface, err error) { return true, watcher, nil }) // when - output, err := f.repoBackend.CreateRepository(t.Context(), repo) + output, err := f.repoBackend.CreateRepository(context.Background(), repo) // then require.Error(t, err) @@ -209,14 +210,14 @@ func TestSecretsRepositoryBackend_GetRepository(t *testing.T) { }, } - clientset := getClientset(repoSecrets...) + clientset := getClientset(map[string]string{}, repoSecrets...) testee := &secretsRepositoryBackend{db: &db{ ns: testNamespace, kubeclientset: clientset, - settingsMgr: settings.NewSettingsManager(t.Context(), clientset, testNamespace), + settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), }} - repository, err := testee.GetRepository(t.Context(), "git@github.com:argoproj/argo-cd.git", "") + repository, err := testee.GetRepository(context.TODO(), "git@github.com:argoproj/argo-cd.git", "") require.NoError(t, err) assert.NotNil(t, repository) assert.Equal(t, "ArgoCD", repository.Name) @@ -224,7 +225,7 @@ func TestSecretsRepositoryBackend_GetRepository(t *testing.T) { assert.Equal(t, "someUsername", repository.Username) assert.Equal(t, "somePassword", repository.Password) - repository, err = testee.GetRepository(t.Context(), "git@github.com:argoproj/argoproj.git", "") + repository, err = testee.GetRepository(context.TODO(), "git@github.com:argoproj/argoproj.git", "") require.NoError(t, err) assert.NotNil(t, repository) assert.Equal(t, "UserManagedRepo", repository.Name) @@ -232,7 +233,7 @@ func TestSecretsRepositoryBackend_GetRepository(t *testing.T) { assert.Equal(t, "someOtherUsername", repository.Username) assert.Equal(t, "someOtherPassword", repository.Password) - repository, err = testee.GetRepository(t.Context(), "git@github.com:argoproj/argo-cd.git", "testProject") + repository, err = testee.GetRepository(context.TODO(), "git@github.com:argoproj/argo-cd.git", "testProject") require.NoError(t, err) assert.NotNil(t, repository) assert.Equal(t, "Scoped ArgoCD", repository.Name) @@ -241,7 +242,7 @@ func TestSecretsRepositoryBackend_GetRepository(t *testing.T) { assert.Equal(t, "someScopedPassword", repository.Password) assert.Equal(t, "testProject", repository.Project) - repository, err = testee.GetRepository(t.Context(), "git@github.com:argoproj/argoproj.git", "testProject") + repository, err = testee.GetRepository(context.TODO(), "git@github.com:argoproj/argoproj.git", "testProject") require.NoError(t, err) assert.NotNil(t, repository) assert.Equal(t, "Scoped UserManagedRepo", repository.Name) @@ -282,28 +283,27 @@ func TestSecretsRepositoryBackend_ListRepositories(t *testing.T) { }, } - clientset := getClientset(repoSecrets...) + clientset := getClientset(map[string]string{}, repoSecrets...) testee := &secretsRepositoryBackend{db: &db{ ns: testNamespace, kubeclientset: clientset, - settingsMgr: settings.NewSettingsManager(t.Context(), clientset, testNamespace), + settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), }} - repositories, err := testee.ListRepositories(t.Context(), nil) + repositories, err := testee.ListRepositories(context.TODO(), nil) require.NoError(t, err) assert.Len(t, repositories, 2) for _, repository := range repositories { - switch repository.Name { - case "ArgoCD": + if repository.Name == "ArgoCD" { assert.Equal(t, "git@github.com:argoproj/argo-cd.git", repository.Repo) assert.Equal(t, "someUsername", repository.Username) assert.Equal(t, "somePassword", repository.Password) - case "UserManagedRepo": + } else if repository.Name == "UserManagedRepo" { assert.Equal(t, "git@github.com:argoproj/argoproj.git", repository.Repo) assert.Equal(t, "someOtherUsername", repository.Username) assert.Equal(t, "someOtherPassword", repository.Password) - default: + } else { assert.Fail(t, "unexpected repository found in list") } } @@ -405,62 +405,62 @@ func TestSecretsRepositoryBackend_UpdateRepository(t *testing.T) { }, } - clientset := getClientset(repoSecrets...) + clientset := getClientset(map[string]string{}, repoSecrets...) testee := &secretsRepositoryBackend{db: &db{ ns: testNamespace, kubeclientset: clientset, - settingsMgr: settings.NewSettingsManager(t.Context(), clientset, testNamespace), + settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), }} managedRepository.Username = "newUsername" - updateRepository, err := testee.UpdateRepository(t.Context(), managedRepository) + updateRepository, err := testee.UpdateRepository(context.TODO(), managedRepository) require.NoError(t, err) assert.Same(t, managedRepository, updateRepository) assert.Equal(t, managedRepository.Username, updateRepository.Username) - secret, err := clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), managedSecretName, metav1.GetOptions{}) + secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), managedSecretName, metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, secret) assert.Equal(t, "newUsername", string(secret.Data["username"])) userProvidedRepository.Username = "newOtherUsername" - updateRepository, err = testee.UpdateRepository(t.Context(), userProvidedRepository) + updateRepository, err = testee.UpdateRepository(context.TODO(), userProvidedRepository) require.NoError(t, err) assert.Same(t, userProvidedRepository, updateRepository) assert.Equal(t, userProvidedRepository.Username, updateRepository.Username) - secret, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), "user-managed", metav1.GetOptions{}) + secret, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), "user-managed", metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, secret) assert.Equal(t, "newOtherUsername", string(secret.Data["username"])) - updateRepository, err = testee.UpdateRepository(t.Context(), newRepository) + updateRepository, err = testee.UpdateRepository(context.TODO(), newRepository) require.NoError(t, err) assert.Same(t, newRepository, updateRepository) - secret, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), newSecretName, metav1.GetOptions{}) + secret, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), newSecretName, metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, secret) assert.Equal(t, "foo", string(secret.Data["username"])) managedProjectRepository.Username = "newUsername" - updateRepository, err = testee.UpdateRepository(t.Context(), managedProjectRepository) + updateRepository, err = testee.UpdateRepository(context.TODO(), managedProjectRepository) require.NoError(t, err) assert.Same(t, managedProjectRepository, updateRepository) assert.Equal(t, managedProjectRepository.Username, updateRepository.Username) - secret, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), managedProjectSecretName, metav1.GetOptions{}) + secret, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), managedProjectSecretName, metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, secret) assert.Equal(t, "newUsername", string(secret.Data["username"])) userProvidedProjectRepository.Username = "newUsernameScoped" - updateRepository, err = testee.UpdateRepository(t.Context(), userProvidedProjectRepository) + updateRepository, err = testee.UpdateRepository(context.TODO(), userProvidedProjectRepository) require.NoError(t, err) assert.Same(t, userProvidedProjectRepository, updateRepository) assert.Equal(t, userProvidedProjectRepository.Username, updateRepository.Username) - secret, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), "user-managed-scoped", metav1.GetOptions{}) + secret, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), "user-managed-scoped", metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, secret) assert.Equal(t, "newUsernameScoped", string(secret.Data["username"])) @@ -514,43 +514,43 @@ func TestSecretsRepositoryBackend_DeleteRepository(t *testing.T) { }, } - clientset := getClientset(repoSecrets...) + clientset := getClientset(map[string]string{}, repoSecrets...) testee := &secretsRepositoryBackend{db: &db{ ns: testNamespace, kubeclientset: clientset, - settingsMgr: settings.NewSettingsManager(t.Context(), clientset, testNamespace), + settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), }} - err := testee.DeleteRepository(t.Context(), "git@github.com:argoproj/argo-cd.git", "") + err := testee.DeleteRepository(context.TODO(), "git@github.com:argoproj/argo-cd.git", "") require.NoError(t, err) - _, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), managedSecretName, metav1.GetOptions{}) + _, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), managedSecretName, metav1.GetOptions{}) require.Error(t, err) - _, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), managedScopedSecretName, metav1.GetOptions{}) + _, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), managedScopedSecretName, metav1.GetOptions{}) require.NoError(t, err) - err = testee.DeleteRepository(t.Context(), "git@github.com:argoproj/argo-cd.git", "someProject") + err = testee.DeleteRepository(context.TODO(), "git@github.com:argoproj/argo-cd.git", "someProject") require.NoError(t, err) - _, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), managedScopedSecretName, metav1.GetOptions{}) + _, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), managedScopedSecretName, metav1.GetOptions{}) require.Error(t, err) - err = testee.DeleteRepository(t.Context(), "git@github.com:argoproj/argoproj.git", "") + err = testee.DeleteRepository(context.TODO(), "git@github.com:argoproj/argoproj.git", "") require.NoError(t, err) - secret, err := clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), "user-managed", metav1.GetOptions{}) + secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), "user-managed", metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, secret) assert.Empty(t, secret.Labels[common.LabelValueSecretTypeRepository]) } func TestSecretsRepositoryBackend_CreateRepoCreds(t *testing.T) { - clientset := getClientset() + clientset := getClientset(map[string]string{}) testee := &secretsRepositoryBackend{db: &db{ ns: testNamespace, kubeclientset: clientset, - settingsMgr: settings.NewSettingsManager(t.Context(), clientset, testNamespace), + settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), }} testCases := []struct { @@ -591,12 +591,12 @@ func TestSecretsRepositoryBackend_CreateRepoCreds(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - output, err := testee.CreateRepoCreds(t.Context(), &testCase.repoCreds) + output, err := testee.CreateRepoCreds(context.TODO(), &testCase.repoCreds) require.NoError(t, err) assert.Same(t, &testCase.repoCreds, output) secret, err := clientset.CoreV1().Secrets(testNamespace).Get( - t.Context(), + context.TODO(), RepoURLToSecretName(credSecretPrefix, testCase.repoCreds.URL, ""), metav1.GetOptions{}, ) @@ -675,21 +675,21 @@ func TestSecretsRepositoryBackend_GetRepoCreds(t *testing.T) { }, } - clientset := getClientset(repoCredSecrets...) + clientset := getClientset(map[string]string{}, repoCredSecrets...) testee := &secretsRepositoryBackend{db: &db{ ns: testNamespace, kubeclientset: clientset, - settingsMgr: settings.NewSettingsManager(t.Context(), clientset, testNamespace), + settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), }} - repoCred, err := testee.GetRepoCreds(t.Context(), "git@github.com:argoproj") + repoCred, err := testee.GetRepoCreds(context.TODO(), "git@github.com:argoproj") require.NoError(t, err) require.NotNil(t, repoCred) assert.Equal(t, "git@github.com:argoproj", repoCred.URL) assert.Equal(t, "someUsername", repoCred.Username) assert.Equal(t, "somePassword", repoCred.Password) - repoCred, err = testee.GetRepoCreds(t.Context(), "git@gitlab.com") + repoCred, err = testee.GetRepoCreds(context.TODO(), "git@gitlab.com") require.NoError(t, err) assert.NotNil(t, repoCred) assert.Equal(t, "git@gitlab.com", repoCred.URL) @@ -732,14 +732,14 @@ func TestSecretsRepositoryBackend_ListRepoCreds(t *testing.T) { }, } - clientset := getClientset(repoCredSecrets...) + clientset := getClientset(map[string]string{}, repoCredSecrets...) testee := &secretsRepositoryBackend{db: &db{ ns: testNamespace, kubeclientset: clientset, - settingsMgr: settings.NewSettingsManager(t.Context(), clientset, testNamespace), + settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), }} - repoCreds, err := testee.ListRepoCreds(t.Context()) + repoCreds, err := testee.ListRepoCreds(context.TODO()) require.NoError(t, err) assert.Len(t, repoCreds, 2) assert.Contains(t, repoCreds, "git@github.com:argoproj") @@ -793,40 +793,40 @@ func TestSecretsRepositoryBackend_UpdateRepoCreds(t *testing.T) { }, } - clientset := getClientset(repoCredSecrets...) + clientset := getClientset(map[string]string{}, repoCredSecrets...) testee := &secretsRepositoryBackend{db: &db{ ns: testNamespace, kubeclientset: clientset, - settingsMgr: settings.NewSettingsManager(t.Context(), clientset, testNamespace), + settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), }} managedCreds.Username = "newUsername" - updateRepoCreds, err := testee.UpdateRepoCreds(t.Context(), managedCreds) + updateRepoCreds, err := testee.UpdateRepoCreds(context.TODO(), managedCreds) require.NoError(t, err) assert.NotSame(t, managedCreds, updateRepoCreds) assert.Equal(t, managedCreds.Username, updateRepoCreds.Username) - secret, err := clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), managedCredsName, metav1.GetOptions{}) + secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), managedCredsName, metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, secret) assert.Equal(t, "newUsername", string(secret.Data["username"])) userProvidedCreds.Username = "newOtherUsername" - updateRepoCreds, err = testee.UpdateRepoCreds(t.Context(), userProvidedCreds) + updateRepoCreds, err = testee.UpdateRepoCreds(context.TODO(), userProvidedCreds) require.NoError(t, err) assert.NotSame(t, userProvidedCreds, updateRepoCreds) assert.Equal(t, userProvidedCreds.Username, updateRepoCreds.Username) - secret, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), "user-managed", metav1.GetOptions{}) + secret, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), "user-managed", metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, secret) assert.Equal(t, "newOtherUsername", string(secret.Data["username"])) - updateRepoCreds, err = testee.UpdateRepoCreds(t.Context(), newCreds) + updateRepoCreds, err = testee.UpdateRepoCreds(context.TODO(), newCreds) require.NoError(t, err) assert.Same(t, newCreds, updateRepoCreds) - secret, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), newCredsName, metav1.GetOptions{}) + secret, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), newCredsName, metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, secret) assert.Equal(t, "foo", string(secret.Data["username"])) @@ -862,23 +862,23 @@ func TestSecretsRepositoryBackend_DeleteRepoCreds(t *testing.T) { }, } - clientset := getClientset(repoSecrets...) + clientset := getClientset(map[string]string{}, repoSecrets...) testee := &secretsRepositoryBackend{db: &db{ ns: testNamespace, kubeclientset: clientset, - settingsMgr: settings.NewSettingsManager(t.Context(), clientset, testNamespace), + settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), }} - err := testee.DeleteRepoCreds(t.Context(), "git@github.com:argoproj") + err := testee.DeleteRepoCreds(context.TODO(), "git@github.com:argoproj") require.NoError(t, err) - _, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), managedSecretName, metav1.GetOptions{}) + _, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), managedSecretName, metav1.GetOptions{}) require.Error(t, err) - err = testee.DeleteRepoCreds(t.Context(), "git@gitlab.com") + err = testee.DeleteRepoCreds(context.TODO(), "git@gitlab.com") require.NoError(t, err) - secret, err := clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), "user-managed", metav1.GetOptions{}) + secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), "user-managed", metav1.GetOptions{}) require.NoError(t, err) assert.NotNil(t, secret) assert.Empty(t, secret.Labels[common.LabelValueSecretTypeRepoCreds]) @@ -916,14 +916,14 @@ func TestSecretsRepositoryBackend_GetAllHelmRepoCreds(t *testing.T) { }, } - clientset := getClientset(repoCredSecrets...) + clientset := getClientset(map[string]string{}, repoCredSecrets...) testee := &secretsRepositoryBackend{db: &db{ ns: testNamespace, kubeclientset: clientset, - settingsMgr: settings.NewSettingsManager(t.Context(), clientset, testNamespace), + settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), }} - repoCreds, err := testee.GetAllHelmRepoCreds(t.Context()) + repoCreds, err := testee.GetAllHelmRepoCreds(context.TODO()) require.NoError(t, err) assert.Len(t, repoCreds, 1) } diff --git a/util/db/repository_test.go b/util/db/repository_test.go index 90552ab847..a0601815e9 100644 --- a/util/db/repository_test.go +++ b/util/db/repository_test.go @@ -1,6 +1,7 @@ package db import ( + "context" "testing" "github.com/stretchr/testify/assert" @@ -8,9 +9,22 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/common" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/settings" +) + +const ( + repoArgoProj = ` +- name: OtherRepo + url: git@github.com:argoproj/argoproj.git + usernameSecret: + name: managed-secret + key: username + passwordSecret: + name: managed-secret + key: password + type: git` ) var repoArgoCD = &corev1.Secret{ @@ -33,29 +47,9 @@ var repoArgoCD = &corev1.Secret{ }, } -var repoArgoProj = &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: testNamespace, - Name: "some-other-repo-secret", - Annotations: map[string]string{ - common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD, - }, - Labels: map[string]string{ - common.LabelKeySecretType: common.LabelValueSecretTypeRepository, - }, - }, - Data: map[string][]byte{ - "name": []byte("OtherRepo"), - "url": []byte("git@github.com:argoproj/argoproj.git"), - "username": []byte("someUsername"), - "password": []byte("somePassword"), - "type": []byte("git"), - }, -} - func TestDb_CreateRepository(t *testing.T) { - clientset := getClientset() - settingsManager := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + clientset := getClientset(map[string]string{}) + settingsManager := settings.NewSettingsManager(context.TODO(), clientset, testNamespace) testee := &db{ ns: testNamespace, kubeclientset: clientset, @@ -70,12 +64,18 @@ func TestDb_CreateRepository(t *testing.T) { } // The repository was indeed created successfully - output, err := testee.CreateRepository(t.Context(), input) + output, err := testee.CreateRepository(context.TODO(), input) require.NoError(t, err) assert.Same(t, input, output) + // New repositories should not be stored in the settings anymore + settingRepositories, err := settingsManager.GetRepositories() + require.NoError(t, err) + assert.Empty(t, settingRepositories) + + // New repositories should be now stored as secrets secret, err := clientset.CoreV1().Secrets(testNamespace).Get( - t.Context(), + context.TODO(), RepoURLToSecretName(repoSecretPrefix, input.Repo, ""), metav1.GetOptions{}, ) @@ -84,40 +84,40 @@ func TestDb_CreateRepository(t *testing.T) { } func TestDb_GetRepository(t *testing.T) { - clientset := getClientset(repoArgoCD, repoArgoProj) - settingsManager := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + clientset := getClientset(map[string]string{"repositories": repoArgoProj}, newManagedSecret(), repoArgoCD) + settingsManager := settings.NewSettingsManager(context.TODO(), clientset, testNamespace) testee := &db{ ns: testNamespace, kubeclientset: clientset, settingsMgr: settingsManager, } - repository, err := testee.GetRepository(t.Context(), "git@github.com:argoproj/argoproj.git", "") + repository, err := testee.GetRepository(context.TODO(), "git@github.com:argoproj/argoproj.git", "") require.NoError(t, err) - require.NotNil(t, repository) + assert.NotNil(t, repository) assert.Equal(t, "OtherRepo", repository.Name) - repository, err = testee.GetRepository(t.Context(), "git@github.com:argoproj/argo-cd.git", "") + repository, err = testee.GetRepository(context.TODO(), "git@github.com:argoproj/argo-cd.git", "") require.NoError(t, err) - require.NotNil(t, repository) + assert.NotNil(t, repository) assert.Equal(t, "SomeRepo", repository.Name) - repository, err = testee.GetRepository(t.Context(), "git@github.com:argoproj/not-existing.git", "") + repository, err = testee.GetRepository(context.TODO(), "git@github.com:argoproj/not-existing.git", "") require.NoError(t, err) assert.NotNil(t, repository) assert.Equal(t, "git@github.com:argoproj/not-existing.git", repository.Repo) } func TestDb_ListRepositories(t *testing.T) { - clientset := getClientset(repoArgoCD, repoArgoProj) - settingsManager := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + clientset := getClientset(map[string]string{"repositories": repoArgoProj}, newManagedSecret(), repoArgoCD) + settingsManager := settings.NewSettingsManager(context.TODO(), clientset, testNamespace) testee := &db{ ns: testNamespace, kubeclientset: clientset, settingsMgr: settingsManager, } - repositories, err := testee.ListRepositories(t.Context()) + repositories, err := testee.ListRepositories(context.TODO()) require.NoError(t, err) assert.Len(t, repositories, 2) } @@ -130,23 +130,47 @@ func TestDb_UpdateRepository(t *testing.T) { Password: "somePassword", Type: "git", } + settingRepository := &appsv1.Repository{ + Name: "OtherRepo", + Repo: "git@github.com:argoproj/argoproj.git", + Username: "otherUsername", + Password: "otherPassword", + Type: "git", + } - clientset := getClientset(repoArgoCD) - settingsManager := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + clientset := getClientset(map[string]string{"repositories": repoArgoProj}, newManagedSecret(), repoArgoCD) + settingsManager := settings.NewSettingsManager(context.TODO(), clientset, testNamespace) testee := &db{ ns: testNamespace, kubeclientset: clientset, settingsMgr: settingsManager, } + // Verify that legacy repository can still be updated + settingRepository.Username = "OtherUpdatedUsername" + repository, err := testee.UpdateRepository(context.TODO(), settingRepository) + require.NoError(t, err) + assert.NotNil(t, repository) + assert.Same(t, settingRepository, repository) + + secret, err := clientset.CoreV1().Secrets(testNamespace).Get( + context.TODO(), + "managed-secret", + metav1.GetOptions{}, + ) + require.NoError(t, err) + assert.NotNil(t, secret) + assert.Equal(t, "OtherUpdatedUsername", string(secret.Data["username"])) + + // Verify that secret-based repository can be updated secretRepository.Username = "UpdatedUsername" - repository, err := testee.UpdateRepository(t.Context(), secretRepository) + repository, err = testee.UpdateRepository(context.TODO(), secretRepository) require.NoError(t, err) assert.NotNil(t, repository) assert.Same(t, secretRepository, repository) - secret, err := clientset.CoreV1().Secrets(testNamespace).Get( - t.Context(), + secret, err = clientset.CoreV1().Secrets(testNamespace).Get( + context.TODO(), "some-repo-secret", metav1.GetOptions{}, ) @@ -156,26 +180,40 @@ func TestDb_UpdateRepository(t *testing.T) { } func TestDb_DeleteRepository(t *testing.T) { - clientset := getClientset(repoArgoCD, repoArgoProj) - settingsManager := settings.NewSettingsManager(t.Context(), clientset, testNamespace) + clientset := getClientset(map[string]string{"repositories": repoArgoProj}, newManagedSecret(), repoArgoCD) + settingsManager := settings.NewSettingsManager(context.TODO(), clientset, testNamespace) testee := &db{ ns: testNamespace, kubeclientset: clientset, settingsMgr: settingsManager, } - err := testee.DeleteRepository(t.Context(), "git@github.com:argoproj/argoproj.git", "") + err := testee.DeleteRepository(context.TODO(), "git@github.com:argoproj/argoproj.git", "") require.NoError(t, err) - err = testee.DeleteRepository(t.Context(), "git@github.com:argoproj/argo-cd.git", "") + repositories, err := settingsManager.GetRepositories() + require.NoError(t, err) + assert.Empty(t, repositories) + + err = testee.DeleteRepository(context.TODO(), "git@github.com:argoproj/argo-cd.git", "") require.NoError(t, err) - _, err = clientset.CoreV1().Secrets(testNamespace).Get(t.Context(), "some-repo-secret", metav1.GetOptions{}) + _, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), "some-repo-secret", metav1.GetOptions{}) require.Error(t, err) } func TestDb_GetRepositoryCredentials(t *testing.T) { - gitHubRepoCredsSecret := &corev1.Secret{ + repositoryCredentialsSettings := ` +- type: git + url: git@github.com:argoproj + usernameSecret: + name: managed-secret + key: username + passwordSecret: + name: managed-secret + key: password +` + repoCredsSecret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, Name: "some-repocreds-secret", @@ -183,21 +221,6 @@ func TestDb_GetRepositoryCredentials(t *testing.T) { common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds, }, }, - Data: map[string][]byte{ - "type": []byte("git"), - "url": []byte("git@github.com:argoproj"), - "username": []byte("someUsername"), - "password": []byte("somePassword"), - }, - } - gitLabRepoCredsSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: testNamespace, - Name: "some-other-repocreds-secret", - Labels: map[string]string{ - common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds, - }, - }, Data: map[string][]byte{ "type": []byte("git"), "url": []byte("git@gitlab.com"), @@ -206,82 +229,83 @@ func TestDb_GetRepositoryCredentials(t *testing.T) { }, } - clientset := getClientset(gitHubRepoCredsSecret, gitLabRepoCredsSecret) - testee := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + clientset := getClientset(map[string]string{"repository.credentials": repositoryCredentialsSettings}, newManagedSecret(), repoCredsSecret) + testee := NewDB(testNamespace, settings.NewSettingsManager(context.TODO(), clientset, testNamespace), clientset) - repoCreds, err := testee.GetRepositoryCredentials(t.Context(), "git@github.com:argoproj/argoproj.git") + repoCreds, err := testee.GetRepositoryCredentials(context.TODO(), "git@github.com:argoproj/argoproj.git") require.NoError(t, err) - require.NotNil(t, repoCreds) + assert.NotNil(t, repoCreds) assert.Equal(t, "git@github.com:argoproj", repoCreds.URL) - repoCreds, err = testee.GetRepositoryCredentials(t.Context(), "git@gitlab.com:someorg/foobar.git") + repoCreds, err = testee.GetRepositoryCredentials(context.TODO(), "git@gitlab.com:someorg/foobar.git") require.NoError(t, err) - require.NotNil(t, repoCreds) + assert.NotNil(t, repoCreds) assert.Equal(t, "git@gitlab.com", repoCreds.URL) - repoCreds, err = testee.GetRepositoryCredentials(t.Context(), "git@github.com:example/not-existing.git") + repoCreds, err = testee.GetRepositoryCredentials(context.TODO(), "git@github.com:example/not-existing.git") require.NoError(t, err) assert.Nil(t, repoCreds) } func TestRepoURLToSecretName(t *testing.T) { tables := []struct { - repoURL string + repoUrl string secretName string project string }{{ - repoURL: "git://git@github.com:argoproj/ARGO-cd.git", + repoUrl: "git://git@github.com:argoproj/ARGO-cd.git", secretName: "repo-83273445", project: "", }, { - repoURL: "git://git@github.com:argoproj/ARGO-cd.git", + repoUrl: "git://git@github.com:argoproj/ARGO-cd.git", secretName: "repo-2733415816", project: "foobar", }, { - repoURL: "https://github.com/argoproj/ARGO-cd", + repoUrl: "https://github.com/argoproj/ARGO-cd", secretName: "repo-1890113693", project: "", }, { - repoURL: "https://github.com/argoproj/ARGO-cd", + repoUrl: "https://github.com/argoproj/ARGO-cd", secretName: "repo-4161185408", project: "foobar", }, { - repoURL: "https://github.com/argoproj/argo-cd", + repoUrl: "https://github.com/argoproj/argo-cd", secretName: "repo-42374749", project: "", }, { - repoURL: "https://github.com/argoproj/argo-cd", + repoUrl: "https://github.com/argoproj/argo-cd", secretName: "repo-1894545728", project: "foobar", }, { - repoURL: "https://github.com/argoproj/argo-cd.git", + repoUrl: "https://github.com/argoproj/argo-cd.git", secretName: "repo-821842295", project: "", }, { - repoURL: "https://github.com/argoproj/argo-cd.git", + repoUrl: "https://github.com/argoproj/argo-cd.git", secretName: "repo-1474166686", project: "foobar", }, { - repoURL: "https://github.com/argoproj/argo_cd.git", + repoUrl: "https://github.com/argoproj/argo_cd.git", secretName: "repo-1049844989", project: "", }, { - repoURL: "https://github.com/argoproj/argo_cd.git", + repoUrl: "https://github.com/argoproj/argo_cd.git", secretName: "repo-3916272608", project: "foobar", }, { - repoURL: "ssh://git@github.com/argoproj/argo-cd.git", + repoUrl: "ssh://git@github.com/argoproj/argo-cd.git", secretName: "repo-3569564120", project: "", }, { - repoURL: "ssh://git@github.com/argoproj/argo-cd.git", + repoUrl: "ssh://git@github.com/argoproj/argo-cd.git", secretName: "repo-754834421", project: "foobar", }} for _, v := range tables { - sn := RepoURLToSecretName(repoSecretPrefix, v.repoURL, v.project) - assert.Equal(t, sn, v.secretName, "Expected secret name %q for repo %q; instead, got %q", v.secretName, v.repoURL, sn) + if sn := RepoURLToSecretName(repoSecretPrefix, v.repoUrl, v.project); sn != v.secretName { + t.Errorf("Expected secret name %q for repo %q; instead, got %q", v.secretName, v.repoUrl, sn) + } } } @@ -294,8 +318,9 @@ func Test_CredsURLToSecretName(t *testing.T) { } for k, v := range tables { - sn := RepoURLToSecretName(credSecretPrefix, k, "") - assert.Equal(t, sn, v, "Expected secret name %q for repo %q; instead, got %q", v, k, sn) + if sn := RepoURLToSecretName(credSecretPrefix, k, ""); sn != v { + t.Errorf("Expected secret name %q for repo %q; instead, got %q", v, k, sn) + } } } @@ -329,10 +354,10 @@ func Test_GetProjectRepositories(t *testing.T) { }, } - clientset := getClientset(repoSecretWithProject, repoSecretWithoutProject) - argoDB := NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset) + clientset := getClientset(map[string]string{}, repoSecretWithProject, repoSecretWithoutProject) + argoDB := NewDB(testNamespace, settings.NewSettingsManager(context.TODO(), clientset, testNamespace), clientset) - repos, err := argoDB.GetProjectRepositories("some-project") + repos, err := argoDB.GetProjectRepositories(context.TODO(), "some-project") require.NoError(t, err) assert.Len(t, repos, 1) assert.Equal(t, "git@github.com:argoproj/argo-cd", repos[0].Repo) diff --git a/util/db/secrets.go b/util/db/secrets.go index 56c075c151..21bef2ab9f 100644 --- a/util/db/secrets.go +++ b/util/db/secrets.go @@ -11,19 +11,19 @@ import ( "time" log "github.com/sirupsen/logrus" - corev1 "k8s.io/api/core/v1" + apiv1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/selection" - informersv1 "k8s.io/client-go/informers/core/v1" + informerv1 "k8s.io/client-go/informers/core/v1" "k8s.io/client-go/tools/cache" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util" ) -func (db *db) listSecretsByType(types ...string) ([]*corev1.Secret, error) { +func (db *db) listSecretsByType(types ...string) ([]*apiv1.Secret, error) { labelSelector := labels.NewSelector() req, err := labels.NewRequirement(common.LabelKeySecretType, selection.Equals, types) if err != nil { @@ -46,7 +46,7 @@ func (db *db) listSecretsByType(types ...string) ([]*corev1.Secret, error) { return secrets, nil } -func boolOrFalse(secret *corev1.Secret, key string) (bool, error) { +func boolOrFalse(secret *apiv1.Secret, key string) (bool, error) { val, present := secret.Data[key] if !present { return false, nil @@ -55,7 +55,7 @@ func boolOrFalse(secret *corev1.Secret, key string) (bool, error) { return strconv.ParseBool(string(val)) } -func intOrZero(secret *corev1.Secret, key string) (int64, error) { +func intOrZero(secret *apiv1.Secret, key string) (int64, error) { val, present := secret.Data[key] if !present { return 0, nil @@ -64,29 +64,29 @@ func intOrZero(secret *corev1.Secret, key string) (int64, error) { return strconv.ParseInt(string(val), 10, 64) } -func updateSecretBool(secret *corev1.Secret, key string, value bool) { +func updateSecretBool(secret *apiv1.Secret, key string, value bool) { if _, present := secret.Data[key]; present || value { secret.Data[key] = []byte(strconv.FormatBool(value)) } } -func updateSecretInt(secret *corev1.Secret, key string, value int64) { +func updateSecretInt(secret *apiv1.Secret, key string, value int64) { if _, present := secret.Data[key]; present || value != 0 { secret.Data[key] = []byte(strconv.FormatInt(value, 10)) } } -func updateSecretString(secret *corev1.Secret, key, value string) { +func updateSecretString(secret *apiv1.Secret, key, value string) { if _, present := secret.Data[key]; present || len(value) > 0 { secret.Data[key] = []byte(value) } } -func (db *db) createSecret(ctx context.Context, secret *corev1.Secret) (*corev1.Secret, error) { +func (db *db) createSecret(ctx context.Context, secret *apiv1.Secret) (*apiv1.Secret, error) { return db.kubeclientset.CoreV1().Secrets(db.ns).Create(ctx, secret, metav1.CreateOptions{}) } -func addSecretMetadata(secret *corev1.Secret, secretType string) { +func addSecretMetadata(secret *apiv1.Secret, secretType string) { if secret.Annotations == nil { secret.Annotations = map[string]string{} } @@ -98,7 +98,7 @@ func addSecretMetadata(secret *corev1.Secret, secretType string) { secret.Labels[common.LabelKeySecretType] = secretType } -func (db *db) deleteSecret(ctx context.Context, secret *corev1.Secret) error { +func (db *db) deleteSecret(ctx context.Context, secret *apiv1.Secret) error { var err error canDelete := secret.Annotations != nil && secret.Annotations[common.AnnotationKeyManagedBy] == common.AnnotationValueManagedByArgoCD @@ -114,28 +114,28 @@ func (db *db) deleteSecret(ctx context.Context, secret *corev1.Secret) error { func (db *db) watchSecrets(ctx context.Context, secretType string, - handleAddEvent func(secret *corev1.Secret), - handleModEvent func(oldSecret *corev1.Secret, newSecret *corev1.Secret), - handleDeleteEvent func(secret *corev1.Secret), + handleAddEvent func(secret *apiv1.Secret), + handleModEvent func(oldSecret *apiv1.Secret, newSecret *apiv1.Secret), + handleDeleteEvent func(secret *apiv1.Secret), ) { secretListOptions := func(options *metav1.ListOptions) { labelSelector := fields.ParseSelectorOrDie(common.LabelKeySecretType + "=" + secretType) options.LabelSelector = labelSelector.String() } secretEventHandler := cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj any) { - if secretObj, ok := obj.(*corev1.Secret); ok { + AddFunc: func(obj interface{}) { + if secretObj, ok := obj.(*apiv1.Secret); ok { handleAddEvent(secretObj) } }, - DeleteFunc: func(obj any) { - if secretObj, ok := obj.(*corev1.Secret); ok { + DeleteFunc: func(obj interface{}) { + if secretObj, ok := obj.(*apiv1.Secret); ok { handleDeleteEvent(secretObj) } }, - UpdateFunc: func(oldObj, newObj any) { - if oldSecretObj, ok := oldObj.(*corev1.Secret); ok { - if newSecretObj, ok := newObj.(*corev1.Secret); ok { + UpdateFunc: func(oldObj, newObj interface{}) { + if oldSecretObj, ok := oldObj.(*apiv1.Secret); ok { + if newSecretObj, ok := newObj.(*apiv1.Secret); ok { handleModEvent(oldSecretObj, newSecretObj) } } @@ -143,7 +143,7 @@ func (db *db) watchSecrets(ctx context.Context, } indexers := cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc} - clusterSecretInformer := informersv1.NewFilteredSecretInformer(db.kubeclientset, db.ns, 3*time.Minute, indexers, secretListOptions) + clusterSecretInformer := informerv1.NewFilteredSecretInformer(db.kubeclientset, db.ns, 3*time.Minute, indexers, secretListOptions) _, err := clusterSecretInformer.AddEventHandler(secretEventHandler) if err != nil { log.Error(err) diff --git a/util/db/write_repository.go b/util/db/write_repository.go new file mode 100644 index 0000000000..0afd57cd5b --- /dev/null +++ b/util/db/write_repository.go @@ -0,0 +1,43 @@ +package db + +import ( + "context" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + corev1 "k8s.io/api/core/v1" + + "github.com/argoproj/argo-cd/v2/common" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func (db *db) GetWriteCredentials(ctx context.Context, repoURL string) (*appsv1.Repository, error) { + secret, err := db.getRepoCredsSecret(repoURL) + if err != nil { + if status.Code(err) == codes.NotFound { + return nil, nil + } + + return nil, fmt.Errorf("failed to get repository-write credentials Secret: %w", err) + } + + return secretToRepository(secret) +} + +func (db *db) getRepoCredsSecret(repoURL string) (*corev1.Secret, error) { + // Should reuse stuff from repo secrets backend... + secretBackend := &secretsRepositoryBackend{db: db} + + secrets, err := db.listSecretsByType(common.LabelValueSecretTypeRepositoryWrite) + if err != nil { + return nil, fmt.Errorf("failed to list repository-write credentials Secrets: %w", err) + } + + index := secretBackend.getRepositoryCredentialIndex(secrets, repoURL) + if index < 0 { + return nil, status.Errorf(codes.NotFound, "repository-write credentials %q not found", repoURL) + } + + return secrets[index], nil +} diff --git a/util/dex/config.go b/util/dex/config.go index a7a25565d5..1b2f0fd02d 100644 --- a/util/dex/config.go +++ b/util/dex/config.go @@ -1,19 +1,18 @@ package dex import ( - "errors" "fmt" "os" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/settings" log "github.com/sirupsen/logrus" ) -func GenerateDexConfigYAML(argocdSettings *settings.ArgoCDSettings, disableTLS bool) ([]byte, error) { +func GenerateDexConfigYAML(argocdSettings *settings.ArgoCDSettings, disableTls bool) ([]byte, error) { if !argocdSettings.IsDexConfigured() { return nil, nil } @@ -21,28 +20,28 @@ func GenerateDexConfigYAML(argocdSettings *settings.ArgoCDSettings, disableTLS b if err != nil { return nil, fmt.Errorf("failed to infer redirect url from config: %w", err) } - var dexCfg map[string]any + var dexCfg map[string]interface{} err = yaml.Unmarshal([]byte(argocdSettings.DexConfig), &dexCfg) if err != nil { return nil, fmt.Errorf("failed to unmarshal dex.config from configmap: %w", err) } dexCfg["issuer"] = argocdSettings.IssuerURL() - dexCfg["storage"] = map[string]any{ + dexCfg["storage"] = map[string]interface{}{ "type": "memory", } - if disableTLS { - dexCfg["web"] = map[string]any{ + if disableTls { + dexCfg["web"] = map[string]interface{}{ "http": "0.0.0.0:5556", } } else { - dexCfg["web"] = map[string]any{ + dexCfg["web"] = map[string]interface{}{ "https": "0.0.0.0:5556", "tlsCert": "/tmp/tls.crt", "tlsKey": "/tmp/tls.key", } } - if loggerCfg, found := dexCfg["logger"].(map[string]any); found { + if loggerCfg, found := dexCfg["logger"].(map[string]interface{}); found { if _, found := loggerCfg["level"]; !found { loggerCfg["level"] = slogLevelFromLogrus(os.Getenv(common.EnvLogLevel)) } @@ -50,25 +49,25 @@ func GenerateDexConfigYAML(argocdSettings *settings.ArgoCDSettings, disableTLS b loggerCfg["format"] = os.Getenv(common.EnvLogFormat) } } else { - dexCfg["logger"] = map[string]any{ + dexCfg["logger"] = map[string]interface{}{ "level": slogLevelFromLogrus(os.Getenv(common.EnvLogLevel)), "format": os.Getenv(common.EnvLogFormat), } } - dexCfg["grpc"] = map[string]any{ + dexCfg["grpc"] = map[string]interface{}{ "addr": "0.0.0.0:5557", } - dexCfg["telemetry"] = map[string]any{ + dexCfg["telemetry"] = map[string]interface{}{ "http": "0.0.0.0:5558", } - if oauth2Cfg, found := dexCfg["oauth2"].(map[string]any); found { + if oauth2Cfg, found := dexCfg["oauth2"].(map[string]interface{}); found { if _, found := oauth2Cfg["skipApprovalScreen"].(bool); !found { oauth2Cfg["skipApprovalScreen"] = true } } else { - dexCfg["oauth2"] = map[string]any{ + dexCfg["oauth2"] = map[string]interface{}{ "skipApprovalScreen": true, } } @@ -77,13 +76,13 @@ func GenerateDexConfigYAML(argocdSettings *settings.ArgoCDSettings, disableTLS b if err != nil { return nil, fmt.Errorf("failed to infer additional redirect urls from config: %w", err) } - argoCDStaticClient := map[string]any{ + argoCDStaticClient := map[string]interface{}{ "id": common.ArgoCDClientAppID, "name": common.ArgoCDClientAppName, "secret": argocdSettings.DexOAuth2ClientSecret(), "redirectURIs": append([]string{redirectURL}, additionalRedirectURLs...), } - argoCDPKCEStaticClient := map[string]any{ + argoCDPKCEStaticClient := map[string]interface{}{ "id": "argo-cd-pkce", "name": "Argo CD PKCE", "redirectURIs": []string{ @@ -91,7 +90,7 @@ func GenerateDexConfigYAML(argocdSettings *settings.ArgoCDSettings, disableTLS b }, "public": true, } - argoCDCLIStaticClient := map[string]any{ + argoCDCLIStaticClient := map[string]interface{}{ "id": common.ArgoCDCLIClientAppID, "name": common.ArgoCDCLIClientAppName, "public": true, @@ -101,33 +100,33 @@ func GenerateDexConfigYAML(argocdSettings *settings.ArgoCDSettings, disableTLS b }, } - staticClients, ok := dexCfg["staticClients"].([]any) + staticClients, ok := dexCfg["staticClients"].([]interface{}) if ok { - dexCfg["staticClients"] = append([]any{argoCDStaticClient, argoCDCLIStaticClient, argoCDPKCEStaticClient}, staticClients...) + dexCfg["staticClients"] = append([]interface{}{argoCDStaticClient, argoCDCLIStaticClient, argoCDPKCEStaticClient}, staticClients...) } else { - dexCfg["staticClients"] = []any{argoCDStaticClient, argoCDCLIStaticClient, argoCDPKCEStaticClient} + dexCfg["staticClients"] = []interface{}{argoCDStaticClient, argoCDCLIStaticClient, argoCDPKCEStaticClient} } dexRedirectURL, err := argocdSettings.DexRedirectURL() if err != nil { return nil, err } - connectors, ok := dexCfg["connectors"].([]any) + connectors, ok := dexCfg["connectors"].([]interface{}) if !ok { - return nil, errors.New("malformed Dex configuration found") + return nil, fmt.Errorf("malformed Dex configuration found") } for i, connectorIf := range connectors { - connector, ok := connectorIf.(map[string]any) + connector, ok := connectorIf.(map[string]interface{}) if !ok { - return nil, errors.New("malformed Dex configuration found") + return nil, fmt.Errorf("malformed Dex configuration found") } connectorType := connector["type"].(string) if !needsRedirectURI(connectorType) { continue } - connectorCfg, ok := connector["config"].(map[string]any) + connectorCfg, ok := connector["config"].(map[string]interface{}) if !ok { - return nil, errors.New("malformed Dex configuration found") + return nil, fmt.Errorf("malformed Dex configuration found") } connectorCfg["redirectURI"] = dexRedirectURL connector["config"] = connectorCfg diff --git a/util/dex/dex.go b/util/dex/dex.go index 11342a1532..34b3c552f3 100644 --- a/util/dex/dex.go +++ b/util/dex/dex.go @@ -4,7 +4,7 @@ import ( "bytes" "crypto/tls" "crypto/x509" - stderrors "errors" + "fmt" "io" "net/http" "net/http/httputil" @@ -15,8 +15,8 @@ import ( log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/errors" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/errors" ) func decorateDirector(director func(req *http.Request), target *url.URL) func(req *http.Request) { @@ -45,9 +45,9 @@ func TLSConfig(tlsConfig *DexTLSConfig) *tls.Config { return &tls.Config{ InsecureSkipVerify: false, RootCAs: tlsConfig.RootCAs, - VerifyPeerCertificate: func(rawCerts [][]byte, _ [][]*x509.Certificate) error { + VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { if !bytes.Equal(rawCerts[0], tlsConfig.Certificate) { - return stderrors.New("dex server certificate does not match") + return fmt.Errorf("dex server certificate does not match") } return nil }, @@ -88,7 +88,7 @@ func NewDexHTTPReverseProxy(serverAddr string, baseHRef string, tlsConfig *DexTL }).Errorf("received error from dex: %s", string(b)) resp.ContentLength = 0 resp.Header.Set("Content-Length", strconv.Itoa(0)) - resp.Header.Set("Location", path.Join(baseHRef, "login")+"?has_sso_error=true") + resp.Header.Set("Location", fmt.Sprintf("%s?has_sso_error=true", path.Join(baseHRef, "login"))) resp.StatusCode = http.StatusSeeOther resp.Body = io.NopCloser(bytes.NewReader(make([]byte, 0))) return nil @@ -129,9 +129,11 @@ func (s DexRewriteURLRoundTripper) RoundTrip(r *http.Request) (*http.Response, e func DexServerAddressWithProtocol(orig string, tlsConfig *DexTLSConfig) string { if strings.Contains(orig, "://") { return orig + } else { + if tlsConfig == nil || tlsConfig.DisableTLS { + return "http://" + orig + } else { + return "https://" + orig + } } - if tlsConfig == nil || tlsConfig.DisableTLS { - return "http://" + orig - } - return "https://" + orig } diff --git a/util/dex/dex_test.go b/util/dex/dex_test.go index b55ce30070..c4413b626e 100644 --- a/util/dex/dex_test.go +++ b/util/dex/dex_test.go @@ -14,9 +14,9 @@ import ( "github.com/stretchr/testify/require" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/common" - utillog "github.com/argoproj/argo-cd/v3/util/log" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + utillog "github.com/argoproj/argo-cd/v2/util/log" + "github.com/argoproj/argo-cd/v2/util/settings" ) const invalidURL = ":://localhost/foo/bar" @@ -258,19 +258,18 @@ func Test_GenerateDexConfig(t *testing.T) { config, err := GenerateDexConfigYAML(&s, false) require.NoError(t, err) assert.NotNil(t, config) - var dexCfg map[string]any + var dexCfg map[string]interface{} err = yaml.Unmarshal(config, &dexCfg) if err != nil { panic(err.Error()) } - connectors, ok := dexCfg["connectors"].([]any) + connectors, ok := dexCfg["connectors"].([]interface{}) assert.True(t, ok) for i, connectorsIf := range connectors { - config := connectorsIf.(map[string]any)["config"].(map[string]any) - switch i { - case 0: + config := connectorsIf.(map[string]interface{})["config"].(map[string]interface{}) + if i == 0 { assert.Equal(t, "foobar", config["clientSecret"]) - case 1: + } else if i == 1 { assert.Equal(t, "barfoo", config["clientSecret"]) } } @@ -285,19 +284,18 @@ func Test_GenerateDexConfig(t *testing.T) { config, err := GenerateDexConfigYAML(&s, false) require.NoError(t, err) assert.NotNil(t, config) - var dexCfg map[string]any + var dexCfg map[string]interface{} err = yaml.Unmarshal(config, &dexCfg) if err != nil { panic(err.Error()) } - connectors, ok := dexCfg["connectors"].([]any) + connectors, ok := dexCfg["connectors"].([]interface{}) assert.True(t, ok) for i, connectorsIf := range connectors { - config := connectorsIf.(map[string]any)["config"].(map[string]any) - switch i { - case 0: + config := connectorsIf.(map[string]interface{})["config"].(map[string]interface{}) + if i == 0 { assert.Equal(t, "foobar", config["clientSecret"]) - case 1: + } else if i == 1 { assert.Equal(t, "barfoo", config["clientSecret"]) } } @@ -314,12 +312,12 @@ func Test_GenerateDexConfig(t *testing.T) { config, err := GenerateDexConfigYAML(&s, false) require.NoError(t, err) assert.NotNil(t, config) - var dexCfg map[string]any + var dexCfg map[string]interface{} err = yaml.Unmarshal(config, &dexCfg) if err != nil { panic(err.Error()) } - loggerCfg, ok := dexCfg["logger"].(map[string]any) + loggerCfg, ok := dexCfg["logger"].(map[string]interface{}) assert.True(t, ok) level, ok := loggerCfg["level"].(string) @@ -342,12 +340,12 @@ func Test_GenerateDexConfig(t *testing.T) { config, err := GenerateDexConfigYAML(&s, false) require.NoError(t, err) assert.NotNil(t, config) - var dexCfg map[string]any + var dexCfg map[string]interface{} err = yaml.Unmarshal(config, &dexCfg) if err != nil { panic(err.Error()) } - loggerCfg, ok := dexCfg["logger"].(map[string]any) + loggerCfg, ok := dexCfg["logger"].(map[string]interface{}) assert.True(t, ok) level, ok := loggerCfg["level"].(string) @@ -379,18 +377,18 @@ func Test_GenerateDexConfig(t *testing.T) { config, err := GenerateDexConfigYAML(&s, false) require.NoError(t, err) assert.NotNil(t, config) - var dexCfg map[string]any + var dexCfg map[string]interface{} err = yaml.Unmarshal(config, &dexCfg) if err != nil { panic(err.Error()) } - clients, ok := dexCfg["staticClients"].([]any) + clients, ok := dexCfg["staticClients"].([]interface{}) assert.True(t, ok) assert.Len(t, clients, 4) - customClient := clients[3].(map[string]any) + customClient := clients[3].(map[string]interface{}) assert.Equal(t, "argo-workflow", customClient["id"].(string)) - assert.Len(t, customClient["redirectURIs"].([]any), 1) + assert.Len(t, customClient["redirectURIs"].([]interface{}), 1) }) t.Run("Custom static clients secret dereference with trailing CRLF", func(t *testing.T) { s := settings.ArgoCDSettings{ @@ -401,16 +399,16 @@ func Test_GenerateDexConfig(t *testing.T) { config, err := GenerateDexConfigYAML(&s, false) require.NoError(t, err) assert.NotNil(t, config) - var dexCfg map[string]any + var dexCfg map[string]interface{} err = yaml.Unmarshal(config, &dexCfg) if err != nil { panic(err.Error()) } - clients, ok := dexCfg["staticClients"].([]any) + clients, ok := dexCfg["staticClients"].([]interface{}) assert.True(t, ok) assert.Len(t, clients, 4) - customClient := clients[3].(map[string]any) + customClient := clients[3].(map[string]interface{}) assert.Equal(t, "barfoo", customClient["secret"]) }) t.Run("Override dex oauth2 configuration", func(t *testing.T) { @@ -421,12 +419,12 @@ func Test_GenerateDexConfig(t *testing.T) { config, err := GenerateDexConfigYAML(&s, false) require.NoError(t, err) assert.NotNil(t, config) - var dexCfg map[string]any + var dexCfg map[string]interface{} err = yaml.Unmarshal(config, &dexCfg) if err != nil { panic(err.Error()) } - oauth2Config, ok := dexCfg["oauth2"].(map[string]any) + oauth2Config, ok := dexCfg["oauth2"].(map[string]interface{}) assert.True(t, ok) pwConn, ok := oauth2Config["passwordConnector"].(string) assert.True(t, ok) @@ -444,12 +442,12 @@ func Test_GenerateDexConfig(t *testing.T) { config, err := GenerateDexConfigYAML(&s, false) require.NoError(t, err) assert.NotNil(t, config) - var dexCfg map[string]any + var dexCfg map[string]interface{} err = yaml.Unmarshal(config, &dexCfg) if err != nil { panic(err.Error()) } - oauth2Config, ok := dexCfg["oauth2"].(map[string]any) + oauth2Config, ok := dexCfg["oauth2"].(map[string]interface{}) assert.True(t, ok) pwConn, ok := oauth2Config["passwordConnector"].(string) assert.True(t, ok) @@ -483,7 +481,7 @@ func Test_DexReverseProxy(t *testing.T) { }) t.Run("Bad case", func(t *testing.T) { - fakeDex := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) { + fakeDex := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { rw.WriteHeader(http.StatusInternalServerError) })) defer fakeDex.Close() @@ -492,7 +490,7 @@ func Test_DexReverseProxy(t *testing.T) { fmt.Printf("Fake API Server listening on %s\n", server.URL) defer server.Close() client := &http.Client{ - CheckRedirect: func(_ *http.Request, _ []*http.Request) error { + CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }, } @@ -513,7 +511,7 @@ func Test_DexReverseProxy(t *testing.T) { }) t.Run("Round Tripper", func(t *testing.T) { - server := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) { + server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { assert.Equal(t, "/", req.URL.String()) })) defer server.Close() diff --git a/util/env/env.go b/util/env/env.go index ca660922f1..686ef80891 100644 --- a/util/env/env.go +++ b/util/env/env.go @@ -13,6 +13,8 @@ import ( // Helper function to parse a number from an environment variable. Returns a // default if env is not set, is not parseable to a number, exceeds max (if // max is greater than 0) or is less than min. +// +// nolint:unparam func ParseNumFromEnv(env string, defaultValue, min, max int) int { str := os.Getenv(env) if str == "" { @@ -41,6 +43,8 @@ func ParseNumFromEnv(env string, defaultValue, min, max int) int { // Helper function to parse a int64 from an environment variable. Returns a // default if env is not set, is not parseable to a number, exceeds max (if // max is greater than 0) or is less than min. +// +// nolint:unparam func ParseInt64FromEnv(env string, defaultValue, min, max int64) int64 { str := os.Getenv(env) if str == "" { @@ -66,6 +70,8 @@ func ParseInt64FromEnv(env string, defaultValue, min, max int64) int64 { // Helper function to parse a float32 from an environment variable. Returns a // default if env is not set, is not parseable to a number, exceeds max (if // max is greater than 0) or is less than min (and min is greater than 0). +// +// nolint:unparam func ParseFloatFromEnv(env string, defaultValue, min, max float32) float32 { str := os.Getenv(env) if str == "" { @@ -91,6 +97,8 @@ func ParseFloatFromEnv(env string, defaultValue, min, max float32) float32 { // Helper function to parse a float64 from an environment variable. Returns a // default if env is not set, is not parseable to a number, exceeds max (if // max is greater than 0) or is less than min (and min is greater than 0). +// +// nolint:unparam func ParseFloat64FromEnv(env string, defaultValue, min, max float64) float64 { str := os.Getenv(env) if str == "" { diff --git a/util/errors/errors.go b/util/errors/errors.go index 34f972ba4a..2c98083273 100644 --- a/util/errors/errors.go +++ b/util/errors/errors.go @@ -2,34 +2,23 @@ package errors import ( "os" - "testing" log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" ) const ( + // ErrorCommandSpecific is reserved for command specific indications + ErrorCommandSpecific = 1 + // ErrorConnectionFailure is returned on connection failure to API endpoint + ErrorConnectionFailure = 11 + // ErrorAPIResponse is returned on unexpected API response, i.e. authorization failure + ErrorAPIResponse = 12 + // ErrorResourceDoesNotExist is returned when the requested resource does not exist + ErrorResourceDoesNotExist = 13 // ErrorGeneric is returned for generic error ErrorGeneric = 20 ) -type Handler struct { - t *testing.T -} - -func NewHandler(t *testing.T) *Handler { - t.Helper() - return &Handler{t: t} -} - -// FailOnErr fails the test if there is an error. It returns the first value so you can use it if you cast it: -// text := FailOrErr(Foo).(string) -func (h *Handler) FailOnErr(v any, err error) any { - h.t.Helper() - require.NoError(h.t, err) - return v -} - // CheckError logs a fatal message and exits with ErrorGeneric if err is not nil func CheckError(err error) { if err != nil { @@ -37,8 +26,15 @@ func CheckError(err error) { } } +// FailOnErr panics if there is an error. It returns the first value so you can use it if you cast it: +// text := FailOrErr(Foo)).(string) +func FailOnErr(v interface{}, err error) interface{} { + CheckError(err) + return v +} + // Fatal is a wrapper for logrus.Fatal() to exit with custom code -func Fatal(exitcode int, args ...any) { +func Fatal(exitcode int, args ...interface{}) { exitfunc := func() { os.Exit(exitcode) } @@ -47,7 +43,7 @@ func Fatal(exitcode int, args ...any) { } // Fatalf is a wrapper for logrus.Fatalf() to exit with custom code -func Fatalf(exitcode int, format string, args ...any) { +func Fatalf(exitcode int, format string, args ...interface{}) { exitfunc := func() { os.Exit(exitcode) } diff --git a/util/exec/exec.go b/util/exec/exec.go index f2aa375300..17eab41a20 100644 --- a/util/exec/exec.go +++ b/util/exec/exec.go @@ -1,34 +1,27 @@ package exec import ( - "bytes" - "errors" "fmt" "os" "os/exec" "strconv" "strings" - "syscall" "time" "unicode" "github.com/argoproj/gitops-engine/pkg/utils/tracing" - "github.com/sirupsen/logrus" + argoexec "github.com/argoproj/pkg/exec" - "github.com/argoproj/argo-cd/v3/util/log" - "github.com/argoproj/argo-cd/v3/util/rand" + "github.com/argoproj/argo-cd/v2/util/log" ) -var ( - timeout time.Duration - Unredacted = Redact(nil) -) +var timeout time.Duration type ExecRunOpts struct { // Redactor redacts tokens from the output Redactor func(text string) string // TimeoutBehavior configures what to do in case of timeout - TimeoutBehavior TimeoutBehavior + TimeoutBehavior argoexec.TimeoutBehavior // SkipErrorLogging determines whether to skip logging of execution errors (rc > 0) SkipErrorLogging bool // CaptureStderr determines whether to capture stderr in addition to stdout @@ -57,7 +50,7 @@ func RunWithRedactor(cmd *exec.Cmd, redactor func(text string) string) (string, } func RunWithExecRunOpts(cmd *exec.Cmd, opts ExecRunOpts) (string, error) { - cmdOpts := CmdOpts{Timeout: timeout, Redactor: opts.Redactor, TimeoutBehavior: opts.TimeoutBehavior, SkipErrorLogging: opts.SkipErrorLogging} + cmdOpts := argoexec.CmdOpts{Timeout: timeout, Redactor: opts.Redactor, TimeoutBehavior: opts.TimeoutBehavior, SkipErrorLogging: opts.SkipErrorLogging} span := tracing.NewLoggingTracer(log.NewLogrusLogger(log.NewWithCurrentConfig())).StartSpan(fmt.Sprintf("exec %v", cmd.Args[0])) span.SetBaggageItem("dir", cmd.Dir) if cmdOpts.Redactor != nil { @@ -66,7 +59,7 @@ func RunWithExecRunOpts(cmd *exec.Cmd, opts ExecRunOpts) (string, error) { span.SetBaggageItem("args", fmt.Sprintf("%v", cmd.Args)) } defer span.Finish() - return RunCommandExt(cmd, cmdOpts) + return argoexec.RunCommandExt(cmd, cmdOpts) } // GetCommandArgsToLog represents the given command in a way that we can copy-and-paste into a terminal @@ -95,156 +88,3 @@ func GetCommandArgsToLog(cmd *exec.Cmd) string { args := strings.Join(argsToLog, " ") return args } - -type CmdError struct { - Args string - Stderr string - Cause error -} - -func (ce *CmdError) Error() string { - res := fmt.Sprintf("`%v` failed %v", ce.Args, ce.Cause) - if ce.Stderr != "" { - res = fmt.Sprintf("%s: %s", res, ce.Stderr) - } - return res -} - -func (ce *CmdError) String() string { - return ce.Error() -} - -func newCmdError(args string, cause error, stderr string) *CmdError { - return &CmdError{Args: args, Stderr: stderr, Cause: cause} -} - -// TimeoutBehavior defines behavior for when the command takes longer than the passed in timeout to exit -// By default, SIGKILL is sent to the process and it is not waited upon -type TimeoutBehavior struct { - // Signal determines the signal to send to the process - Signal syscall.Signal - // ShouldWait determines whether to wait for the command to exit once timeout is reached - ShouldWait bool -} - -type CmdOpts struct { - // Timeout determines how long to wait for the command to exit - Timeout time.Duration - // Redactor redacts tokens from the output - Redactor func(text string) string - // TimeoutBehavior configures what to do in case of timeout - TimeoutBehavior TimeoutBehavior - // SkipErrorLogging defines whether to skip logging of execution errors (rc > 0) - SkipErrorLogging bool - // CaptureStderr defines whether to capture stderr in addition to stdout - CaptureStderr bool -} - -var DefaultCmdOpts = CmdOpts{ - Timeout: time.Duration(0), - Redactor: Unredacted, - TimeoutBehavior: TimeoutBehavior{syscall.SIGKILL, false}, - SkipErrorLogging: false, - CaptureStderr: false, -} - -func Redact(items []string) func(text string) string { - return func(text string) string { - for _, item := range items { - text = strings.ReplaceAll(text, item, "******") - } - return text - } -} - -// RunCommandExt is a convenience function to run/log a command and return/log stderr in an error upon -// failure. -func RunCommandExt(cmd *exec.Cmd, opts CmdOpts) (string, error) { - execId, err := rand.RandHex(5) - if err != nil { - return "", err - } - logCtx := logrus.WithFields(logrus.Fields{"execID": execId}) - - redactor := DefaultCmdOpts.Redactor - if opts.Redactor != nil { - redactor = opts.Redactor - } - - // log in a way we can copy-and-paste into a terminal - args := strings.Join(cmd.Args, " ") - logCtx.WithFields(logrus.Fields{"dir": cmd.Dir}).Info(redactor(args)) - - var stdout bytes.Buffer - var stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - - start := time.Now() - err = cmd.Start() - if err != nil { - return "", err - } - - done := make(chan error) - go func() { done <- cmd.Wait() }() - - // Start a timer - timeout := DefaultCmdOpts.Timeout - - if opts.Timeout != time.Duration(0) { - timeout = opts.Timeout - } - - var timoutCh <-chan time.Time - if timeout != 0 { - timoutCh = time.NewTimer(timeout).C - } - - timeoutBehavior := DefaultCmdOpts.TimeoutBehavior - if opts.TimeoutBehavior.Signal != syscall.Signal(0) { - timeoutBehavior = opts.TimeoutBehavior - } - - select { - // noinspection ALL - case <-timoutCh: - _ = cmd.Process.Signal(timeoutBehavior.Signal) - if timeoutBehavior.ShouldWait { - <-done - } - output := stdout.String() - if opts.CaptureStderr { - output += stderr.String() - } - logCtx.WithFields(logrus.Fields{"duration": time.Since(start)}).Debug(redactor(output)) - err = newCmdError(redactor(args), fmt.Errorf("timeout after %v", timeout), "") - logCtx.Error(err.Error()) - return strings.TrimSuffix(output, "\n"), err - case err := <-done: - if err != nil { - output := stdout.String() - if opts.CaptureStderr { - output += stderr.String() - } - logCtx.WithFields(logrus.Fields{"duration": time.Since(start)}).Debug(redactor(output)) - err := newCmdError(redactor(args), errors.New(redactor(err.Error())), strings.TrimSpace(redactor(stderr.String()))) - if !opts.SkipErrorLogging { - logCtx.Error(err.Error()) - } - return strings.TrimSuffix(output, "\n"), err - } - } - - output := stdout.String() - if opts.CaptureStderr { - output += stderr.String() - } - logCtx.WithFields(logrus.Fields{"duration": time.Since(start)}).Debug(redactor(output)) - - return strings.TrimSuffix(output, "\n"), nil -} - -func RunCommand(name string, opts CmdOpts, arg ...string) (string, error) { - return RunCommandExt(exec.Command(name, arg...), opts) -} diff --git a/util/exec/exec_norace_test.go b/util/exec/exec_norace_test.go deleted file mode 100644 index 9c4cbeb728..0000000000 --- a/util/exec/exec_norace_test.go +++ /dev/null @@ -1,44 +0,0 @@ -//go:build !race - -package exec - -import ( - "testing" - "time" - - log "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/test" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -// FIXME: there's a race in RunCommand that causes the test to fail when -race is enabled. The race is in the timeout -// handling, which shares bytes buffers between the exec goroutine and the timeout handler code. -func TestRunCommandTimeout(t *testing.T) { - hook := test.NewGlobal() - log.SetLevel(log.DebugLevel) - defer log.SetLevel(log.InfoLevel) - - output, err := RunCommand("sh", CmdOpts{Timeout: 500 * time.Millisecond}, "-c", "echo hello world && echo my-error >&2 && sleep 2") - assert.Equal(t, "hello world", output) - require.EqualError(t, err, "`sh -c echo hello world && echo my-error >&2 && sleep 2` failed timeout after 500ms") - - assert.Len(t, hook.Entries, 3) - - entry := hook.Entries[0] - assert.Equal(t, log.InfoLevel, entry.Level) - assert.Equal(t, "sh -c echo hello world && echo my-error >&2 && sleep 2", entry.Message) - assert.Contains(t, entry.Data, "dir") - assert.Contains(t, entry.Data, "execID") - - entry = hook.Entries[1] - assert.Equal(t, log.DebugLevel, entry.Level) - assert.Equal(t, "hello world\n", entry.Message) - assert.Contains(t, entry.Data, "duration") - assert.Contains(t, entry.Data, "execID") - - entry = hook.Entries[2] - assert.Equal(t, log.ErrorLevel, entry.Level) - assert.Equal(t, "`sh -c echo hello world && echo my-error >&2 && sleep 2` failed timeout after 500ms", entry.Message) - assert.Contains(t, entry.Data, "execID") -} diff --git a/util/exec/exec_test.go b/util/exec/exec_test.go index 7f8f3137cc..c41ee100f5 100644 --- a/util/exec/exec_test.go +++ b/util/exec/exec_test.go @@ -7,8 +7,7 @@ import ( "testing" "time" - log "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/test" + argoexec "github.com/argoproj/pkg/exec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -47,7 +46,7 @@ func TestRunWithExecRunOpts(t *testing.T) { initTimeout() opts := ExecRunOpts{ - TimeoutBehavior: TimeoutBehavior{ + TimeoutBehavior: argoexec.TimeoutBehavior{ Signal: syscall.SIGTERM, ShouldWait: true, }, @@ -87,108 +86,3 @@ func Test_getCommandArgsToLog(t *testing.T) { }) } } - -func TestRunCommand(t *testing.T) { - hook := test.NewGlobal() - log.SetLevel(log.DebugLevel) - defer log.SetLevel(log.InfoLevel) - - message, err := RunCommand("echo", CmdOpts{Redactor: Redact([]string{"world"})}, "hello world") - require.NoError(t, err) - assert.Equal(t, "hello world", message) - - assert.Len(t, hook.Entries, 2) - - entry := hook.Entries[0] - assert.Equal(t, log.InfoLevel, entry.Level) - assert.Equal(t, "echo hello ******", entry.Message) - assert.Contains(t, entry.Data, "dir") - assert.Contains(t, entry.Data, "execID") - - entry = hook.Entries[1] - assert.Equal(t, log.DebugLevel, entry.Level) - assert.Equal(t, "hello ******\n", entry.Message) - assert.Contains(t, entry.Data, "duration") - assert.Contains(t, entry.Data, "execID") -} - -func TestRunCommandSignal(t *testing.T) { - hook := test.NewGlobal() - log.SetLevel(log.DebugLevel) - defer log.SetLevel(log.InfoLevel) - - timeoutBehavior := TimeoutBehavior{Signal: syscall.SIGTERM, ShouldWait: true} - output, err := RunCommand("sh", CmdOpts{Timeout: 200 * time.Millisecond, TimeoutBehavior: timeoutBehavior}, "-c", "trap 'trap - 15 && echo captured && exit' 15 && sleep 2") - assert.Equal(t, "captured", output) - require.EqualError(t, err, "`sh -c trap 'trap - 15 && echo captured && exit' 15 && sleep 2` failed timeout after 200ms") - - assert.Len(t, hook.Entries, 3) -} - -func TestTrimmedOutput(t *testing.T) { - message, err := RunCommand("printf", CmdOpts{}, "hello world") - require.NoError(t, err) - assert.Equal(t, "hello world", message) -} - -func TestRunCommandExitErr(t *testing.T) { - hook := test.NewGlobal() - log.SetLevel(log.DebugLevel) - defer log.SetLevel(log.InfoLevel) - - output, err := RunCommand("sh", CmdOpts{Redactor: Redact([]string{"world"})}, "-c", "echo hello world && echo my-error >&2 && exit 1") - assert.Equal(t, "hello world", output) - require.EqualError(t, err, "`sh -c echo hello ****** && echo my-error >&2 && exit 1` failed exit status 1: my-error") - - assert.Len(t, hook.Entries, 3) - - entry := hook.Entries[0] - assert.Equal(t, log.InfoLevel, entry.Level) - assert.Equal(t, "sh -c echo hello ****** && echo my-error >&2 && exit 1", entry.Message) - assert.Contains(t, entry.Data, "dir") - assert.Contains(t, entry.Data, "execID") - - entry = hook.Entries[1] - assert.Equal(t, log.DebugLevel, entry.Level) - assert.Equal(t, "hello ******\n", entry.Message) - assert.Contains(t, entry.Data, "duration") - assert.Contains(t, entry.Data, "execID") - - entry = hook.Entries[2] - assert.Equal(t, log.ErrorLevel, entry.Level) - assert.Equal(t, "`sh -c echo hello ****** && echo my-error >&2 && exit 1` failed exit status 1: my-error", entry.Message) - assert.Contains(t, entry.Data, "execID") -} - -func TestRunCommandErr(t *testing.T) { - log.SetLevel(log.DebugLevel) - defer log.SetLevel(log.InfoLevel) - - output, err := RunCommand("sh", CmdOpts{Redactor: Redact([]string{"world"})}, "-c", ">&2 echo 'failure'; false") - assert.Empty(t, output) - assert.EqualError(t, err, "`sh -c >&2 echo 'failure'; false` failed exit status 1: failure") -} - -func TestRunInDir(t *testing.T) { - cmd := exec.Command("pwd") - cmd.Dir = "/" - message, err := RunCommandExt(cmd, CmdOpts{}) - require.NoError(t, err) - assert.Equal(t, "/", message) -} - -func TestRedact(t *testing.T) { - assert.Empty(t, Redact(nil)("")) - assert.Empty(t, Redact([]string{})("")) - assert.Empty(t, Redact([]string{"foo"})("")) - assert.Equal(t, "foo", Redact([]string{})("foo")) - assert.Equal(t, "******", Redact([]string{"foo"})("foo")) - assert.Equal(t, "****** ******", Redact([]string{"foo", "bar"})("foo bar")) - assert.Equal(t, "****** ******", Redact([]string{"foo"})("foo foo")) -} - -func TestRunCaptureStderr(t *testing.T) { - output, err := RunCommand("sh", CmdOpts{CaptureStderr: true}, "-c", "echo hello world && echo my-error >&2 && exit 0") - assert.Equal(t, "hello world\nmy-error", output) - assert.NoError(t, err) -} diff --git a/util/git/client.go b/util/git/client.go index d911a18076..0b9ab11b79 100644 --- a/util/git/client.go +++ b/util/git/client.go @@ -17,6 +17,9 @@ import ( "syscall" "time" + "github.com/Masterminds/semver/v3" + + argoexec "github.com/argoproj/pkg/exec" "github.com/bmatcuk/doublestar/v4" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" @@ -31,15 +34,14 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" utilnet "k8s.io/apimachinery/pkg/util/net" - "github.com/argoproj/argo-cd/v3/common" - certutil "github.com/argoproj/argo-cd/v3/util/cert" - "github.com/argoproj/argo-cd/v3/util/env" - executil "github.com/argoproj/argo-cd/v3/util/exec" - "github.com/argoproj/argo-cd/v3/util/proxy" - "github.com/argoproj/argo-cd/v3/util/versions" + "github.com/argoproj/argo-cd/v2/common" + certutil "github.com/argoproj/argo-cd/v2/util/cert" + "github.com/argoproj/argo-cd/v2/util/env" + executil "github.com/argoproj/argo-cd/v2/util/exec" + "github.com/argoproj/argo-cd/v2/util/proxy" ) -var ErrInvalidRepoURL = errors.New("repo URL is invalid") +var ErrInvalidRepoURL = fmt.Errorf("repo URL is invalid") type RevisionMetadata struct { Author string @@ -135,11 +137,11 @@ var ( func init() { if countStr := os.Getenv(common.EnvGitAttemptsCount); countStr != "" { - cnt, err := strconv.Atoi(countStr) - if err != nil { + if cnt, err := strconv.Atoi(countStr); err != nil { panic(fmt.Sprintf("Invalid value in %s env variable: %v", common.EnvGitAttemptsCount, err)) + } else { + maxAttemptsCount = int(math.Max(float64(cnt), 1)) } - maxAttemptsCount = int(math.Max(float64(cnt), 1)) } maxRetryDuration = env.ParseDurationFromEnv(common.EnvGitRetryMaxDuration, common.DefaultGitRetryMaxDuration, 0, math.MaxInt64) @@ -209,7 +211,7 @@ func GetRepoHTTPClient(repoURL string, insecure bool, creds Creds, proxyURL stri // 15 second timeout by default Timeout: gitClientTimeout, // don't follow redirect - CheckRedirect: func(_ *http.Request, _ []*http.Request) error { + CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }, } @@ -218,7 +220,7 @@ func GetRepoHTTPClient(repoURL string, insecure bool, creds Creds, proxyURL stri // Callback function to return any configured client certificate // We never return err, but an empty cert instead. - clientCertFunc := func(_ *tls.CertificateRequestInfo) (*tls.Certificate, error) { + clientCertFunc := func(req *tls.CertificateRequestInfo) (*tls.Certificate, error) { var err error cert := tls.Certificate{} @@ -293,9 +295,6 @@ func newAuth(repoURL string, creds Creds) (transport.AuthMethod, error) { } return auth, nil case HTTPSCreds: - if creds.bearerToken != "" { - return &githttp.TokenAuth{Token: creds.bearerToken}, nil - } auth := githttp.BasicAuth{Username: creds.username, Password: creds.password} if auth.Username == "" { auth.Username = "x-access-token" @@ -320,16 +319,7 @@ func newAuth(repoURL string, creds Creds) (transport.AuthMethod, error) { auth := githttp.BasicAuth{Username: username, Password: token} return &auth, nil - case AzureWorkloadIdentityCreds: - token, err := creds.GetAzureDevOpsAccessToken() - if err != nil { - return nil, fmt.Errorf("failed to get access token from creds: %w", err) - } - - auth := githttp.TokenAuth{Token: token} - return &auth, nil } - return nil, nil } @@ -366,7 +356,7 @@ func (m *nativeGitClient) Init() error { return err } -// IsLFSEnabled returns true if the repository is LFS enabled +// Returns true if the repository is LFS enabled func (m *nativeGitClient) IsLFSEnabled() bool { return m.enableLfs } @@ -391,8 +381,9 @@ func (m *nativeGitClient) IsRevisionPresent(revision string) bool { out, err := m.runCmdOutput(cmd, runOpts{SkipErrorLogging: true}) if out == "commit" && err == nil { return true + } else { + return false } - return false } // Fetch fetches latest updates from origin @@ -422,19 +413,16 @@ func (m *nativeGitClient) Fetch(revision string) error { func (m *nativeGitClient) LsFiles(path string, enableNewGitFileGlobbing bool) ([]string, error) { if enableNewGitFileGlobbing { // This is the new way with safer globbing - - // evaluating the root path for symlinks - realRoot, err := filepath.EvalSymlinks(m.root) + err := os.Chdir(m.root) if err != nil { return nil, err } - // searching for the pattern inside the root path - allFiles, err := doublestar.FilepathGlob(filepath.Join(realRoot, path)) + all_files, err := doublestar.FilepathGlob(path) if err != nil { return nil, err } var files []string - for _, file := range allFiles { + for _, file := range all_files { link, err := filepath.EvalSymlinks(file) if err != nil { return nil, err @@ -443,28 +431,23 @@ func (m *nativeGitClient) LsFiles(path string, enableNewGitFileGlobbing bool) ([ if err != nil { return nil, err } - - if strings.HasPrefix(absPath, realRoot) { - // removing the repository root prefix from the file path - relativeFile, err := filepath.Rel(realRoot, file) - if err != nil { - return nil, err - } - files = append(files, relativeFile) + if strings.HasPrefix(absPath, m.root) { + files = append(files, file) } else { - log.Warnf("Absolute path for %s is outside of repository, ignoring it", file) + log.Warnf("Absolute path for %s is outside of repository, removing it", file) } } return files, nil + } else { + // This is the old and default way + out, err := m.runCmd("ls-files", "--full-name", "-z", "--", path) + if err != nil { + return nil, err + } + // remove last element, which is blank regardless of whether we're using nullbyte or newline + ss := strings.Split(out, "\000") + return ss[:len(ss)-1], nil } - // This is the old and default way - out, err := m.runCmd("ls-files", "--full-name", "-z", "--", path) - if err != nil { - return nil, err - } - // remove last element, which is blank regardless of whether we're using nullbyte or newline - ss := strings.Split(out, "\000") - return ss[:len(ss)-1], nil } // LsLargeFiles lists all files that have references to LFS storage @@ -482,7 +465,10 @@ func (m *nativeGitClient) Submodule() error { if err := m.runCredentialedCmd("submodule", "sync", "--recursive"); err != nil { return err } - return m.runCredentialedCmd("submodule", "update", "--init", "--recursive") + if err := m.runCredentialedCmd("submodule", "update", "--init", "--recursive"); err != nil { + return err + } + return nil } // Checkout checks out the specified revision @@ -496,14 +482,14 @@ func (m *nativeGitClient) Checkout(revision string, submoduleEnabled bool) (stri // We must populate LFS content by using lfs checkout, if we have at least // one LFS reference in the current revision. if m.IsLFSEnabled() { - largeFiles, err := m.LsLargeFiles() - if err != nil { - return "", fmt.Errorf("failed to list LFS files: %w", err) - } - if len(largeFiles) > 0 { - if out, err := m.runCmd("lfs", "checkout"); err != nil { - return out, fmt.Errorf("failed to checkout LFS files: %w", err) + if largeFiles, err := m.LsLargeFiles(); err == nil { + if len(largeFiles) > 0 { + if out, err := m.runCmd("lfs", "checkout"); err != nil { + return out, fmt.Errorf("failed to checkout LFS files: %w", err) + } } + } else { + return "", fmt.Errorf("failed to list LFS files: %w", err) } } if _, err := os.Stat(m.root + "/.gitmodules"); !os.IsNotExist(err) { @@ -643,16 +629,6 @@ func (m *nativeGitClient) LsRemote(revision string) (res string, err error) { return } -func getGitTags(refs []*plumbing.Reference) []string { - var tags []string - for _, ref := range refs { - if ref.Name().IsTag() { - tags = append(tags, ref.Name().Short()) - } - } - return tags -} - func (m *nativeGitClient) lsRemote(revision string) (string, error) { if IsCommitSHA(revision) { return revision, nil @@ -667,9 +643,9 @@ func (m *nativeGitClient) lsRemote(revision string) (string, error) { revision = "HEAD" } - maxV, err := versions.MaxVersion(revision, getGitTags(refs)) - if err == nil { - revision = maxV + semverSha := m.resolveSemverRevision(revision, refs) + if semverSha != "" { + return semverSha, nil } // refToHash keeps a maps of remote refs to their hash @@ -718,6 +694,59 @@ func (m *nativeGitClient) lsRemote(revision string) (string, error) { return "", fmt.Errorf("unable to resolve '%s' to a commit SHA", revision) } +// resolveSemverRevision is a part of the lsRemote method workflow. +// 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 { + if !ref.Name().IsTag() { + continue + } + + tag := ref.Name().Short() + version, err := semver.NewVersion(tag) + if err != nil { + log.Debugf("Error parsing version for tag: '%s': %v", tag, err) + // Skip this tag and continue to the next one + continue + } + + if constraint.Check(version) { + if version.GreaterThan(maxVersion) { + maxVersion = version + maxVersionHash = ref.Hash() + } + } + } + + if maxVersionHash.IsZero() { + return "" + } + + log.Debugf("Semver constraint '%s' resolved to tag '%s', at reference '%s'", revision, maxVersion.Original(), maxVersionHash.String()) + return maxVersionHash.String() +} + // CommitSHA returns current commit sha from `git rev-parse HEAD` func (m *nativeGitClient) CommitSHA() (string, error) { out, err := m.runCmd("rev-parse", "HEAD") @@ -755,7 +784,7 @@ func (m *nativeGitClient) VerifyCommitSignature(revision string) (string, error) out, err := m.runGnuPGWrapper("git-verify-wrapper.sh", revision) if err != nil { log.Errorf("error verifying commit signature: %v", err) - return "", errors.New("permission denied") + return "", fmt.Errorf("permission denied") } return out, nil } @@ -766,8 +795,9 @@ func (m *nativeGitClient) IsAnnotatedTag(revision string) bool { out, err := m.runCmdOutput(cmd, runOpts{SkipErrorLogging: true}) if out != "" && err == nil { return true + } else { + return false } - return false } // ChangedFiles returns a list of files changed between two revisions @@ -777,7 +807,7 @@ func (m *nativeGitClient) ChangedFiles(revision string, targetRevision string) ( } if !IsCommitSHA(revision) || !IsCommitSHA(targetRevision) { - return []string{}, errors.New("invalid revision provided, must be SHA") + return []string{}, fmt.Errorf("invalid revision provided, must be SHA") } out, err := m.runCmd("diff", "--name-only", fmt.Sprintf("%s..%s", revision, targetRevision)) @@ -825,13 +855,14 @@ func (m *nativeGitClient) CheckoutOrOrphan(branch string, submoduleEnabled bool) out, err := m.Checkout(branch, submoduleEnabled) if err != nil { // If the branch doesn't exist, create it as an orphan branch. - if !strings.Contains(err.Error(), "did not match any file(s) known to git") { + if strings.Contains(err.Error(), "did not match any file(s) known to git") { + out, err = m.runCmd("switch", "--orphan", branch) + if err != nil { + return out, fmt.Errorf("failed to create orphan branch: %w", err) + } + } else { return out, fmt.Errorf("failed to checkout branch: %w", err) } - out, err = m.runCmd("switch", "--orphan", branch) - if err != nil { - return out, fmt.Errorf("failed to create orphan branch: %w", err) - } // Make an empty initial commit. out, err = m.runCmd("commit", "--allow-empty", "-m", "Initial commit") @@ -853,19 +884,20 @@ func (m *nativeGitClient) CheckoutOrOrphan(branch string, submoduleEnabled bool) func (m *nativeGitClient) CheckoutOrNew(branch, base string, submoduleEnabled bool) (string, error) { out, err := m.Checkout(branch, submoduleEnabled) if err != nil { - if !strings.Contains(err.Error(), "did not match any file(s) known to git") { - return out, fmt.Errorf("failed to checkout branch: %w", err) - } - // If the branch does not exist, create any empty branch based on the sync branch - // First, checkout the sync branch. - out, err = m.Checkout(base, submoduleEnabled) - if err != nil { - return out, fmt.Errorf("failed to checkout sync branch: %w", err) - } + if strings.Contains(err.Error(), "did not match any file(s) known to git") { + // If the branch does not exist, create any empty branch based on the sync branch + // First, checkout the sync branch. + out, err = m.Checkout(base, submoduleEnabled) + if err != nil { + return out, fmt.Errorf("failed to checkout sync branch: %w", err) + } - out, err = m.runCmd("checkout", "-b", branch) - if err != nil { - return out, fmt.Errorf("failed to create branch: %w", err) + out, err = m.runCmd("checkout", "-b", branch) + if err != nil { + return out, fmt.Errorf("failed to create branch: %w", err) + } + } else { + return out, fmt.Errorf("failed to checkout branch: %w", err) } } return "", nil @@ -911,7 +943,7 @@ func (m *nativeGitClient) CommitAndPush(branch, message string) (string, error) // runWrapper runs a custom command with all the semantics of running the Git client func (m *nativeGitClient) runGnuPGWrapper(wrapper string, args ...string) (string, error) { cmd := exec.Command(wrapper, args...) - cmd.Env = append(cmd.Env, "GNUPGHOME="+common.GetGnuPGHomePath(), "LANG=C") + cmd.Env = append(cmd.Env, fmt.Sprintf("GNUPGHOME=%s", common.GetGnuPGHomePath()), "LANG=C") return m.runCmdOutput(cmd, runOpts{}) } @@ -922,6 +954,7 @@ func (m *nativeGitClient) runCmd(args ...string) (string, error) { } // runCredentialedCmd is a convenience function to run a git command with username/password credentials +// nolint:unparam func (m *nativeGitClient) runCredentialedCmd(args ...string) error { closer, environ, err := m.creds.Environ() if err != nil { @@ -932,10 +965,8 @@ func (m *nativeGitClient) runCredentialedCmd(args ...string) error { // If a basic auth header is explicitly set, tell Git to send it to the // server to force use of basic auth instead of negotiating the auth scheme for _, e := range environ { - if strings.HasPrefix(e, forceBasicAuthHeaderEnv+"=") { - args = append([]string{"--config-env", "http.extraHeader=" + forceBasicAuthHeaderEnv}, args...) - } else if strings.HasPrefix(e, bearerAuthHeaderEnv+"=") { - args = append([]string{"--config-env", "http.extraHeader=" + bearerAuthHeaderEnv}, args...) + if strings.HasPrefix(e, fmt.Sprintf("%s=", forceBasicAuthHeaderEnv)) { + args = append([]string{"--config-env", fmt.Sprintf("http.extraHeader=%s", forceBasicAuthHeaderEnv)}, args...) } } @@ -971,14 +1002,14 @@ func (m *nativeGitClient) runCmdOutput(cmd *exec.Cmd, ropts runOpts) (string, er } else { caPath, err := certutil.GetCertBundlePathForRepository(parsedURL.Host) if err == nil && caPath != "" { - cmd.Env = append(cmd.Env, "GIT_SSL_CAINFO="+caPath) + cmd.Env = append(cmd.Env, fmt.Sprintf("GIT_SSL_CAINFO=%s", caPath)) } } } } cmd.Env = proxy.UpsertEnv(cmd, m.proxy, m.noProxy) opts := executil.ExecRunOpts{ - TimeoutBehavior: executil.TimeoutBehavior{ + TimeoutBehavior: argoexec.TimeoutBehavior{ Signal: syscall.SIGTERM, ShouldWait: true, }, diff --git a/util/git/client_test.go b/util/git/client_test.go index 6e63637a57..93ba0115f4 100644 --- a/util/git/client_test.go +++ b/util/git/client_test.go @@ -1,25 +1,18 @@ package git import ( - "context" - "errors" - "io" + "fmt" "os" "os/exec" "path" "path/filepath" "strings" - "sync" "testing" "time" "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/transport" - githttp "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - - "github.com/argoproj/argo-cd/v3/util/workloadidentity/mocks" ) func runCmd(workingDir string, name string, args ...string) error { @@ -56,7 +49,7 @@ func Test_nativeGitClient_Fetch(t *testing.T) { tempDir, err := _createEmptyGitRepo() require.NoError(t, err) - client, err := NewClient("file://"+tempDir, NopCreds{}, true, false, "", "") + client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -70,7 +63,7 @@ func Test_nativeGitClient_Fetch_Prune(t *testing.T) { tempDir, err := _createEmptyGitRepo() require.NoError(t, err) - client, err := NewClient("file://"+tempDir, NopCreds{}, true, false, "", "") + client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -93,7 +86,7 @@ func Test_nativeGitClient_Fetch_Prune(t *testing.T) { func Test_IsAnnotatedTag(t *testing.T) { tempDir := t.TempDir() - client, err := NewClient("file://"+tempDir, NopCreds{}, true, false, "", "") + client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -151,7 +144,7 @@ func Test_resolveTagReference(t *testing.T) { func Test_ChangedFiles(t *testing.T) { tempDir := t.TempDir() - client, err := NewClientExt("file://"+tempDir, tempDir, NopCreds{}, true, false, "", "") + client, err := NewClientExt(fmt.Sprintf("file://%s", tempDir), tempDir, NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -206,7 +199,7 @@ func Test_ChangedFiles(t *testing.T) { func Test_SemverTags(t *testing.T) { tempDir := t.TempDir() - client, err := NewClientExt("file://"+tempDir, tempDir, NopCreds{}, true, false, "", "") + client, err := NewClientExt(fmt.Sprintf("file://%s", tempDir), tempDir, NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -328,7 +321,7 @@ func Test_SemverTags(t *testing.T) { // 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 semver tags", + name: "semver constraints on non-semver tags", ref: "> 2024.0.0-apple", expected: mapTagRefs["2024-banana"], }} { @@ -381,7 +374,7 @@ func Test_nativeGitClient_Submodule(t *testing.T) { err = runCmd(tempDir, "git", "clone", foo) require.NoError(t, err) - client, err := NewClient("file://"+foo, NopCreds{}, true, false, "", "") + client, err := NewClient(fmt.Sprintf("file://%s", foo), NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -437,7 +430,7 @@ func TestNewClient_invalidSSHURL(t *testing.T) { func Test_IsRevisionPresent(t *testing.T) { tempDir := t.TempDir() - client, err := NewClientExt("file://"+tempDir, tempDir, NopCreds{}, true, false, "", "") + client, err := NewClientExt(fmt.Sprintf("file://%s", tempDir), tempDir, NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -471,7 +464,7 @@ func Test_IsRevisionPresent(t *testing.T) { func Test_nativeGitClient_RevisionMetadata(t *testing.T) { tempDir := t.TempDir() - client, err := NewClient("file://"+tempDir, NopCreds{}, true, false, "", "") + client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -516,7 +509,7 @@ func Test_nativeGitClient_SetAuthor(t *testing.T) { tempDir, err := _createEmptyGitRepo() require.NoError(t, err) - client, err := NewClient("file://"+tempDir, NopCreds{}, true, false, "", "") + client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -546,7 +539,7 @@ func Test_nativeGitClient_CheckoutOrOrphan(t *testing.T) { tempDir, err := _createEmptyGitRepo() require.NoError(t, err) - client, err := NewClientExt("file://"+tempDir, tempDir, NopCreds{}, true, false, "", "") + client, err := NewClientExt(fmt.Sprintf("file://%s", tempDir), tempDir, NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -598,7 +591,7 @@ func Test_nativeGitClient_CheckoutOrOrphan(t *testing.T) { // make origin git repository tempDir, err := _createEmptyGitRepo() require.NoError(t, err) - originGitRepoURL := "file://" + tempDir + originGitRepoUrl := fmt.Sprintf("file://%s", tempDir) err = runCmd(tempDir, "git", "commit", "-m", "Second commit", "--allow-empty") require.NoError(t, err) @@ -611,7 +604,7 @@ func Test_nativeGitClient_CheckoutOrOrphan(t *testing.T) { tempDir, err = os.MkdirTemp("", "") require.NoError(t, err) - client, err := NewClientExt(originGitRepoURL, tempDir, NopCreds{}, true, false, "", "") + client, err := NewClientExt(originGitRepoUrl, tempDir, NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -675,7 +668,7 @@ func Test_nativeGitClient_CheckoutOrNew(t *testing.T) { tempDir, err := _createEmptyGitRepo() require.NoError(t, err) - client, err := NewClientExt("file://"+tempDir, tempDir, NopCreds{}, true, false, "", "") + client, err := NewClientExt(fmt.Sprintf("file://%s", tempDir), tempDir, NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -734,7 +727,7 @@ func Test_nativeGitClient_CheckoutOrNew(t *testing.T) { tempDir, err := _createEmptyGitRepo() require.NoError(t, err) - client, err := NewClientExt("file://"+tempDir, tempDir, NopCreds{}, true, false, "", "") + client, err := NewClientExt(fmt.Sprintf("file://%s", tempDir), tempDir, NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -778,7 +771,7 @@ func Test_nativeGitClient_RemoveContents(t *testing.T) { tempDir, err := _createEmptyGitRepo() require.NoError(t, err) - client, err := NewClient("file://"+tempDir, NopCreds{}, true, false, "", "") + client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -826,7 +819,7 @@ func Test_nativeGitClient_CommitAndPush(t *testing.T) { require.NoError(t, err) branch := strings.TrimSpace(string(gitCurrentBranch)) - client, err := NewClient("file://"+tempDir, NopCreds{}, true, false, "", "") + client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "", "") require.NoError(t, err) err = client.Init() @@ -858,213 +851,3 @@ func Test_nativeGitClient_CommitAndPush(t *testing.T) { actualCommitHash := strings.TrimSpace(string(gitCurrentCommitHash)) require.Equal(t, expectedCommitHash, actualCommitHash) } - -func Test_newAuth_AzureWorkloadIdentity(t *testing.T) { - tokenprovider := new(mocks.TokenProvider) - tokenprovider.On("GetToken", azureDevopsEntraResourceId).Return("accessToken", nil) - - creds := AzureWorkloadIdentityCreds{store: NoopCredsStore{}, tokenProvider: tokenprovider} - - auth, err := newAuth("", creds) - require.NoError(t, err) - _, ok := auth.(*githttp.TokenAuth) - require.Truef(t, ok, "expected TokenAuth but got %T", auth) -} - -func TestNewAuth(t *testing.T) { - tests := []struct { - name string - repoURL string - creds Creds - expected transport.AuthMethod - wantErr bool - }{ - { - name: "HTTPSCreds with bearer token", - repoURL: "https://github.com/org/repo.git", - creds: HTTPSCreds{ - bearerToken: "test-token", - }, - expected: &githttp.TokenAuth{Token: "test-token"}, - wantErr: false, - }, - { - name: "HTTPSCreds with basic auth", - repoURL: "https://github.com/org/repo.git", - creds: HTTPSCreds{ - username: "test-user", - password: "test-password", - }, - expected: &githttp.BasicAuth{Username: "test-user", Password: "test-password"}, - wantErr: false, - }, - { - name: "HTTPSCreds with basic auth no username", - repoURL: "https://github.com/org/repo.git", - creds: HTTPSCreds{ - password: "test-password", - }, - expected: &githttp.BasicAuth{Username: "x-access-token", Password: "test-password"}, - wantErr: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - auth, err := newAuth(tt.repoURL, tt.creds) - if (err != nil) != tt.wantErr { - t.Errorf("newAuth() error = %v, wantErr %v", err, tt.wantErr) - return - } - assert.Equal(t, tt.expected, auth) - }) - } -} - -func Test_nativeGitClient_runCredentialedCmd(t *testing.T) { - tests := []struct { - name string - creds Creds - environ []string - expectedArgs []string - expectedEnv []string - expectedErr bool - }{ - { - name: "basic auth header set", - creds: &mockCreds{ - environ: []string{forceBasicAuthHeaderEnv + "=Basic dGVzdDp0ZXN0"}, - }, - expectedArgs: []string{"--config-env", "http.extraHeader=" + forceBasicAuthHeaderEnv, "status"}, - expectedEnv: []string{forceBasicAuthHeaderEnv + "=Basic dGVzdDp0ZXN0"}, - expectedErr: false, - }, - { - name: "bearer auth header set", - creds: &mockCreds{ - environ: []string{bearerAuthHeaderEnv + "=Bearer test-token"}, - }, - expectedArgs: []string{"--config-env", "http.extraHeader=" + bearerAuthHeaderEnv, "status"}, - expectedEnv: []string{bearerAuthHeaderEnv + "=Bearer test-token"}, - expectedErr: false, - }, - { - name: "no auth header set", - creds: &mockCreds{ - environ: []string{}, - }, - expectedArgs: []string{"status"}, - expectedEnv: []string{}, - expectedErr: false, - }, - { - name: "error getting environment", - creds: &mockCreds{ - environErr: true, - }, - expectedArgs: []string{}, - expectedEnv: []string{}, - expectedErr: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - client := &nativeGitClient{ - creds: tt.creds, - } - - err := client.runCredentialedCmd("status") - if (err != nil) != tt.expectedErr { - t.Errorf("runCredentialedCmd() error = %v, expectedErr %v", err, tt.expectedErr) - return - } - - if tt.expectedErr { - return - } - - cmd := exec.Command("git", tt.expectedArgs...) - cmd.Env = append(os.Environ(), tt.expectedEnv...) - output, err := cmd.CombinedOutput() - if err != nil { - t.Errorf("runCredentialedCmd() command error = %v, output = %s", err, output) - } - }) - } -} - -func Test_LsFiles_RaceCondition(t *testing.T) { - // Create two temporary directories and initialize them as git repositories - tempDir1 := t.TempDir() - tempDir2 := t.TempDir() - - client1, err := NewClient("file://"+tempDir1, NopCreds{}, true, false, "", "") - require.NoError(t, err) - client2, err := NewClient("file://"+tempDir2, NopCreds{}, true, false, "", "") - require.NoError(t, err) - - err = client1.Init() - require.NoError(t, err) - err = client2.Init() - require.NoError(t, err) - - // Add different files to each repository - file1 := filepath.Join(client1.Root(), "file1.txt") - err = os.WriteFile(file1, []byte("content1"), 0o644) - require.NoError(t, err) - err = runCmd(client1.Root(), "git", "add", "file1.txt") - require.NoError(t, err) - err = runCmd(client1.Root(), "git", "commit", "-m", "Add file1") - require.NoError(t, err) - - file2 := filepath.Join(client2.Root(), "file2.txt") - err = os.WriteFile(file2, []byte("content2"), 0o644) - require.NoError(t, err) - err = runCmd(client2.Root(), "git", "add", "file2.txt") - require.NoError(t, err) - err = runCmd(client2.Root(), "git", "commit", "-m", "Add file2") - require.NoError(t, err) - - // Assert that LsFiles returns the correct files when called sequentially - files1, err := client1.LsFiles("*", true) - require.NoError(t, err) - require.Contains(t, files1, "file1.txt") - - files2, err := client2.LsFiles("*", true) - require.NoError(t, err) - require.Contains(t, files2, "file2.txt") - - // Define a function to call LsFiles multiple times in parallel - var wg sync.WaitGroup - callLsFiles := func(client Client, expectedFile string) { - defer wg.Done() - for i := 0; i < 100; i++ { - files, err := client.LsFiles("*", true) - require.NoError(t, err) - require.Contains(t, files, expectedFile) - } - } - - // Call LsFiles in parallel for both clients - wg.Add(2) - go callLsFiles(client1, "file1.txt") - go callLsFiles(client2, "file2.txt") - wg.Wait() -} - -type mockCreds struct { - environ []string - environErr bool -} - -func (m *mockCreds) Environ() (io.Closer, []string, error) { - if m.environErr { - return nil, nil, errors.New("error getting environment") - } - return io.NopCloser(nil), m.environ, nil -} - -func (m *mockCreds) GetUserInfo(_ context.Context) (string, string, error) { - return "", "", nil -} diff --git a/util/git/creds.go b/util/git/creds.go index 4657c4a209..9f3675cac1 100644 --- a/util/git/creds.go +++ b/util/git/creds.go @@ -16,7 +16,7 @@ import ( "strings" "time" - "github.com/google/go-github/v69/github" + "github.com/google/go-github/v66/github" "golang.org/x/oauth2" "golang.org/x/oauth2/google" @@ -28,11 +28,9 @@ import ( "github.com/bradleyfalzon/ghinstallation/v2" log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/common" - argoutils "github.com/argoproj/argo-cd/v3/util" - certutil "github.com/argoproj/argo-cd/v3/util/cert" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/workloadidentity" + "github.com/argoproj/argo-cd/v2/common" + certutil "github.com/argoproj/argo-cd/v2/util/cert" + argoioutils "github.com/argoproj/argo-cd/v2/util/io" ) var ( @@ -40,18 +38,12 @@ var ( githubAppTokenCache *gocache.Cache // In memory cache for storing oauth2.TokenSource used to generate Google Cloud OAuth tokens googleCloudTokenSource *gocache.Cache - - // In memory cache for storing Azure tokens - azureTokenCache *gocache.Cache ) const ( // githubAccessTokenUsername is a username that is used to with the github access token githubAccessTokenUsername = "x-access-token" forceBasicAuthHeaderEnv = "ARGOCD_GIT_AUTH_HEADER" - bearerAuthHeaderEnv = "ARGOCD_GIT_BEARER_AUTH_HEADER" - // This is the resource id of the OAuth application of Azure Devops. - azureDevopsEntraResourceId = "499b84ac-1321-427f-aa17-267ca6975798/.default" ) func init() { @@ -65,19 +57,18 @@ func init() { githubAppTokenCache = gocache.New(githubAppCredsExp, 1*time.Minute) // oauth2.TokenSource handles fetching new Tokens once they are expired. The oauth2.TokenSource itself does not expire. googleCloudTokenSource = gocache.New(gocache.NoExpiration, 0) - azureTokenCache = gocache.New(gocache.NoExpiration, 0) } type NoopCredsStore struct{} -func (d NoopCredsStore) Add(_ string, _ string) string { +func (d NoopCredsStore) Add(username string, password string) string { return "" } -func (d NoopCredsStore) Remove(_ string) { +func (d NoopCredsStore) Remove(id string) { } -func (d NoopCredsStore) Environ(_ string) []string { +func (d NoopCredsStore) Environ(id string) []string { return []string{} } @@ -110,7 +101,7 @@ func (c NopCreds) Environ() (io.Closer, []string, error) { } // GetUserInfo returns empty strings for user info -func (c NopCreds) GetUserInfo(_ context.Context) (name string, email string, err error) { +func (c NopCreds) GetUserInfo(ctx context.Context) (name string, email string, err error) { return "", "", nil } @@ -134,8 +125,6 @@ type HTTPSCreds struct { username string // Password for authentication password string - // Bearer token for authentication - bearerToken string // Whether to ignore invalid server certificates insecure bool // Client certificate to use @@ -152,11 +141,10 @@ type HTTPSCreds struct { forceBasicAuth bool } -func NewHTTPSCreds(username string, password string, bearerToken string, clientCertData string, clientCertKey string, insecure bool, proxy string, noProxy string, store CredsStore, forceBasicAuth bool) GenericHTTPSCreds { +func NewHTTPSCreds(username string, password string, clientCertData string, clientCertKey string, insecure bool, proxy string, noProxy string, store CredsStore, forceBasicAuth bool) GenericHTTPSCreds { return HTTPSCreds{ username, password, - bearerToken, insecure, clientCertData, clientCertKey, @@ -168,106 +156,99 @@ func NewHTTPSCreds(username string, password string, bearerToken string, clientC } // GetUserInfo returns the username and email address for the credentials, if they're available. -func (creds HTTPSCreds) GetUserInfo(_ context.Context) (string, string, error) { +func (c HTTPSCreds) GetUserInfo(ctx context.Context) (string, string, error) { // Email not implemented for HTTPS creds. - return creds.username, "", nil + return c.username, "", nil } -func (creds HTTPSCreds) BasicAuthHeader() string { +func (c HTTPSCreds) BasicAuthHeader() string { h := "Authorization: Basic " - t := creds.username + ":" + creds.password + t := c.username + ":" + c.password h += base64.StdEncoding.EncodeToString([]byte(t)) return h } -func (creds HTTPSCreds) BearerAuthHeader() string { - h := "Authorization: Bearer " + creds.bearerToken - return h -} - // Get additional required environment variables for executing git client to // access specific repository via HTTPS. -func (creds HTTPSCreds) Environ() (io.Closer, []string, error) { +func (c HTTPSCreds) Environ() (io.Closer, []string, error) { var env []string httpCloser := authFilePaths(make([]string, 0)) // GIT_SSL_NO_VERIFY is used to tell git not to validate the server's cert at // all. - if creds.insecure { + if c.insecure { env = append(env, "GIT_SSL_NO_VERIFY=true") } // In case the repo is configured for using a TLS client cert, we need to make // sure git client will use it. The certificate's key must not be password // protected. - if creds.HasClientCert() { + if c.HasClientCert() { var certFile, keyFile *os.File // We need to actually create two temp files, one for storing cert data and // another for storing the key. If we fail to create second fail, the first // must be removed. certFile, err := os.CreateTemp(argoio.TempDir, "") - if err != nil { - return NopCloser{}, nil, err - } - defer certFile.Close() - keyFile, err = os.CreateTemp(argoio.TempDir, "") - if err != nil { - removeErr := os.Remove(certFile.Name()) - if removeErr != nil { - log.Errorf("Could not remove previously created tempfile %s: %v", certFile.Name(), removeErr) + if err == nil { + defer certFile.Close() + keyFile, err = os.CreateTemp(argoio.TempDir, "") + if err != nil { + removeErr := os.Remove(certFile.Name()) + if removeErr != nil { + log.Errorf("Could not remove previously created tempfile %s: %v", certFile.Name(), removeErr) + } + return NopCloser{}, nil, err } + defer keyFile.Close() + } else { return NopCloser{}, nil, err } - defer keyFile.Close() // We should have both temp files by now httpCloser = authFilePaths([]string{certFile.Name(), keyFile.Name()}) - _, err = certFile.WriteString(creds.clientCertData) + _, err = certFile.WriteString(c.clientCertData) if err != nil { httpCloser.Close() return NopCloser{}, nil, err } // GIT_SSL_CERT is the full path to a client certificate to be used - env = append(env, "GIT_SSL_CERT="+certFile.Name()) + env = append(env, fmt.Sprintf("GIT_SSL_CERT=%s", certFile.Name())) - _, err = keyFile.WriteString(creds.clientCertKey) + _, err = keyFile.WriteString(c.clientCertKey) if err != nil { httpCloser.Close() return NopCloser{}, nil, err } // GIT_SSL_KEY is the full path to a client certificate's key to be used - env = append(env, "GIT_SSL_KEY="+keyFile.Name()) + env = append(env, fmt.Sprintf("GIT_SSL_KEY=%s", keyFile.Name())) } // If at least password is set, we will set ARGOCD_BASIC_AUTH_HEADER to // hold the HTTP authorization header, so auth mechanism negotiation is // skipped. This is insecure, but some environments may need it. - if creds.password != "" && creds.forceBasicAuth { - env = append(env, fmt.Sprintf("%s=%s", forceBasicAuthHeaderEnv, creds.BasicAuthHeader())) - } else if creds.bearerToken != "" { - // If bearer token is set, we will set ARGOCD_BEARER_AUTH_HEADER to hold the HTTP authorization header - env = append(env, fmt.Sprintf("%s=%s", bearerAuthHeaderEnv, creds.BearerAuthHeader())) + if c.password != "" && c.forceBasicAuth { + env = append(env, fmt.Sprintf("%s=%s", forceBasicAuthHeaderEnv, c.BasicAuthHeader())) } - nonce := creds.store.Add(text.FirstNonEmpty(creds.username, githubAccessTokenUsername), creds.password) - env = append(env, creds.store.Environ(nonce)...) - return utilio.NewCloser(func() error { - creds.store.Remove(nonce) + nonce := c.store.Add(text.FirstNonEmpty(c.username, githubAccessTokenUsername), c.password) + env = append(env, c.store.Environ(nonce)...) + return argoioutils.NewCloser(func() error { + c.store.Remove(nonce) return httpCloser.Close() }), env, nil } -func (creds HTTPSCreds) HasClientCert() bool { - return creds.clientCertData != "" && creds.clientCertKey != "" +func (g HTTPSCreds) HasClientCert() bool { + return g.clientCertData != "" && g.clientCertKey != "" } -func (creds HTTPSCreds) GetClientCertData() string { - return creds.clientCertData +func (c HTTPSCreds) GetClientCertData() string { + return c.clientCertData } -func (creds HTTPSCreds) GetClientCertKey() string { - return creds.clientCertKey +func (c HTTPSCreds) GetClientCertKey() string { + return c.clientCertKey } var _ Creds = SSHCreds{} @@ -288,7 +269,7 @@ func NewSSHCreds(sshPrivateKey string, caPath string, insecureIgnoreHostKey bool // GetUserInfo returns empty strings for user info. // TODO: Implement this method to return the username and email address for the credentials, if they're available. -func (c SSHCreds) GetUserInfo(_ context.Context) (string, string, error) { +func (c SSHCreds) GetUserInfo(ctx context.Context) (string, string, error) { // User info not implemented for SSH creds. return "", "", nil } @@ -304,7 +285,7 @@ func (f sshPrivateKeyFile) Close() error { // Remove a list of files that have been created as temp files while creating // HTTPCreds object above. func (f authFilePaths) Close() error { - var retErr error + var retErr error = nil for _, path := range f { err := os.Remove(path) if err != nil { @@ -342,7 +323,7 @@ func (c SSHCreds) Environ() (io.Closer, []string, error) { args := []string{"ssh", "-i", file.Name()} var env []string if c.caPath != "" { - env = append(env, "GIT_SSL_CAINFO="+c.caPath) + env = append(env, fmt.Sprintf("GIT_SSL_CAINFO=%s", c.caPath)) } if c.insecure { log.Warn("temporarily disabling strict host key checking (i.e. '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'), please don't use in production") @@ -351,7 +332,7 @@ func (c SSHCreds) Environ() (io.Closer, []string, error) { args = append(args, "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null") } else { knownHostsFile := certutil.GetSSHKnownHostsDataPath() - args = append(args, "-o", "StrictHostKeyChecking=yes", "-o", "UserKnownHostsFile="+knownHostsFile) + args = append(args, "-o", "StrictHostKeyChecking=yes", "-o", fmt.Sprintf("UserKnownHostsFile=%s", knownHostsFile)) } // Handle SSH socks5 proxy settings proxyEnv := []string{} @@ -365,13 +346,13 @@ func (c SSHCreds) Environ() (io.Closer, []string, error) { parsedProxyURL.Hostname(), parsedProxyURL.Port())) if parsedProxyURL.User != nil { - proxyEnv = append(proxyEnv, "SOCKS5_USER="+parsedProxyURL.User.Username()) - if socks5Passwd, isPasswdSet := parsedProxyURL.User.Password(); isPasswdSet { - proxyEnv = append(proxyEnv, "SOCKS5_PASSWD="+socks5Passwd) + proxyEnv = append(proxyEnv, fmt.Sprintf("SOCKS5_USER=%s", parsedProxyURL.User.Username())) + if socks5_passwd, isPasswdSet := parsedProxyURL.User.Password(); isPasswdSet { + proxyEnv = append(proxyEnv, fmt.Sprintf("SOCKS5_PASSWD=%s", socks5_passwd)) } } } - env = append(env, []string{"GIT_SSH_COMMAND=" + strings.Join(args, " ")}...) + env = append(env, []string{fmt.Sprintf("GIT_SSH_COMMAND=%s", strings.Join(args, " "))}...) env = append(env, proxyEnv...) return sshCloser, env, nil } @@ -420,19 +401,20 @@ func (g GitHubAppCreds) Environ() (io.Closer, []string, error) { // another for storing the key. If we fail to create second fail, the first // must be removed. certFile, err := os.CreateTemp(argoio.TempDir, "") - if err != nil { - return NopCloser{}, nil, err - } - defer certFile.Close() - keyFile, err = os.CreateTemp(argoio.TempDir, "") - if err != nil { - removeErr := os.Remove(certFile.Name()) - if removeErr != nil { - log.Errorf("Could not remove previously created tempfile %s: %v", certFile.Name(), removeErr) + if err == nil { + defer certFile.Close() + keyFile, err = os.CreateTemp(argoio.TempDir, "") + if err != nil { + removeErr := os.Remove(certFile.Name()) + if removeErr != nil { + log.Errorf("Could not remove previously created tempfile %s: %v", certFile.Name(), removeErr) + } + return NopCloser{}, nil, err } + defer keyFile.Close() + } else { return NopCloser{}, nil, err } - defer keyFile.Close() // We should have both temp files by now httpCloser = authFilePaths([]string{certFile.Name(), keyFile.Name()}) @@ -443,7 +425,7 @@ func (g GitHubAppCreds) Environ() (io.Closer, []string, error) { return NopCloser{}, nil, err } // GIT_SSL_CERT is the full path to a client certificate to be used - env = append(env, "GIT_SSL_CERT="+certFile.Name()) + env = append(env, fmt.Sprintf("GIT_SSL_CERT=%s", certFile.Name())) _, err = keyFile.WriteString(g.clientCertKey) if err != nil { @@ -451,11 +433,11 @@ func (g GitHubAppCreds) Environ() (io.Closer, []string, error) { return NopCloser{}, nil, err } // GIT_SSL_KEY is the full path to a client certificate's key to be used - env = append(env, "GIT_SSL_KEY="+keyFile.Name()) + env = append(env, fmt.Sprintf("GIT_SSL_KEY=%s", keyFile.Name())) } nonce := g.store.Add(githubAccessTokenUsername, token) env = append(env, g.store.Environ(nonce)...) - return utilio.NewCloser(func() error { + return argoioutils.NewCloser(func() error { g.store.Remove(nonce) return httpCloser.Close() }), env, nil @@ -482,7 +464,7 @@ func (g GitHubAppCreds) GetUserInfo(ctx context.Context) (string, string, error) httpClient := http.Client{Transport: appInstallTransport} client := github.NewClient(&httpClient) - appLogin := app.GetSlug() + "[bot]" + appLogin := fmt.Sprintf("%s[bot]", app.GetSlug()) user, _, err := client.Users.Get(ctx, appLogin) if err != nil { return "", "", fmt.Errorf("failed to get app user info: %w", err) @@ -510,13 +492,13 @@ func (g GitHubAppCreds) getAccessToken() (string, error) { // getAppTransport creates a new GitHub transport for the app func (g GitHubAppCreds) getAppTransport() (*ghinstallation.AppsTransport, error) { // GitHub API url - baseURL := "https://api.github.com" + baseUrl := "https://api.github.com" if g.baseURL != "" { - baseURL = strings.TrimSuffix(g.baseURL, "/") + baseUrl = strings.TrimSuffix(g.baseURL, "/") } // Create a new GitHub transport - c := GetRepoHTTPClient(baseURL, g.insecure, g, g.proxy, g.noProxy) + c := GetRepoHTTPClient(baseUrl, g.insecure, g, g.proxy, g.noProxy) itr, err := ghinstallation.NewAppsTransport(c.Transport, g.appID, []byte(g.privateKey), @@ -525,7 +507,7 @@ func (g GitHubAppCreds) getAppTransport() (*ghinstallation.AppsTransport, error) return nil, fmt.Errorf("failed to initialize GitHub installation transport: %w", err) } - itr.BaseURL = baseURL + itr.BaseURL = baseUrl return itr, nil } @@ -534,7 +516,7 @@ func (g GitHubAppCreds) getAppTransport() (*ghinstallation.AppsTransport, error) func (g GitHubAppCreds) getInstallationTransport() (*ghinstallation.Transport, error) { // Compute hash of creds for lookup in cache h := sha256.New() - _, err := fmt.Fprintf(h, "%s %d %d %s", g.privateKey, g.appID, g.appInstallId, g.baseURL) + _, err := h.Write([]byte(fmt.Sprintf("%s %d %d %s", g.privateKey, g.appID, g.appInstallId, g.baseURL))) if err != nil { return nil, fmt.Errorf("failed to get get SHA256 hash for GitHub app credentials: %w", err) } @@ -549,13 +531,13 @@ func (g GitHubAppCreds) getInstallationTransport() (*ghinstallation.Transport, e } // GitHub API url - baseURL := "https://api.github.com" + baseUrl := "https://api.github.com" if g.baseURL != "" { - baseURL = strings.TrimSuffix(g.baseURL, "/") + baseUrl = strings.TrimSuffix(g.baseURL, "/") } // Create a new GitHub transport - c := GetRepoHTTPClient(baseURL, g.insecure, g, g.proxy, g.noProxy) + c := GetRepoHTTPClient(baseUrl, g.insecure, g, g.proxy, g.noProxy) itr, err := ghinstallation.New(c.Transport, g.appID, g.appInstallId, @@ -565,7 +547,7 @@ func (g GitHubAppCreds) getInstallationTransport() (*ghinstallation.Transport, e return nil, fmt.Errorf("failed to initialize GitHub installation transport: %w", err) } - itr.BaseURL = baseURL + itr.BaseURL = baseUrl // Add transport to cache githubAppTokenCache.Set(key, itr, time.Minute*60) @@ -604,7 +586,7 @@ func NewGoogleCloudCreds(jsonData string, store CredsStore) GoogleCloudCreds { // GetUserInfo returns the username and email address for the credentials, if they're available. // TODO: implement getting email instead of just username. -func (c GoogleCloudCreds) GetUserInfo(_ context.Context) (string, string, error) { +func (c GoogleCloudCreds) GetUserInfo(ctx context.Context) (string, string, error) { username, err := c.getUsername() if err != nil { return "", "", fmt.Errorf("failed to get username from creds: %w", err) @@ -625,7 +607,7 @@ func (c GoogleCloudCreds) Environ() (io.Closer, []string, error) { nonce := c.store.Add(username, token) env := c.store.Environ(nonce) - return utilio.NewCloser(func() error { + return argoioutils.NewCloser(func() error { c.store.Remove(nonce) return NopCloser{}.Close() }), env, nil @@ -691,63 +673,3 @@ func (c GoogleCloudCreds) getAccessToken() (string, error) { return token.AccessToken, nil } - -var _ Creds = AzureWorkloadIdentityCreds{} - -type AzureWorkloadIdentityCreds struct { - store CredsStore - tokenProvider workloadidentity.TokenProvider -} - -func NewAzureWorkloadIdentityCreds(store CredsStore, tokenProvider workloadidentity.TokenProvider) AzureWorkloadIdentityCreds { - return AzureWorkloadIdentityCreds{ - store: store, - tokenProvider: tokenProvider, - } -} - -// GetUserInfo returns the username and email address for the credentials, if they're available. -func (creds AzureWorkloadIdentityCreds) GetUserInfo(_ context.Context) (string, string, error) { - // Email not implemented for HTTPS creds. - return workloadidentity.EmptyGuid, "", nil -} - -func (creds AzureWorkloadIdentityCreds) Environ() (io.Closer, []string, error) { - token, err := creds.GetAzureDevOpsAccessToken() - if err != nil { - return NopCloser{}, nil, err - } - nonce := creds.store.Add("", token) - env := creds.store.Environ(nonce) - - return utilio.NewCloser(func() error { - creds.store.Remove(nonce) - return nil - }), env, nil -} - -func (creds AzureWorkloadIdentityCreds) getAccessToken(scope string) (string, error) { - // Compute hash of creds for lookup in cache - key, err := argoutils.GenerateCacheKey("%s", scope) - if err != nil { - return "", fmt.Errorf("failed to get get SHA256 hash for Azure credentials: %w", err) - } - - t, found := azureTokenCache.Get(key) - if found { - return t.(string), nil - } - - token, err := creds.tokenProvider.GetToken(scope) - if err != nil { - return "", fmt.Errorf("failed to get Azure access token: %w", err) - } - - azureTokenCache.Set(key, token, 2*time.Hour) - return token, nil -} - -func (creds AzureWorkloadIdentityCreds) GetAzureDevOpsAccessToken() (string, error) { - accessToken, err := creds.getAccessToken(azureDevopsEntraResourceId) // wellknown resourceid of Azure DevOps - return accessToken, err -} diff --git a/util/git/creds_test.go b/util/git/creds_test.go index d3f3b704b6..865e2316e0 100644 --- a/util/git/creds_test.go +++ b/util/git/creds_test.go @@ -17,10 +17,8 @@ import ( argoio "github.com/argoproj/gitops-engine/pkg/utils/io" - "github.com/argoproj/argo-cd/v3/util/cert" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/workloadidentity" - "github.com/argoproj/argo-cd/v3/util/workloadidentity/mocks" + "github.com/argoproj/argo-cd/v2/util/cert" + "github.com/argoproj/argo-cd/v2/util/io" ) type cred struct { @@ -45,25 +43,25 @@ func (s *memoryCredsStore) Remove(id string) { delete(s.creds, id) } -func (s *memoryCredsStore) Environ(_ string) []string { +func (s *memoryCredsStore) Environ(id string) []string { return nil } func TestHTTPSCreds_Environ_no_cert_cleanup(t *testing.T) { store := &memoryCredsStore{creds: make(map[string]cred)} - creds := NewHTTPSCreds("", "", "", "", "", true, "", "", store, false) + creds := NewHTTPSCreds("", "", "", "", true, "", "", store, false) closer, _, err := creds.Environ() require.NoError(t, err) credsLenBefore := len(store.creds) - utilio.Close(closer) + io.Close(closer) assert.Len(t, store.creds, credsLenBefore-1) } func TestHTTPSCreds_Environ_insecure_true(t *testing.T) { - creds := NewHTTPSCreds("", "", "", "", "", true, "", "", &NoopCredsStore{}, false) + creds := NewHTTPSCreds("", "", "", "", true, "", "", &NoopCredsStore{}, false) closer, env, err := creds.Environ() t.Cleanup(func() { - utilio.Close(closer) + io.Close(closer) }) require.NoError(t, err) found := false @@ -77,10 +75,10 @@ func TestHTTPSCreds_Environ_insecure_true(t *testing.T) { } func TestHTTPSCreds_Environ_insecure_false(t *testing.T) { - creds := NewHTTPSCreds("", "", "", "", "", false, "", "", &NoopCredsStore{}, false) + creds := NewHTTPSCreds("", "", "", "", false, "", "", &NoopCredsStore{}, false) closer, env, err := creds.Environ() t.Cleanup(func() { - utilio.Close(closer) + io.Close(closer) }) require.NoError(t, err) found := false @@ -96,13 +94,13 @@ func TestHTTPSCreds_Environ_insecure_false(t *testing.T) { func TestHTTPSCreds_Environ_forceBasicAuth(t *testing.T) { t.Run("Enabled and credentials set", func(t *testing.T) { store := &memoryCredsStore{creds: make(map[string]cred)} - creds := NewHTTPSCreds("username", "password", "", "", "", false, "", "", store, true) + creds := NewHTTPSCreds("username", "password", "", "", false, "", "", store, true) closer, env, err := creds.Environ() require.NoError(t, err) defer closer.Close() var header string for _, envVar := range env { - if strings.HasPrefix(envVar, forceBasicAuthHeaderEnv+"=") { + if strings.HasPrefix(envVar, fmt.Sprintf("%s=", forceBasicAuthHeaderEnv)) { header = envVar[len(forceBasicAuthHeaderEnv)+1:] } if header != "" { @@ -114,13 +112,13 @@ func TestHTTPSCreds_Environ_forceBasicAuth(t *testing.T) { }) t.Run("Enabled but credentials not set", func(t *testing.T) { store := &memoryCredsStore{creds: make(map[string]cred)} - creds := NewHTTPSCreds("", "", "", "", "", false, "", "", store, true) + creds := NewHTTPSCreds("", "", "", "", false, "", "", store, true) closer, env, err := creds.Environ() require.NoError(t, err) defer closer.Close() var header string for _, envVar := range env { - if strings.HasPrefix(envVar, forceBasicAuthHeaderEnv+"=") { + if strings.HasPrefix(envVar, fmt.Sprintf("%s=", forceBasicAuthHeaderEnv)) { header = envVar[len(forceBasicAuthHeaderEnv)+1:] } if header != "" { @@ -131,13 +129,13 @@ func TestHTTPSCreds_Environ_forceBasicAuth(t *testing.T) { }) t.Run("Disabled with credentials set", func(t *testing.T) { store := &memoryCredsStore{creds: make(map[string]cred)} - creds := NewHTTPSCreds("username", "password", "", "", "", false, "", "", store, false) + creds := NewHTTPSCreds("username", "password", "", "", false, "", "", store, false) closer, env, err := creds.Environ() require.NoError(t, err) defer closer.Close() var header string for _, envVar := range env { - if strings.HasPrefix(envVar, forceBasicAuthHeaderEnv+"=") { + if strings.HasPrefix(envVar, fmt.Sprintf("%s=", forceBasicAuthHeaderEnv)) { header = envVar[len(forceBasicAuthHeaderEnv)+1:] } if header != "" { @@ -149,13 +147,13 @@ func TestHTTPSCreds_Environ_forceBasicAuth(t *testing.T) { t.Run("Disabled with credentials not set", func(t *testing.T) { store := &memoryCredsStore{creds: make(map[string]cred)} - creds := NewHTTPSCreds("", "", "", "", "", false, "", "", store, false) + creds := NewHTTPSCreds("", "", "", "", false, "", "", store, false) closer, env, err := creds.Environ() require.NoError(t, err) defer closer.Close() var header string for _, envVar := range env { - if strings.HasPrefix(envVar, forceBasicAuthHeaderEnv+"=") { + if strings.HasPrefix(envVar, fmt.Sprintf("%s=", forceBasicAuthHeaderEnv)) { header = envVar[len(forceBasicAuthHeaderEnv)+1:] } if header != "" { @@ -166,29 +164,9 @@ func TestHTTPSCreds_Environ_forceBasicAuth(t *testing.T) { }) } -func TestHTTPSCreds_Environ_bearerTokenAuth(t *testing.T) { - t.Run("Enabled and credentials set", func(t *testing.T) { - store := &memoryCredsStore{creds: make(map[string]cred)} - creds := NewHTTPSCreds("", "", "token", "", "", false, "", "", store, false) - closer, env, err := creds.Environ() - require.NoError(t, err) - defer closer.Close() - var header string - for _, envVar := range env { - if strings.HasPrefix(envVar, bearerAuthHeaderEnv+"=") { - header = envVar[len(bearerAuthHeaderEnv)+1:] - } - if header != "" { - break - } - } - assert.Equal(t, "Authorization: Bearer token", header) - }) -} - func TestHTTPSCreds_Environ_clientCert(t *testing.T) { store := &memoryCredsStore{creds: make(map[string]cred)} - creds := NewHTTPSCreds("", "", "", "clientCertData", "clientCertKey", false, "", "", store, false) + creds := NewHTTPSCreds("", "", "clientCertData", "clientCertKey", false, "", "", store, false) closer, env, err := creds.Environ() require.NoError(t, err) var cert, key string @@ -212,7 +190,7 @@ func TestHTTPSCreds_Environ_clientCert(t *testing.T) { assert.Equal(t, "clientCertKey", string(keyBytes)) require.NoError(t, err) - utilio.Close(closer) + io.Close(closer) _, err = os.Stat(cert) require.ErrorIs(t, err, os.ErrNotExist) @@ -241,14 +219,14 @@ func Test_SSHCreds_Environ(t *testing.T) { } else { assert.Contains(t, env[1], "-o StrictHostKeyChecking=yes") hostsPath := cert.GetSSHKnownHostsDataPath() - assert.Contains(t, env[1], "-o UserKnownHostsFile="+hostsPath) + assert.Contains(t, env[1], fmt.Sprintf("-o UserKnownHostsFile=%s", hostsPath)) } envRegex := regexp.MustCompile("-i ([^ ]+)") assert.Regexp(t, envRegex, env[1]) privateKeyFile := envRegex.FindStringSubmatch(env[1])[1] assert.FileExists(t, privateKeyFile) - utilio.Close(closer) + io.Close(closer) assert.NoFileExists(t, privateKeyFile) } } @@ -274,7 +252,7 @@ func Test_SSHCreds_Environ_WithProxy(t *testing.T) { } else { assert.Contains(t, env[1], "-o StrictHostKeyChecking=yes") hostsPath := cert.GetSSHKnownHostsDataPath() - assert.Contains(t, env[1], "-o UserKnownHostsFile="+hostsPath) + assert.Contains(t, env[1], fmt.Sprintf("-o UserKnownHostsFile=%s", hostsPath)) } assert.Contains(t, env[1], "-o ProxyCommand='connect-proxy -S 127.0.0.1:1080 -5 %h %p'") @@ -282,7 +260,7 @@ func Test_SSHCreds_Environ_WithProxy(t *testing.T) { assert.Regexp(t, envRegex, env[1]) privateKeyFile := envRegex.FindStringSubmatch(env[1])[1] assert.FileExists(t, privateKeyFile) - utilio.Close(closer) + io.Close(closer) assert.NoFileExists(t, privateKeyFile) } } @@ -310,7 +288,7 @@ func Test_SSHCreds_Environ_WithProxyUserNamePassword(t *testing.T) { } else { assert.Contains(t, env[1], "-o StrictHostKeyChecking=yes") hostsPath := cert.GetSSHKnownHostsDataPath() - assert.Contains(t, env[1], "-o UserKnownHostsFile="+hostsPath) + assert.Contains(t, env[1], fmt.Sprintf("-o UserKnownHostsFile=%s", hostsPath)) } assert.Contains(t, env[1], "-o ProxyCommand='connect-proxy -S 127.0.0.1:1080 -5 %h %p'") @@ -318,7 +296,7 @@ func Test_SSHCreds_Environ_WithProxyUserNamePassword(t *testing.T) { assert.Regexp(t, envRegex, env[1]) privateKeyFile := envRegex.FindStringSubmatch(env[1])[1] assert.FileExists(t, privateKeyFile) - utilio.Close(closer) + io.Close(closer) assert.NoFileExists(t, privateKeyFile) } } @@ -326,7 +304,7 @@ func Test_SSHCreds_Environ_WithProxyUserNamePassword(t *testing.T) { func Test_SSHCreds_Environ_TempFileCleanupOnInvalidProxyURL(t *testing.T) { // Previously, if the proxy URL was invalid, a temporary file would be left in /dev/shm. This ensures the file is cleaned up in this case. - // countDev returns the number of files in /dev/shm (argoutilio.TempDir) + // countDev returns the number of files in /dev/shm (argoio.TempDir) countFilesInDevShm := func() int { entries, err := os.ReadDir(argoio.TempDir) require.NoError(t, err) @@ -382,11 +360,11 @@ func TestNewGoogleCloudCreds_invalidJSON(t *testing.T) { assert.Nil(t, googleCloudCreds.creds) token, err := googleCloudCreds.getAccessToken() - assert.Empty(t, token) + assert.Equal(t, "", token) require.Error(t, err) username, err := googleCloudCreds.getUsername() - assert.Empty(t, username) + assert.Equal(t, "", username) require.Error(t, err) closer, envStringSlice, err := googleCloudCreds.Environ() @@ -407,52 +385,6 @@ func TestGoogleCloudCreds_Environ_cleanup(t *testing.T) { closer, _, err := googleCloudCreds.Environ() require.NoError(t, err) credsLenBefore := len(store.creds) - utilio.Close(closer) + io.Close(closer) assert.Len(t, store.creds, credsLenBefore-1) } - -func TestAzureWorkloadIdentityCreds_Environ(t *testing.T) { - store := &memoryCredsStore{creds: make(map[string]cred)} - workloadIdentityMock := new(mocks.TokenProvider) - workloadIdentityMock.On("GetToken", azureDevopsEntraResourceId).Return("accessToken", nil) - creds := AzureWorkloadIdentityCreds{store, workloadIdentityMock} - _, _, err := creds.Environ() - require.NoError(t, err) - assert.Len(t, store.creds, 1) - - for _, value := range store.creds { - assert.Empty(t, value.username) - assert.Equal(t, "accessToken", value.password) - } -} - -func TestAzureWorkloadIdentityCreds_Environ_cleanup(t *testing.T) { - store := &memoryCredsStore{creds: make(map[string]cred)} - workloadIdentityMock := new(mocks.TokenProvider) - workloadIdentityMock.On("GetToken", azureDevopsEntraResourceId).Return("accessToken", nil) - creds := AzureWorkloadIdentityCreds{store, workloadIdentityMock} - closer, _, err := creds.Environ() - require.NoError(t, err) - credsLenBefore := len(store.creds) - utilio.Close(closer) - assert.Len(t, store.creds, credsLenBefore-1) -} - -func TestAzureWorkloadIdentityCreds_GetUserInfo(t *testing.T) { - store := &memoryCredsStore{creds: make(map[string]cred)} - workloadIdentityMock := new(mocks.TokenProvider) - workloadIdentityMock.On("GetToken", azureDevopsEntraResourceId).Return("accessToken", nil) - creds := AzureWorkloadIdentityCreds{store, workloadIdentityMock} - - user, email, err := creds.GetUserInfo(t.Context()) - require.NoError(t, err) - assert.Equal(t, workloadidentity.EmptyGuid, user) - assert.Empty(t, email) -} - -func TestGetHelmCredsShouldReturnHelmCredsIfAzureWorkloadIdentityNotSpecified(t *testing.T) { - var creds Creds = NewAzureWorkloadIdentityCreds(NoopCredsStore{}, new(mocks.TokenProvider)) - - _, ok := creds.(AzureWorkloadIdentityCreds) - require.Truef(t, ok, "expected HelmCreds but got %T", creds) -} diff --git a/util/git/git_test.go b/util/git/git_test.go index 216184a5ca..3010f3e971 100644 --- a/util/git/git_test.go +++ b/util/git/git_test.go @@ -1,6 +1,7 @@ package git import ( + "fmt" "io" "net/http" "os" @@ -10,10 +11,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/test/fixture/log" - "github.com/argoproj/argo-cd/v3/test/fixture/path" - "github.com/argoproj/argo-cd/v3/test/fixture/test" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/test/fixture/log" + "github.com/argoproj/argo-cd/v2/test/fixture/path" + "github.com/argoproj/argo-cd/v2/test/fixture/test" ) func TestIsCommitSHA(t *testing.T) { @@ -119,22 +120,22 @@ func TestSameURL(t *testing.T) { func TestCustomHTTPClient(t *testing.T) { certFile, err := filepath.Abs("../../test/fixture/certs/argocd-test-client.crt") require.NoError(t, err) - assert.NotEmpty(t, certFile) + assert.NotEqual(t, "", certFile) keyFile, err := filepath.Abs("../../test/fixture/certs/argocd-test-client.key") require.NoError(t, err) - assert.NotEmpty(t, keyFile) + assert.NotEqual(t, "", keyFile) certData, err := os.ReadFile(certFile) require.NoError(t, err) - assert.NotEmpty(t, string(certData)) + assert.NotEqual(t, "", string(certData)) keyData, err := os.ReadFile(keyFile) require.NoError(t, err) - assert.NotEmpty(t, string(keyData)) + assert.NotEqual(t, "", string(keyData)) // Get HTTPSCreds with client cert creds specified, and insecure connection - creds := NewHTTPSCreds("test", "test", "", string(certData), string(keyData), false, "http://proxy:5000", "", &NoopCredsStore{}, false) + creds := NewHTTPSCreds("test", "test", string(certData), string(keyData), false, "http://proxy:5000", "", &NoopCredsStore{}, false) client := GetRepoHTTPClient("https://localhost:9443/foo/bar", false, creds, "http://proxy:5000", "") assert.NotNil(t, client) assert.NotNil(t, client.Transport) @@ -163,7 +164,7 @@ func TestCustomHTTPClient(t *testing.T) { t.Setenv("http_proxy", "http://proxy-from-env:7878") // Get HTTPSCreds without client cert creds, but insecure connection - creds = NewHTTPSCreds("test", "test", "", "", "", true, "", "", &NoopCredsStore{}, false) + creds = NewHTTPSCreds("test", "test", "", "", true, "", "", &NoopCredsStore{}, false) client = GetRepoHTTPClient("https://localhost:9443/foo/bar", true, creds, "", "") assert.NotNil(t, client) assert.NotNil(t, client.Transport) @@ -311,7 +312,7 @@ func TestLFSClient(t *testing.T) { commitSHA, err := client.LsRemote("HEAD") require.NoError(t, err) - assert.NotEmpty(t, commitSHA) + assert.NotEqual(t, "", commitSHA) err = client.Init() require.NoError(t, err) @@ -326,7 +327,7 @@ func TestLFSClient(t *testing.T) { require.NoError(t, err) assert.Len(t, largeFiles, 3) - fileHandle, err := os.Open(tempDir + "/test3.yaml") + fileHandle, err := os.Open(fmt.Sprintf("%s/test3.yaml", tempDir)) require.NoError(t, err) if err == nil { defer func() { @@ -378,7 +379,7 @@ func TestVerifyCommitSignature(t *testing.T) { } func TestNewFactory(t *testing.T) { - addBinDirToPath := path.NewBinDirToPath(t) + addBinDirToPath := path.NewBinDirToPath() defer addBinDirToPath.Close() closer := log.Debug() defer closer() @@ -458,234 +459,48 @@ func TestLsFiles(t *testing.T) { client, err := NewClientExt("", tmpDir1, NopCreds{}, false, false, "", "") require.NoError(t, err) - require.NoError(t, runCmd(tmpDir1, "git", "init")) - - // Setup files - require.NoError(t, os.WriteFile(filepath.Join(tmpDir1, "a.yaml"), []byte{}, 0o644)) - require.NoError(t, os.MkdirAll(filepath.Join(tmpDir1, "subdir"), 0o755)) - require.NoError(t, os.WriteFile(filepath.Join(tmpDir1, "subdir", "b.yaml"), []byte{}, 0o644)) - - require.NoError(t, os.MkdirAll(filepath.Join(tmpDir2, "subdir"), 0o755)) - require.NoError(t, os.WriteFile(filepath.Join(tmpDir2, "c.yaml"), []byte{}, 0o644)) - - require.NoError(t, os.Symlink(filepath.Join(tmpDir2, "c.yaml"), filepath.Join(tmpDir1, "link.yaml"))) - - require.NoError(t, runCmd(tmpDir1, "git", "add", ".")) - require.NoError(t, runCmd(tmpDir1, "git", "commit", "-m", "Initial commit")) - - tests := []struct { - name string - pattern string - safeGlobbing bool - expectedResult []string - }{ - { - name: "Old globbing with symlinks and subdir", - pattern: "*.yaml", - safeGlobbing: false, - expectedResult: []string{"a.yaml", "link.yaml", "subdir/b.yaml"}, - }, - { - name: "Safe globbing excludes symlinks", - pattern: "*.yaml", - safeGlobbing: true, - expectedResult: []string{"a.yaml"}, - }, - { - name: "Safe globbing excludes external paths", - pattern: filepath.Join(tmpDir2, "*.yaml"), - safeGlobbing: true, - expectedResult: nil, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - lsResult, err := client.LsFiles(tt.pattern, tt.safeGlobbing) - require.NoError(t, err) - assert.Equal(t, tt.expectedResult, lsResult) - }) - } -} - -func TestLsFilesForGitFileGeneratorGlobbingPatterns(t *testing.T) { - tmpDir := t.TempDir() - - client, err := NewClientExt("", tmpDir, NopCreds{}, false, false, "", "") + err = runCmd(tmpDir1, "git", "init") require.NoError(t, err) - err = runCmd(tmpDir, "git", "init") + // Prepare files + a, err := os.Create(filepath.Join(tmpDir1, "a.yaml")) + require.NoError(t, err) + a.Close() + err = os.MkdirAll(filepath.Join(tmpDir1, "subdir"), 0o755) + require.NoError(t, err) + b, err := os.Create(filepath.Join(tmpDir1, "subdir", "b.yaml")) + require.NoError(t, err) + b.Close() + err = os.MkdirAll(filepath.Join(tmpDir2, "subdir"), 0o755) + require.NoError(t, err) + c, err := os.Create(filepath.Join(tmpDir2, "c.yaml")) + require.NoError(t, err) + c.Close() + err = os.Symlink(filepath.Join(tmpDir2, "c.yaml"), filepath.Join(tmpDir1, "link.yaml")) require.NoError(t, err) - // Setup directory structure and files - files := []string{ - "cluster-charts/cluster1/mychart/charts/mysubchart/values.yaml", - "cluster-charts/cluster1/mychart/values.yaml", - "cluster-charts/cluster1/myotherchart/values.yaml", - "cluster-charts/cluster2/values.yaml", - "some-path/values.yaml", - "some-path/staging/values.yaml", - "cluster-config/engineering/production/config.json", - "cluster-config/engineering/dev/config.json", - "p1/p2/config.json", - "p1/app2/config.json", - "p1/app3/config.json", - "p1/config.json", - } - for _, file := range files { - dir := filepath.Dir(file) - require.NoError(t, os.MkdirAll(filepath.Join(tmpDir, dir), 0o755)) - _, err := os.Create(filepath.Join(tmpDir, file)) - require.NoError(t, err) - } - require.NoError(t, runCmd(tmpDir, "git", "add", ".")) - require.NoError(t, runCmd(tmpDir, "git", "commit", "-m", "Initial commit")) + err = runCmd(tmpDir1, "git", "add", ".") + require.NoError(t, err) + err = runCmd(tmpDir1, "git", "commit", "-m", "Initial commit") + require.NoError(t, err) - tests := []struct { - name string - pattern string - isNewGlobbingEnabled bool - expected []string - }{ - { - name: "**/config.json (isNewGlobbingEnabled)", - pattern: "**/config.json", - isNewGlobbingEnabled: true, - expected: []string{ - "cluster-config/engineering/production/config.json", - "cluster-config/engineering/dev/config.json", - "p1/config.json", - "p1/p2/config.json", - "p1/app2/config.json", - "p1/app3/config.json", - }, - }, - { - name: "**/config.json (non-isNewGlobbingEnabled)", - pattern: "**/config.json", - isNewGlobbingEnabled: false, - expected: []string{ - "cluster-config/engineering/production/config.json", - "cluster-config/engineering/dev/config.json", - "p1/config.json", - "p1/p2/config.json", - "p1/app2/config.json", - "p1/app3/config.json", - }, - }, - { - name: "some-path/*.yaml (isNewGlobbingEnabled)", - pattern: "some-path/*.yaml", - isNewGlobbingEnabled: true, - expected: []string{"some-path/values.yaml"}, - }, - { - name: "some-path/*.yaml (non-isNewGlobbingEnabled)", - pattern: "some-path/*.yaml", - isNewGlobbingEnabled: false, - expected: []string{ - "some-path/values.yaml", - "some-path/staging/values.yaml", - }, - }, - { - name: "p1/**/config.json (isNewGlobbingEnabled)", - pattern: "p1/**/config.json", - isNewGlobbingEnabled: true, - expected: []string{ - "p1/config.json", - "p1/p2/config.json", - "p1/app2/config.json", - "p1/app3/config.json", - }, - }, - { - name: "p1/**/config.json (non-isNewGlobbingEnabled)", - pattern: "p1/**/config.json", - isNewGlobbingEnabled: false, - expected: []string{ - "p1/p2/config.json", - "p1/app2/config.json", - "p1/app3/config.json", - }, - }, - { - name: "cluster-config/**/config.json (isNewGlobbingEnabled)", - pattern: "cluster-config/**/config.json", - isNewGlobbingEnabled: true, - expected: []string{ - "cluster-config/engineering/production/config.json", - "cluster-config/engineering/dev/config.json", - }, - }, - { - name: "cluster-config/**/config.json (isNewGlobbingEnabled=false)", - pattern: "cluster-config/**/config.json", - isNewGlobbingEnabled: false, - expected: []string{ - "cluster-config/engineering/dev/config.json", - "cluster-config/engineering/production/config.json", - }, - }, - { - name: "cluster-config/*/dev/config.json (isNewGlobbingEnabled)", - pattern: "cluster-config/*/dev/config.json", - isNewGlobbingEnabled: true, - expected: []string{"cluster-config/engineering/dev/config.json"}, - }, - { - name: "cluster-config/*/dev/config.json (isNewGlobbingEnabled=false)", - pattern: "cluster-config/*/dev/config.json", - isNewGlobbingEnabled: false, - expected: []string{"cluster-config/engineering/dev/config.json"}, - }, - { - name: "cluster-charts/*/*/values.yaml (isNewGlobbingEnabled)", - pattern: "cluster-charts/*/*/values.yaml", - isNewGlobbingEnabled: true, - expected: []string{ - "cluster-charts/cluster1/mychart/values.yaml", - "cluster-charts/cluster1/myotherchart/values.yaml", - }, - }, - { - name: "cluster-charts/*/*/values.yaml (isNewGlobbingEnabled=false)", - pattern: "cluster-charts/*/*/values.yaml", - isNewGlobbingEnabled: false, - expected: []string{ - "cluster-charts/cluster1/mychart/values.yaml", - "cluster-charts/cluster1/myotherchart/values.yaml", - "cluster-charts/cluster1/mychart/charts/mysubchart/values.yaml", - }, - }, - { - name: "cluster-charts/*/values.yaml (isNewGlobbingEnabled)", - pattern: "cluster-charts/*/values.yaml", - isNewGlobbingEnabled: true, - expected: []string{ - "cluster-charts/cluster2/values.yaml", - }, - }, - { - name: "cluster-charts/*/values.yaml (non-isNewGlobbingEnabled)", - pattern: "cluster-charts/*/values.yaml", - isNewGlobbingEnabled: false, - expected: []string{ - "cluster-charts/cluster2/values.yaml", - "cluster-charts/cluster1/mychart/values.yaml", - "cluster-charts/cluster1/myotherchart/values.yaml", - "cluster-charts/cluster1/mychart/charts/mysubchart/values.yaml", - }, - }, - } + // Old and default globbing + expectedResult := []string{"a.yaml", "link.yaml", "subdir/b.yaml"} + lsResult, err := client.LsFiles("*.yaml", false) + require.NoError(t, err) + assert.Equal(t, expectedResult, lsResult) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - lsResult, err := client.LsFiles(tt.pattern, tt.isNewGlobbingEnabled) - require.NoError(t, err) - assert.ElementsMatch(t, tt.expected, lsResult) - }) - } + // New and safer globbing, do not return symlinks resolving outside of the repo + expectedResult = []string{"a.yaml"} + lsResult, err = client.LsFiles("*.yaml", true) + require.NoError(t, err) + assert.Equal(t, expectedResult, lsResult) + + // New globbing, do not return files outside of the repo + var nilResult []string + lsResult, err = client.LsFiles(filepath.Join(tmpDir2, "*.yaml"), true) + require.NoError(t, err) + assert.Equal(t, nilResult, lsResult) } func TestAnnotatedTagHandling(t *testing.T) { diff --git a/util/git/mocks/Client.go b/util/git/mocks/Client.go index b539d50ba7..33370cb5be 100644 --- a/util/git/mocks/Client.go +++ b/util/git/mocks/Client.go @@ -1,14 +1,527 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "github.com/argoproj/argo-cd/v3/util/git" + git "github.com/argoproj/argo-cd/v2/util/git" mock "github.com/stretchr/testify/mock" ) +// Client is an autogenerated mock type for the Client type +type Client struct { + mock.Mock +} + +// ChangedFiles provides a mock function with given fields: revision, targetRevision +func (_m *Client) ChangedFiles(revision string, targetRevision string) ([]string, error) { + ret := _m.Called(revision, targetRevision) + + if len(ret) == 0 { + panic("no return value specified for ChangedFiles") + } + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(string, string) ([]string, error)); ok { + return rf(revision, targetRevision) + } + if rf, ok := ret.Get(0).(func(string, string) []string); ok { + r0 = rf(revision, targetRevision) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(revision, targetRevision) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Checkout provides a mock function with given fields: revision, submoduleEnabled +func (_m *Client) Checkout(revision string, submoduleEnabled bool) (string, error) { + ret := _m.Called(revision, submoduleEnabled) + + if len(ret) == 0 { + panic("no return value specified for Checkout") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, bool) (string, error)); ok { + return rf(revision, submoduleEnabled) + } + if rf, ok := ret.Get(0).(func(string, bool) string); ok { + r0 = rf(revision, submoduleEnabled) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string, bool) error); ok { + r1 = rf(revision, submoduleEnabled) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CheckoutOrNew provides a mock function with given fields: branch, base, submoduleEnabled +func (_m *Client) CheckoutOrNew(branch string, base string, submoduleEnabled bool) (string, error) { + ret := _m.Called(branch, base, submoduleEnabled) + + if len(ret) == 0 { + panic("no return value specified for CheckoutOrNew") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, string, bool) (string, error)); ok { + return rf(branch, base, submoduleEnabled) + } + if rf, ok := ret.Get(0).(func(string, string, bool) string); ok { + r0 = rf(branch, base, submoduleEnabled) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string, string, bool) error); ok { + r1 = rf(branch, base, submoduleEnabled) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CheckoutOrOrphan provides a mock function with given fields: branch, submoduleEnabled +func (_m *Client) CheckoutOrOrphan(branch string, submoduleEnabled bool) (string, error) { + ret := _m.Called(branch, submoduleEnabled) + + if len(ret) == 0 { + panic("no return value specified for CheckoutOrOrphan") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, bool) (string, error)); ok { + return rf(branch, submoduleEnabled) + } + if rf, ok := ret.Get(0).(func(string, bool) string); ok { + r0 = rf(branch, submoduleEnabled) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string, bool) error); ok { + r1 = rf(branch, submoduleEnabled) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitAndPush provides a mock function with given fields: branch, message +func (_m *Client) CommitAndPush(branch string, message string) (string, error) { + ret := _m.Called(branch, message) + + if len(ret) == 0 { + panic("no return value specified for CommitAndPush") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (string, error)); ok { + return rf(branch, message) + } + if rf, ok := ret.Get(0).(func(string, string) string); ok { + r0 = rf(branch, message) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(branch, message) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitSHA provides a mock function with no fields +func (_m *Client) CommitSHA() (string, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for CommitSHA") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func() (string, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Fetch provides a mock function with given fields: revision +func (_m *Client) Fetch(revision string) error { + ret := _m.Called(revision) + + if len(ret) == 0 { + panic("no return value specified for Fetch") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(revision) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Init provides a mock function with no fields +func (_m *Client) Init() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Init") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// IsAnnotatedTag provides a mock function with given fields: _a0 +func (_m *Client) IsAnnotatedTag(_a0 string) bool { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for IsAnnotatedTag") + } + + var r0 bool + if rf, ok := ret.Get(0).(func(string) bool); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// IsRevisionPresent provides a mock function with given fields: revision +func (_m *Client) IsRevisionPresent(revision string) bool { + ret := _m.Called(revision) + + if len(ret) == 0 { + panic("no return value specified for IsRevisionPresent") + } + + var r0 bool + if rf, ok := ret.Get(0).(func(string) bool); ok { + r0 = rf(revision) + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// LsFiles provides a mock function with given fields: path, enableNewGitFileGlobbing +func (_m *Client) LsFiles(path string, enableNewGitFileGlobbing bool) ([]string, error) { + ret := _m.Called(path, enableNewGitFileGlobbing) + + if len(ret) == 0 { + panic("no return value specified for LsFiles") + } + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(string, bool) ([]string, error)); ok { + return rf(path, enableNewGitFileGlobbing) + } + if rf, ok := ret.Get(0).(func(string, bool) []string); ok { + r0 = rf(path, enableNewGitFileGlobbing) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(string, bool) error); ok { + r1 = rf(path, enableNewGitFileGlobbing) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LsLargeFiles provides a mock function with no fields +func (_m *Client) LsLargeFiles() ([]string, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for LsLargeFiles") + } + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func() ([]string, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() []string); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LsRefs provides a mock function with no fields +func (_m *Client) LsRefs() (*git.Refs, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for LsRefs") + } + + var r0 *git.Refs + var r1 error + if rf, ok := ret.Get(0).(func() (*git.Refs, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() *git.Refs); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.Refs) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LsRemote provides a mock function with given fields: revision +func (_m *Client) LsRemote(revision string) (string, error) { + ret := _m.Called(revision) + + if len(ret) == 0 { + panic("no return value specified for LsRemote") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string) (string, error)); ok { + return rf(revision) + } + if rf, ok := ret.Get(0).(func(string) string); ok { + r0 = rf(revision) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(revision) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RemoveContents provides a mock function with no fields +func (_m *Client) RemoveContents() (string, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for RemoveContents") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func() (string, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RevisionMetadata provides a mock function with given fields: revision +func (_m *Client) RevisionMetadata(revision string) (*git.RevisionMetadata, error) { + ret := _m.Called(revision) + + if len(ret) == 0 { + panic("no return value specified for RevisionMetadata") + } + + var r0 *git.RevisionMetadata + var r1 error + if rf, ok := ret.Get(0).(func(string) (*git.RevisionMetadata, error)); ok { + return rf(revision) + } + if rf, ok := ret.Get(0).(func(string) *git.RevisionMetadata); ok { + r0 = rf(revision) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.RevisionMetadata) + } + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(revision) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Root provides a mock function with no fields +func (_m *Client) Root() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Root") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// SetAuthor provides a mock function with given fields: name, email +func (_m *Client) SetAuthor(name string, email string) (string, error) { + ret := _m.Called(name, email) + + if len(ret) == 0 { + panic("no return value specified for SetAuthor") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (string, error)); ok { + return rf(name, email) + } + if rf, ok := ret.Get(0).(func(string, string) string); ok { + r0 = rf(name, email) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(name, email) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Submodule provides a mock function with no fields +func (_m *Client) Submodule() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Submodule") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// VerifyCommitSignature provides a mock function with given fields: _a0 +func (_m *Client) VerifyCommitSignature(_a0 string) (string, error) { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for VerifyCommitSignature") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string) (string, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(string) string); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewClient(t interface { @@ -22,1053 +535,3 @@ func NewClient(t interface { return mock } - -// Client is an autogenerated mock type for the Client type -type Client struct { - mock.Mock -} - -type Client_Expecter struct { - mock *mock.Mock -} - -func (_m *Client) EXPECT() *Client_Expecter { - return &Client_Expecter{mock: &_m.Mock} -} - -// ChangedFiles provides a mock function for the type Client -func (_mock *Client) ChangedFiles(revision string, targetRevision string) ([]string, error) { - ret := _mock.Called(revision, targetRevision) - - if len(ret) == 0 { - panic("no return value specified for ChangedFiles") - } - - var r0 []string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string, string) ([]string, error)); ok { - return returnFunc(revision, targetRevision) - } - if returnFunc, ok := ret.Get(0).(func(string, string) []string); ok { - r0 = returnFunc(revision, targetRevision) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - if returnFunc, ok := ret.Get(1).(func(string, string) error); ok { - r1 = returnFunc(revision, targetRevision) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_ChangedFiles_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ChangedFiles' -type Client_ChangedFiles_Call struct { - *mock.Call -} - -// ChangedFiles is a helper method to define mock.On call -// - revision -// - targetRevision -func (_e *Client_Expecter) ChangedFiles(revision interface{}, targetRevision interface{}) *Client_ChangedFiles_Call { - return &Client_ChangedFiles_Call{Call: _e.mock.On("ChangedFiles", revision, targetRevision)} -} - -func (_c *Client_ChangedFiles_Call) Run(run func(revision string, targetRevision string)) *Client_ChangedFiles_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) - }) - return _c -} - -func (_c *Client_ChangedFiles_Call) Return(strings []string, err error) *Client_ChangedFiles_Call { - _c.Call.Return(strings, err) - return _c -} - -func (_c *Client_ChangedFiles_Call) RunAndReturn(run func(revision string, targetRevision string) ([]string, error)) *Client_ChangedFiles_Call { - _c.Call.Return(run) - return _c -} - -// Checkout provides a mock function for the type Client -func (_mock *Client) Checkout(revision string, submoduleEnabled bool) (string, error) { - ret := _mock.Called(revision, submoduleEnabled) - - if len(ret) == 0 { - panic("no return value specified for Checkout") - } - - var r0 string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string, bool) (string, error)); ok { - return returnFunc(revision, submoduleEnabled) - } - if returnFunc, ok := ret.Get(0).(func(string, bool) string); ok { - r0 = returnFunc(revision, submoduleEnabled) - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = returnFunc(revision, submoduleEnabled) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_Checkout_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Checkout' -type Client_Checkout_Call struct { - *mock.Call -} - -// Checkout is a helper method to define mock.On call -// - revision -// - submoduleEnabled -func (_e *Client_Expecter) Checkout(revision interface{}, submoduleEnabled interface{}) *Client_Checkout_Call { - return &Client_Checkout_Call{Call: _e.mock.On("Checkout", revision, submoduleEnabled)} -} - -func (_c *Client_Checkout_Call) Run(run func(revision string, submoduleEnabled bool)) *Client_Checkout_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(bool)) - }) - return _c -} - -func (_c *Client_Checkout_Call) Return(s string, err error) *Client_Checkout_Call { - _c.Call.Return(s, err) - return _c -} - -func (_c *Client_Checkout_Call) RunAndReturn(run func(revision string, submoduleEnabled bool) (string, error)) *Client_Checkout_Call { - _c.Call.Return(run) - return _c -} - -// CheckoutOrNew provides a mock function for the type Client -func (_mock *Client) CheckoutOrNew(branch string, base string, submoduleEnabled bool) (string, error) { - ret := _mock.Called(branch, base, submoduleEnabled) - - if len(ret) == 0 { - panic("no return value specified for CheckoutOrNew") - } - - var r0 string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string, string, bool) (string, error)); ok { - return returnFunc(branch, base, submoduleEnabled) - } - if returnFunc, ok := ret.Get(0).(func(string, string, bool) string); ok { - r0 = returnFunc(branch, base, submoduleEnabled) - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func(string, string, bool) error); ok { - r1 = returnFunc(branch, base, submoduleEnabled) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CheckoutOrNew_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CheckoutOrNew' -type Client_CheckoutOrNew_Call struct { - *mock.Call -} - -// CheckoutOrNew is a helper method to define mock.On call -// - branch -// - base -// - submoduleEnabled -func (_e *Client_Expecter) CheckoutOrNew(branch interface{}, base interface{}, submoduleEnabled interface{}) *Client_CheckoutOrNew_Call { - return &Client_CheckoutOrNew_Call{Call: _e.mock.On("CheckoutOrNew", branch, base, submoduleEnabled)} -} - -func (_c *Client_CheckoutOrNew_Call) Run(run func(branch string, base string, submoduleEnabled bool)) *Client_CheckoutOrNew_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(bool)) - }) - return _c -} - -func (_c *Client_CheckoutOrNew_Call) Return(s string, err error) *Client_CheckoutOrNew_Call { - _c.Call.Return(s, err) - return _c -} - -func (_c *Client_CheckoutOrNew_Call) RunAndReturn(run func(branch string, base string, submoduleEnabled bool) (string, error)) *Client_CheckoutOrNew_Call { - _c.Call.Return(run) - return _c -} - -// CheckoutOrOrphan provides a mock function for the type Client -func (_mock *Client) CheckoutOrOrphan(branch string, submoduleEnabled bool) (string, error) { - ret := _mock.Called(branch, submoduleEnabled) - - if len(ret) == 0 { - panic("no return value specified for CheckoutOrOrphan") - } - - var r0 string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string, bool) (string, error)); ok { - return returnFunc(branch, submoduleEnabled) - } - if returnFunc, ok := ret.Get(0).(func(string, bool) string); ok { - r0 = returnFunc(branch, submoduleEnabled) - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = returnFunc(branch, submoduleEnabled) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CheckoutOrOrphan_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CheckoutOrOrphan' -type Client_CheckoutOrOrphan_Call struct { - *mock.Call -} - -// CheckoutOrOrphan is a helper method to define mock.On call -// - branch -// - submoduleEnabled -func (_e *Client_Expecter) CheckoutOrOrphan(branch interface{}, submoduleEnabled interface{}) *Client_CheckoutOrOrphan_Call { - return &Client_CheckoutOrOrphan_Call{Call: _e.mock.On("CheckoutOrOrphan", branch, submoduleEnabled)} -} - -func (_c *Client_CheckoutOrOrphan_Call) Run(run func(branch string, submoduleEnabled bool)) *Client_CheckoutOrOrphan_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(bool)) - }) - return _c -} - -func (_c *Client_CheckoutOrOrphan_Call) Return(s string, err error) *Client_CheckoutOrOrphan_Call { - _c.Call.Return(s, err) - return _c -} - -func (_c *Client_CheckoutOrOrphan_Call) RunAndReturn(run func(branch string, submoduleEnabled bool) (string, error)) *Client_CheckoutOrOrphan_Call { - _c.Call.Return(run) - return _c -} - -// CommitAndPush provides a mock function for the type Client -func (_mock *Client) CommitAndPush(branch string, message string) (string, error) { - ret := _mock.Called(branch, message) - - if len(ret) == 0 { - panic("no return value specified for CommitAndPush") - } - - var r0 string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string, string) (string, error)); ok { - return returnFunc(branch, message) - } - if returnFunc, ok := ret.Get(0).(func(string, string) string); ok { - r0 = returnFunc(branch, message) - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func(string, string) error); ok { - r1 = returnFunc(branch, message) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CommitAndPush_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CommitAndPush' -type Client_CommitAndPush_Call struct { - *mock.Call -} - -// CommitAndPush is a helper method to define mock.On call -// - branch -// - message -func (_e *Client_Expecter) CommitAndPush(branch interface{}, message interface{}) *Client_CommitAndPush_Call { - return &Client_CommitAndPush_Call{Call: _e.mock.On("CommitAndPush", branch, message)} -} - -func (_c *Client_CommitAndPush_Call) Run(run func(branch string, message string)) *Client_CommitAndPush_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) - }) - return _c -} - -func (_c *Client_CommitAndPush_Call) Return(s string, err error) *Client_CommitAndPush_Call { - _c.Call.Return(s, err) - return _c -} - -func (_c *Client_CommitAndPush_Call) RunAndReturn(run func(branch string, message string) (string, error)) *Client_CommitAndPush_Call { - _c.Call.Return(run) - return _c -} - -// CommitSHA provides a mock function for the type Client -func (_mock *Client) CommitSHA() (string, error) { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for CommitSHA") - } - - var r0 string - var r1 error - if returnFunc, ok := ret.Get(0).(func() (string, error)); ok { - return returnFunc() - } - if returnFunc, ok := ret.Get(0).(func() string); ok { - r0 = returnFunc() - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func() error); ok { - r1 = returnFunc() - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_CommitSHA_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CommitSHA' -type Client_CommitSHA_Call struct { - *mock.Call -} - -// CommitSHA is a helper method to define mock.On call -func (_e *Client_Expecter) CommitSHA() *Client_CommitSHA_Call { - return &Client_CommitSHA_Call{Call: _e.mock.On("CommitSHA")} -} - -func (_c *Client_CommitSHA_Call) Run(run func()) *Client_CommitSHA_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *Client_CommitSHA_Call) Return(s string, err error) *Client_CommitSHA_Call { - _c.Call.Return(s, err) - return _c -} - -func (_c *Client_CommitSHA_Call) RunAndReturn(run func() (string, error)) *Client_CommitSHA_Call { - _c.Call.Return(run) - return _c -} - -// Fetch provides a mock function for the type Client -func (_mock *Client) Fetch(revision string) error { - ret := _mock.Called(revision) - - if len(ret) == 0 { - panic("no return value specified for Fetch") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(string) error); ok { - r0 = returnFunc(revision) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_Fetch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Fetch' -type Client_Fetch_Call struct { - *mock.Call -} - -// Fetch is a helper method to define mock.On call -// - revision -func (_e *Client_Expecter) Fetch(revision interface{}) *Client_Fetch_Call { - return &Client_Fetch_Call{Call: _e.mock.On("Fetch", revision)} -} - -func (_c *Client_Fetch_Call) Run(run func(revision string)) *Client_Fetch_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *Client_Fetch_Call) Return(err error) *Client_Fetch_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_Fetch_Call) RunAndReturn(run func(revision string) error) *Client_Fetch_Call { - _c.Call.Return(run) - return _c -} - -// Init provides a mock function for the type Client -func (_mock *Client) Init() error { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for Init") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func() error); ok { - r0 = returnFunc() - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' -type Client_Init_Call struct { - *mock.Call -} - -// Init is a helper method to define mock.On call -func (_e *Client_Expecter) Init() *Client_Init_Call { - return &Client_Init_Call{Call: _e.mock.On("Init")} -} - -func (_c *Client_Init_Call) Run(run func()) *Client_Init_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *Client_Init_Call) Return(err error) *Client_Init_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_Init_Call) RunAndReturn(run func() error) *Client_Init_Call { - _c.Call.Return(run) - return _c -} - -// IsAnnotatedTag provides a mock function for the type Client -func (_mock *Client) IsAnnotatedTag(s string) bool { - ret := _mock.Called(s) - - if len(ret) == 0 { - panic("no return value specified for IsAnnotatedTag") - } - - var r0 bool - if returnFunc, ok := ret.Get(0).(func(string) bool); ok { - r0 = returnFunc(s) - } else { - r0 = ret.Get(0).(bool) - } - return r0 -} - -// Client_IsAnnotatedTag_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsAnnotatedTag' -type Client_IsAnnotatedTag_Call struct { - *mock.Call -} - -// IsAnnotatedTag is a helper method to define mock.On call -// - s -func (_e *Client_Expecter) IsAnnotatedTag(s interface{}) *Client_IsAnnotatedTag_Call { - return &Client_IsAnnotatedTag_Call{Call: _e.mock.On("IsAnnotatedTag", s)} -} - -func (_c *Client_IsAnnotatedTag_Call) Run(run func(s string)) *Client_IsAnnotatedTag_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *Client_IsAnnotatedTag_Call) Return(b bool) *Client_IsAnnotatedTag_Call { - _c.Call.Return(b) - return _c -} - -func (_c *Client_IsAnnotatedTag_Call) RunAndReturn(run func(s string) bool) *Client_IsAnnotatedTag_Call { - _c.Call.Return(run) - return _c -} - -// IsRevisionPresent provides a mock function for the type Client -func (_mock *Client) IsRevisionPresent(revision string) bool { - ret := _mock.Called(revision) - - if len(ret) == 0 { - panic("no return value specified for IsRevisionPresent") - } - - var r0 bool - if returnFunc, ok := ret.Get(0).(func(string) bool); ok { - r0 = returnFunc(revision) - } else { - r0 = ret.Get(0).(bool) - } - return r0 -} - -// Client_IsRevisionPresent_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsRevisionPresent' -type Client_IsRevisionPresent_Call struct { - *mock.Call -} - -// IsRevisionPresent is a helper method to define mock.On call -// - revision -func (_e *Client_Expecter) IsRevisionPresent(revision interface{}) *Client_IsRevisionPresent_Call { - return &Client_IsRevisionPresent_Call{Call: _e.mock.On("IsRevisionPresent", revision)} -} - -func (_c *Client_IsRevisionPresent_Call) Run(run func(revision string)) *Client_IsRevisionPresent_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *Client_IsRevisionPresent_Call) Return(b bool) *Client_IsRevisionPresent_Call { - _c.Call.Return(b) - return _c -} - -func (_c *Client_IsRevisionPresent_Call) RunAndReturn(run func(revision string) bool) *Client_IsRevisionPresent_Call { - _c.Call.Return(run) - return _c -} - -// LsFiles provides a mock function for the type Client -func (_mock *Client) LsFiles(path string, enableNewGitFileGlobbing bool) ([]string, error) { - ret := _mock.Called(path, enableNewGitFileGlobbing) - - if len(ret) == 0 { - panic("no return value specified for LsFiles") - } - - var r0 []string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string, bool) ([]string, error)); ok { - return returnFunc(path, enableNewGitFileGlobbing) - } - if returnFunc, ok := ret.Get(0).(func(string, bool) []string); ok { - r0 = returnFunc(path, enableNewGitFileGlobbing) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - if returnFunc, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = returnFunc(path, enableNewGitFileGlobbing) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_LsFiles_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LsFiles' -type Client_LsFiles_Call struct { - *mock.Call -} - -// LsFiles is a helper method to define mock.On call -// - path -// - enableNewGitFileGlobbing -func (_e *Client_Expecter) LsFiles(path interface{}, enableNewGitFileGlobbing interface{}) *Client_LsFiles_Call { - return &Client_LsFiles_Call{Call: _e.mock.On("LsFiles", path, enableNewGitFileGlobbing)} -} - -func (_c *Client_LsFiles_Call) Run(run func(path string, enableNewGitFileGlobbing bool)) *Client_LsFiles_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(bool)) - }) - return _c -} - -func (_c *Client_LsFiles_Call) Return(strings []string, err error) *Client_LsFiles_Call { - _c.Call.Return(strings, err) - return _c -} - -func (_c *Client_LsFiles_Call) RunAndReturn(run func(path string, enableNewGitFileGlobbing bool) ([]string, error)) *Client_LsFiles_Call { - _c.Call.Return(run) - return _c -} - -// LsLargeFiles provides a mock function for the type Client -func (_mock *Client) LsLargeFiles() ([]string, error) { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for LsLargeFiles") - } - - var r0 []string - var r1 error - if returnFunc, ok := ret.Get(0).(func() ([]string, error)); ok { - return returnFunc() - } - if returnFunc, ok := ret.Get(0).(func() []string); ok { - r0 = returnFunc() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - if returnFunc, ok := ret.Get(1).(func() error); ok { - r1 = returnFunc() - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_LsLargeFiles_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LsLargeFiles' -type Client_LsLargeFiles_Call struct { - *mock.Call -} - -// LsLargeFiles is a helper method to define mock.On call -func (_e *Client_Expecter) LsLargeFiles() *Client_LsLargeFiles_Call { - return &Client_LsLargeFiles_Call{Call: _e.mock.On("LsLargeFiles")} -} - -func (_c *Client_LsLargeFiles_Call) Run(run func()) *Client_LsLargeFiles_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *Client_LsLargeFiles_Call) Return(strings []string, err error) *Client_LsLargeFiles_Call { - _c.Call.Return(strings, err) - return _c -} - -func (_c *Client_LsLargeFiles_Call) RunAndReturn(run func() ([]string, error)) *Client_LsLargeFiles_Call { - _c.Call.Return(run) - return _c -} - -// LsRefs provides a mock function for the type Client -func (_mock *Client) LsRefs() (*git.Refs, error) { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for LsRefs") - } - - var r0 *git.Refs - var r1 error - if returnFunc, ok := ret.Get(0).(func() (*git.Refs, error)); ok { - return returnFunc() - } - if returnFunc, ok := ret.Get(0).(func() *git.Refs); ok { - r0 = returnFunc() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.Refs) - } - } - if returnFunc, ok := ret.Get(1).(func() error); ok { - r1 = returnFunc() - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_LsRefs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LsRefs' -type Client_LsRefs_Call struct { - *mock.Call -} - -// LsRefs is a helper method to define mock.On call -func (_e *Client_Expecter) LsRefs() *Client_LsRefs_Call { - return &Client_LsRefs_Call{Call: _e.mock.On("LsRefs")} -} - -func (_c *Client_LsRefs_Call) Run(run func()) *Client_LsRefs_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *Client_LsRefs_Call) Return(refs *git.Refs, err error) *Client_LsRefs_Call { - _c.Call.Return(refs, err) - return _c -} - -func (_c *Client_LsRefs_Call) RunAndReturn(run func() (*git.Refs, error)) *Client_LsRefs_Call { - _c.Call.Return(run) - return _c -} - -// LsRemote provides a mock function for the type Client -func (_mock *Client) LsRemote(revision string) (string, error) { - ret := _mock.Called(revision) - - if len(ret) == 0 { - panic("no return value specified for LsRemote") - } - - var r0 string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) (string, error)); ok { - return returnFunc(revision) - } - if returnFunc, ok := ret.Get(0).(func(string) string); ok { - r0 = returnFunc(revision) - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(revision) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_LsRemote_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LsRemote' -type Client_LsRemote_Call struct { - *mock.Call -} - -// LsRemote is a helper method to define mock.On call -// - revision -func (_e *Client_Expecter) LsRemote(revision interface{}) *Client_LsRemote_Call { - return &Client_LsRemote_Call{Call: _e.mock.On("LsRemote", revision)} -} - -func (_c *Client_LsRemote_Call) Run(run func(revision string)) *Client_LsRemote_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *Client_LsRemote_Call) Return(s string, err error) *Client_LsRemote_Call { - _c.Call.Return(s, err) - return _c -} - -func (_c *Client_LsRemote_Call) RunAndReturn(run func(revision string) (string, error)) *Client_LsRemote_Call { - _c.Call.Return(run) - return _c -} - -// RemoveContents provides a mock function for the type Client -func (_mock *Client) RemoveContents() (string, error) { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for RemoveContents") - } - - var r0 string - var r1 error - if returnFunc, ok := ret.Get(0).(func() (string, error)); ok { - return returnFunc() - } - if returnFunc, ok := ret.Get(0).(func() string); ok { - r0 = returnFunc() - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func() error); ok { - r1 = returnFunc() - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_RemoveContents_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveContents' -type Client_RemoveContents_Call struct { - *mock.Call -} - -// RemoveContents is a helper method to define mock.On call -func (_e *Client_Expecter) RemoveContents() *Client_RemoveContents_Call { - return &Client_RemoveContents_Call{Call: _e.mock.On("RemoveContents")} -} - -func (_c *Client_RemoveContents_Call) Run(run func()) *Client_RemoveContents_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *Client_RemoveContents_Call) Return(s string, err error) *Client_RemoveContents_Call { - _c.Call.Return(s, err) - return _c -} - -func (_c *Client_RemoveContents_Call) RunAndReturn(run func() (string, error)) *Client_RemoveContents_Call { - _c.Call.Return(run) - return _c -} - -// RevisionMetadata provides a mock function for the type Client -func (_mock *Client) RevisionMetadata(revision string) (*git.RevisionMetadata, error) { - ret := _mock.Called(revision) - - if len(ret) == 0 { - panic("no return value specified for RevisionMetadata") - } - - var r0 *git.RevisionMetadata - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) (*git.RevisionMetadata, error)); ok { - return returnFunc(revision) - } - if returnFunc, ok := ret.Get(0).(func(string) *git.RevisionMetadata); ok { - r0 = returnFunc(revision) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git.RevisionMetadata) - } - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(revision) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_RevisionMetadata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RevisionMetadata' -type Client_RevisionMetadata_Call struct { - *mock.Call -} - -// RevisionMetadata is a helper method to define mock.On call -// - revision -func (_e *Client_Expecter) RevisionMetadata(revision interface{}) *Client_RevisionMetadata_Call { - return &Client_RevisionMetadata_Call{Call: _e.mock.On("RevisionMetadata", revision)} -} - -func (_c *Client_RevisionMetadata_Call) Run(run func(revision string)) *Client_RevisionMetadata_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *Client_RevisionMetadata_Call) Return(revisionMetadata *git.RevisionMetadata, err error) *Client_RevisionMetadata_Call { - _c.Call.Return(revisionMetadata, err) - return _c -} - -func (_c *Client_RevisionMetadata_Call) RunAndReturn(run func(revision string) (*git.RevisionMetadata, error)) *Client_RevisionMetadata_Call { - _c.Call.Return(run) - return _c -} - -// Root provides a mock function for the type Client -func (_mock *Client) Root() string { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for Root") - } - - var r0 string - if returnFunc, ok := ret.Get(0).(func() string); ok { - r0 = returnFunc() - } else { - r0 = ret.Get(0).(string) - } - return r0 -} - -// Client_Root_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Root' -type Client_Root_Call struct { - *mock.Call -} - -// Root is a helper method to define mock.On call -func (_e *Client_Expecter) Root() *Client_Root_Call { - return &Client_Root_Call{Call: _e.mock.On("Root")} -} - -func (_c *Client_Root_Call) Run(run func()) *Client_Root_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *Client_Root_Call) Return(s string) *Client_Root_Call { - _c.Call.Return(s) - return _c -} - -func (_c *Client_Root_Call) RunAndReturn(run func() string) *Client_Root_Call { - _c.Call.Return(run) - return _c -} - -// SetAuthor provides a mock function for the type Client -func (_mock *Client) SetAuthor(name string, email string) (string, error) { - ret := _mock.Called(name, email) - - if len(ret) == 0 { - panic("no return value specified for SetAuthor") - } - - var r0 string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string, string) (string, error)); ok { - return returnFunc(name, email) - } - if returnFunc, ok := ret.Get(0).(func(string, string) string); ok { - r0 = returnFunc(name, email) - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func(string, string) error); ok { - r1 = returnFunc(name, email) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_SetAuthor_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetAuthor' -type Client_SetAuthor_Call struct { - *mock.Call -} - -// SetAuthor is a helper method to define mock.On call -// - name -// - email -func (_e *Client_Expecter) SetAuthor(name interface{}, email interface{}) *Client_SetAuthor_Call { - return &Client_SetAuthor_Call{Call: _e.mock.On("SetAuthor", name, email)} -} - -func (_c *Client_SetAuthor_Call) Run(run func(name string, email string)) *Client_SetAuthor_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) - }) - return _c -} - -func (_c *Client_SetAuthor_Call) Return(s string, err error) *Client_SetAuthor_Call { - _c.Call.Return(s, err) - return _c -} - -func (_c *Client_SetAuthor_Call) RunAndReturn(run func(name string, email string) (string, error)) *Client_SetAuthor_Call { - _c.Call.Return(run) - return _c -} - -// Submodule provides a mock function for the type Client -func (_mock *Client) Submodule() error { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for Submodule") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func() error); ok { - r0 = returnFunc() - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_Submodule_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Submodule' -type Client_Submodule_Call struct { - *mock.Call -} - -// Submodule is a helper method to define mock.On call -func (_e *Client_Expecter) Submodule() *Client_Submodule_Call { - return &Client_Submodule_Call{Call: _e.mock.On("Submodule")} -} - -func (_c *Client_Submodule_Call) Run(run func()) *Client_Submodule_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *Client_Submodule_Call) Return(err error) *Client_Submodule_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_Submodule_Call) RunAndReturn(run func() error) *Client_Submodule_Call { - _c.Call.Return(run) - return _c -} - -// VerifyCommitSignature provides a mock function for the type Client -func (_mock *Client) VerifyCommitSignature(s string) (string, error) { - ret := _mock.Called(s) - - if len(ret) == 0 { - panic("no return value specified for VerifyCommitSignature") - } - - var r0 string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) (string, error)); ok { - return returnFunc(s) - } - if returnFunc, ok := ret.Get(0).(func(string) string); ok { - r0 = returnFunc(s) - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(s) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_VerifyCommitSignature_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'VerifyCommitSignature' -type Client_VerifyCommitSignature_Call struct { - *mock.Call -} - -// VerifyCommitSignature is a helper method to define mock.On call -// - s -func (_e *Client_Expecter) VerifyCommitSignature(s interface{}) *Client_VerifyCommitSignature_Call { - return &Client_VerifyCommitSignature_Call{Call: _e.mock.On("VerifyCommitSignature", s)} -} - -func (_c *Client_VerifyCommitSignature_Call) Run(run func(s string)) *Client_VerifyCommitSignature_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *Client_VerifyCommitSignature_Call) Return(s1 string, err error) *Client_VerifyCommitSignature_Call { - _c.Call.Return(s1, err) - return _c -} - -func (_c *Client_VerifyCommitSignature_Call) RunAndReturn(run func(s string) (string, error)) *Client_VerifyCommitSignature_Call { - _c.Call.Return(run) - return _c -} diff --git a/util/github_app/repos.go b/util/github_app/repos.go index 8d4f8b2913..6654a06112 100644 --- a/util/github_app/repos.go +++ b/util/github_app/repos.go @@ -4,8 +4,8 @@ import ( "context" "fmt" - "github.com/argoproj/argo-cd/v3/applicationset/services/github_app_auth" - "github.com/argoproj/argo-cd/v3/util/db" + "github.com/argoproj/argo-cd/v2/applicationset/services/github_app_auth" + "github.com/argoproj/argo-cd/v2/util/db" ) // NewAuthCredentials returns a GtiHub App credentials lookup by repo-creds url. diff --git a/util/github_app/repos_test.go b/util/github_app/repos_test.go index d2adb57d24..67f49412ce 100644 --- a/util/github_app/repos_test.go +++ b/util/github_app/repos_test.go @@ -8,8 +8,8 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/applicationset/services/github_app_auth" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/applicationset/services/github_app_auth" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) type ArgocdRepositoryMock struct { @@ -47,7 +47,7 @@ func Test_repoAsCredentials_GetAuth(t *testing.T) { m.On("GetRepoCredsBySecretName", mock.Anything, mock.Anything).Return(&tt.repo, nil) creds := NewAuthCredentials(ArgocdRepositoryMock{mock: &m}) - auth, err := creds.GetAuthSecret(t.Context(), "https://github.com/foo") + auth, err := creds.GetAuthSecret(context.Background(), "https://github.com/foo") if tt.wantErr { assert.Error(t, err) return diff --git a/util/glob/list.go b/util/glob/list.go index 9a62374c2e..f257302af9 100644 --- a/util/glob/list.go +++ b/util/glob/list.go @@ -3,7 +3,7 @@ package glob import ( "strings" - "github.com/argoproj/argo-cd/v3/util/regex" + "github.com/argoproj/argo-cd/v2/util/regex" ) const ( @@ -20,12 +20,11 @@ const ( func MatchStringInList(list []string, item string, patternMatch string) bool { for _, ll := range list { // If string is wrapped in "/", assume it is a regular expression. - switch { - case patternMatch == REGEXP && strings.HasPrefix(ll, "/") && strings.HasSuffix(ll, "/") && regex.Match(ll[1:len(ll)-1], item): + if patternMatch == REGEXP && strings.HasPrefix(ll, "/") && strings.HasSuffix(ll, "/") && regex.Match(ll[1:len(ll)-1], item) { return true - case (patternMatch == REGEXP || patternMatch == GLOB) && Match(ll, item): + } else if (patternMatch == REGEXP || patternMatch == GLOB) && Match(ll, item) { return true - case patternMatch == EXACT && item == ll: + } else if patternMatch == EXACT && item == ll { return true } } diff --git a/util/gpg/gpg.go b/util/gpg/gpg.go index cb948af218..100a6e7b68 100644 --- a/util/gpg/gpg.go +++ b/util/gpg/gpg.go @@ -3,7 +3,6 @@ package gpg import ( "bufio" "encoding/hex" - "errors" "fmt" "os" "os/exec" @@ -14,9 +13,9 @@ import ( log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/common" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - executil "github.com/argoproj/argo-cd/v3/util/exec" + "github.com/argoproj/argo-cd/v2/common" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + executil "github.com/argoproj/argo-cd/v2/util/exec" ) // Regular expression to match public key beginning @@ -66,7 +65,11 @@ type PGPKeyID string func isHexString(s string) bool { _, err := hex.DecodeString(s) - return err == nil + if err != nil { + return false + } else { + return true + } } // KeyID get the actual correct (short) key ID from either a fingerprint or the key ID. Returns the empty string if k seems not to be a PGP key ID. @@ -84,16 +87,18 @@ func KeyID(k string) string { func IsLongKeyID(k string) bool { if len(k) == 40 && isHexString(k) { return true + } else { + return false } - return false } // IsShortKeyID returns true if the string represents a short key ID func IsShortKeyID(k string) bool { if len(k) == 16 && isHexString(k) { return true + } else { + return false } - return false } // Result of a git commit verification @@ -145,7 +150,7 @@ const MaxVerificationLinesToParse = 40 // Helper function to append GNUPGHOME for a command execution environment func getGPGEnviron() []string { - return append(os.Environ(), "GNUPGHOME="+common.GetGnuPGHomePath(), "LANG=C") + return append(os.Environ(), fmt.Sprintf("GNUPGHOME=%s", common.GetGnuPGHomePath()), "LANG=C") } // Helper function to write some data to a temp file and return its path @@ -180,8 +185,9 @@ func removeKeyRing(path string) error { if err != nil { if os.IsNotExist(err) { return fmt.Errorf("refusing to remove directory %s: it's not initialized by Argo CD", path) + } else { + return err } - return err } rd, err := os.Open(path) if err != nil { @@ -400,7 +406,7 @@ func SetPGPTrustLevelById(kids []string, trustLevel string) error { func SetPGPTrustLevel(pgpKeys []*appsv1.GnuPGPublicKey, trustLevel string) error { trust, ok := pgpTrustLevels[trustLevel] if !ok { - return fmt.Errorf("unknown trust level: %s", trustLevel) + return fmt.Errorf("Unknown trust level: %s", trustLevel) } // We need to store ownertrust specification in a temp file. Format is : @@ -412,7 +418,7 @@ func SetPGPTrustLevel(pgpKeys []*appsv1.GnuPGPublicKey, trustLevel string) error defer os.Remove(f.Name()) for _, k := range pgpKeys { - _, err := fmt.Fprintf(f, "%s:%d\n", k.KeyID, trust) + _, err := f.WriteString(fmt.Sprintf("%s:%d\n", k.KeyID, trust)) if err != nil { return err } @@ -495,7 +501,7 @@ func GetInstalledPGPKeys(kids []string) ([]*appsv1.GnuPGPublicKey, error) { } scanner := bufio.NewScanner(strings.NewReader(out)) - var curKey *appsv1.GnuPGPublicKey + var curKey *appsv1.GnuPGPublicKey = nil for scanner.Scan() { if strings.HasPrefix(scanner.Text(), "pub ") { // This is the beginning of a new key, time to store the previously parsed one in our list and start fresh. @@ -509,18 +515,18 @@ func GetInstalledPGPKeys(kids []string) ([]*appsv1.GnuPGPublicKey, error) { // Second field in pub output denotes key sub type (cipher and length) token := subTypeMatch.FindStringSubmatch(scanner.Text()) if len(token) != 2 { - return nil, fmt.Errorf("invalid line: %s (len=%d)", scanner.Text(), len(token)) + return nil, fmt.Errorf("Invalid line: %s (len=%d)", scanner.Text(), len(token)) } key.SubType = token[1] // Next line should be the key ID, no prefix if !scanner.Scan() { - return nil, errors.New("invalid output from gpg, end of text after primary key") + return nil, fmt.Errorf("Invalid output from gpg, end of text after primary key") } token = keyIdMatch.FindStringSubmatch(scanner.Text()) if len(token) != 2 { - return nil, errors.New("invalid output from gpg, no key ID for primary key") + return nil, fmt.Errorf("Invalid output from gpg, no key ID for primary key") } key.Fingerprint = token[1] @@ -533,17 +539,17 @@ func GetInstalledPGPKeys(kids []string) ([]*appsv1.GnuPGPublicKey, error) { // Next line should be UID if !scanner.Scan() { - return nil, errors.New("invalid output from gpg, end of text after key ID") + return nil, fmt.Errorf("Invalid output from gpg, end of text after key ID") } if !strings.HasPrefix(scanner.Text(), "uid ") { - return nil, errors.New("invalid output from gpg, no identity for primary key") + return nil, fmt.Errorf("Invalid output from gpg, no identity for primary key") } token = uidMatch.FindStringSubmatch(scanner.Text()) if len(token) < 3 { - return nil, fmt.Errorf("malformed identity line: %s (len=%d)", scanner.Text(), len(token)) + return nil, fmt.Errorf("Malformed identity line: %s (len=%d)", scanner.Text(), len(token)) } // Store trust level @@ -590,7 +596,7 @@ func ParseGitCommitVerification(signature string) PGPVerifyResult { scanner := bufio.NewScanner(strings.NewReader(signature)) for scanner.Scan() && linesParsed < MaxVerificationLinesToParse { - linesParsed++ + linesParsed += 1 // Indicating the beginning of a signature start := verificationStartMatch.FindStringSubmatch(scanner.Text()) @@ -600,7 +606,7 @@ func ParseGitCommitVerification(signature string) PGPVerifyResult { return unknownResult("Unexpected end-of-file while parsing commit verification output.") } - linesParsed++ + linesParsed += 1 // What key has made the signature? keyID := verificationKeyIDMatch.FindStringSubmatch(scanner.Text()) @@ -611,7 +617,7 @@ func ParseGitCommitVerification(signature string) PGPVerifyResult { result.Cipher = keyID[1] result.KeyID = KeyID(keyID[2]) if result.KeyID == "" { - return unknownResult("Invalid PGP key ID found in verification result: " + result.KeyID) + return unknownResult(fmt.Sprintf("Invalid PGP key ID found in verification result: %s", result.KeyID)) } // What was the result of signature verification? @@ -619,7 +625,7 @@ func ParseGitCommitVerification(signature string) PGPVerifyResult { return unknownResult("Unexpected end-of-file while parsing commit verification output.") } - linesParsed++ + linesParsed += 1 // Skip additional fields for verificationAdditionalFields.MatchString(scanner.Text()) { @@ -627,7 +633,7 @@ func ParseGitCommitVerification(signature string) PGPVerifyResult { return unknownResult("Unexpected end-of-file while parsing commit verification output.") } - linesParsed++ + linesParsed += 1 } if strings.HasPrefix(scanner.Text(), "gpg: Can't check signature: ") { @@ -672,9 +678,10 @@ func ParseGitCommitVerification(signature string) PGPVerifyResult { } else if linesParsed >= MaxVerificationLinesToParse { // Too many output lines, return error return unknownResult("Too many lines of gpg verify-commit output, abort.") + } else { + // No data found, return error + return unknownResult("Could not parse output of verify-commit, no verification data found.") } - // No data found, return error - return unknownResult("Could not parse output of verify-commit, no verification data found.") } // SyncKeyRingFromDirectory will sync the GPG keyring with files in a directory. This is a one-way sync, @@ -683,7 +690,7 @@ func ParseGitCommitVerification(signature string) PGPVerifyResult { // in the keyring will be installed to the keyring, files that exist in the keyring but do not exist in // the directory will be deleted. func SyncKeyRingFromDirectory(basePath string) ([]string, []string, error) { - configured := make(map[string]any) + configured := make(map[string]interface{}) newKeys := make([]string, 0) fingerprints := make([]string, 0) removedKeys := make([]string, 0) @@ -696,7 +703,7 @@ func SyncKeyRingFromDirectory(basePath string) ([]string, []string, error) { } // Collect configuration, i.e. files in basePath - err = filepath.Walk(basePath, func(_ string, fi os.FileInfo, err error) error { + err = filepath.Walk(basePath, func(path string, fi os.FileInfo, err error) error { if err != nil { return err } diff --git a/util/gpg/gpg_test.go b/util/gpg/gpg_test.go index 9aaa259ae4..e279f1e9ad 100644 --- a/util/gpg/gpg_test.go +++ b/util/gpg/gpg_test.go @@ -11,8 +11,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/test" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/test" ) const ( @@ -79,7 +79,7 @@ func Test_GPG_InitializeGnuPG(t *testing.T) { // During unit-tests, we need to also kill gpg-agent so we can create a new key. // In real world scenario -- i.e. container crash -- gpg-agent is not running yet. cmd := exec.Command("gpgconf", "--kill", "gpg-agent") - cmd.Env = []string{"GNUPGHOME=" + p} + cmd.Env = []string{fmt.Sprintf("GNUPGHOME=%s", p)} err = cmd.Run() require.NoError(t, err) @@ -92,7 +92,7 @@ func Test_GPG_InitializeGnuPG(t *testing.T) { assert.Equal(t, "ultimate", keys[0].Trust) t.Run("GNUPGHOME is a file", func(t *testing.T) { - f, err := os.CreateTemp(t.TempDir(), "gpg-test") + f, err := os.CreateTemp("", "gpg-test") require.NoError(t, err) defer os.Remove(f.Name()) @@ -104,7 +104,7 @@ func Test_GPG_InitializeGnuPG(t *testing.T) { t.Run("Unaccessible GNUPGHOME", func(t *testing.T) { p := initTempDir(t) - fp := p + "/gpg" + fp := fmt.Sprintf("%s/gpg", p) err = os.Mkdir(fp, 0o000) if err != nil { panic(err.Error()) diff --git a/util/grpc/errors.go b/util/grpc/errors.go index 141c76e7b1..1bd3686fa2 100644 --- a/util/grpc/errors.go +++ b/util/grpc/errors.go @@ -8,7 +8,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - apierrors "k8s.io/apimachinery/pkg/api/errors" + apierr "k8s.io/apimachinery/pkg/api/errors" ) func rewrapError(err error, code codes.Code) error { @@ -24,7 +24,8 @@ func gitErrToGRPC(err error) error { errMsg = grpcStatus.Message() } - if errMsg == giterr.ErrRepositoryNotFound.Error() { + switch errMsg { + case giterr.ErrRepositoryNotFound.Error(): err = rewrapError(errors.New(errMsg), codes.NotFound) } return err @@ -65,31 +66,31 @@ func kubeErrToGRPC(err error) error { */ switch { - case apierrors.IsNotFound(err): + case apierr.IsNotFound(err): err = rewrapError(err, codes.NotFound) - case apierrors.IsAlreadyExists(err): + case apierr.IsAlreadyExists(err): err = rewrapError(err, codes.AlreadyExists) - case apierrors.IsInvalid(err): + case apierr.IsInvalid(err): err = rewrapError(err, codes.InvalidArgument) - case apierrors.IsMethodNotSupported(err): + case apierr.IsMethodNotSupported(err): err = rewrapError(err, codes.Unimplemented) - case apierrors.IsServiceUnavailable(err): + case apierr.IsServiceUnavailable(err): err = rewrapError(err, codes.Unavailable) - case apierrors.IsBadRequest(err): + case apierr.IsBadRequest(err): err = rewrapError(err, codes.FailedPrecondition) - case apierrors.IsUnauthorized(err): + case apierr.IsUnauthorized(err): err = rewrapError(err, codes.Unauthenticated) - case apierrors.IsForbidden(err): + case apierr.IsForbidden(err): err = rewrapError(err, codes.PermissionDenied) - case apierrors.IsTimeout(err): + case apierr.IsTimeout(err): err = rewrapError(err, codes.DeadlineExceeded) - case apierrors.IsServerTimeout(err): + case apierr.IsServerTimeout(err): err = rewrapError(err, codes.Unavailable) - case apierrors.IsConflict(err): + case apierr.IsConflict(err): err = rewrapError(err, codes.Aborted) - case apierrors.IsTooManyRequests(err): + case apierr.IsTooManyRequests(err): err = rewrapError(err, codes.ResourceExhausted) - case apierrors.IsInternalError(err): + case apierr.IsInternalError(err): err = rewrapError(err, codes.Internal) default: // This is necessary as GRPC Status don't support wrapped errors: @@ -103,7 +104,7 @@ func kubeErrToGRPC(err error) error { // ErrorCodeGitUnaryServerInterceptor replaces Kubernetes errors with relevant gRPC equivalents, if any. func ErrorCodeGitUnaryServerInterceptor() grpc.UnaryServerInterceptor { - return func(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { resp, err = handler(ctx, req) return resp, gitErrToGRPC(err) } @@ -111,7 +112,7 @@ func ErrorCodeGitUnaryServerInterceptor() grpc.UnaryServerInterceptor { // ErrorCodeGitStreamServerInterceptor replaces Kubernetes errors with relevant gRPC equivalents, if any. func ErrorCodeGitStreamServerInterceptor() grpc.StreamServerInterceptor { - return func(srv any, ss grpc.ServerStream, _ *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { err := handler(srv, ss) return gitErrToGRPC(err) } @@ -119,7 +120,7 @@ func ErrorCodeGitStreamServerInterceptor() grpc.StreamServerInterceptor { // ErrorCodeK8sUnaryServerInterceptor replaces Kubernetes errors with relevant gRPC equivalents, if any. func ErrorCodeK8sUnaryServerInterceptor() grpc.UnaryServerInterceptor { - return func(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { resp, err = handler(ctx, req) return resp, kubeErrToGRPC(err) } @@ -127,7 +128,7 @@ func ErrorCodeK8sUnaryServerInterceptor() grpc.UnaryServerInterceptor { // ErrorCodeK8sStreamServerInterceptor replaces Kubernetes errors with relevant gRPC equivalents, if any. func ErrorCodeK8sStreamServerInterceptor() grpc.StreamServerInterceptor { - return func(srv any, ss grpc.ServerStream, _ *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { err := handler(srv, ss) return kubeErrToGRPC(err) } diff --git a/util/grpc/errors_test.go b/util/grpc/errors_test.go index 5e6bfd7b69..710a6c9ffc 100644 --- a/util/grpc/errors_test.go +++ b/util/grpc/errors_test.go @@ -7,7 +7,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - apierrors "k8s.io/apimachinery/pkg/api/errors" + apierr "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/schema" "github.com/stretchr/testify/assert" @@ -51,19 +51,19 @@ func Test_kubeErrToGRPC(t *testing.T) { Group: "apps", Resource: "Deployment", } - return apierrors.NewForbidden(gr, "some-app", errors.New("authentication error")) + return apierr.NewForbidden(gr, "some-app", fmt.Errorf("authentication error")) } newUnauthorizedError := func() error { - return apierrors.NewUnauthorized("unauthenticated") + return apierr.NewUnauthorized("unauthenticated") } cases := []*testCase{ { name: "will return standard error if not grpc status", givenErrFn: func() error { - return errors.New("standard error") + return fmt.Errorf("standard error") }, expectedErrFn: func() error { - return errors.New("standard error") + return fmt.Errorf("standard error") }, expectedGRPCStatus: nil, }, @@ -80,7 +80,7 @@ func Test_kubeErrToGRPC(t *testing.T) { expectedGRPCStatus: status.New(codes.NotFound, "Not found"), }, { - name: "will return permission denied if apierrors.IsForbidden", + name: "will return permission denied if apierr.IsForbidden", givenErrFn: func() error { return newForbiddenError() }, @@ -92,7 +92,7 @@ func Test_kubeErrToGRPC(t *testing.T) { expectedGRPCStatus: status.New(codes.PermissionDenied, newForbiddenError().Error()), }, { - name: "will return unauthenticated if apierrors.IsUnauthorized", + name: "will return unauthenticated if apierr.IsUnauthorized", givenErrFn: func() error { return newUnauthorizedError() }, @@ -104,40 +104,40 @@ func Test_kubeErrToGRPC(t *testing.T) { expectedGRPCStatus: status.New(codes.Unauthenticated, newUnauthorizedError().Error()), }, { - name: "will return Unavailable if apierrors.IsServerTimeout", + name: "will return Unavailable if apierr.IsServerTimeout", givenErrFn: func() error { - return apierrors.NewServerTimeout(schema.GroupResource{}, "update", 1) + return apierr.NewServerTimeout(schema.GroupResource{}, "update", 1) }, expectedErrFn: func() error { - err := apierrors.NewServerTimeout(schema.GroupResource{}, "update", 1) + err := apierr.NewServerTimeout(schema.GroupResource{}, "update", 1) grpcStatus := status.New(codes.Unavailable, err.Error()) return grpcStatus.Err() }, - expectedGRPCStatus: status.New(codes.Unavailable, apierrors.NewServerTimeout(schema.GroupResource{}, "update", 1).Error()), + expectedGRPCStatus: status.New(codes.Unavailable, apierr.NewServerTimeout(schema.GroupResource{}, "update", 1).Error()), }, { - name: "will return Aborted if apierrors.IsConflict", + name: "will return Aborted if apierr.IsConflict", givenErrFn: func() error { - return apierrors.NewConflict(schema.GroupResource{}, "foo", errors.New("foo")) + return apierr.NewConflict(schema.GroupResource{}, "foo", errors.New("foo")) }, expectedErrFn: func() error { - err := apierrors.NewConflict(schema.GroupResource{}, "foo", errors.New("foo")) + err := apierr.NewConflict(schema.GroupResource{}, "foo", errors.New("foo")) grpcStatus := status.New(codes.Aborted, err.Error()) return grpcStatus.Err() }, - expectedGRPCStatus: status.New(codes.Aborted, apierrors.NewConflict(schema.GroupResource{}, "foo", errors.New("foo")).Error()), + expectedGRPCStatus: status.New(codes.Aborted, apierr.NewConflict(schema.GroupResource{}, "foo", errors.New("foo")).Error()), }, { - name: "will return ResourceExhausted if apierrors.IsTooManyRequests", + name: "will return ResourceExhausted if apierr.IsTooManyRequests", givenErrFn: func() error { - return apierrors.NewTooManyRequests("foo", 1) + return apierr.NewTooManyRequests("foo", 1) }, expectedErrFn: func() error { - err := apierrors.NewTooManyRequests("foo", 1) + err := apierr.NewTooManyRequests("foo", 1) grpcStatus := status.New(codes.ResourceExhausted, err.Error()) return grpcStatus.Err() }, - expectedGRPCStatus: status.New(codes.ResourceExhausted, apierrors.NewTooManyRequests("foo", 1).Error()), + expectedGRPCStatus: status.New(codes.ResourceExhausted, apierr.NewTooManyRequests("foo", 1).Error()), }, } for _, c := range cases { diff --git a/util/grpc/grpc.go b/util/grpc/grpc.go index cce7c1258d..cc4c6b46e0 100644 --- a/util/grpc/grpc.go +++ b/util/grpc/grpc.go @@ -9,7 +9,6 @@ import ( "strings" "time" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery" "github.com/sirupsen/logrus" "golang.org/x/net/proxy" "google.golang.org/grpc" @@ -19,14 +18,32 @@ import ( "google.golang.org/grpc/keepalive" "google.golang.org/grpc/status" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) -// LoggerRecoveryHandler return a handler for recovering from panics and returning error -func LoggerRecoveryHandler(log *logrus.Entry) recovery.RecoveryHandlerFunc { - return func(p any) (err error) { - log.Errorf("Recovered from panic: %+v\n%s", p, debug.Stack()) - return status.Errorf(codes.Internal, "%s", p) +// PanicLoggerUnaryServerInterceptor returns a new unary server interceptor for recovering from panics and returning error +func PanicLoggerUnaryServerInterceptor(log *logrus.Entry) grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) { + defer func() { + if r := recover(); r != nil { + log.Errorf("Recovered from panic: %+v\n%s", r, debug.Stack()) + err = status.Errorf(codes.Internal, "%s", r) + } + }() + return handler(ctx, req) + } +} + +// PanicLoggerStreamServerInterceptor returns a new streaming server interceptor for recovering from panics and returning error +func PanicLoggerStreamServerInterceptor(log *logrus.Entry) grpc.StreamServerInterceptor { + return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) { + defer func() { + if r := recover(); r != nil { + log.Errorf("Recovered from panic: %+v\n%s", r, debug.Stack()) + err = status.Errorf(codes.Internal, "%s", r) + } + }() + return handler(srv, stream) } } @@ -38,8 +55,8 @@ func BlockingDial(ctx context.Context, network, address string, creds credential // grpc.Dial doesn't provide any information on permanent connection errors (like // TLS handshake failures). So in order to provide good error messages, we need a // custom dialer that can provide that info. That means we manage the TLS handshake. - result := make(chan any, 1) - writeResult := func(res any) { + result := make(chan interface{}, 1) + writeResult := func(res interface{}) { // non-blocking write: we only need the first result select { case result <- res: @@ -69,17 +86,17 @@ func BlockingDial(ctx context.Context, network, address string, creds credential // channel to either get the channel or fail-fast. go func() { opts = append(opts, - //nolint:staticcheck + // nolint:staticcheck grpc.WithBlock(), - //nolint:staticcheck + // nolint:staticcheck grpc.FailOnNonTempDialError(true), grpc.WithContextDialer(dialer), grpc.WithTransportCredentials(insecure.NewCredentials()), // we are handling TLS, so tell grpc not to grpc.WithKeepaliveParams(keepalive.ClientParameters{Time: common.GetGRPCKeepAliveTime()}), ) - //nolint:staticcheck + // nolint:staticcheck conn, err := grpc.DialContext(ctx, address, opts...) - var res any + var res interface{} if err != nil { res = err } else { @@ -150,3 +167,12 @@ func TestTLS(address string, dialTime time.Duration) (*TLSTestResult, error) { } return nil, err } + +func WithTimeout(duration time.Duration) grpc.UnaryClientInterceptor { + return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + clientDeadline := time.Now().Add(duration) + ctx, cancel := context.WithDeadline(ctx, clientDeadline) + defer cancel() + return invoker(ctx, method, req, reply, cc, opts...) + } +} diff --git a/util/grpc/json.go b/util/grpc/json.go index 9852e52627..93e8f9688b 100644 --- a/util/grpc/json.go +++ b/util/grpc/json.go @@ -16,7 +16,7 @@ func (j *JSONMarshaler) ContentType() string { } // Marshal implements gwruntime.Marshaler. -func (j *JSONMarshaler) Marshal(v any) ([]byte, error) { +func (j *JSONMarshaler) Marshal(v interface{}) ([]byte, error) { return json.Marshal(v) } @@ -31,12 +31,12 @@ func (j *JSONMarshaler) NewEncoder(w io.Writer) gwruntime.Encoder { } // Unmarshal implements gwruntime.Marshaler. -func (j *JSONMarshaler) Unmarshal(data []byte, v any) error { +func (j *JSONMarshaler) Unmarshal(data []byte, v interface{}) error { return json.Unmarshal(data, v) } // MustMarshal is a convenience function to marshal an object successfully or panic -func MustMarshal(v any) []byte { +func MustMarshal(v interface{}) []byte { bytes, err := json.Marshal(v) if err != nil { panic(err) diff --git a/util/grpc/logging.go b/util/grpc/logging.go index 3bb1dfe34f..37dfc286ca 100644 --- a/util/grpc/logging.go +++ b/util/grpc/logging.go @@ -5,24 +5,22 @@ import ( "context" "encoding/json" "fmt" - "time" "github.com/gogo/protobuf/jsonpb" "github.com/gogo/protobuf/proto" - "github.com/golang-jwt/jwt/v5" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/selector" + "github.com/golang-jwt/jwt/v4" + grpc_logging "github.com/grpc-ecosystem/go-grpc-middleware/logging" + ctx_logrus "github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus" "github.com/sirupsen/logrus" "google.golang.org/grpc" ) -func logRequest(ctx context.Context, entry *logrus.Entry, info string, pbMsg any, logClaims bool) { +func logRequest(entry *logrus.Entry, info string, pbMsg interface{}, ctx context.Context, logClaims bool) { if logClaims { claims := ctx.Value("claims") mapClaims, ok := claims.(jwt.MapClaims) if ok { - copy := make(map[string]any) + copy := make(map[string]interface{}) for k, v := range mapClaims { if k != "groups" || entry.Logger.IsLevelEnabled(logrus.DebugLevel) { copy[k] = v @@ -53,64 +51,44 @@ func (j *jsonpbMarshalleble) MarshalJSON() ([]byte, error) { return b.Bytes(), nil } -type reporter struct { - ctx context.Context +type loggingServerStream struct { + grpc.ServerStream entry *logrus.Entry logClaims bool info string } -func (r *reporter) PostCall(_ error, _ time.Duration) {} +func (l *loggingServerStream) SendMsg(m interface{}) error { + return l.ServerStream.SendMsg(m) +} -func (r *reporter) PostMsgSend(_ any, _ error, _ time.Duration) {} - -func (r *reporter) PostMsgReceive(payload any, err error, _ time.Duration) { +func (l *loggingServerStream) RecvMsg(m interface{}) error { + err := l.ServerStream.RecvMsg(m) if err == nil { - logRequest(r.ctx, r.entry, r.info, payload, r.logClaims) + logRequest(l.entry, l.info, m, l.ServerStream.Context(), l.logClaims) + } + return err +} + +func PayloadStreamServerInterceptor(entry *logrus.Entry, logClaims bool, decider grpc_logging.ServerPayloadLoggingDecider) grpc.StreamServerInterceptor { + return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + if !decider(stream.Context(), info.FullMethod, srv) { + return handler(srv, stream) + } + logEntry := entry.WithFields(ctx_logrus.Extract(stream.Context()).Data) + newStream := &loggingServerStream{ServerStream: stream, entry: logEntry, logClaims: logClaims, info: fmt.Sprintf("received streaming call %s", info.FullMethod)} + return handler(srv, newStream) } } -func PayloadStreamServerInterceptor(entry *logrus.Entry, logClaims bool, decider func(context.Context, interceptors.CallMeta) bool) grpc.StreamServerInterceptor { - return selector.StreamServerInterceptor(interceptors.StreamServerInterceptor(reportable(entry, "streaming", logClaims)), selector.MatchFunc(decider)) -} - -func PayloadUnaryServerInterceptor(entry *logrus.Entry, logClaims bool, decider func(context.Context, interceptors.CallMeta) bool) grpc.UnaryServerInterceptor { - return selector.UnaryServerInterceptor(interceptors.UnaryServerInterceptor(reportable(entry, "unary", logClaims)), selector.MatchFunc(decider)) -} - -func reportable(entry *logrus.Entry, callType string, logClaims bool) interceptors.CommonReportableFunc { - return func(ctx context.Context, c interceptors.CallMeta) (interceptors.Reporter, context.Context) { - return &reporter{ - ctx: ctx, - entry: entry, - info: fmt.Sprintf("received %s call %s", callType, c.FullMethod()), - logClaims: logClaims, - }, ctx +func PayloadUnaryServerInterceptor(entry *logrus.Entry, logClaims bool, decider grpc_logging.ServerPayloadLoggingDecider) grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + if !decider(ctx, info.FullMethod, info.Server) { + return handler(ctx, req) + } + logEntry := entry.WithFields(ctx_logrus.Extract(ctx).Data) + logRequest(logEntry, fmt.Sprintf("received unary call %s", info.FullMethod), req, ctx, logClaims) + resp, err := handler(ctx, req) + return resp, err } } - -// InterceptorLogger adapts logrus logger to interceptor logger. -func InterceptorLogger(l logrus.FieldLogger) logging.Logger { - return logging.LoggerFunc(func(_ context.Context, lvl logging.Level, msg string, fields ...any) { - f := make(map[string]any, len(fields)/2) - i := logging.Fields(fields).Iterator() - for i.Next() { - k, v := i.At() - f[k] = v - } - l := l.WithFields(f) - - switch lvl { - case logging.LevelDebug: - l.Debug(msg) - case logging.LevelInfo: - l.Info(msg) - case logging.LevelWarn: - l.Warn(msg) - case logging.LevelError: - l.Error(msg) - default: - panic(fmt.Sprintf("unknown level %v", lvl)) - } - }) -} diff --git a/util/grpc/logging_test.go b/util/grpc/logging_test.go index e3e549701b..98be425928 100644 --- a/util/grpc/logging_test.go +++ b/util/grpc/logging_test.go @@ -6,14 +6,13 @@ import ( "fmt" "testing" - "github.com/golang-jwt/jwt/v5" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors" + "github.com/golang-jwt/jwt/v4" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/grpc" - "github.com/argoproj/argo-cd/v3/pkg/apiclient/account" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/account" ) func Test_JSONLogging(t *testing.T) { @@ -23,14 +22,14 @@ func Test_JSONLogging(t *testing.T) { l.SetOutput(&buf) entry := logrus.NewEntry(l) - c := t.Context() + c := context.Background() req := new(account.CreateTokenRequest) req.Name = "create-token-name" info := &grpc.UnaryServerInfo{} - handler := func(_ context.Context, _ any) (any, error) { + handler := func(ctx context.Context, req interface{}) (interface{}, error) { return nil, nil } - decider := func(_ context.Context, _ interceptors.CallMeta) bool { + decider := func(ctx context.Context, fullMethodName string, servingObject interface{}) bool { return true } interceptor := PayloadUnaryServerInterceptor(entry, false, decider) @@ -42,16 +41,16 @@ func Test_JSONLogging(t *testing.T) { } func Test_logRequest(t *testing.T) { - c := t.Context() + c := context.Background() //nolint:staticcheck c = context.WithValue(c, "claims", jwt.MapClaims{"groups": []string{"expected-group-claim"}}) req := new(account.CreateTokenRequest) req.Name = "create-token-name" info := &grpc.UnaryServerInfo{} - handler := func(_ context.Context, _ any) (any, error) { + handler := func(ctx context.Context, req interface{}) (interface{}, error) { return nil, nil } - decider := func(_ context.Context, _ interceptors.CallMeta) bool { + decider := func(ctx context.Context, fullMethodName string, servingObject interface{}) bool { return true } diff --git a/util/grpc/sanitizer.go b/util/grpc/sanitizer.go index 1afae682fb..36739e7def 100644 --- a/util/grpc/sanitizer.go +++ b/util/grpc/sanitizer.go @@ -19,7 +19,7 @@ const ( // ErrorSanitizerUnaryServerInterceptor returns a new unary server interceptor that sanitizes error messages // and provides Sanitizer to define replacements. func ErrorSanitizerUnaryServerInterceptor() grpc.UnaryServerInterceptor { - return func(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { sanitizer := NewSanitizer() resp, err = handler(ContextWithSanitizer(ctx, sanitizer), req) if err == nil { diff --git a/util/grpc/sanitizer_test.go b/util/grpc/sanitizer_test.go index 3867f3f5b1..bd7108b6d0 100644 --- a/util/grpc/sanitizer_test.go +++ b/util/grpc/sanitizer_test.go @@ -14,7 +14,7 @@ import ( func TestSanitizer(t *testing.T) { s := NewSanitizer() - ctx := ContextWithSanitizer(t.Context(), s) + ctx := ContextWithSanitizer(context.TODO(), s) sanitizer, ok := SanitizerFromContext(ctx) require.True(t, ok) @@ -27,7 +27,7 @@ func TestSanitizer(t *testing.T) { func TestSanitizer_RegexReplacement(t *testing.T) { s := NewSanitizer() - ctx := ContextWithSanitizer(t.Context(), s) + ctx := ContextWithSanitizer(context.TODO(), s) sanitizer, ok := SanitizerFromContext(ctx) require.True(t, ok) @@ -40,12 +40,12 @@ func TestSanitizer_RegexReplacement(t *testing.T) { func TestErrorSanitizerUnaryServerInterceptor(t *testing.T) { interceptor := ErrorSanitizerUnaryServerInterceptor() - _, err := interceptor(t.Context(), nil, nil, func(ctx context.Context, _ any) (any, error) { + _, err := interceptor(context.Background(), nil, nil, func(ctx context.Context, req interface{}) (interface{}, error) { sanitizer, ok := SanitizerFromContext(ctx) require.True(t, ok) sanitizer.AddReplacement("/my-random/path", ".") return nil, status.Error(codes.Internal, "error at /my-random/path/sub-dir: something went wrong") }) - assert.EqualError(t, err, "rpc error: code = Internal desc = error at ./sub-dir: something went wrong") + assert.Equal(t, "rpc error: code = Internal desc = error at ./sub-dir: something went wrong", err.Error()) } diff --git a/util/grpc/useragent.go b/util/grpc/useragent.go index 6d5d59c6b7..c71f5e1a8a 100644 --- a/util/grpc/useragent.go +++ b/util/grpc/useragent.go @@ -2,7 +2,6 @@ package grpc import ( "context" - "errors" "strings" "github.com/Masterminds/semver/v3" @@ -12,21 +11,15 @@ import ( "google.golang.org/grpc/status" ) -// parseSemVerConstraint returns a semVer Constraint instance or panic if there is a parsing error with the provided constraint. -func parseSemVerConstraint(constraintStr string) *semver.Constraints { +// UserAgentUnaryServerInterceptor returns a UnaryServerInterceptor which enforces a minimum client +// version in the user agent +func UserAgentUnaryServerInterceptor(clientName, constraintStr string) grpc.UnaryServerInterceptor { semVerConstraint, err := semver.NewConstraint(constraintStr) if err != nil { panic(err) } - return semVerConstraint -} - -// UserAgentUnaryServerInterceptor returns a UnaryServerInterceptor which enforces a minimum client -// version in the user agent -func UserAgentUnaryServerInterceptor(clientName, constraintStr string) grpc.UnaryServerInterceptor { - semVerConstraint := parseSemVerConstraint(constraintStr) - return func(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { - if err := userAgentEnforcer(ctx, clientName, semVerConstraint); err != nil { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + if err := userAgentEnforcer(ctx, clientName, constraintStr, semVerConstraint); err != nil { return nil, err } return handler(ctx, req) @@ -36,16 +29,19 @@ func UserAgentUnaryServerInterceptor(clientName, constraintStr string) grpc.Unar // UserAgentStreamServerInterceptor returns a StreamServerInterceptor which enforces a minimum client // version in the user agent func UserAgentStreamServerInterceptor(clientName, constraintStr string) grpc.StreamServerInterceptor { - semVerConstraint := parseSemVerConstraint(constraintStr) - return func(srv any, stream grpc.ServerStream, _ *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - if err := userAgentEnforcer(stream.Context(), clientName, semVerConstraint); err != nil { + semVerConstraint, err := semver.NewConstraint(constraintStr) + if err != nil { + panic(err) + } + return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + if err := userAgentEnforcer(stream.Context(), clientName, constraintStr, semVerConstraint); err != nil { return err } return handler(srv, stream) } } -func userAgentEnforcer(ctx context.Context, clientName string, semVerConstraint *semver.Constraints) error { +func userAgentEnforcer(ctx context.Context, clientName, constraintStr string, semVerConstraint *semver.Constraints) error { var userAgents []string if md, ok := metadata.FromIncomingContext(ctx); ok { for _, ua := range md["user-agent"] { @@ -55,7 +51,7 @@ func userAgentEnforcer(ctx context.Context, clientName string, semVerConstraint } } if isLegacyClient(userAgents) { - return status.Errorf(codes.FailedPrecondition, "unsatisfied client version constraint: %s", semVerConstraint) + return status.Errorf(codes.FailedPrecondition, "unsatisfied client version constraint: %s", constraintStr) } for _, userAgent := range userAgents { @@ -72,7 +68,7 @@ func userAgentEnforcer(ctx context.Context, clientName string, semVerConstraint return status.Errorf(codes.InvalidArgument, "could not parse version from user-agent: %s", userAgent) } if ok, errs := semVerConstraint.Validate(uaVers); !ok { - return status.Errorf(codes.FailedPrecondition, "unsatisfied client version constraint: %s", errors.Join(errs...)) + return status.Errorf(codes.FailedPrecondition, "unsatisfied client version constraint: %s", errs[0].Error()) } return nil } diff --git a/util/grpc/useragent_test.go b/util/grpc/useragent_test.go index 8716aa6968..6520acf005 100644 --- a/util/grpc/useragent_test.go +++ b/util/grpc/useragent_test.go @@ -1,6 +1,7 @@ package grpc import ( + "context" "testing" "github.com/Masterminds/semver/v3" @@ -9,36 +10,49 @@ import ( ) func Test_UserAgentEnforcer(t *testing.T) { - clientName := "argo-cd" - semverConstraint, _ := semver.NewConstraint("^1") t.Run("Test enforcing valid user-agent", func(t *testing.T) { + clientName := "argo-cd" + constraintStr := "^1" + semverConstraint, _ := semver.NewConstraint(constraintStr) md := metadata.New(map[string]string{"user-agent": "argo-cd/1.0"}) - ctx := metadata.NewIncomingContext(t.Context(), md) - err := userAgentEnforcer(ctx, clientName, semverConstraint) + ctx := metadata.NewIncomingContext(context.Background(), md) + err := userAgentEnforcer(ctx, clientName, constraintStr, semverConstraint) require.NoError(t, err) }) t.Run("Test enforcing ignored user-agent", func(t *testing.T) { + clientName := "argo-cd" + constraintStr := "^1" + semverConstraint, _ := semver.NewConstraint(constraintStr) md := metadata.New(map[string]string{"user-agent": "flux/3.0"}) - ctx := metadata.NewIncomingContext(t.Context(), md) - err := userAgentEnforcer(ctx, clientName, semverConstraint) + ctx := metadata.NewIncomingContext(context.Background(), md) + err := userAgentEnforcer(ctx, clientName, constraintStr, semverConstraint) require.NoError(t, err) }) t.Run("Test enforcing user-agent with version not matching constraint", func(t *testing.T) { + clientName := "argo-cd" + constraintStr := "^1" + semverConstraint, _ := semver.NewConstraint(constraintStr) md := metadata.New(map[string]string{"user-agent": "argo-cd/3.0"}) - ctx := metadata.NewIncomingContext(t.Context(), md) - err := userAgentEnforcer(ctx, clientName, semverConstraint) + ctx := metadata.NewIncomingContext(context.Background(), md) + err := userAgentEnforcer(ctx, clientName, constraintStr, semverConstraint) require.ErrorContains(t, err, "unsatisfied client version constraint") }) t.Run("Test legacy user-agent", func(t *testing.T) { + clientName := "argo-cd" + constraintStr := "^1" + semverConstraint, _ := semver.NewConstraint(constraintStr) md := metadata.New(map[string]string{"user-agent": "grpc-go/1.15.0"}) - ctx := metadata.NewIncomingContext(t.Context(), md) - err := userAgentEnforcer(ctx, clientName, semverConstraint) - require.ErrorContains(t, err, "unsatisfied client version constraint: ^1") + ctx := metadata.NewIncomingContext(context.Background(), md) + err := userAgentEnforcer(ctx, clientName, constraintStr, semverConstraint) + require.ErrorContains(t, err, "unsatisfied client version constraint") }) t.Run("Test invalid version", func(t *testing.T) { + clientName := "argo-cd" + constraintStr := "^1" + semverConstraint, _ := semver.NewConstraint(constraintStr) md := metadata.New(map[string]string{"user-agent": "argo-cd/super"}) - ctx := metadata.NewIncomingContext(t.Context(), md) - err := userAgentEnforcer(ctx, clientName, semverConstraint) + ctx := metadata.NewIncomingContext(context.Background(), md) + err := userAgentEnforcer(ctx, clientName, constraintStr, semverConstraint) require.ErrorContains(t, err, "could not parse version") }) } diff --git a/util/healthz/healthz_test.go b/util/healthz/healthz_test.go index c76a284c67..cf68eb419b 100644 --- a/util/healthz/healthz_test.go +++ b/util/healthz/healthz_test.go @@ -1,7 +1,7 @@ package healthz import ( - "errors" + "fmt" "net" "net/http" "testing" @@ -23,9 +23,9 @@ func TestHealthCheck(t *testing.T) { c <- listener.Addr().String() mux := http.NewServeMux() - ServeHealthCheck(mux, func(_ *http.Request) error { + ServeHealthCheck(mux, func(r *http.Request) error { if sentinel { - return errors.New("This is a dummy error") + return fmt.Errorf("This is a dummy error") } return nil }) diff --git a/util/helm/client.go b/util/helm/client.go index 66cc59a129..e2e03fa412 100644 --- a/util/helm/client.go +++ b/util/helm/client.go @@ -18,28 +18,37 @@ import ( "strings" "time" - executil "github.com/argoproj/argo-cd/v3/util/exec" + executil "github.com/argoproj/argo-cd/v2/util/exec" - "github.com/argoproj/pkg/v2/sync" + "github.com/argoproj/pkg/sync" log "github.com/sirupsen/logrus" "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/v3/util/cache" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/io/files" - "github.com/argoproj/argo-cd/v3/util/proxy" + "github.com/argoproj/argo-cd/v2/util/cache" + argoio "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/io/files" + "github.com/argoproj/argo-cd/v2/util/proxy" ) var ( globalLock = sync.NewKeyLock() indexLock = sync.NewKeyLock() - ErrOCINotEnabled = errors.New("could not perform the action when oci is not enabled") + OCINotEnabledErr = errors.New("could not perform the action when oci is not enabled") ) +type Creds struct { + Username string + Password string + CAPath string + CertData []byte + KeyData []byte + InsecureSkipVerify bool +} + type indexCache interface { SetHelmIndex(repo string, indexData []byte) error GetHelmIndex(repo string, indexData *[]byte) error @@ -47,9 +56,9 @@ type indexCache interface { type Client interface { CleanChartCache(chart string, version string) error - ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, utilio.Closer, error) + ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, argoio.Closer, error) GetIndex(noCache bool, maxIndexSize int64) (*Index, error) - GetTags(chart string, noCache bool) ([]string, error) + GetTags(chart string, noCache bool) (*TagsList, error) TestHelmOCI() (bool, error) } @@ -61,7 +70,7 @@ func WithIndexCache(indexCache indexCache) ClientOpts { } } -func WithChartPaths(chartPaths utilio.TempPaths) ClientOpts { +func WithChartPaths(chartPaths argoio.TempPaths) ClientOpts { return func(c *nativeHelmChart) { c.chartCachePaths = chartPaths } @@ -79,7 +88,7 @@ func NewClientWithLock(repoURL string, creds Creds, repoLock sync.KeyLock, enabl enableOci: enableOci, proxy: proxy, noProxy: noProxy, - chartCachePaths: utilio.NewRandomizedTempPaths(os.TempDir()), + chartCachePaths: argoio.NewRandomizedTempPaths(os.TempDir()), } for i := range opts { opts[i](c) @@ -90,7 +99,7 @@ func NewClientWithLock(repoURL string, creds Creds, repoLock sync.KeyLock, enabl var _ Client = &nativeHelmChart{} type nativeHelmChart struct { - chartCachePaths utilio.TempPaths + chartCachePaths argoio.TempPaths repoURL string creds Creds repoLock sync.KeyLock @@ -104,8 +113,9 @@ func fileExist(filePath string) (bool, error) { if _, err := os.Stat(filePath); err != nil { if os.IsNotExist(err) { return false, nil + } else { + return false, fmt.Errorf("error checking file existence for %s: %w", filePath, err) } - return false, fmt.Errorf("error checking file existence for %s: %w", filePath, err) } return true, nil } @@ -138,7 +148,7 @@ func untarChart(tempDir string, cachedChartPath string, manifestMaxExtractedSize return files.Untgz(tempDir, reader, manifestMaxExtractedSize, false) } -func (c *nativeHelmChart) ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, utilio.Closer, error) { +func (c *nativeHelmChart) ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, argoio.Closer, error) { // always use Helm V3 since we don't have chart content to determine correct Helm version helmCmd, err := NewCmdWithVersion("", c.enableOci, c.proxy, c.noProxy) if err != nil { @@ -178,11 +188,7 @@ func (c *nativeHelmChart) ExtractChart(chart string, version string, passCredent defer func() { _ = os.RemoveAll(tempDest) }() if c.enableOci { - helmPassword, err := c.creds.GetPassword() - if err != nil { - return "", nil, fmt.Errorf("failed to get password for helm registry: %w", err) - } - if helmPassword != "" && c.creds.GetUsername() != "" { + if c.creds.Password != "" && c.creds.Username != "" { _, err = helmCmd.RegistryLogin(c.repoURL, c.creds) if err != nil { _ = os.RemoveAll(tempDir) @@ -230,7 +236,7 @@ func (c *nativeHelmChart) ExtractChart(chart string, version string, passCredent _ = os.RemoveAll(tempDir) return "", nil, fmt.Errorf("error untarring chart: %w", err) } - return path.Join(tempDir, normalizeChartName(chart)), utilio.NewCloser(func() error { + return path.Join(tempDir, normalizeChartName(chart)), argoio.NewCloser(func() error { return os.RemoveAll(tempDir) }), nil } @@ -288,11 +294,7 @@ func (c *nativeHelmChart) TestHelmOCI() (bool, error) { // Looks like there is no good way to test access to OCI repo if credentials are not provided // just assume it is accessible - helmPassword, err := c.creds.GetPassword() - if err != nil { - return false, fmt.Errorf("failed to get password for helm registry: %w", err) - } - if c.creds.GetUsername() != "" && helmPassword != "" { + if c.creds.Username != "" && c.creds.Password != "" { _, err = helmCmd.RegistryLogin(c.repoURL, c.creds) if err != nil { return false, fmt.Errorf("error logging into OCI registry: %w", err) @@ -316,13 +318,9 @@ func (c *nativeHelmChart) loadRepoIndex(maxIndexSize int64) ([]byte, error) { if err != nil { return nil, fmt.Errorf("error creating HTTP request: %w", err) } - helmPassword, err := c.creds.GetPassword() - if err != nil { - return nil, fmt.Errorf("failed to get password for helm registry: %w", err) - } - if c.creds.GetUsername() != "" || helmPassword != "" { + if c.creds.Username != "" || c.creds.Password != "" { // only basic supported - req.SetBasicAuth(c.creds.GetUsername(), helmPassword) + req.SetBasicAuth(c.creds.Username, c.creds.Password) } tlsConf, err := newTLSConfig(c.creds) @@ -349,12 +347,12 @@ func (c *nativeHelmChart) loadRepoIndex(maxIndexSize int64) ([]byte, error) { } func newTLSConfig(creds Creds) (*tls.Config, error) { - tlsConfig := &tls.Config{InsecureSkipVerify: creds.GetInsecureSkipVerify()} + tlsConfig := &tls.Config{InsecureSkipVerify: creds.InsecureSkipVerify} - if creds.GetCAPath() != "" { - caData, err := os.ReadFile(creds.GetCAPath()) + if creds.CAPath != "" { + caData, err := os.ReadFile(creds.CAPath) if err != nil { - return nil, fmt.Errorf("error reading CA file %s: %w", creds.GetCAPath(), err) + return nil, fmt.Errorf("error reading CA file %s: %w", creds.CAPath, err) } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caData) @@ -362,14 +360,14 @@ func newTLSConfig(creds Creds) (*tls.Config, error) { } // If a client cert & key is provided then configure TLS config accordingly. - if len(creds.GetCertData()) > 0 && len(creds.GetKeyData()) > 0 { - cert, err := tls.X509KeyPair(creds.GetCertData(), creds.GetKeyData()) + if len(creds.CertData) > 0 && len(creds.KeyData) > 0 { + cert, err := tls.X509KeyPair(creds.CertData, creds.KeyData) if err != nil { return nil, fmt.Errorf("error creating X509 key pair: %w", err) } tlsConfig.Certificates = []tls.Certificate{cert} } - //nolint:staticcheck + // nolint:staticcheck tlsConfig.BuildNameToCertificate() return tlsConfig, nil @@ -416,9 +414,9 @@ func getIndexURL(rawURL string) (string, error) { return repoURL.String(), nil } -func (c *nativeHelmChart) GetTags(chart string, noCache bool) ([]string, error) { +func (c *nativeHelmChart) GetTags(chart string, noCache bool) (*TagsList, error) { if !c.enableOci { - return nil, ErrOCINotEnabled + return nil, OCINotEnabledErr } tagsURL := strings.Replace(fmt.Sprintf("%s/%s", c.repoURL, chart), "https://", "", 1) @@ -432,11 +430,7 @@ func (c *nativeHelmChart) GetTags(chart string, noCache bool) ([]string, error) } } - type entriesStruct struct { - Tags []string - } - - entries := &entriesStruct{} + tags := &TagsList{} if len(data) == 0 { start := time.Now() repo, err := remote.NewRepository(tagsURL) @@ -454,18 +448,13 @@ func (c *nativeHelmChart) GetTags(chart string, noCache bool) ([]string, error) }} repoHost, _, _ := strings.Cut(tagsURL, "/") - - helmPassword, err := c.creds.GetPassword() - if err != nil { - return nil, fmt.Errorf("failed to get password for helm registry: %w", err) - } credential := auth.StaticCredential(repoHost, auth.Credential{ - Username: c.creds.GetUsername(), - Password: helmPassword, + 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.GetUsername() == "" && helmPassword == "" { + if c.creds.Username == "" && c.creds.Password == "" { store, _ := credentials.NewStoreFromDocker(credentials.StoreOptions{}) if store != nil { credential = credentials.Credential(store) @@ -483,7 +472,7 @@ func (c *nativeHelmChart) GetTags(chart string, noCache bool) ([]string, error) for _, tag := range tagsResult { // By convention: Change underscore (_) back to plus (+) to get valid SemVer convertedTag := strings.ReplaceAll(tag, "_", "+") - entries.Tags = append(entries.Tags, convertedTag) + tags.Tags = append(tags.Tags, convertedTag) } return nil @@ -501,11 +490,11 @@ func (c *nativeHelmChart) GetTags(chart string, noCache bool) ([]string, error) } } } else { - err := json.Unmarshal(data, entries) + err := json.Unmarshal(data, tags) if err != nil { return nil, fmt.Errorf("failed to decode tags: %w", err) } } - return entries.Tags, nil + return tags, nil } diff --git a/util/helm/client_test.go b/util/helm/client_test.go index 5d7bf6281a..e32f3d3c70 100644 --- a/util/helm/client_test.go +++ b/util/helm/client_test.go @@ -17,18 +17,13 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/yaml.v2" - utilio "github.com/argoproj/argo-cd/v3/util/io" - "github.com/argoproj/argo-cd/v3/util/workloadidentity/mocks" + "github.com/argoproj/argo-cd/v2/util/io" ) type fakeIndexCache struct { data []byte } -type fakeTagsList struct { - Tags []string `json:"tags"` -} - func (f *fakeIndexCache) SetHelmIndex(_ string, indexData []byte) error { f.data = indexData return nil @@ -41,18 +36,18 @@ func (f *fakeIndexCache) GetHelmIndex(_ string, indexData *[]byte) error { func TestIndex(t *testing.T) { t.Run("Invalid", func(t *testing.T) { - client := NewClient("", HelmCreds{}, false, "", "") + client := NewClient("", Creds{}, false, "", "") _, err := client.GetIndex(false, 10000) require.Error(t, err) }) t.Run("Stable", func(t *testing.T) { - client := NewClient("https://argoproj.github.io/argo-helm", HelmCreds{}, false, "", "") + client := NewClient("https://argoproj.github.io/argo-helm", Creds{}, false, "", "") index, err := client.GetIndex(false, 10000) require.NoError(t, err) assert.NotNil(t, index) }) t.Run("BasicAuth", func(t *testing.T) { - client := NewClient("https://argoproj.github.io/argo-helm", HelmCreds{ + client := NewClient("https://argoproj.github.io/argo-helm", Creds{ Username: "my-password", Password: "my-username", }, false, "", "") @@ -67,7 +62,7 @@ func TestIndex(t *testing.T) { err := yaml.NewEncoder(&data).Encode(fakeIndex) require.NoError(t, err) - client := NewClient("https://argoproj.github.io/argo-helm", HelmCreds{}, false, "", "", WithIndexCache(&fakeIndexCache{data: data.Bytes()})) + client := NewClient("https://argoproj.github.io/argo-helm", Creds{}, false, "", "", WithIndexCache(&fakeIndexCache{data: data.Bytes()})) index, err := client.GetIndex(false, 10000) require.NoError(t, err) @@ -75,7 +70,7 @@ func TestIndex(t *testing.T) { }) t.Run("Limited", func(t *testing.T) { - client := NewClient("https://argoproj.github.io/argo-helm", HelmCreds{}, false, "", "") + client := NewClient("https://argoproj.github.io/argo-helm", Creds{}, false, "", "") _, err := client.GetIndex(false, 100) assert.ErrorContains(t, err, "unexpected end of stream") @@ -83,26 +78,26 @@ func TestIndex(t *testing.T) { } func Test_nativeHelmChart_ExtractChart(t *testing.T) { - client := NewClient("https://argoproj.github.io/argo-helm", HelmCreds{}, false, "", "") + client := NewClient("https://argoproj.github.io/argo-helm", Creds{}, false, "", "") path, closer, err := client.ExtractChart("argo-cd", "0.7.1", false, math.MaxInt64, true) require.NoError(t, err) - defer utilio.Close(closer) + defer io.Close(closer) info, err := os.Stat(path) require.NoError(t, err) assert.True(t, info.IsDir()) } func Test_nativeHelmChart_ExtractChartWithLimiter(t *testing.T) { - client := NewClient("https://argoproj.github.io/argo-helm", HelmCreds{}, false, "", "") + client := NewClient("https://argoproj.github.io/argo-helm", Creds{}, false, "", "") _, _, err := client.ExtractChart("argo-cd", "0.7.1", false, 100, false) require.Error(t, err, "error while iterating on tar reader: unexpected EOF") } func Test_nativeHelmChart_ExtractChart_insecure(t *testing.T) { - client := NewClient("https://argoproj.github.io/argo-helm", HelmCreds{InsecureSkipVerify: true}, false, "", "") + client := NewClient("https://argoproj.github.io/argo-helm", Creds{InsecureSkipVerify: true}, false, "", "") path, closer, err := client.ExtractChart("argo-cd", "0.7.1", false, math.MaxInt64, true) require.NoError(t, err) - defer utilio.Close(closer) + defer io.Close(closer) info, err := os.Stat(path) require.NoError(t, err) assert.True(t, info.IsDir()) @@ -165,7 +160,7 @@ func TestGetIndexURL(t *testing.T) { t.Run("URL with invalid escaped characters", func(t *testing.T) { rawURL := fmt.Sprintf(urlTemplate, "mygroup%**myproject") got, err := getIndexURL(rawURL) - assert.Empty(t, got) + assert.Equal(t, "", got) require.Error(t, err) }) } @@ -174,34 +169,30 @@ func TestGetTagsFromUrl(t *testing.T) { t.Run("should return tags correctly while following the link header", func(t *testing.T) { server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { t.Logf("called %s", r.URL.Path) - var responseTags fakeTagsList + responseTags := TagsList{} w.Header().Set("Content-Type", "application/json") if !strings.Contains(r.URL.String(), "token") { w.Header().Set("Link", fmt.Sprintf("; rel=next", r.Host, r.URL.Path)) - responseTags = fakeTagsList{ - Tags: []string{"first"}, - } + responseTags.Tags = []string{"first"} } else { - responseTags = fakeTagsList{ - Tags: []string{ - "second", - "2.8.0", - "2.8.0-prerelease", - "2.8.0_build", - "2.8.0-prerelease_build", - "2.8.0-prerelease.1_build.1234", - }, + responseTags.Tags = []string{ + "second", + "2.8.0", + "2.8.0-prerelease", + "2.8.0_build", + "2.8.0-prerelease_build", + "2.8.0-prerelease.1_build.1234", } } w.WriteHeader(http.StatusOK) require.NoError(t, json.NewEncoder(w).Encode(responseTags)) })) - client := NewClient(server.URL, HelmCreds{InsecureSkipVerify: true}, true, "", "") + client := NewClient(server.URL, Creds{InsecureSkipVerify: true}, true, "", "") tags, err := client.GetTags("mychart", true) require.NoError(t, err) - assert.ElementsMatch(t, tags, []string{ + assert.ElementsMatch(t, tags.Tags, []string{ "first", "second", "2.8.0", @@ -213,10 +204,10 @@ func TestGetTagsFromUrl(t *testing.T) { }) t.Run("should return an error not when oci is not enabled", func(t *testing.T) { - client := NewClient("example.com", HelmCreds{}, false, "", "") + client := NewClient("example.com", Creds{}, false, "", "") _, err := client.GetTags("my-chart", true) - assert.ErrorIs(t, ErrOCINotEnabled, err) + assert.ErrorIs(t, OCINotEnabledErr, err) }) } @@ -237,7 +228,7 @@ func TestGetTagsFromURLPrivateRepoAuthentication(t *testing.T) { assert.Equal(t, expectedAuthorization, authorization) - responseTags := fakeTagsList{ + responseTags := TagsList{ Tags: []string{ "2.8.0", "2.8.0-prerelease", @@ -266,7 +257,7 @@ func TestGetTagsFromURLPrivateRepoAuthentication(t *testing.T) { }, { name: "should login correctly when the repo path is not in the server root with http scheme", - repoURL: server.URL + "/my-repo", + repoURL: fmt.Sprintf("%s/my-repo", server.URL), }, { name: "should login correctly when the repo path is in the server root without http scheme", @@ -274,13 +265,13 @@ func TestGetTagsFromURLPrivateRepoAuthentication(t *testing.T) { }, { name: "should login correctly when the repo path is not in the server root without http scheme", - repoURL: serverURL.Host + "/my-repo", + repoURL: fmt.Sprintf("%s/my-repo", serverURL.Host), }, } for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - client := NewClient(testCase.repoURL, HelmCreds{ + client := NewClient(testCase.repoURL, Creds{ InsecureSkipVerify: true, Username: username, Password: password, @@ -289,105 +280,7 @@ func TestGetTagsFromURLPrivateRepoAuthentication(t *testing.T) { tags, err := client.GetTags("mychart", true) require.NoError(t, err) - assert.ElementsMatch(t, 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 TestGetTagsFromURLPrivateRepoWithAzureWorkloadIdentityAuthentication(t *testing.T) { - expectedAuthorization := "Basic MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwOmFjY2Vzc1Rva2Vu" // base64(00000000-0000-0000-0000-000000000000:accessToken) - mockServerURL := "" - mockedServerURL := func() string { - return mockServerURL - } - - workloadIdentityMock := new(mocks.TokenProvider) - workloadIdentityMock.On("GetToken", "https://management.core.windows.net/.default").Return("accessToken", nil) - - mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - t.Logf("called %s", r.URL.Path) - - switch r.URL.Path { - case "/v2/": - w.Header().Set("Www-Authenticate", fmt.Sprintf(`Bearer realm="%s",service="%s"`, mockedServerURL(), mockedServerURL()[8:])) - w.WriteHeader(http.StatusUnauthorized) - - case "/oauth2/exchange": - response := `{"refresh_token":"accessToken"}` - w.WriteHeader(http.StatusOK) - _, err := w.Write([]byte(response)) - require.NoError(t, err) - default: - 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 := fakeTagsList{ - Tags: []string{ - "2.8.0", - "2.8.0-prerelease", - "2.8.0_build", - "2.8.0-prerelease_build", - "2.8.0-prerelease.1_build.1234", - }, - } - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - require.NoError(t, json.NewEncoder(w).Encode(responseTags)) - } - })) - mockServerURL = mockServer.URL - t.Cleanup(mockServer.Close) - - serverURL, err := url.Parse(mockServer.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: mockServer.URL, - }, - { - name: "should login correctly when the repo path is not in the server root with http scheme", - repoURL: mockServer.URL + "/my-repo", - }, - { - 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: serverURL.Host + "/my-repo", - }, - } - - for _, testCase := range testCases { - t.Run(testCase.name, func(t *testing.T) { - client := NewClient(testCase.repoURL, AzureWorkloadIdentityCreds{ - repoURL: mockServer.URL[8:], - InsecureSkipVerify: true, - tokenProvider: workloadIdentityMock, - }, true, "", "") - - tags, err := client.GetTags("mychart", true) - - require.NoError(t, err) - assert.ElementsMatch(t, tags, []string{ + assert.ElementsMatch(t, tags.Tags, []string{ "2.8.0", "2.8.0-prerelease", "2.8.0+build", @@ -413,7 +306,7 @@ func TestGetTagsFromURLEnvironmentAuthentication(t *testing.T) { assert.Equal(t, expectedAuthorization, authorization) - responseTags := fakeTagsList{ + responseTags := TagsList{ Tags: []string{ "2.8.0", "2.8.0-prerelease", @@ -449,7 +342,7 @@ func TestGetTagsFromURLEnvironmentAuthentication(t *testing.T) { }, { name: "should login correctly when the repo path is not in the server root with http scheme", - repoURL: server.URL + "/my-repo", + repoURL: fmt.Sprintf("%s/my-repo", server.URL), }, { name: "should login correctly when the repo path is in the server root without http scheme", @@ -457,20 +350,20 @@ func TestGetTagsFromURLEnvironmentAuthentication(t *testing.T) { }, { name: "should login correctly when the repo path is not in the server root without http scheme", - repoURL: serverURL.Host + "/my-repo", + repoURL: fmt.Sprintf("%s/my-repo", serverURL.Host), }, } for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - client := NewClient(testCase.repoURL, HelmCreds{ + client := NewClient(testCase.repoURL, Creds{ InsecureSkipVerify: true, }, true, "", "") tags, err := client.GetTags("mychart", true) require.NoError(t, err) - assert.ElementsMatch(t, tags, []string{ + assert.ElementsMatch(t, tags.Tags, []string{ "2.8.0", "2.8.0-prerelease", "2.8.0+build", diff --git a/util/helm/cmd.go b/util/helm/cmd.go index 0300b19693..28b458fa51 100644 --- a/util/helm/cmd.go +++ b/util/helm/cmd.go @@ -12,11 +12,11 @@ import ( log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/common" - executil "github.com/argoproj/argo-cd/v3/util/exec" - utilio "github.com/argoproj/argo-cd/v3/util/io" - pathutil "github.com/argoproj/argo-cd/v3/util/io/path" - "github.com/argoproj/argo-cd/v3/util/proxy" + "github.com/argoproj/argo-cd/v2/common" + executil "github.com/argoproj/argo-cd/v2/util/exec" + argoio "github.com/argoproj/argo-cd/v2/util/io" + pathutil "github.com/argoproj/argo-cd/v2/util/io/path" + "github.com/argoproj/argo-cd/v2/util/proxy" ) // A thin wrapper around the "helm" command, adding logging and error translation. @@ -80,41 +80,37 @@ func (c *Cmd) RegistryLogin(repo string, creds Creds) (string, error) { args := []string{"registry", "login"} args = append(args, repo) - if creds.GetUsername() != "" { - args = append(args, "--username", creds.GetUsername()) + if creds.Username != "" { + args = append(args, "--username", creds.Username) } - helmPassword, err := creds.GetPassword() - if err != nil { - return "", fmt.Errorf("failed to get password for helm registry: %w", err) - } - if helmPassword != "" { - args = append(args, "--password", helmPassword) + if creds.Password != "" { + args = append(args, "--password", creds.Password) } - if creds.GetCAPath() != "" { - args = append(args, "--ca-file", creds.GetCAPath()) + if creds.CAPath != "" { + args = append(args, "--ca-file", creds.CAPath) } - if len(creds.GetCertData()) > 0 { - filePath, closer, err := writeToTmp(creds.GetCertData()) + if len(creds.CertData) > 0 { + filePath, closer, err := writeToTmp(creds.CertData) if err != nil { return "", fmt.Errorf("failed to write certificate data to temporary file: %w", err) } - defer utilio.Close(closer) + defer argoio.Close(closer) args = append(args, "--cert-file", filePath) } - if len(creds.GetKeyData()) > 0 { - filePath, closer, err := writeToTmp(creds.GetKeyData()) + if len(creds.KeyData) > 0 { + filePath, closer, err := writeToTmp(creds.KeyData) if err != nil { return "", fmt.Errorf("failed to write key data to temporary file: %w", err) } - defer utilio.Close(closer) + defer argoio.Close(closer) args = append(args, "--key-file", filePath) } - if creds.GetInsecureSkipVerify() { + if creds.InsecureSkipVerify { args = append(args, "--insecure") } out, _, err := c.run(args...) @@ -124,7 +120,7 @@ func (c *Cmd) RegistryLogin(repo string, creds Creds) (string, error) { return out, nil } -func (c *Cmd) RegistryLogout(repo string, _ Creds) (string, error) { +func (c *Cmd) RegistryLogout(repo string, creds Creds) (string, error) { args := []string{"registry", "logout"} args = append(args, repo) out, _, err := c.run(args...) @@ -143,32 +139,28 @@ func (c *Cmd) RepoAdd(name string, url string, opts Creds, passCredentials bool) args := []string{"repo", "add"} - if opts.GetUsername() != "" { - args = append(args, "--username", opts.GetUsername()) + if opts.Username != "" { + args = append(args, "--username", opts.Username) } - helmPassword, err := opts.GetPassword() - if err != nil { - return "", fmt.Errorf("failed to get password for helm registry: %w", err) - } - if helmPassword != "" { - args = append(args, "--password", helmPassword) + if opts.Password != "" { + args = append(args, "--password", opts.Password) } - if opts.GetCAPath() != "" { - args = append(args, "--ca-file", opts.GetCAPath()) + if opts.CAPath != "" { + args = append(args, "--ca-file", opts.CAPath) } - if opts.GetInsecureSkipVerify() { + if opts.InsecureSkipVerify { args = append(args, "--insecure-skip-tls-verify") } - if len(opts.GetCertData()) > 0 { + if len(opts.CertData) > 0 { certFile, err := os.CreateTemp("", "helm") if err != nil { return "", fmt.Errorf("failed to create temporary certificate file: %w", err) } - _, err = certFile.Write(opts.GetCertData()) + _, err = certFile.Write(opts.CertData) if err != nil { return "", fmt.Errorf("failed to write certificate data: %w", err) } @@ -176,12 +168,12 @@ func (c *Cmd) RepoAdd(name string, url string, opts Creds, passCredentials bool) args = append(args, "--cert-file", certFile.Name()) } - if len(opts.GetKeyData()) > 0 { + if len(opts.KeyData) > 0 { keyFile, err := os.CreateTemp("", "helm") if err != nil { return "", fmt.Errorf("failed to create temporary key file: %w", err) } - _, err = keyFile.Write(opts.GetKeyData()) + _, err = keyFile.Write(opts.KeyData) if err != nil { return "", fmt.Errorf("failed to write key data: %w", err) } @@ -202,7 +194,7 @@ func (c *Cmd) RepoAdd(name string, url string, opts Creds, passCredentials bool) return out, err } -func writeToTmp(data []byte) (string, utilio.Closer, error) { +func writeToTmp(data []byte) (string, argoio.Closer, error) { file, err := os.CreateTemp("", "") if err != nil { return "", nil, fmt.Errorf("failed to create temporary file: %w", err) @@ -220,7 +212,7 @@ func writeToTmp(data []byte) (string, utilio.Closer, error) { }).Errorf("error closing file %q: %v", file.Name(), err) } }() - return file.Name(), utilio.NewCloser(func() error { + return file.Name(), argoio.NewCloser(func() error { return os.RemoveAll(file.Name()) }), nil } @@ -230,40 +222,35 @@ func (c *Cmd) Fetch(repo, chartName, version, destination string, creds Creds, p if version != "" { args = append(args, "--version", version) } - if creds.GetUsername() != "" { - args = append(args, "--username", creds.GetUsername()) + if creds.Username != "" { + args = append(args, "--username", creds.Username) } - - helmPassword, err := creds.GetPassword() - if err != nil { - return "", fmt.Errorf("failed to get password for helm registry: %w", err) + if creds.Password != "" { + args = append(args, "--password", creds.Password) } - if helmPassword != "" { - args = append(args, "--password", helmPassword) - } - if creds.GetInsecureSkipVerify() { + if creds.InsecureSkipVerify { args = append(args, "--insecure-skip-tls-verify") } args = append(args, "--repo", repo, chartName) - if creds.GetCAPath() != "" { - args = append(args, "--ca-file", creds.GetCAPath()) + if creds.CAPath != "" { + args = append(args, "--ca-file", creds.CAPath) } - if len(creds.GetCertData()) > 0 { - filePath, closer, err := writeToTmp(creds.GetCertData()) + if len(creds.CertData) > 0 { + filePath, closer, err := writeToTmp(creds.CertData) if err != nil { return "", fmt.Errorf("failed to write certificate data to temporary file: %w", err) } - defer utilio.Close(closer) + defer argoio.Close(closer) args = append(args, "--cert-file", filePath) } - if len(creds.GetKeyData()) > 0 { - filePath, closer, err := writeToTmp(creds.GetKeyData()) + if len(creds.KeyData) > 0 { + filePath, closer, err := writeToTmp(creds.KeyData) if err != nil { return "", fmt.Errorf("failed to write key data to temporary file: %w", err) } - defer utilio.Close(closer) + defer argoio.Close(closer) args = append(args, "--key-file", filePath) } if passCredentials { @@ -284,29 +271,29 @@ func (c *Cmd) PullOCI(repo string, chart string, version string, destination str "--destination", destination, } - if creds.GetCAPath() != "" { - args = append(args, "--ca-file", creds.GetCAPath()) + if creds.CAPath != "" { + args = append(args, "--ca-file", creds.CAPath) } - if len(creds.GetCertData()) > 0 { - filePath, closer, err := writeToTmp(creds.GetCertData()) + if len(creds.CertData) > 0 { + filePath, closer, err := writeToTmp(creds.CertData) if err != nil { return "", fmt.Errorf("failed to write certificate data to temporary file: %w", err) } - defer utilio.Close(closer) + defer argoio.Close(closer) args = append(args, "--cert-file", filePath) } - if len(creds.GetKeyData()) > 0 { - filePath, closer, err := writeToTmp(creds.GetKeyData()) + if len(creds.KeyData) > 0 { + filePath, closer, err := writeToTmp(creds.KeyData) if err != nil { return "", fmt.Errorf("failed to write key data to temporary file: %w", err) } - defer utilio.Close(closer) + defer argoio.Close(closer) args = append(args, "--key-file", filePath) } - if creds.GetInsecureSkipVerify() { + if creds.InsecureSkipVerify { args = append(args, "--insecure-skip-tls-verify") } out, _, err := c.run(args...) @@ -449,10 +436,11 @@ func cleanupChartLockFile(chartPath string) (func(), error) { exists := true lockPath := path.Join(chartPath, "Chart.lock") if _, err := os.Stat(lockPath); err != nil { - if !os.IsNotExist(err) { + if os.IsNotExist(err) { + exists = false + } else { return nil, fmt.Errorf("failed to check lock file status: %w", err) } - exists = false } return func() { if !exists { diff --git a/util/helm/creds.go b/util/helm/creds.go deleted file mode 100644 index 3b6001f757..0000000000 --- a/util/helm/creds.go +++ /dev/null @@ -1,262 +0,0 @@ -package helm - -import ( - "crypto/tls" - "encoding/json" - "errors" - "fmt" - "io" - "net/http" - "net/url" - "strings" - "time" - - gocache "github.com/patrickmn/go-cache" - - argoutils "github.com/argoproj/argo-cd/v3/util" - "github.com/argoproj/argo-cd/v3/util/env" - "github.com/argoproj/argo-cd/v3/util/workloadidentity" -) - -// In memory cache for storing Azure tokens -var azureTokenCache *gocache.Cache - -func init() { - azureTokenCache = gocache.New(gocache.NoExpiration, 0) -} - -// StoreToken stores a token in the cache -func storeAzureToken(key, token string, expiration time.Duration) { - azureTokenCache.Set(key, token, expiration) -} - -type Creds interface { - GetUsername() string - GetPassword() (string, error) - GetCAPath() string - GetCertData() []byte - GetKeyData() []byte - GetInsecureSkipVerify() bool -} - -var _ Creds = HelmCreds{} - -type HelmCreds struct { - Username string - Password string - CAPath string - CertData []byte - KeyData []byte - InsecureSkipVerify bool -} - -func (creds HelmCreds) GetUsername() string { - return creds.Username -} - -func (creds HelmCreds) GetPassword() (string, error) { - return creds.Password, nil -} - -func (creds HelmCreds) GetCAPath() string { - return creds.CAPath -} - -func (creds HelmCreds) GetCertData() []byte { - return creds.CertData -} - -func (creds HelmCreds) GetKeyData() []byte { - return creds.KeyData -} - -func (creds HelmCreds) GetInsecureSkipVerify() bool { - return creds.InsecureSkipVerify -} - -var _ Creds = AzureWorkloadIdentityCreds{} - -type AzureWorkloadIdentityCreds struct { - repoURL string - CAPath string - CertData []byte - KeyData []byte - InsecureSkipVerify bool - tokenProvider workloadidentity.TokenProvider -} - -func (creds AzureWorkloadIdentityCreds) GetUsername() string { - return workloadidentity.EmptyGuid -} - -func (creds AzureWorkloadIdentityCreds) GetPassword() (string, error) { - return creds.GetAccessToken() -} - -func (creds AzureWorkloadIdentityCreds) GetCAPath() string { - return creds.CAPath -} - -func (creds AzureWorkloadIdentityCreds) GetCertData() []byte { - return creds.CertData -} - -func (creds AzureWorkloadIdentityCreds) GetKeyData() []byte { - return creds.KeyData -} - -func (creds AzureWorkloadIdentityCreds) GetInsecureSkipVerify() bool { - return creds.InsecureSkipVerify -} - -func NewAzureWorkloadIdentityCreds(repoURL string, caPath string, certData []byte, keyData []byte, insecureSkipVerify bool, tokenProvider workloadidentity.TokenProvider) AzureWorkloadIdentityCreds { - return AzureWorkloadIdentityCreds{ - repoURL: repoURL, - CAPath: caPath, - CertData: certData, - KeyData: keyData, - InsecureSkipVerify: insecureSkipVerify, - tokenProvider: tokenProvider, - } -} - -func (creds AzureWorkloadIdentityCreds) GetAccessToken() (string, error) { - registryHost := strings.Split(creds.repoURL, "/")[0] - - // Compute hash as key for refresh token in the cache - key, err := argoutils.GenerateCacheKey("accesstoken-%s", registryHost) - if err != nil { - return "", fmt.Errorf("failed to compute key for cache: %w", err) - } - - // Check cache for GitHub transport which helps fetch an API token - t, found := azureTokenCache.Get(key) - if found { - fmt.Println("access token found token in cache") - return t.(string), nil - } - - tokenParams, err := creds.challengeAzureContainerRegistry(registryHost) - if err != nil { - return "", fmt.Errorf("failed to challenge Azure Container Registry: %w", err) - } - - token, err := creds.getAccessTokenAfterChallenge(tokenParams) - if err != nil { - return "", fmt.Errorf("failed to get Azure access token after challenge: %w", err) - } - - // Access token has a lifetime of 3 hours - storeAzureToken(key, token, 2*time.Hour) - return token, nil -} - -func (creds AzureWorkloadIdentityCreds) getAccessTokenAfterChallenge(tokenParams map[string]string) (string, error) { - realm := tokenParams["realm"] - service := tokenParams["service"] - - armTokenScope := env.StringFromEnv("AZURE_ARM_TOKEN_RESOURCE", "https://management.core.windows.net") - armAccessToken, err := creds.tokenProvider.GetToken(armTokenScope + "/.default") - if err != nil { - return "", fmt.Errorf("failed to get Azure access token: %w", err) - } - - parsedURL, _ := url.Parse(realm) - parsedURL.Path = "/oauth2/exchange" - refreshTokenURL := parsedURL.String() - - client := &http.Client{ - Timeout: 10 * time.Second, - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: creds.GetInsecureSkipVerify(), - }, - }, - } - - formValues := url.Values{} - formValues.Add("grant_type", "access_token") - formValues.Add("service", service) - formValues.Add("access_token", armAccessToken) - - resp, err := client.PostForm(refreshTokenURL, formValues) - if err != nil { - return "", fmt.Errorf("unable to connect to registry '%w'", err) - } - - defer resp.Body.Close() - body, err := io.ReadAll(resp.Body) - - if resp.StatusCode != http.StatusOK { - return "", fmt.Errorf("failed to get refresh token: %s", resp.Status) - } - - if err != nil { - return "", fmt.Errorf("failed to read response body: %w", err) - } - - type Response struct { - RefreshToken string `json:"refresh_token"` - } - - var res Response - err = json.Unmarshal(body, &res) - if err != nil { - return "", fmt.Errorf("failed to unmarshal response body: %w", err) - } - - return res.RefreshToken, nil -} - -func (creds AzureWorkloadIdentityCreds) challengeAzureContainerRegistry(azureContainerRegistry string) (map[string]string, error) { - requestURL := fmt.Sprintf("https://%s/v2/", azureContainerRegistry) - - client := &http.Client{ - Timeout: 10 * time.Second, - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: creds.GetInsecureSkipVerify(), - }, - }, - } - - req, err := http.NewRequest(http.MethodGet, requestURL, nil) - if err != nil { - return nil, err - } - - resp, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("unable to connect to registry '%w'", err) - } - - defer resp.Body.Close() - - if resp.StatusCode != http.StatusUnauthorized || resp.Header.Get("Www-Authenticate") == "" { - return nil, fmt.Errorf("registry '%s' did not issue a challenge", azureContainerRegistry) - } - - authenticate := resp.Header.Get("Www-Authenticate") - tokens := strings.Split(authenticate, " ") - - if strings.ToLower(tokens[0]) != "bearer" { - return nil, fmt.Errorf("registry does not allow 'Bearer' authentication, got '%s'", tokens[0]) - } - - tokenParams := make(map[string]string) - - for _, token := range strings.Split(tokens[1], ",") { - kvPair := strings.Split(token, "=") - tokenParams[kvPair[0]] = strings.Trim(kvPair[1], "\"") - } - - if _, realmExists := tokenParams["realm"]; !realmExists { - return nil, errors.New("realm parameter not found in challenge") - } - - if _, serviceExists := tokenParams["service"]; !serviceExists { - return nil, errors.New("service parameter not found in challenge") - } - - return tokenParams, nil -} diff --git a/util/helm/creds_test.go b/util/helm/creds_test.go deleted file mode 100644 index 90a232643e..0000000000 --- a/util/helm/creds_test.go +++ /dev/null @@ -1,255 +0,0 @@ -package helm - -import ( - "fmt" - "net/http" - "net/http/httptest" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - argoutils "github.com/argoproj/argo-cd/v3/util" - "github.com/argoproj/argo-cd/v3/util/workloadidentity" - "github.com/argoproj/argo-cd/v3/util/workloadidentity/mocks" -) - -func TestWorkLoadIdentityUserNameShouldBeEmptyGuid(t *testing.T) { - workloadIdentityMock := new(mocks.TokenProvider) - creds := NewAzureWorkloadIdentityCreds("contoso.azurecr.io/charts", "", nil, nil, false, workloadIdentityMock) - username := creds.GetUsername() - - assert.Equal(t, workloadidentity.EmptyGuid, username, "The username for azure workload identity is not empty Guid") -} - -func TestGetAccessTokenShouldReturnTokenFromCacheIfPresent(t *testing.T) { - workloadIdentityMock := new(mocks.TokenProvider) - creds := NewAzureWorkloadIdentityCreds("contoso.azurecr.io/charts", "", nil, nil, false, workloadIdentityMock) - - cacheKey, err := argoutils.GenerateCacheKey("accesstoken-%s", "contoso.azurecr.io") - require.NoError(t, err, "Error generating cache key") - - // Store the token in the cache - storeAzureToken(cacheKey, "testToken", time.Hour) - - // Retrieve the token from the cache - token, err := creds.GetAccessToken() - require.NoError(t, err, "Error getting access token") - assert.Equal(t, "testToken", token, "The retrieved token should match the stored token") -} - -func TestGetPasswordShouldReturnTokenFromCacheIfPresent(t *testing.T) { - workloadIdentityMock := new(mocks.TokenProvider) - creds := NewAzureWorkloadIdentityCreds("contoso.azurecr.io/charts", "", nil, nil, false, workloadIdentityMock) - - cacheKey, err := argoutils.GenerateCacheKey("accesstoken-%s", "contoso.azurecr.io") - require.NoError(t, err, "Error generating cache key") - - // Store the token in the cache - storeAzureToken(cacheKey, "testToken", time.Hour) - - // Retrieve the token from the cache - token, err := creds.GetPassword() - require.NoError(t, err, "Error getting access token") - assert.Equal(t, "testToken", token, "The retrieved token should match the stored token") -} - -func TestGetPasswordShouldGenerateTokenIfNotPresentInCache(t *testing.T) { - mockServerURL := "" - mockedServerURL := func() string { - return mockServerURL - } - - // Mock the server to return a successful response - mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - switch r.URL.Path { - case "/v2/": - w.Header().Set("Www-Authenticate", fmt.Sprintf(`Bearer realm="%s",service="%s"`, mockedServerURL(), mockedServerURL()[8:])) - w.WriteHeader(http.StatusUnauthorized) - - case "/oauth2/exchange": - response := `{"refresh_token":"newRefreshToken"}` - w.WriteHeader(http.StatusOK) - _, err := w.Write([]byte(response)) - require.NoError(t, err) - } - })) - mockServerURL = mockServer.URL - defer mockServer.Close() - - workloadIdentityMock := new(mocks.TokenProvider) - workloadIdentityMock.On("GetToken", "https://management.core.windows.net/.default").Return("accessToken", nil) - creds := NewAzureWorkloadIdentityCreds(mockServer.URL[8:], "", nil, nil, true, workloadIdentityMock) - - // Retrieve the token from the cache - token, err := creds.GetPassword() - require.NoError(t, err) - assert.Equal(t, "newRefreshToken", token, "The retrieved token should match the stored token") -} - -func TestChallengeAzureContainerRegistry(t *testing.T) { - // Set up the mock server - mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - assert.Equal(t, "/v2/", r.URL.Path) - w.Header().Set("Www-Authenticate", `Bearer realm="https://login.microsoftonline.com/",service="registry.example.com"`) - w.WriteHeader(http.StatusUnauthorized) - })) - defer mockServer.Close() - - workloadIdentityMock := new(mocks.TokenProvider) - creds := NewAzureWorkloadIdentityCreds(mockServer.URL[8:], "", nil, nil, true, workloadIdentityMock) - - tokenParams, err := creds.challengeAzureContainerRegistry(creds.repoURL) - require.NoError(t, err) - - expectedParams := map[string]string{ - "realm": "https://login.microsoftonline.com/", - "service": "registry.example.com", - } - assert.Equal(t, expectedParams, tokenParams) -} - -func TestChallengeAzureContainerRegistryNoChallenge(t *testing.T) { - // Set up the mock server without Www-Authenticate header - mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - assert.Equal(t, "/v2/", r.URL.Path) - w.WriteHeader(http.StatusOK) - })) - defer mockServer.Close() - - // Replace the real URL with the mock server URL - workloadIdentityMock := new(mocks.TokenProvider) - creds := NewAzureWorkloadIdentityCreds(mockServer.URL[8:], "", nil, nil, true, workloadIdentityMock) - - _, err := creds.challengeAzureContainerRegistry(creds.repoURL) - require.Error(t, err) - assert.Contains(t, err.Error(), "did not issue a challenge") -} - -func TestChallengeAzureContainerRegistryNonBearer(t *testing.T) { - // Set up the mock server with a non-Bearer Www-Authenticate header - mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - assert.Equal(t, "/v2/", r.URL.Path) - w.Header().Set("Www-Authenticate", `Basic realm="example"`) - w.WriteHeader(http.StatusUnauthorized) - })) - defer mockServer.Close() - - // Replace the real URL with the mock server URL - workloadIdentityMock := new(mocks.TokenProvider) - creds := NewAzureWorkloadIdentityCreds(mockServer.URL[8:], "", nil, nil, true, workloadIdentityMock) - - _, err := creds.challengeAzureContainerRegistry(creds.repoURL) - assert.ErrorContains(t, err, "does not allow 'Bearer' authentication") -} - -func TestChallengeAzureContainerRegistryNoService(t *testing.T) { - // Set up the mock server with a non-Bearer Www-Authenticate header - mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - assert.Equal(t, "/v2/", r.URL.Path) - w.Header().Set("Www-Authenticate", `Bearer realm="example"`) - w.WriteHeader(http.StatusUnauthorized) - })) - defer mockServer.Close() - - // Replace the real URL with the mock server URL - workloadIdentityMock := new(mocks.TokenProvider) - creds := NewAzureWorkloadIdentityCreds(mockServer.URL[8:], "", nil, nil, true, workloadIdentityMock) - - _, err := creds.challengeAzureContainerRegistry(creds.repoURL) - assert.ErrorContains(t, err, "service parameter not found in challenge") -} - -func TestChallengeAzureContainerRegistryNoRealm(t *testing.T) { - // Set up the mock server with a non-Bearer Www-Authenticate header - mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - assert.Equal(t, "/v2/", r.URL.Path) - w.Header().Set("Www-Authenticate", `Bearer service="example"`) - w.WriteHeader(http.StatusUnauthorized) - })) - defer mockServer.Close() - - // Replace the real URL with the mock server URL - workloadIdentityMock := new(mocks.TokenProvider) - creds := NewAzureWorkloadIdentityCreds(mockServer.URL[8:], "", nil, nil, true, workloadIdentityMock) - - _, err := creds.challengeAzureContainerRegistry(creds.repoURL) - assert.ErrorContains(t, err, "realm parameter not found in challenge") -} - -func TestGetAccessTokenAfterChallenge_Success(t *testing.T) { - // Mock the server to return a successful response - mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - assert.Equal(t, "/oauth2/exchange", r.URL.Path) - - response := `{"refresh_token":"newRefreshToken"}` - w.WriteHeader(http.StatusOK) - _, err := w.Write([]byte(response)) - require.NoError(t, err) - })) - defer mockServer.Close() - - workloadIdentityMock := new(mocks.TokenProvider) - workloadIdentityMock.On("GetToken", "https://management.core.windows.net/.default").Return("accessToken", nil) - creds := NewAzureWorkloadIdentityCreds(mockServer.URL[8:], "", nil, nil, true, workloadIdentityMock) - - tokenParams := map[string]string{ - "realm": mockServer.URL, - "service": "registry.example.com", - } - - refreshToken, err := creds.getAccessTokenAfterChallenge(tokenParams) - require.NoError(t, err) - assert.Equal(t, "newRefreshToken", refreshToken) -} - -func TestGetAccessTokenAfterChallenge_Failure(t *testing.T) { - // Mock the server to return an error response - mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - assert.Equal(t, "/oauth2/exchange", r.URL.Path) - w.WriteHeader(http.StatusBadRequest) - _, err := w.Write([]byte(`{"error": "invalid_request"}`)) - require.NoError(t, err) - })) - defer mockServer.Close() - - // Create an instance of AzureWorkloadIdentityCreds with the mock credential wrapper - workloadIdentityMock := new(mocks.TokenProvider) - workloadIdentityMock.On("GetToken", "https://management.core.windows.net/.default").Return("accessToken", nil) - creds := NewAzureWorkloadIdentityCreds(mockServer.URL[8:], "", nil, nil, true, workloadIdentityMock) - - tokenParams := map[string]string{ - "realm": mockServer.URL, - "service": "registry.example.com", - } - - refreshToken, err := creds.getAccessTokenAfterChallenge(tokenParams) - require.ErrorContains(t, err, "failed to get refresh token") - assert.Empty(t, refreshToken) -} - -func TestGetAccessTokenAfterChallenge_MalformedResponse(t *testing.T) { - // Mock the server to return a malformed JSON response - mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - assert.Equal(t, "/oauth2/exchange", r.URL.Path) - w.WriteHeader(http.StatusOK) - _, err := w.Write([]byte(`{"refresh_token":`)) - require.NoError(t, err) - })) - defer mockServer.Close() - - // Create an instance of AzureWorkloadIdentityCreds with the mock credential wrapper - workloadIdentityMock := new(mocks.TokenProvider) - workloadIdentityMock.On("GetToken", "https://management.core.windows.net/.default").Return("accessToken", nil) - creds := NewAzureWorkloadIdentityCreds(mockServer.URL[8:], "", nil, nil, true, workloadIdentityMock) - - tokenParams := map[string]string{ - "realm": mockServer.URL, - "service": "registry.example.com", - } - - refreshToken, err := creds.getAccessTokenAfterChallenge(tokenParams) - require.ErrorContains(t, err, "failed to unmarshal response body") - assert.Empty(t, refreshToken) -} diff --git a/util/helm/helm.go b/util/helm/helm.go index 9bdea79c84..fb557010c8 100644 --- a/util/helm/helm.go +++ b/util/helm/helm.go @@ -12,9 +12,9 @@ import ( log "github.com/sirupsen/logrus" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/util/config" - executil "github.com/argoproj/argo-cd/v3/util/exec" - pathutil "github.com/argoproj/argo-cd/v3/util/io/path" + "github.com/argoproj/argo-cd/v2/util/config" + executil "github.com/argoproj/argo-cd/v2/util/exec" + pathutil "github.com/argoproj/argo-cd/v2/util/io/path" ) const ( @@ -84,11 +84,7 @@ func (h *helm) DependencyBuild() error { repo := h.repos[i] if repo.EnableOci { h.cmd.IsHelmOci = true - helmPassword, err := repo.GetPassword() - if err != nil { - return fmt.Errorf("failed to get password for helm registry: %w", err) - } - if repo.GetUsername() != "" && helmPassword != "" { + if repo.Creds.Username != "" && repo.Creds.Password != "" { _, err := h.cmd.RegistryLogin(repo.Repo, repo.Creds) defer func() { @@ -118,9 +114,15 @@ func (h *helm) Dispose() { h.cmd.Close() } -func Version() (string, error) { - cmd := exec.Command("helm", "version", "--client", "--short") +func Version(shortForm bool) (string, error) { + executable := "helm" + cmdArgs := []string{"version", "--client"} + if shortForm { + cmdArgs = append(cmdArgs, "--short") + } + cmd := exec.Command(executable, cmdArgs...) // example version output: + // long: "version.BuildInfo{Version:\"v3.3.1\", GitCommit:\"249e5215cde0c3fa72e27eb7a30e8d55c9696144\", GitTreeState:\"clean\", GoVersion:\"go1.14.7\"}" // short: "v3.3.1+g249e521" version, err := executil.RunWithRedactor(cmd, redactor) if err != nil { @@ -167,7 +169,7 @@ func (h *helm) GetParameters(valuesFiles []pathutil.ResolvedFilePath, appPath, r output := map[string]string{} for _, file := range values { - values := map[string]any{} + values := map[string]interface{}{} if err := yaml.Unmarshal([]byte(file), &values); err != nil { return nil, fmt.Errorf("failed to parse values: %w", err) } @@ -177,13 +179,13 @@ func (h *helm) GetParameters(valuesFiles []pathutil.ResolvedFilePath, appPath, r return output, nil } -func flatVals(input any, output map[string]string, prefixes ...string) { +func flatVals(input interface{}, output map[string]string, prefixes ...string) { switch i := input.(type) { - case map[string]any: + case map[string]interface{}: for k, v := range i { flatVals(v, output, append(prefixes, k)...) } - case []any: + case []interface{}: p := append([]string(nil), prefixes...) for j, v := range i { flatVals(v, output, append(p[0:len(p)-1], fmt.Sprintf("%s[%v]", prefixes[len(p)-1], j))...) diff --git a/util/helm/helm_test.go b/util/helm/helm_test.go index da262d7982..2d72a87745 100644 --- a/util/helm/helm_test.go +++ b/util/helm/helm_test.go @@ -6,12 +6,12 @@ import ( "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/util/io/path" + "github.com/argoproj/argo-cd/v2/util/io/path" "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/stretchr/testify/assert" appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" + apiv1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" ) @@ -43,12 +43,12 @@ func TestHelmTemplateParams(t *testing.T) { for _, obj := range objs { if obj.GetKind() == "Service" && obj.GetName() == "test-minio" { - var svc corev1.Service + var svc apiv1.Service err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &svc) require.NoError(t, err) - assert.Equal(t, corev1.ServiceTypeLoadBalancer, svc.Spec.Type) + assert.Equal(t, apiv1.ServiceTypeLoadBalancer, svc.Spec.Type) assert.Equal(t, int32(1234), svc.Spec.Ports[0].TargetPort.IntVal) - assert.Equal(t, "true", svc.Annotations["prometheus.io/scrape"]) + assert.Equal(t, "true", svc.ObjectMeta.Annotations["prometheus.io/scrape"]) } } } @@ -137,7 +137,7 @@ func TestHelmTemplateReleaseNameOverwrite(t *testing.T) { var stateful appsv1.StatefulSet err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &stateful) require.NoError(t, err) - assert.Equal(t, "my-release-redis-master", stateful.Name) + assert.Equal(t, "my-release-redis-master", stateful.ObjectMeta.Name) } } } @@ -154,7 +154,7 @@ func TestHelmTemplateReleaseName(t *testing.T) { var stateful appsv1.StatefulSet err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &stateful) require.NoError(t, err) - assert.Equal(t, "test-redis-master", stateful.Name) + assert.Equal(t, "test-redis-master", stateful.ObjectMeta.Name) } } } @@ -175,7 +175,7 @@ func TestHelmArgCleaner(t *testing.T) { } func TestVersion(t *testing.T) { - ver, err := Version() + ver, err := Version(false) require.NoError(t, err) assert.NotEmpty(t, ver) } @@ -184,21 +184,21 @@ func Test_flatVals(t *testing.T) { t.Run("Map", func(t *testing.T) { output := map[string]string{} - flatVals(map[string]any{"foo": map[string]any{"bar": "baz"}}, output) + flatVals(map[string]interface{}{"foo": map[string]interface{}{"bar": "baz"}}, output) assert.Equal(t, map[string]string{"foo.bar": "baz"}, output) }) t.Run("Array", func(t *testing.T) { output := map[string]string{} - flatVals(map[string]any{"foo": []any{"bar", "baz"}}, output) + flatVals(map[string]interface{}{"foo": []interface{}{"bar", "baz"}}, output) assert.Equal(t, map[string]string{"foo[0]": "bar", "foo[1]": "baz"}, output) }) t.Run("Val", func(t *testing.T) { output := map[string]string{} - flatVals(map[string]any{"foo": 1}, output) + flatVals(map[string]interface{}{"foo": 1}, output) assert.Equal(t, map[string]string{"foo": "1"}, output) }) diff --git a/util/helm/index.go b/util/helm/index.go index 0c054970a4..2dca5041d4 100644 --- a/util/helm/index.go +++ b/util/helm/index.go @@ -1,8 +1,13 @@ package helm import ( + "errors" "fmt" "time" + + log "github.com/sirupsen/logrus" + + "github.com/Masterminds/semver/v3" ) type Entry struct { @@ -10,16 +15,6 @@ type Entry struct { Created time.Time } -type Entries []Entry - -func (es Entries) Tags() []string { - tags := make([]string, len(es)) - for i, e := range es { - tags[i] = e.Version - } - return tags -} - type Index struct { Entries map[string]Entries } @@ -31,3 +26,34 @@ func (i *Index) GetEntries(chart string) (Entries, error) { } return entries, nil } + +type Entries []Entry + +func (e Entries) MaxVersion(constraints *semver.Constraints) (*semver.Version, error) { + versions := semver.Collection{} + for _, entry := range e { + v, err := semver.NewVersion(entry.Version) + + // Invalid semantic version ignored + if errors.Is(err, semver.ErrInvalidSemVer) { + log.Debugf("Invalid sementic version: %s", entry.Version) + continue + } + if err != nil { + return nil, fmt.Errorf("invalid constraint in index: %w", err) + } + if constraints.Check(v) { + versions = append(versions, v) + } + } + if len(versions) == 0 { + return nil, fmt.Errorf("constraint not found in index") + } + maxVersion := versions[0] + for _, v := range versions { + if v.GreaterThan(maxVersion) { + maxVersion = v + } + } + return maxVersion, nil +} diff --git a/util/helm/index_test.go b/util/helm/index_test.go index b7f3a55b63..c195710ff3 100644 --- a/util/helm/index_test.go +++ b/util/helm/index_test.go @@ -3,6 +3,7 @@ package helm import ( "testing" + "github.com/Masterminds/semver/v3" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -11,10 +12,10 @@ var index = Index{ Entries: map[string]Entries{ "argo-cd": { {Version: "~0.7.3"}, + {Version: "0.7.2"}, {Version: "0.7.1"}, {Version: "0.5.4"}, {Version: "0.5.3"}, - {Version: "0.7.2"}, {Version: "0.5.2"}, {Version: "~0.5.2"}, {Version: "0.5.1"}, @@ -29,8 +30,53 @@ func TestIndex_GetEntries(t *testing.T) { require.EqualError(t, err, "chart 'foo' not found in index") }) t.Run("Found", func(t *testing.T) { - ts, err := index.GetEntries("argo-cd") + entries, err := index.GetEntries("argo-cd") require.NoError(t, err) - assert.Len(t, ts, len(index.Entries["argo-cd"])) + assert.Len(t, entries, 9) + }) +} + +func TestEntries_MaxVersion(t *testing.T) { + entries, _ := index.GetEntries("argo-cd") + t.Run("NotFound", func(t *testing.T) { + constraints, _ := semver.NewConstraint("0.8.1") + _, err := entries.MaxVersion(constraints) + require.EqualError(t, err, "constraint not found in index") + }) + t.Run("Exact", func(t *testing.T) { + constraints, _ := semver.NewConstraint("0.5.3") + version, err := entries.MaxVersion(constraints) + require.NoError(t, err) + assert.Equal(t, semver.MustParse("0.5.3"), version) + }) + t.Run("Constraint", func(t *testing.T) { + constraints, _ := semver.NewConstraint("> 0.5.3") + version, err := entries.MaxVersion(constraints) + require.NoError(t, err) + assert.Equal(t, semver.MustParse("0.7.2"), version) + }) + t.Run("Constraint", func(t *testing.T) { + constraints, _ := semver.NewConstraint("> 0.0.0") + version, err := entries.MaxVersion(constraints) + require.NoError(t, err) + assert.Equal(t, semver.MustParse("0.7.2"), version) + }) + t.Run("Constraint", func(t *testing.T) { + constraints, _ := semver.NewConstraint(">0.5.0,<0.7.0") + version, err := entries.MaxVersion(constraints) + require.NoError(t, err) + assert.Equal(t, semver.MustParse("0.5.4"), version) + }) + t.Run("Constraint", func(t *testing.T) { + constraints, _ := semver.NewConstraint("0.7.*") + version, err := entries.MaxVersion(constraints) + require.NoError(t, err) + assert.Equal(t, semver.MustParse("0.7.2"), version) + }) + t.Run("Constraint", func(t *testing.T) { + constraints, _ := semver.NewConstraint("*") + version, err := entries.MaxVersion(constraints) + require.NoError(t, err) + assert.Equal(t, semver.MustParse("0.7.2"), version) }) } diff --git a/util/helm/mocks/Client.go b/util/helm/mocks/Client.go index 56957472f2..798a632fe6 100644 --- a/util/helm/mocks/Client.go +++ b/util/helm/mocks/Client.go @@ -1,15 +1,162 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "github.com/argoproj/argo-cd/v3/util/helm" - "github.com/argoproj/argo-cd/v3/util/io" + helm "github.com/argoproj/argo-cd/v2/util/helm" + io "github.com/argoproj/argo-cd/v2/util/io" + mock "github.com/stretchr/testify/mock" ) +// Client is an autogenerated mock type for the Client type +type Client struct { + mock.Mock +} + +// CleanChartCache provides a mock function with given fields: chart, version +func (_m *Client) CleanChartCache(chart string, version string) error { + ret := _m.Called(chart, version) + + if len(ret) == 0 { + panic("no return value specified for CleanChartCache") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string, string) error); ok { + r0 = rf(chart, version) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ExtractChart provides a mock function with given fields: chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize +func (_m *Client) ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, io.Closer, error) { + ret := _m.Called(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize) + + if len(ret) == 0 { + panic("no return value specified for ExtractChart") + } + + var r0 string + var r1 io.Closer + var r2 error + if rf, ok := ret.Get(0).(func(string, string, bool, int64, bool) (string, io.Closer, error)); ok { + return rf(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize) + } + if rf, ok := ret.Get(0).(func(string, string, bool, int64, bool) string); ok { + r0 = rf(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string, string, bool, int64, bool) io.Closer); ok { + r1 = rf(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(io.Closer) + } + } + + if rf, ok := ret.Get(2).(func(string, string, bool, int64, bool) error); ok { + r2 = rf(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// GetIndex provides a mock function with given fields: noCache, maxIndexSize +func (_m *Client) GetIndex(noCache bool, maxIndexSize int64) (*helm.Index, error) { + ret := _m.Called(noCache, maxIndexSize) + + if len(ret) == 0 { + panic("no return value specified for GetIndex") + } + + var r0 *helm.Index + var r1 error + if rf, ok := ret.Get(0).(func(bool, int64) (*helm.Index, error)); ok { + return rf(noCache, maxIndexSize) + } + if rf, ok := ret.Get(0).(func(bool, int64) *helm.Index); ok { + r0 = rf(noCache, maxIndexSize) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*helm.Index) + } + } + + if rf, ok := ret.Get(1).(func(bool, int64) error); ok { + r1 = rf(noCache, maxIndexSize) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetTags provides a mock function with given fields: chart, noCache +func (_m *Client) GetTags(chart string, noCache bool) (*helm.TagsList, error) { + ret := _m.Called(chart, noCache) + + if len(ret) == 0 { + panic("no return value specified for GetTags") + } + + var r0 *helm.TagsList + var r1 error + if rf, ok := ret.Get(0).(func(string, bool) (*helm.TagsList, error)); ok { + return rf(chart, noCache) + } + if rf, ok := ret.Get(0).(func(string, bool) *helm.TagsList); ok { + r0 = rf(chart, noCache) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*helm.TagsList) + } + } + + if rf, ok := ret.Get(1).(func(string, bool) error); ok { + r1 = rf(chart, noCache) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// TestHelmOCI provides a mock function with no fields +func (_m *Client) TestHelmOCI() (bool, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for TestHelmOCI") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func() (bool, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewClient(t interface { @@ -23,295 +170,3 @@ func NewClient(t interface { return mock } - -// Client is an autogenerated mock type for the Client type -type Client struct { - mock.Mock -} - -type Client_Expecter struct { - mock *mock.Mock -} - -func (_m *Client) EXPECT() *Client_Expecter { - return &Client_Expecter{mock: &_m.Mock} -} - -// CleanChartCache provides a mock function for the type Client -func (_mock *Client) CleanChartCache(chart string, version string) error { - ret := _mock.Called(chart, version) - - if len(ret) == 0 { - panic("no return value specified for CleanChartCache") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(string, string) error); ok { - r0 = returnFunc(chart, version) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// Client_CleanChartCache_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CleanChartCache' -type Client_CleanChartCache_Call struct { - *mock.Call -} - -// CleanChartCache is a helper method to define mock.On call -// - chart -// - version -func (_e *Client_Expecter) CleanChartCache(chart interface{}, version interface{}) *Client_CleanChartCache_Call { - return &Client_CleanChartCache_Call{Call: _e.mock.On("CleanChartCache", chart, version)} -} - -func (_c *Client_CleanChartCache_Call) Run(run func(chart string, version string)) *Client_CleanChartCache_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) - }) - return _c -} - -func (_c *Client_CleanChartCache_Call) Return(err error) *Client_CleanChartCache_Call { - _c.Call.Return(err) - return _c -} - -func (_c *Client_CleanChartCache_Call) RunAndReturn(run func(chart string, version string) error) *Client_CleanChartCache_Call { - _c.Call.Return(run) - return _c -} - -// ExtractChart provides a mock function for the type Client -func (_mock *Client) ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, io.Closer, error) { - ret := _mock.Called(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize) - - if len(ret) == 0 { - panic("no return value specified for ExtractChart") - } - - var r0 string - var r1 io.Closer - var r2 error - if returnFunc, ok := ret.Get(0).(func(string, string, bool, int64, bool) (string, io.Closer, error)); ok { - return returnFunc(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize) - } - if returnFunc, ok := ret.Get(0).(func(string, string, bool, int64, bool) string); ok { - r0 = returnFunc(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize) - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func(string, string, bool, int64, bool) io.Closer); ok { - r1 = returnFunc(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize) - } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).(io.Closer) - } - } - if returnFunc, ok := ret.Get(2).(func(string, string, bool, int64, bool) error); ok { - r2 = returnFunc(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize) - } else { - r2 = ret.Error(2) - } - return r0, r1, r2 -} - -// Client_ExtractChart_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExtractChart' -type Client_ExtractChart_Call struct { - *mock.Call -} - -// ExtractChart is a helper method to define mock.On call -// - chart -// - version -// - passCredentials -// - manifestMaxExtractedSize -// - disableManifestMaxExtractedSize -func (_e *Client_Expecter) ExtractChart(chart interface{}, version interface{}, passCredentials interface{}, manifestMaxExtractedSize interface{}, disableManifestMaxExtractedSize interface{}) *Client_ExtractChart_Call { - return &Client_ExtractChart_Call{Call: _e.mock.On("ExtractChart", chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize)} -} - -func (_c *Client_ExtractChart_Call) Run(run func(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool)) *Client_ExtractChart_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(bool), args[3].(int64), args[4].(bool)) - }) - return _c -} - -func (_c *Client_ExtractChart_Call) Return(s string, closer io.Closer, err error) *Client_ExtractChart_Call { - _c.Call.Return(s, closer, err) - return _c -} - -func (_c *Client_ExtractChart_Call) RunAndReturn(run func(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, io.Closer, error)) *Client_ExtractChart_Call { - _c.Call.Return(run) - return _c -} - -// GetIndex provides a mock function for the type Client -func (_mock *Client) GetIndex(noCache bool, maxIndexSize int64) (*helm.Index, error) { - ret := _mock.Called(noCache, maxIndexSize) - - if len(ret) == 0 { - panic("no return value specified for GetIndex") - } - - var r0 *helm.Index - var r1 error - if returnFunc, ok := ret.Get(0).(func(bool, int64) (*helm.Index, error)); ok { - return returnFunc(noCache, maxIndexSize) - } - if returnFunc, ok := ret.Get(0).(func(bool, int64) *helm.Index); ok { - r0 = returnFunc(noCache, maxIndexSize) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*helm.Index) - } - } - if returnFunc, ok := ret.Get(1).(func(bool, int64) error); ok { - r1 = returnFunc(noCache, maxIndexSize) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetIndex_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetIndex' -type Client_GetIndex_Call struct { - *mock.Call -} - -// GetIndex is a helper method to define mock.On call -// - noCache -// - maxIndexSize -func (_e *Client_Expecter) GetIndex(noCache interface{}, maxIndexSize interface{}) *Client_GetIndex_Call { - return &Client_GetIndex_Call{Call: _e.mock.On("GetIndex", noCache, maxIndexSize)} -} - -func (_c *Client_GetIndex_Call) Run(run func(noCache bool, maxIndexSize int64)) *Client_GetIndex_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(bool), args[1].(int64)) - }) - return _c -} - -func (_c *Client_GetIndex_Call) Return(index *helm.Index, err error) *Client_GetIndex_Call { - _c.Call.Return(index, err) - return _c -} - -func (_c *Client_GetIndex_Call) RunAndReturn(run func(noCache bool, maxIndexSize int64) (*helm.Index, error)) *Client_GetIndex_Call { - _c.Call.Return(run) - return _c -} - -// GetTags provides a mock function for the type Client -func (_mock *Client) GetTags(chart string, noCache bool) ([]string, error) { - ret := _mock.Called(chart, noCache) - - if len(ret) == 0 { - panic("no return value specified for GetTags") - } - - var r0 []string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string, bool) ([]string, error)); ok { - return returnFunc(chart, noCache) - } - if returnFunc, ok := ret.Get(0).(func(string, bool) []string); ok { - r0 = returnFunc(chart, noCache) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - if returnFunc, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = returnFunc(chart, noCache) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_GetTags_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTags' -type Client_GetTags_Call struct { - *mock.Call -} - -// GetTags is a helper method to define mock.On call -// - chart -// - noCache -func (_e *Client_Expecter) GetTags(chart interface{}, noCache interface{}) *Client_GetTags_Call { - return &Client_GetTags_Call{Call: _e.mock.On("GetTags", chart, noCache)} -} - -func (_c *Client_GetTags_Call) Run(run func(chart string, noCache bool)) *Client_GetTags_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(bool)) - }) - return _c -} - -func (_c *Client_GetTags_Call) Return(strings []string, err error) *Client_GetTags_Call { - _c.Call.Return(strings, err) - return _c -} - -func (_c *Client_GetTags_Call) RunAndReturn(run func(chart string, noCache bool) ([]string, error)) *Client_GetTags_Call { - _c.Call.Return(run) - return _c -} - -// TestHelmOCI provides a mock function for the type Client -func (_mock *Client) TestHelmOCI() (bool, error) { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for TestHelmOCI") - } - - var r0 bool - var r1 error - if returnFunc, ok := ret.Get(0).(func() (bool, error)); ok { - return returnFunc() - } - if returnFunc, ok := ret.Get(0).(func() bool); ok { - r0 = returnFunc() - } else { - r0 = ret.Get(0).(bool) - } - if returnFunc, ok := ret.Get(1).(func() error); ok { - r1 = returnFunc() - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Client_TestHelmOCI_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TestHelmOCI' -type Client_TestHelmOCI_Call struct { - *mock.Call -} - -// TestHelmOCI is a helper method to define mock.On call -func (_e *Client_Expecter) TestHelmOCI() *Client_TestHelmOCI_Call { - return &Client_TestHelmOCI_Call{Call: _e.mock.On("TestHelmOCI")} -} - -func (_c *Client_TestHelmOCI_Call) Run(run func()) *Client_TestHelmOCI_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *Client_TestHelmOCI_Call) Return(b bool, err error) *Client_TestHelmOCI_Call { - _c.Call.Return(b, err) - return _c -} - -func (_c *Client_TestHelmOCI_Call) RunAndReturn(run func() (bool, error)) *Client_TestHelmOCI_Call { - _c.Call.Return(run) - return _c -} diff --git a/util/helm/tags.go b/util/helm/tags.go new file mode 100644 index 0000000000..6cfa745fb3 --- /dev/null +++ b/util/helm/tags.go @@ -0,0 +1,43 @@ +package helm + +import ( + "errors" + "fmt" + + log "github.com/sirupsen/logrus" + + "github.com/Masterminds/semver/v3" +) + +type TagsList struct { + Tags []string +} + +func (t TagsList) MaxVersion(constraints *semver.Constraints) (*semver.Version, error) { + versions := semver.Collection{} + for _, tag := range t.Tags { + v, err := semver.NewVersion(tag) + + // Invalid semantic version ignored + if errors.Is(err, semver.ErrInvalidSemVer) { + log.Debugf("Invalid semantic version: %s", tag) + continue + } + if err != nil { + return nil, fmt.Errorf("invalid constraint in tags: %w", err) + } + if constraints.Check(v) { + versions = append(versions, v) + } + } + if len(versions) == 0 { + return nil, fmt.Errorf("constraint not found in %v tags", len(t.Tags)) + } + maxVersion := versions[0] + for _, v := range versions { + if v.GreaterThan(maxVersion) { + maxVersion = v + } + } + return maxVersion, nil +} diff --git a/util/helm/tags_test.go b/util/helm/tags_test.go new file mode 100644 index 0000000000..6eb7cf902e --- /dev/null +++ b/util/helm/tags_test.go @@ -0,0 +1,43 @@ +package helm + +import ( + "testing" + + "github.com/Masterminds/semver/v3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var tags = TagsList{ + Tags: []string{ + "~0.7.3", + "0.7.1", + "0.5.4", + "0.5.3", + "0.7.2", + "0.5.2", + "~0.5.2", + "0.5.1", + "0.5.0", + }, +} + +func TestTagsList_MaxVersion(t *testing.T) { + t.Run("NotFound", func(t *testing.T) { + constraints, _ := semver.NewConstraint("0.8.1") + _, err := tags.MaxVersion(constraints) + assert.EqualError(t, err, "constraint not found in 9 tags") + }) + t.Run("Exact", func(t *testing.T) { + constraints, _ := semver.NewConstraint("0.5.3") + version, err := tags.MaxVersion(constraints) + require.NoError(t, err) + assert.Equal(t, semver.MustParse("0.5.3"), version) + }) + t.Run("Constraint", func(t *testing.T) { + constraints, _ := semver.NewConstraint("> 0.5.3") + version, err := tags.MaxVersion(constraints) + require.NoError(t, err) + assert.Equal(t, semver.MustParse("0.7.2"), version) + }) +} diff --git a/util/versions/version.go b/util/helm/version.go similarity index 88% rename from util/versions/version.go rename to util/helm/version.go index 10c7378ed2..8974684352 100644 --- a/util/versions/version.go +++ b/util/helm/version.go @@ -1,4 +1,4 @@ -package versions +package helm import "github.com/Masterminds/semver/v3" diff --git a/util/versions/version_test.go b/util/helm/version_test.go similarity index 82% rename from util/versions/version_test.go rename to util/helm/version_test.go index 617eb81b07..7b389caf6f 100644 --- a/util/versions/version_test.go +++ b/util/helm/version_test.go @@ -1,4 +1,4 @@ -package versions +package helm import ( "testing" @@ -10,6 +10,5 @@ func TestIsVersion(t *testing.T) { assert.False(t, IsVersion("*")) assert.False(t, IsVersion("1.*")) assert.False(t, IsVersion("1.0.*")) - assert.True(t, IsVersion("1.0")) assert.True(t, IsVersion("1.0.0")) } diff --git a/util/http/http.go b/util/http/http.go index 954117d7dc..7c13c71fde 100644 --- a/util/http/http.go +++ b/util/http/http.go @@ -14,8 +14,8 @@ import ( log "github.com/sirupsen/logrus" "k8s.io/client-go/transport" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/env" ) const ( @@ -64,12 +64,11 @@ func splitCookie(key, value, attributes string) []string { } var cookie string - switch { - case j == 0 && numberOfChunks == 1: + if j == 0 && numberOfChunks == 1 { cookie = fmt.Sprintf("%s=%s", key, value[i:end]) - case j == 0: + } else if j == 0 { cookie = fmt.Sprintf("%s=%d:%s", key, numberOfChunks, value[i:end]) - default: + } else { cookie = fmt.Sprintf("%s-%d=%s", key, j, value[i:end]) } if attributes != "" { @@ -103,16 +102,15 @@ func JoinCookies(key string, cookieList []*http.Cookie) (string, error) { } parts := strings.Split(token, ":") - switch len(parts) { - case 2: + if len(parts) == 2 { if numOfChunks, err = strconv.Atoi(parts[0]); err != nil { return "", err } sb.WriteString(parts[1]) - case 1: + } else if len(parts) == 1 { numOfChunks = 1 sb.WriteString(parts[0]) - default: + } else { return "", fmt.Errorf("invalid cookie for key %s", key) } diff --git a/util/io/files/secure_mkdir_linux.go b/util/io/files/secure_mkdir_linux.go index f6755c578b..14f727dda4 100644 --- a/util/io/files/secure_mkdir_linux.go +++ b/util/io/files/secure_mkdir_linux.go @@ -13,7 +13,7 @@ import ( // directory traversal attacks by ensuring the path is within the root directory. The path is constructed as if the // given root is the root of the filesystem. So anything traversing outside the root is simply removed from the path. func SecureMkdirAll(root, unsafePath string, mode os.FileMode) (string, error) { - err := securejoin.MkdirAll(root, unsafePath, mode) + err := securejoin.MkdirAll(root, unsafePath, int(mode)) if err != nil { return "", fmt.Errorf("failed to make directory: %w", err) } diff --git a/util/io/files/tar_test.go b/util/io/files/tar_test.go index cce5bda2e1..3ef7d24e0e 100644 --- a/util/io/files/tar_test.go +++ b/util/io/files/tar_test.go @@ -14,8 +14,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/io/files" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/io/files" ) func TestTgz(t *testing.T) { @@ -113,7 +113,10 @@ func TestUntgz(t *testing.T) { } deleteTmpDir := func(t *testing.T, dirname string) { t.Helper() - assert.NoError(t, os.RemoveAll(dirname), "error removing tmpDir") + err := os.RemoveAll(dirname) + if err != nil { + t.Errorf("error removing tmpDir: %s", err) + } } createTgz := func(t *testing.T, fromDir, destDir string) *os.File { t.Helper() diff --git a/util/io/files/testdata/executable/script.sh b/util/io/files/testdata/executable/script.sh index a33ea1e6de..e78c829c17 100755 --- a/util/io/files/testdata/executable/script.sh +++ b/util/io/files/testdata/executable/script.sh @@ -1,3 +1 @@ -#!/usr/bin/env bash - -echo hello world +echo hello world \ No newline at end of file diff --git a/util/io/files/util.go b/util/io/files/util.go index 681e84bc57..deef3166fc 100644 --- a/util/io/files/util.go +++ b/util/io/files/util.go @@ -12,11 +12,11 @@ import ( "github.com/google/uuid" ) -var ErrRelativeOutOfBound = errors.New("full path does not contain base path") +var RelativeOutOfBoundErr = errors.New("full path does not contain base path") // RelativePath will remove the basePath string from the fullPath // including the path separator. Differently from filepath.Rel, this -// function will return error (ErrRelativeOutOfBound) if basePath +// function will return error (RelativeOutOfBoundErr) if basePath // does not match (example 2). // // Example 1: @@ -39,7 +39,7 @@ var ErrRelativeOutOfBound = errors.New("full path does not contain base path") func RelativePath(fullPath, basePath string) (string, error) { fp := filepath.Clean(fullPath) if !strings.HasPrefix(fp, filepath.Clean(basePath)) { - return "", ErrRelativeOutOfBound + return "", RelativeOutOfBoundErr } return filepath.Rel(basePath, fp) } diff --git a/util/io/files/util_test.go b/util/io/files/util_test.go index 85fa049d5d..d9bdfa74a0 100644 --- a/util/io/files/util_test.go +++ b/util/io/files/util_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/argoproj/argo-cd/v3/util/io/files" + "github.com/argoproj/argo-cd/v2/util/io/files" ) func TestRelativePath(t *testing.T) { @@ -43,7 +43,7 @@ func TestRelativePath(t *testing.T) { fullpath: "/home/test/app/readme.md", basepath: "/somewhere/else", expected: "", - expectedErr: files.ErrRelativeOutOfBound, + expectedErr: files.RelativeOutOfBoundErr, }, { name: "will return relative path from dir path", @@ -57,14 +57,14 @@ func TestRelativePath(t *testing.T) { fullpath: "./app/", basepath: "/home/test", expected: "", - expectedErr: files.ErrRelativeOutOfBound, + expectedErr: files.RelativeOutOfBoundErr, }, { name: "will handle relative basepath", fullpath: "/home/test/app/", basepath: "./test", expected: "", - expectedErr: files.ErrRelativeOutOfBound, + expectedErr: files.RelativeOutOfBoundErr, }, { name: "will handle relative paths", diff --git a/util/io/mocks/TempPaths.go b/util/io/mocks/TempPaths.go index c84b4d5c5f..4787927855 100644 --- a/util/io/mocks/TempPaths.go +++ b/util/io/mocks/TempPaths.go @@ -1,12 +1,84 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks -import ( - mock "github.com/stretchr/testify/mock" -) +import mock "github.com/stretchr/testify/mock" + +// TempPaths is an autogenerated mock type for the TempPaths type +type TempPaths struct { + mock.Mock +} + +// Add provides a mock function with given fields: key, value +func (_m *TempPaths) Add(key string, value string) { + _m.Called(key, value) +} + +// GetPath provides a mock function with given fields: key +func (_m *TempPaths) GetPath(key string) (string, error) { + ret := _m.Called(key) + + if len(ret) == 0 { + panic("no return value specified for GetPath") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string) (string, error)); ok { + return rf(key) + } + if rf, ok := ret.Get(0).(func(string) string); ok { + r0 = rf(key) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(key) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPathIfExists provides a mock function with given fields: key +func (_m *TempPaths) GetPathIfExists(key string) string { + ret := _m.Called(key) + + if len(ret) == 0 { + panic("no return value specified for GetPathIfExists") + } + + var r0 string + if rf, ok := ret.Get(0).(func(string) string); ok { + r0 = rf(key) + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// GetPaths provides a mock function with no fields +func (_m *TempPaths) GetPaths() map[string]string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetPaths") + } + + var r0 map[string]string + if rf, ok := ret.Get(0).(func() map[string]string); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]string) + } + } + + return r0 +} // NewTempPaths creates a new instance of TempPaths. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. @@ -21,196 +93,3 @@ func NewTempPaths(t interface { return mock } - -// TempPaths is an autogenerated mock type for the TempPaths type -type TempPaths struct { - mock.Mock -} - -type TempPaths_Expecter struct { - mock *mock.Mock -} - -func (_m *TempPaths) EXPECT() *TempPaths_Expecter { - return &TempPaths_Expecter{mock: &_m.Mock} -} - -// Add provides a mock function for the type TempPaths -func (_mock *TempPaths) Add(key string, value string) { - _mock.Called(key, value) - return -} - -// TempPaths_Add_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Add' -type TempPaths_Add_Call struct { - *mock.Call -} - -// Add is a helper method to define mock.On call -// - key -// - value -func (_e *TempPaths_Expecter) Add(key interface{}, value interface{}) *TempPaths_Add_Call { - return &TempPaths_Add_Call{Call: _e.mock.On("Add", key, value)} -} - -func (_c *TempPaths_Add_Call) Run(run func(key string, value string)) *TempPaths_Add_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) - }) - return _c -} - -func (_c *TempPaths_Add_Call) Return() *TempPaths_Add_Call { - _c.Call.Return() - return _c -} - -func (_c *TempPaths_Add_Call) RunAndReturn(run func(key string, value string)) *TempPaths_Add_Call { - _c.Run(run) - return _c -} - -// GetPath provides a mock function for the type TempPaths -func (_mock *TempPaths) GetPath(key string) (string, error) { - ret := _mock.Called(key) - - if len(ret) == 0 { - panic("no return value specified for GetPath") - } - - var r0 string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) (string, error)); ok { - return returnFunc(key) - } - if returnFunc, ok := ret.Get(0).(func(string) string); ok { - r0 = returnFunc(key) - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(key) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// TempPaths_GetPath_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPath' -type TempPaths_GetPath_Call struct { - *mock.Call -} - -// GetPath is a helper method to define mock.On call -// - key -func (_e *TempPaths_Expecter) GetPath(key interface{}) *TempPaths_GetPath_Call { - return &TempPaths_GetPath_Call{Call: _e.mock.On("GetPath", key)} -} - -func (_c *TempPaths_GetPath_Call) Run(run func(key string)) *TempPaths_GetPath_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *TempPaths_GetPath_Call) Return(s string, err error) *TempPaths_GetPath_Call { - _c.Call.Return(s, err) - return _c -} - -func (_c *TempPaths_GetPath_Call) RunAndReturn(run func(key string) (string, error)) *TempPaths_GetPath_Call { - _c.Call.Return(run) - return _c -} - -// GetPathIfExists provides a mock function for the type TempPaths -func (_mock *TempPaths) GetPathIfExists(key string) string { - ret := _mock.Called(key) - - if len(ret) == 0 { - panic("no return value specified for GetPathIfExists") - } - - var r0 string - if returnFunc, ok := ret.Get(0).(func(string) string); ok { - r0 = returnFunc(key) - } else { - r0 = ret.Get(0).(string) - } - return r0 -} - -// TempPaths_GetPathIfExists_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPathIfExists' -type TempPaths_GetPathIfExists_Call struct { - *mock.Call -} - -// GetPathIfExists is a helper method to define mock.On call -// - key -func (_e *TempPaths_Expecter) GetPathIfExists(key interface{}) *TempPaths_GetPathIfExists_Call { - return &TempPaths_GetPathIfExists_Call{Call: _e.mock.On("GetPathIfExists", key)} -} - -func (_c *TempPaths_GetPathIfExists_Call) Run(run func(key string)) *TempPaths_GetPathIfExists_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *TempPaths_GetPathIfExists_Call) Return(s string) *TempPaths_GetPathIfExists_Call { - _c.Call.Return(s) - return _c -} - -func (_c *TempPaths_GetPathIfExists_Call) RunAndReturn(run func(key string) string) *TempPaths_GetPathIfExists_Call { - _c.Call.Return(run) - return _c -} - -// GetPaths provides a mock function for the type TempPaths -func (_mock *TempPaths) GetPaths() map[string]string { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for GetPaths") - } - - var r0 map[string]string - if returnFunc, ok := ret.Get(0).(func() map[string]string); ok { - r0 = returnFunc() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[string]string) - } - } - return r0 -} - -// TempPaths_GetPaths_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPaths' -type TempPaths_GetPaths_Call struct { - *mock.Call -} - -// GetPaths is a helper method to define mock.On call -func (_e *TempPaths_Expecter) GetPaths() *TempPaths_GetPaths_Call { - return &TempPaths_GetPaths_Call{Call: _e.mock.On("GetPaths")} -} - -func (_c *TempPaths_GetPaths_Call) Run(run func()) *TempPaths_GetPaths_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *TempPaths_GetPaths_Call) Return(stringToString map[string]string) *TempPaths_GetPaths_Call { - _c.Call.Return(stringToString) - return _c -} - -func (_c *TempPaths_GetPaths_Call) RunAndReturn(run func() map[string]string) *TempPaths_GetPaths_Call { - _c.Call.Return(run) - return _c -} diff --git a/util/io/path/resolved.go b/util/io/path/resolved.go index f5dd215d28..4ac5831c54 100644 --- a/util/io/path/resolved.go +++ b/util/io/path/resolved.go @@ -35,7 +35,7 @@ func resolveSymbolicLinkRecursive(path string, maxDepth int) (string, error) { } if maxDepth == 0 { - return "", errors.New("maximum nesting level reached") + return "", fmt.Errorf("maximum nesting level reached") } // If we resolved to a relative symlink, make sure we use the absolute @@ -70,7 +70,7 @@ func isURLSchemeAllowed(scheme string, allowed []string) bool { // Instead, we log the concrete error details. func resolveFailure(path string, err error) error { log.Errorf("failed to resolve path '%s': %v", path, err) - return errors.New("internal error: failed to resolve path. Check logs for more details") + return fmt.Errorf("internal error: failed to resolve path. Check logs for more details") } func ResolveFileOrDirectoryPath(appPath, repoRoot, dir string) (ResolvedFileOrDirectoryPath, error) { @@ -110,7 +110,7 @@ func ResolveFileOrDirectoryPath(appPath, repoRoot, dir string) (ResolvedFileOrDi // // isRemote will be set to true if valueFile is an URL using an allowed // protocol scheme, or to false if it resolved to a local file. -func ResolveValueFilePathOrUrl(appPath, repoRoot, valueFile string, allowedURLSchemes []string) (resolvedPath ResolvedFilePath, isRemote bool, err error) { //nolint:revive //FIXME(var-naming) +func ResolveValueFilePathOrUrl(appPath, repoRoot, valueFile string, allowedURLSchemes []string) (resolvedPath ResolvedFilePath, isRemote bool, err error) { // A value file can be specified as an URL to a remote resource. // We only allow certain URL schemes for remote value files. url, err := url.Parse(valueFile) @@ -119,8 +119,9 @@ func ResolveValueFilePathOrUrl(appPath, repoRoot, valueFile string, allowedURLSc if url.Scheme != "" { if isURLSchemeAllowed(url.Scheme, allowedURLSchemes) { return ResolvedFilePath(valueFile), true, nil + } else { + return "", false, fmt.Errorf("the URL scheme '%s' is not allowed", url.Scheme) } - return "", false, fmt.Errorf("the URL scheme '%s' is not allowed", url.Scheme) } } @@ -175,7 +176,7 @@ func resolveFileOrDirectory(appPath string, repoRoot string, fileOrDirectory str resolvedToRoot := path+string(os.PathSeparator) == requiredRootPath if resolvedToRoot { if !allowResolveToRoot { - return "", resolveFailure(path, errors.New("path resolved to repository root, which is not allowed")) + return "", resolveFailure(path, fmt.Errorf("path resolved to repository root, which is not allowed")) } } else { // Make sure that the resolved path to file is within the repository's root path diff --git a/util/io/path/resolved_test.go b/util/io/path/resolved_test.go index 57471fdaea..36472e8788 100644 --- a/util/io/path/resolved_test.go +++ b/util/io/path/resolved_test.go @@ -27,12 +27,12 @@ func Test_resolveSymlinkRecursive(t *testing.T) { t.Run("Do not allow symlink at all", func(t *testing.T) { r, err := resolveSymbolicLinkRecursive(testsDir+"/bar", 0) require.Error(t, err) - assert.Empty(t, r) + assert.Equal(t, "", r) }) t.Run("Error because too nested symlink", func(t *testing.T) { r, err := resolveSymbolicLinkRecursive(testsDir+"/bam", 2) require.Error(t, err) - assert.Empty(t, r) + assert.Equal(t, "", r) }) t.Run("No such file or directory", func(t *testing.T) { r, err := resolveSymbolicLinkRecursive(testsDir+"/foobar", 2) @@ -48,7 +48,7 @@ func Test_isURLSchemeAllowed(t *testing.T) { allowed []string expected bool } - tts := []testdata{ + var tts []testdata = []testdata{ { name: "Allowed scheme matches", scheme: "http", @@ -113,7 +113,7 @@ func Test_resolveFilePath(t *testing.T) { p, remote, err := ResolveValueFilePathOrUrl("/foo/bar", "/foo", "baz/../../../bim.yaml", allowedRemoteProtocols) require.ErrorContains(t, err, "outside repository root") assert.False(t, remote) - assert.Empty(t, string(p)) + assert.Equal(t, "", string(p)) }) t.Run("Return verbatim URL", func(t *testing.T) { url := "https://some.where/foo,yaml" @@ -127,7 +127,7 @@ func Test_resolveFilePath(t *testing.T) { p, remote, err := ResolveValueFilePathOrUrl("/foo/bar", "/foo", url, allowedRemoteProtocols) require.Error(t, err) assert.False(t, remote) - assert.Empty(t, string(p)) + assert.Equal(t, "", string(p)) }) t.Run("Implicit URL by absolute path", func(t *testing.T) { p, remote, err := ResolveValueFilePathOrUrl("/foo/bar", "/foo", "/baz.yaml", allowedRemoteProtocols) @@ -153,25 +153,25 @@ func Test_resolveFilePath(t *testing.T) { p, remote, err := ResolveValueFilePathOrUrl(".", "/foo", "../foo2/baz.yaml", allowedRemoteProtocols) require.ErrorContains(t, err, "outside repository root") assert.False(t, remote) - assert.Empty(t, string(p)) + 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.ErrorContains(t, err, "outside repository root") assert.False(t, remote) - assert.Empty(t, string(p)) + 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.ErrorContains(t, err, "outside repository root") assert.False(t, remote) - assert.Empty(t, string(p)) + 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.ErrorContains(t, err, "outside repository root") assert.False(t, remote) - assert.Empty(t, string(p)) + assert.Equal(t, "", string(p)) }) t.Run("Resolve root path into absolute path - jsonnet library path", func(t *testing.T) { p, err := ResolveFileOrDirectoryPath("/foo", "/foo", "./") diff --git a/util/io/subdirfs.go b/util/io/subdirfs.go new file mode 100644 index 0000000000..93b0ab7a6e --- /dev/null +++ b/util/io/subdirfs.go @@ -0,0 +1,20 @@ +package io + +import ( + "io/fs" + "path/filepath" +) + +type subDirFs struct { + dir string + fs fs.FS +} + +func (s subDirFs) Open(name string) (fs.File, error) { + return s.fs.Open(filepath.Join(s.dir, name)) +} + +// NewSubDirFS returns file system that represents sub-directory in a wrapped file system +func NewSubDirFS(dir string, fs fs.FS) *subDirFs { + return &subDirFs{dir: dir, fs: fs} +} diff --git a/util/jwt/jwt.go b/util/jwt/jwt.go index bb6770da33..585025990b 100644 --- a/util/jwt/jwt.go +++ b/util/jwt/jwt.go @@ -6,7 +6,7 @@ import ( "strings" "time" - jwtgo "github.com/golang-jwt/jwt/v5" + jwtgo "github.com/golang-jwt/jwt/v4" ) // MapClaims converts a jwt.Claims to a MapClaims @@ -56,7 +56,7 @@ func GetScopeValues(claims jwtgo.MapClaims, scopes []string) []string { } switch val := scopeIf.(type) { - case []any: + case []interface{}: for _, groupIf := range val { group, ok := groupIf.(string) if ok { @@ -107,7 +107,7 @@ func ExpirationTime(m jwtgo.MapClaims) (time.Time, error) { return time.Unix(exp, 0), err } -func Claims(in any) jwtgo.Claims { +func Claims(in interface{}) jwtgo.Claims { claims, ok := in.(jwtgo.Claims) if ok { return claims diff --git a/util/jwt/jwt_test.go b/util/jwt/jwt_test.go index 5ef645abb8..1b0ac87fe9 100644 --- a/util/jwt/jwt_test.go +++ b/util/jwt/jwt_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/golang-jwt/jwt/v5" + jwt "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/util/kube/failureretrywrapper.go b/util/kube/failureretrywrapper.go index 60ceb21858..f9d66e8910 100644 --- a/util/kube/failureretrywrapper.go +++ b/util/kube/failureretrywrapper.go @@ -16,7 +16,8 @@ type failureRetryRoundTripper struct { failureRetryPeriodMilliSeconds int } -func shouldRetry(counter int, _ *http.Request, response *http.Response, err error) bool { +// nolint:unparam +func shouldRetry(counter int, r *http.Request, response *http.Response, err error) bool { if counter <= 0 { return false } diff --git a/util/kube/kube.go b/util/kube/kube.go index 6e1d67f98e..aa96dfc4d3 100644 --- a/util/kube/kube.go +++ b/util/kube/kube.go @@ -8,7 +8,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) var resourceNamePattern = regexp.MustCompile("^[a-z0-9]([-a-z0-9]*[a-z0-9])?$") @@ -47,7 +47,7 @@ func SetAppInstanceLabel(target *unstructured.Unstructured, key, val string) err return err } if !ok || templateLabels == nil { - templateLabels = make(map[string]any) + templateLabels = make(map[string]interface{}) } templateLabels[key] = val err = unstructured.SetNestedMap(target.UnstructuredContent(), templateLabels, "spec", "template", "metadata", "labels") @@ -78,13 +78,14 @@ func SetAppInstanceLabel(target *unstructured.Unstructured, key, val string) err } } case "batch": - if gvk.Kind == kube.JobKind { + switch gvk.Kind { + case kube.JobKind: templateLabels, ok, err := unstructured.NestedMap(target.UnstructuredContent(), "spec", "template", "metadata", "labels") if err != nil { return err } if !ok || templateLabels == nil { - templateLabels = make(map[string]any) + templateLabels = make(map[string]interface{}) } templateLabels[key] = val err = unstructured.SetNestedMap(target.UnstructuredContent(), templateLabels, "spec", "template", "metadata", "labels") @@ -185,8 +186,8 @@ func RemoveAnnotation(un *unstructured.Unstructured, key string) error { } // 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]any or nil, or contains non-string values in the map. -func nestedNullableStringMap(obj map[string]any, fields ...string) (map[string]string, error) { +// 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) { var m map[string]string val, found, err := unstructured.NestedFieldNoCopy(obj, fields...) if err != nil { diff --git a/util/kube/kube_test.go b/util/kube/kube_test.go index df5f25f6d3..51474359bd 100644 --- a/util/kube/kube_test.go +++ b/util/kube/kube_test.go @@ -8,12 +8,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + apiv1 "k8s.io/api/core/v1" extv1beta1 "k8s.io/api/extensions/v1beta1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) const depWithoutSelector = ` @@ -73,10 +73,9 @@ func TestSetLabels(t *testing.T) { require.NoError(t, err) // the following makes sure we are not falling into legacy code which injects labels - switch yamlStr { - case depWithoutSelector: + if yamlStr == depWithoutSelector { assert.Nil(t, depV1Beta1.Spec.Selector) - case depWithSelector: + } else if yamlStr == depWithSelector { assert.Len(t, depV1Beta1.Spec.Selector.MatchLabels, 1) assert.Equal(t, "nginx", depV1Beta1.Spec.Selector.MatchLabels["app"]) } @@ -148,13 +147,13 @@ func TestSetSvcLabel(t *testing.T) { require.NoError(t, err) log.Println(string(manifestBytes)) - var s corev1.Service + var s apiv1.Service err = json.Unmarshal(manifestBytes, &s) require.NoError(t, err) log.Println(s.Name) log.Println(s.ObjectMeta) - assert.Equal(t, "my-app", s.Labels[common.LabelKeyAppInstance]) + assert.Equal(t, "my-app", s.ObjectMeta.Labels[common.LabelKeyAppInstance]) } func TestIsValidResourceName(t *testing.T) { @@ -177,13 +176,13 @@ func TestSetAppInstanceAnnotation(t *testing.T) { require.NoError(t, err) log.Println(string(manifestBytes)) - var s corev1.Service + var s apiv1.Service err = json.Unmarshal(manifestBytes, &s) require.NoError(t, err) log.Println(s.Name) log.Println(s.ObjectMeta) - assert.Equal(t, "my-app", s.Annotations[common.LabelKeyAppInstance]) + assert.Equal(t, "my-app", s.ObjectMeta.Annotations[common.LabelKeyAppInstance]) } func TestSetAppInstanceAnnotationWithInvalidData(t *testing.T) { @@ -193,7 +192,8 @@ func TestSetAppInstanceAnnotationWithInvalidData(t *testing.T) { err = yaml.Unmarshal(yamlBytes, &obj) require.NoError(t, err) err = SetAppInstanceAnnotation(&obj, common.LabelKeyAppInstance, "my-app") - assert.EqualError(t, err, "failed to get annotations from target object /v1, Kind=Service /my-service: .metadata.annotations accessor error: contains non-string value in the map under key \"invalid-annotation\": is of the type , expected string") + require.Error(t, err) + assert.Equal(t, "failed to get annotations from target object /v1, Kind=Service /my-service: .metadata.annotations accessor error: contains non-string value in the map under key \"invalid-annotation\": is of the type , expected string", err.Error()) } func TestGetAppInstanceAnnotation(t *testing.T) { @@ -218,7 +218,8 @@ func TestGetAppInstanceAnnotationWithInvalidData(t *testing.T) { require.NoError(t, err) _, err = GetAppInstanceAnnotation(&obj, "valid-annotation") - assert.EqualError(t, err, "failed to get annotations from target object /v1, Kind=Service /my-service: .metadata.annotations accessor error: contains non-string value in the map under key \"invalid-annotation\": is of the type , expected string") + require.Error(t, err) + assert.Equal(t, "failed to get annotations from target object /v1, Kind=Service /my-service: .metadata.annotations accessor error: contains non-string value in the map under key \"invalid-annotation\": is of the type , expected string", err.Error()) } func TestGetAppInstanceLabel(t *testing.T) { @@ -241,7 +242,8 @@ func TestGetAppInstanceLabelWithInvalidData(t *testing.T) { err = yaml.Unmarshal(yamlBytes, &obj) require.NoError(t, err) _, err = GetAppInstanceLabel(&obj, "valid-label") - assert.EqualError(t, err, "failed to get labels for /v1, Kind=Service /my-service: .metadata.labels accessor error: contains non-string value in the map under key \"invalid-label\": is of the type , expected string") + require.Error(t, err) + assert.Equal(t, "failed to get labels for /v1, Kind=Service /my-service: .metadata.labels accessor error: contains non-string value in the map under key \"invalid-label\": is of the type , expected string", err.Error()) } func TestRemoveLabel(t *testing.T) { @@ -266,5 +268,6 @@ func TestRemoveLabelWithInvalidData(t *testing.T) { require.NoError(t, err) err = RemoveLabel(&obj, "valid-label") - assert.EqualError(t, err, "failed to get labels for /v1, Kind=Service /my-service: .metadata.labels accessor error: contains non-string value in the map under key \"invalid-label\": is of the type , expected string") + require.Error(t, err) + assert.Equal(t, "failed to get labels for /v1, Kind=Service /my-service: .metadata.labels accessor error: contains non-string value in the map under key \"invalid-label\": is of the type , expected string", err.Error()) } diff --git a/util/kube/kubectl.go b/util/kube/kubectl.go index 5c5996bcdd..de9dc7bc1b 100644 --- a/util/kube/kubectl.go +++ b/util/kube/kubectl.go @@ -7,7 +7,7 @@ import ( "k8s.io/client-go/rest" "k8s.io/kubectl/pkg/util/openapi" - "github.com/argoproj/argo-cd/v3/util/log" + "github.com/argoproj/argo-cd/v2/util/log" "github.com/argoproj/gitops-engine/pkg/diff" "github.com/argoproj/gitops-engine/pkg/utils/kube" diff --git a/util/kube/portforwarder.go b/util/kube/portforwarder.go index 9a0698abd4..0efa19374d 100644 --- a/util/kube/portforwarder.go +++ b/util/kube/portforwarder.go @@ -9,21 +9,19 @@ import ( "os" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/httpstream" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/portforward" "k8s.io/client-go/transport/spdy" - cmdutil "k8s.io/kubectl/pkg/cmd/util" "k8s.io/kubectl/pkg/util/podutils" - utilio "github.com/argoproj/argo-cd/v3/util/io" + "github.com/argoproj/argo-cd/v2/util/io" ) func selectPodForPortForward(clientSet kubernetes.Interface, namespace string, podSelectors ...string) (*corev1.Pod, error) { for _, podSelector := range podSelectors { - pods, err := clientSet.CoreV1().Pods(namespace).List(context.Background(), metav1.ListOptions{ + pods, err := clientSet.CoreV1().Pods(namespace).List(context.Background(), v1.ListOptions{ LabelSelector: podSelector, }) if err != nil { @@ -77,18 +75,6 @@ func PortForward(targetPort int, namespace string, overrides *clientcmd.ConfigOv } dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, "POST", url) - // Reuse environment variable for kubectl to disable the feature flag, default is enabled. - if !cmdutil.PortForwardWebsockets.IsDisabled() { - tunnelingDialer, err := portforward.NewSPDYOverWebsocketDialer(url, config) - if err != nil { - return -1, fmt.Errorf("could not create tunneling dialer: %w", err) - } - // First attempt tunneling (websocket) dialer, then fallback to spdy dialer. - dialer = portforward.NewFallbackDialer(tunnelingDialer, dialer, func(err error) bool { - return httpstream.IsUpgradeFailure(err) || httpstream.IsHTTPSProxyError(err) - }) - } - readyChan := make(chan struct{}, 1) failedChan := make(chan error, 1) out := new(bytes.Buffer) @@ -99,8 +85,9 @@ func PortForward(targetPort int, namespace string, overrides *clientcmd.ConfigOv return -1, err } port := ln.Addr().(*net.TCPAddr).Port - utilio.Close(ln) - forwarder, err := portforward.NewOnAddresses(dialer, []string{"localhost"}, []string{fmt.Sprintf("%d:%d", port, targetPort)}, context.Background().Done(), readyChan, out, errOut) + io.Close(ln) + + forwarder, err := portforward.New(dialer, []string{fmt.Sprintf("%d:%d", port, targetPort)}, context.Background().Done(), readyChan, out, errOut) if err != nil { return -1, err } diff --git a/util/kube/util.go b/util/kube/util.go index 684e5a1e02..81c7c0d44c 100644 --- a/util/kube/util.go +++ b/util/kube/util.go @@ -3,7 +3,7 @@ package kube import ( "context" - corev1 "k8s.io/api/core/v1" + apiv1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" @@ -18,10 +18,10 @@ type kubeUtil struct { // updateFn will be called to set data for secret s. new will be true if the // secret was created by the caller, or false if it has existed before. -type updateFn func(s *corev1.Secret, new bool) error +type updateFn func(s *apiv1.Secret, new bool) error // NewKubeUtil NewUtil returns a new kubeUtil receiver -func NewKubeUtil(ctx context.Context, client kubernetes.Interface) *kubeUtil { +func NewKubeUtil(client kubernetes.Interface, ctx context.Context) *kubeUtil { return &kubeUtil{client: client, ctx: ctx} } @@ -30,7 +30,7 @@ func NewKubeUtil(ctx context.Context, client kubernetes.Interface) *kubeUtil { // the receiver. If the secret is updated, labels and annotations will not be // touched. func (ku *kubeUtil) CreateOrUpdateSecret(ns string, name string, update updateFn) error { - var s *corev1.Secret + var s *apiv1.Secret var err error var new bool @@ -43,7 +43,7 @@ func (ku *kubeUtil) CreateOrUpdateSecret(ns string, name string, update updateFn } if new { - s = &corev1.Secret{ + s = &apiv1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: ns, @@ -70,7 +70,7 @@ func (ku *kubeUtil) CreateOrUpdateSecret(ns string, name string, update updateFn // CreateOrUpdateSecretField creates or updates a secret name in namespace ns, with given value for given field func (ku *kubeUtil) CreateOrUpdateSecretField(ns string, name string, field string, value string) error { - err := ku.CreateOrUpdateSecret(ns, name, func(s *corev1.Secret, _ bool) error { + err := ku.CreateOrUpdateSecret(ns, name, func(s *apiv1.Secret, new bool) error { s.Data[field] = []byte(value) return nil }) @@ -80,7 +80,7 @@ func (ku *kubeUtil) CreateOrUpdateSecretField(ns string, name string, field stri // CreateOrUpdateSecretData creates or updates a secret name in namespace ns, with given data. // If merge is true, merges data with the existing data, otherwise overwrites it. func (ku *kubeUtil) CreateOrUpdateSecretData(ns string, name string, data map[string][]byte, merge bool) error { - err := ku.CreateOrUpdateSecret(ns, name, func(s *corev1.Secret, new bool) error { + err := ku.CreateOrUpdateSecret(ns, name, func(s *apiv1.Secret, new bool) error { if !merge || new { s.Data = data } else { diff --git a/util/kube/util_test.go b/util/kube/util_test.go index a81d479bf8..ac3e5a3527 100644 --- a/util/kube/util_test.go +++ b/util/kube/util_test.go @@ -6,13 +6,14 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + apiv1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/fake" ) -func getSecret(client kubernetes.Interface, ns, name string) (*corev1.Secret, error) { +// nolint:unparam +func getSecret(client kubernetes.Interface, ns, name string) (*apiv1.Secret, error) { s, err := client.CoreV1().Secrets(ns).Get(context.TODO(), name, metav1.GetOptions{}) if err != nil { return nil, err @@ -21,7 +22,7 @@ func getSecret(client kubernetes.Interface, ns, name string) (*corev1.Secret, er } func Test_CreateOrUpdateSecretField(t *testing.T) { - secret := &corev1.Secret{ + secret := &apiv1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "test-secret", Namespace: "test", @@ -49,7 +50,7 @@ func Test_CreateOrUpdateSecretField(t *testing.T) { client := fake.NewClientset(secret) t.Run("Change field in existing secret", func(t *testing.T) { - ku := NewKubeUtil(t.Context(), client) + ku := NewKubeUtil(client, context.TODO()) err := ku.CreateOrUpdateSecretField("test", "test-secret", "password", "barfoo") require.NoError(t, err) s, err := getSecret(client, "test", "test-secret") @@ -64,7 +65,7 @@ func Test_CreateOrUpdateSecretField(t *testing.T) { }) t.Run("Change field in non-existing secret", func(t *testing.T) { - ku := NewKubeUtil(t.Context(), client) + ku := NewKubeUtil(client, context.TODO()) err := ku.CreateOrUpdateSecretField("test", "nonexist-secret", "password", "foobaz") require.NoError(t, err) s, err := getSecret(client, "test", "nonexist-secret") @@ -79,7 +80,7 @@ func Test_CreateOrUpdateSecretField(t *testing.T) { }) t.Run("Change field in existing secret with labels", func(t *testing.T) { - ku := NewKubeUtil(t.Context(), client).WithAnnotations(annotations).WithLabels(labels) + ku := NewKubeUtil(client, context.TODO()).WithAnnotations(annotations).WithLabels(labels) err := ku.CreateOrUpdateSecretField("test", "test-secret", "password", "barfoo") require.NoError(t, err) s, err := getSecret(client, "test", "test-secret") @@ -94,7 +95,7 @@ func Test_CreateOrUpdateSecretField(t *testing.T) { }) t.Run("Change field in existing secret with labels", func(t *testing.T) { - ku := NewKubeUtil(t.Context(), client).WithAnnotations(annotations).WithLabels(labels) + ku := NewKubeUtil(client, context.TODO()).WithAnnotations(annotations).WithLabels(labels) err := ku.CreateOrUpdateSecretField("test", "nonexisting-secret", "password", "barfoo") require.NoError(t, err) s, err := getSecret(client, "test", "nonexisting-secret") @@ -112,7 +113,7 @@ func Test_CreateOrUpdateSecretField(t *testing.T) { } func Test_CreateOrUpdateSecretData(t *testing.T) { - secret := &corev1.Secret{ + secret := &apiv1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "test-secret", Namespace: "test", @@ -135,7 +136,7 @@ func Test_CreateOrUpdateSecretData(t *testing.T) { client := fake.NewClientset(secret) t.Run("Change data in existing secret with merge", func(t *testing.T) { - ku := NewKubeUtil(t.Context(), client) + ku := NewKubeUtil(client, context.TODO()) err := ku.CreateOrUpdateSecretData("test", "test-secret", data1, true) require.NoError(t, err) s, err := getSecret(client, "test", "test-secret") @@ -146,7 +147,7 @@ func Test_CreateOrUpdateSecretData(t *testing.T) { }) t.Run("Change data in non-existing secret with merge", func(t *testing.T) { - ku := NewKubeUtil(t.Context(), client) + ku := NewKubeUtil(client, context.TODO()) err := ku.CreateOrUpdateSecretData("test", "nonexist-secret", data1, true) require.NoError(t, err) s, err := getSecret(client, "test", "nonexist-secret") @@ -156,7 +157,7 @@ func Test_CreateOrUpdateSecretData(t *testing.T) { }) t.Run("Change data in existing secret without merge", func(t *testing.T) { - ku := NewKubeUtil(t.Context(), client) + ku := NewKubeUtil(client, context.TODO()) err := ku.CreateOrUpdateSecretData("test", "test-secret", data2, false) require.NoError(t, err) s, err := getSecret(client, "test", "test-secret") @@ -168,7 +169,7 @@ func Test_CreateOrUpdateSecretData(t *testing.T) { }) t.Run("Change data in non-existing secret without merge", func(t *testing.T) { - ku := NewKubeUtil(t.Context(), client) + ku := NewKubeUtil(client, context.TODO()) err := ku.CreateOrUpdateSecretData("test", "nonexist-secret", data2, false) require.NoError(t, err) s, err := getSecret(client, "test", "nonexist-secret") diff --git a/util/kustomize/kustomize.go b/util/kustomize/kustomize.go index c4eda8fc2f..3fb15a64d3 100644 --- a/util/kustomize/kustomize.go +++ b/util/kustomize/kustomize.go @@ -1,7 +1,6 @@ package kustomize import ( - "errors" "fmt" "net/url" "os" @@ -19,13 +18,11 @@ import ( log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - certutil "github.com/argoproj/argo-cd/v3/util/cert" - executil "github.com/argoproj/argo-cd/v3/util/exec" - "github.com/argoproj/argo-cd/v3/util/git" - "github.com/argoproj/argo-cd/v3/util/proxy" - - securejoin "github.com/cyphar/filepath-securejoin" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + certutil "github.com/argoproj/argo-cd/v2/util/cert" + executil "github.com/argoproj/argo-cd/v2/util/exec" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/proxy" ) // Image represents a Docker image in the format NAME[:TAG]. @@ -107,7 +104,7 @@ func (k *kustomize) getBinaryPath() string { // https://github.com/kubernetes-sigs/kustomize/commit/b214fa7d5aa51d7c2ae306ec15115bf1c044fed8#diff-0328c59bcd29799e365ff0647653b886f17c8853df008cd54e7981db882c1b36 func mapToEditAddArgs(val map[string]string) []string { var args []string - if getSemverSafe(&kustomize{}).LessThan(semver.MustParse("v3.8.5")) { + if getSemverSafe().LessThan(semver.MustParse("v3.8.5")) { arg := "" for labelName, labelValue := range val { if arg != "" { @@ -147,16 +144,15 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp log.Warnf("Could not parse URL %s: %v", k.repo, err) } else { caPath, err := certutil.GetCertBundlePathForRepository(parsedURL.Host) - switch { - case err != nil: + if err != nil { // Some error while getting CA bundle log.Warnf("Could not get CA bundle path for %s: %v", parsedURL.Host, err) - case caPath == "": + } else if caPath == "" { // No cert configured log.Debugf("No caCert found for repo %s", parsedURL.Host) - default: + } else { // Make Git use CA bundle - environ = append(environ, "GIT_SSL_CAINFO="+caPath) + environ = append(environ, fmt.Sprintf("GIT_SSL_CAINFO=%s", caPath)) } } } @@ -230,9 +226,6 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp if opts.LabelWithoutSelector { args = append(args, "--without-selector") } - if opts.LabelIncludeTemplates { - args = append(args, "--include-templates") - } commonLabels := map[string]string{} for name, value := range opts.CommonLabels { commonLabels[name] = envVars.Envsubst(value) @@ -285,32 +278,32 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp // If the kustomization file is not found, return early. // There is no point reading the kustomization path if it doesn't exist. if kustFile == "" { - return nil, nil, nil, errors.New("kustomization file not found in the path") + return nil, nil, nil, fmt.Errorf("kustomization file not found in the path") } kustomizationPath := filepath.Join(k.path, kustFile) b, err := os.ReadFile(kustomizationPath) if err != nil { return nil, nil, nil, fmt.Errorf("failed to load kustomization.yaml: %w", err) } - var kustomization any + var kustomization interface{} err = yaml.Unmarshal(b, &kustomization) if err != nil { return nil, nil, nil, fmt.Errorf("failed to unmarshal kustomization.yaml: %w", err) } - kMap, ok := kustomization.(map[string]any) + kMap, ok := kustomization.(map[string]interface{}) if !ok { - return nil, nil, nil, fmt.Errorf("expected kustomization.yaml to be type map[string]any, but got %T", kMap) + return nil, nil, nil, fmt.Errorf("expected kustomization.yaml to be type map[string]interface{}, but got %T", kMap) } patches, ok := kMap["patches"] if ok { // The kustomization.yaml already had a patches field, so we need to append to it. - patchesList, ok := patches.([]any) + patchesList, ok := patches.([]interface{}) if !ok { - return nil, nil, nil, fmt.Errorf("expected 'patches' field in kustomization.yaml to be []any, but got %T", patches) + return nil, nil, nil, fmt.Errorf("expected 'patches' field in kustomization.yaml to be []interface{}, but got %T", patches) } // Since the patches from the Application manifest are typed, we need to convert them to a type which // can be appended to the existing list. - untypedPatches := make([]any, len(opts.Patches)) + untypedPatches := make([]interface{}, len(opts.Patches)) for i := range opts.Patches { untypedPatches[i] = opts.Patches[i] } @@ -338,29 +331,13 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp if len(opts.Components) > 0 { // components only supported in kustomize >= v3.7.0 // https://github.com/kubernetes-sigs/kustomize/blob/master/examples/components.md - if getSemverSafe(k).LessThan(semver.MustParse("v3.7.0")) { - return nil, nil, nil, errors.New("kustomize components require kustomize v3.7.0 and above") + if getSemverSafe().LessThan(semver.MustParse("v3.7.0")) { + return nil, nil, nil, fmt.Errorf("kustomize components require kustomize v3.7.0 and above") } // add components - foundComponents := opts.Components - if opts.IgnoreMissingComponents { - foundComponents = make([]string, 0) - for _, c := range opts.Components { - resolvedPath, err := securejoin.SecureJoin(k.path, c) - if err != nil { - return nil, nil, nil, fmt.Errorf("Kustomize components path failed: %w", err) - } - _, err = os.Stat(resolvedPath) - if err != nil { - log.Debugf("%s component directory does not exist", resolvedPath) - continue - } - foundComponents = append(foundComponents, c) - } - } args := []string{"edit", "add", "component"} - args = append(args, foundComponents...) + args = append(args, opts.Components...) cmd := exec.Command(k.getBinaryPath(), args...) cmd.Dir = k.path cmd.Env = env @@ -374,7 +351,7 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp var cmd *exec.Cmd if kustomizeOptions != nil && kustomizeOptions.BuildOptions != "" { - params := parseKustomizeBuildOptions(k, kustomizeOptions.BuildOptions, buildOpts) + params := parseKustomizeBuildOptions(k.path, kustomizeOptions.BuildOptions, buildOpts) cmd = exec.Command(k.getBinaryPath(), params...) } else { cmd = exec.Command(k.getBinaryPath(), "build", k.path) @@ -401,10 +378,10 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp return objs, getImageParameters(objs), redactedCommands, nil } -func parseKustomizeBuildOptions(k *kustomize, buildOptions string, buildOpts *BuildOpts) []string { - buildOptsParams := append([]string{"build", k.path}, strings.Fields(buildOptions)...) +func parseKustomizeBuildOptions(path string, buildOptions string, buildOpts *BuildOpts) []string { + buildOptsParams := append([]string{"build", path}, strings.Fields(buildOptions)...) - if buildOpts != nil && !getSemverSafe(k).LessThan(semver.MustParse("v5.3.0")) && isHelmEnabled(buildOptions) { + if buildOpts != nil && !getSemverSafe().LessThan(semver.MustParse("v5.3.0")) && isHelmEnabled(buildOptions) { if buildOpts.KubeVersion != "" { buildOptsParams = append(buildOptsParams, "--helm-kube-version", buildOpts.KubeVersion) } @@ -435,8 +412,8 @@ var ( ) // getSemver returns parsed kustomize version -func getSemver(k *kustomize) (*semver.Version, error) { - verStr, err := versionWithBinaryPath(k) +func getSemver() (*semver.Version, error) { + verStr, err := Version(true) if err != nil { return nil, err } @@ -452,12 +429,12 @@ func getSemver(k *kustomize) (*semver.Version, error) { // getSemverSafe returns parsed kustomize version; // if version cannot be parsed assumes that "kustomize version" output format changed again // and fallback to latest ( v99.99.99 ) -func getSemverSafe(k *kustomize) *semver.Version { +func getSemverSafe() *semver.Version { if semVer == nil { semVerLock.Lock() defer semVerLock.Unlock() - if ver, err := getSemver(k); err != nil { + if ver, err := getSemver(); err != nil { semVer = unknownVersion log.Warnf("Failed to parse kustomize version: %v", err) } else { @@ -467,30 +444,33 @@ func getSemverSafe(k *kustomize) *semver.Version { return semVer } -func Version() (string, error) { - return versionWithBinaryPath(&kustomize{}) -} - -func versionWithBinaryPath(k *kustomize) (string, error) { - executable := k.getBinaryPath() - cmd := exec.Command(executable, "version", "--short") +func Version(shortForm bool) (string, error) { + executable := "kustomize" + cmdArgs := []string{"version"} + if shortForm { + cmdArgs = append(cmdArgs, "--short") + } + cmd := exec.Command(executable, cmdArgs...) // example version output: + // long: "{Version:kustomize/v3.8.1 GitCommit:0b359d0ef0272e6545eda0e99aacd63aef99c4d0 BuildDate:2020-07-16T00:58:46Z GoOs:linux GoArch:amd64}" // short: "{kustomize/v3.8.1 2020-07-16T00:58:46Z }" version, err := executil.Run(cmd) if err != nil { return "", fmt.Errorf("could not get kustomize version: %w", err) } version = strings.TrimSpace(version) - // trim the curly braces - version = strings.TrimPrefix(version, "{") - version = strings.TrimSuffix(version, "}") - version = strings.TrimSpace(version) + if shortForm { + // trim the curly braces + version = strings.TrimPrefix(version, "{") + version = strings.TrimSuffix(version, "}") + version = strings.TrimSpace(version) - // remove double space in middle - version = strings.ReplaceAll(version, " ", " ") + // remove double space in middle + version = strings.ReplaceAll(version, " ", " ") - // remove extra 'kustomize/' before version - version = strings.TrimPrefix(version, "kustomize/") + // remove extra 'kustomize/' before version + version = strings.TrimPrefix(version, "kustomize/") + } return version, nil } @@ -505,13 +485,13 @@ func getImageParameters(objs []*unstructured.Unstructured) []Image { return images } -func getImages(object map[string]any) []Image { +func getImages(object map[string]interface{}) []Image { var images []Image for k, v := range object { - if array, ok := v.([]any); ok { + if array, ok := v.([]interface{}); ok { if k == "containers" || k == "initContainers" { for _, obj := range array { - if mapObj, isMapObj := obj.(map[string]any); isMapObj { + if mapObj, isMapObj := obj.(map[string]interface{}); isMapObj { if image, hasImage := mapObj["image"]; hasImage { images = append(images, fmt.Sprintf("%s", image)) } @@ -519,12 +499,12 @@ func getImages(object map[string]any) []Image { } } else { for i := range array { - if mapObj, isMapObj := array[i].(map[string]any); isMapObj { + if mapObj, isMapObj := array[i].(map[string]interface{}); isMapObj { images = append(images, getImages(mapObj)...) } } } - } else if objMap, ok := v.(map[string]any); ok { + } else if objMap, ok := v.(map[string]interface{}); ok { images = append(images, getImages(objMap)...) } } diff --git a/util/kustomize/kustomize_test.go b/util/kustomize/kustomize_test.go index badda80875..f58e58d2c2 100644 --- a/util/kustomize/kustomize_test.go +++ b/util/kustomize/kustomize_test.go @@ -7,14 +7,14 @@ import ( "path/filepath" "testing" + "github.com/argoproj/pkg/exec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/exec" - "github.com/argoproj/argo-cd/v3/util/git" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/git" ) const ( @@ -118,7 +118,8 @@ func TestKustomizeBuild(t *testing.T) { } for _, image := range images { - if image == "nginx" { + switch image { + case "nginx": assert.Equal(t, "1.15.5", image) } } @@ -148,7 +149,7 @@ func TestIsKustomization(t *testing.T) { } func TestParseKustomizeBuildOptions(t *testing.T) { - built := parseKustomizeBuildOptions(&kustomize{path: "guestbook"}, "-v 6 --logtostderr", &BuildOpts{ + built := parseKustomizeBuildOptions("guestbook", "-v 6 --logtostderr", &BuildOpts{ KubeVersion: "1.27", APIVersions: []string{"foo", "bar"}, }) // Helm is not enabled so helm options are not in the params @@ -156,7 +157,7 @@ func TestParseKustomizeBuildOptions(t *testing.T) { } func TestParseKustomizeBuildHelmOptions(t *testing.T) { - built := parseKustomizeBuildOptions(&kustomize{path: "guestbook"}, "-v 6 --logtostderr --enable-helm", &BuildOpts{ + built := parseKustomizeBuildOptions("guestbook", "-v 6 --logtostderr --enable-helm", &BuildOpts{ KubeVersion: "1.27", APIVersions: []string{"foo", "bar"}, }) @@ -169,19 +170,13 @@ func TestParseKustomizeBuildHelmOptions(t *testing.T) { } func TestVersion(t *testing.T) { - ver, err := Version() - require.NoError(t, err) - assert.NotEmpty(t, ver) -} - -func TestVersionWithBinaryPath(t *testing.T) { - ver, err := versionWithBinaryPath(&kustomize{binaryPath: "kustomize"}) + ver, err := Version(false) require.NoError(t, err) assert.NotEmpty(t, ver) } func TestGetSemver(t *testing.T) { - ver, err := getSemver(&kustomize{}) + ver, err := getSemver() require.NoError(t, err) assert.NotEmpty(t, ver) } @@ -390,45 +385,6 @@ func TestKustomizeLabelWithoutSelector(t *testing.T) { }, }, }, - { - TestData: kustomization7, - KustomizeSource: v1alpha1.ApplicationSourceKustomize{ - CommonLabels: map[string]string{ - "foo": "bar", - }, - LabelWithoutSelector: true, - LabelIncludeTemplates: true, - }, - ExpectedMetadataLabels: map[string]string{"app": "nginx", "managed-by": "helm", "foo": "bar"}, - ExpectedSelectorLabels: map[string]string{"app": "nginx"}, - ExpectedTemplateLabels: map[string]string{"app": "nginx", "foo": "bar"}, - Env: &v1alpha1.Env{ - &v1alpha1.EnvEntry{ - Name: "ARGOCD_APP_NAME", - Value: "argo-cd-tests", - }, - }, - }, - { - TestData: kustomization7, - KustomizeSource: v1alpha1.ApplicationSourceKustomize{ - CommonLabels: map[string]string{ - "managed-by": "argocd", - }, - LabelWithoutSelector: true, - LabelIncludeTemplates: true, - ForceCommonLabels: true, - }, - ExpectedMetadataLabels: map[string]string{"app": "nginx", "managed-by": "argocd"}, - ExpectedSelectorLabels: map[string]string{"app": "nginx"}, - ExpectedTemplateLabels: map[string]string{"app": "nginx", "managed-by": "argocd"}, - Env: &v1alpha1.Env{ - &v1alpha1.EnvEntry{ - Name: "ARGOCD_APP_NAME", - Value: "argo-cd-tests", - }, - }, - }, } for _, tc := range testCases { @@ -489,15 +445,7 @@ func TestKustomizeBuildComponents(t *testing.T) { kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "", "", "") kustomizeSource := v1alpha1.ApplicationSourceKustomize{ - Components: []string{"./components", "./missing-components"}, - IgnoreMissingComponents: false, - } - _, _, _, err = kustomize.Build(&kustomizeSource, nil, nil, nil) - require.Error(t, err) - - kustomizeSource = v1alpha1.ApplicationSourceKustomize{ - Components: []string{"./components", "./missing-components"}, - IgnoreMissingComponents: true, + Components: []string{"./components"}, } objs, _, _, err := kustomize.Build(&kustomizeSource, nil, nil, nil) require.NoError(t, err) @@ -540,14 +488,14 @@ func TestKustomizeBuildPatches(t *testing.T) { assert.True(t, found) ports, found, err := unstructured.NestedSlice( - containers[0].(map[string]any), + containers[0].(map[string]interface{}), "ports", ) assert.True(t, found) require.NoError(t, err) port, found, err := unstructured.NestedInt64( - ports[0].(map[string]any), + ports[0].(map[string]interface{}), "containerPort", ) @@ -556,7 +504,7 @@ func TestKustomizeBuildPatches(t *testing.T) { assert.Equal(t, int64(443), port) name, found, err := unstructured.NestedString( - containers[0].(map[string]any), + containers[0].(map[string]interface{}), "name", ) assert.True(t, found) diff --git a/util/localconfig/file_perm_unix.go b/util/localconfig/file_perm_unix.go index c2fcff661e..2e2d3eb47e 100644 --- a/util/localconfig/file_perm_unix.go +++ b/util/localconfig/file_perm_unix.go @@ -11,5 +11,6 @@ func getFilePermission(fi os.FileInfo) error { if fi.Mode().Perm() == 0o600 || fi.Mode().Perm() == 0o400 { return nil } - return fmt.Errorf("config file has incorrect permission flags %s, change the file permission either to 0400 or 0600", fi.Mode().Perm().String()) + return fmt.Errorf("config file has incorrect permission flags:%s."+ + "change the file permission either to 0400 or 0600.", fi.Mode().Perm().String()) } diff --git a/util/localconfig/localconfig.go b/util/localconfig/localconfig.go index 59099c81f8..221695354e 100644 --- a/util/localconfig/localconfig.go +++ b/util/localconfig/localconfig.go @@ -1,15 +1,15 @@ package localconfig import ( - "errors" "fmt" "os" "path" "strings" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" - "github.com/argoproj/argo-cd/v3/util/config" + "github.com/argoproj/argo-cd/v2/util/config" + configUtil "github.com/argoproj/argo-cd/v2/util/config" ) // LocalConfig is a local Argo CD config file @@ -79,7 +79,7 @@ func (u *User) Claims() (*jwt.RegisteredClaims, error) { // ReadLocalConfig loads up the local configuration file. Returns nil if config does not exist func ReadLocalConfig(path string) (*LocalConfig, error) { var err error - var localconfig LocalConfig + var config LocalConfig // check file permission only when argocd config exists if fi, err := os.Stat(path); err == nil { @@ -89,15 +89,15 @@ func ReadLocalConfig(path string) (*LocalConfig, error) { } } - err = config.UnmarshalLocalFile(path, &localconfig) + err = configUtil.UnmarshalLocalFile(path, &config) if os.IsNotExist(err) { return nil, nil } - err = ValidateLocalConfig(localconfig) + err = ValidateLocalConfig(config) if err != nil { return nil, err } - return &localconfig, nil + return &config, nil } func ValidateLocalConfig(config LocalConfig) error { @@ -105,18 +105,18 @@ func ValidateLocalConfig(config LocalConfig) error { return nil } if _, err := config.ResolveContext(config.CurrentContext); err != nil { - return fmt.Errorf("local config invalid: %w", err) + return fmt.Errorf("Local config invalid: %w", err) } return nil } // WriteLocalConfig writes a new local configuration file. -func WriteLocalConfig(localconfig LocalConfig, configPath string) error { +func WriteLocalConfig(config LocalConfig, configPath string) error { err := os.MkdirAll(path.Dir(configPath), os.ModePerm) if err != nil { return err } - return config.MarshalLocalYAMLFile(configPath, localconfig) + return configUtil.MarshalLocalYAMLFile(configPath, config) } func DeleteLocalConfig(configPath string) error { @@ -131,7 +131,7 @@ func DeleteLocalConfig(configPath string) error { func (l *LocalConfig) ResolveContext(name string) (*Context, error) { if name == "" { if l.CurrentContext == "" { - return nil, errors.New("local config: current-context unset") + return nil, fmt.Errorf("Local config: current-context unset") } name = l.CurrentContext } diff --git a/util/localconfig/localconfig_test.go b/util/localconfig/localconfig_test.go index dcd8453a82..ada30b865b 100644 --- a/util/localconfig/localconfig_test.go +++ b/util/localconfig/localconfig_test.go @@ -3,13 +3,13 @@ package localconfig import ( - "errors" + "fmt" "os" "path" "path/filepath" "testing" - "github.com/argoproj/argo-cd/v3/util/config" + "github.com/argoproj/argo-cd/v2/util/config" "github.com/stretchr/testify/require" @@ -19,7 +19,7 @@ import ( func TestGetUsername(t *testing.T) { assert.Equal(t, "admin", GetUsername("admin:login")) assert.Equal(t, "admin", GetUsername("admin")) - assert.Empty(t, GetUsername("")) + assert.Equal(t, "", GetUsername("")) } func TestFilePermission(t *testing.T) { @@ -43,13 +43,13 @@ func TestFilePermission(t *testing.T) { name: "Test config file with permission 0700", testfile: ".config_0700", perm: 0o700, - expectedError: errors.New("config file has incorrect permission flags -rwx------, change the file permission either to 0400 or 0600"), + expectedError: fmt.Errorf("config file has incorrect permission flags:-rwx------.change the file permission either to 0400 or 0600."), }, { name: "Test config file with permission 0777", testfile: ".config_0777", perm: 0o777, - expectedError: errors.New("config file has incorrect permission flags -rwxrwxrwx, change the file permission either to 0400 or 0600"), + expectedError: fmt.Errorf("config file has incorrect permission flags:-rwxrwxrwx.change the file permission either to 0400 or 0600."), }, { name: "Test config file with permission 0600", @@ -67,7 +67,7 @@ func TestFilePermission(t *testing.T) { name: "Test config file with permission 0300", testfile: ".config_0300", perm: 0o300, - expectedError: errors.New("config file has incorrect permission flags --wx------, change the file permission either to 0400 or 0600"), + expectedError: fmt.Errorf("config file has incorrect permission flags:--wx------.change the file permission either to 0400 or 0600."), }, } { t.Run(c.name, func(t *testing.T) { diff --git a/util/log/logrus.go b/util/log/logrus.go index 43418310b2..dd583fb5a3 100644 --- a/util/log/logrus.go +++ b/util/log/logrus.go @@ -5,20 +5,20 @@ import ( "os" "strings" - adapter "github.com/bombsimon/logrusr/v4" + adapter "github.com/bombsimon/logrusr/v2" "github.com/go-logr/logr" "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) const ( - JsonFormat = "json" //nolint:revive //FIXME(var-naming) + JsonFormat = "json" TextFormat = "text" ) func NewLogrusLogger(fieldLogger logrus.FieldLogger) logr.Logger { - return adapter.New(fieldLogger, adapter.WithFormatter(func(val any) any { + return adapter.New(fieldLogger, adapter.WithFormatter(func(val interface{}) string { return fmt.Sprintf("%v", val) })) } @@ -36,18 +36,15 @@ func CreateFormatter(logFormat string) logrus.Formatter { var formatType logrus.Formatter switch strings.ToLower(logFormat) { case JsonFormat: - formatType = &logrus.JSONFormatter{ - TimestampFormat: checkTimestampFormat(), - } + formatType = &logrus.JSONFormatter{} case TextFormat: formatType = &logrus.TextFormatter{ - ForceColors: checkForceLogColors(), - FullTimestamp: checkEnableFullTimestamp(), - TimestampFormat: checkTimestampFormat(), + ForceColors: checkForceLogColors(), + FullTimestamp: checkEnableFullTimestamp(), } default: - formatType = &logrus.JSONFormatter{ - TimestampFormat: checkTimestampFormat(), + formatType = &logrus.TextFormatter{ + FullTimestamp: checkEnableFullTimestamp(), } } @@ -69,7 +66,3 @@ func checkForceLogColors() bool { func checkEnableFullTimestamp() bool { return strings.ToLower(os.Getenv(common.EnvLogFormatEnableFullTimestamp)) == "1" } - -func checkTimestampFormat() string { - return os.Getenv(common.EnvLogFormatTimestamp) -} diff --git a/util/log/logrus_test.go b/util/log/logrus_test.go index f25ab4ca7b..0613d4ced0 100644 --- a/util/log/logrus_test.go +++ b/util/log/logrus_test.go @@ -1,13 +1,13 @@ package log import ( + "fmt" "testing" - "time" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) func TestCreateFormatter(t *testing.T) { @@ -26,28 +26,19 @@ func TestCreateFormatter(t *testing.T) { result := CreateFormatter("text") assert.Equal(t, &logrus.TextFormatter{}, result) }) - t.Run(common.EnvLogFormatEnableFullTimestamp+" == 1", func(t *testing.T) { + t.Run(fmt.Sprintf("%s == 1", common.EnvLogFormatEnableFullTimestamp), func(t *testing.T) { t.Setenv(common.EnvLogFormatEnableFullTimestamp, "1") result := CreateFormatter("text") assert.Equal(t, &logrus.TextFormatter{FullTimestamp: true}, result) }) - t.Run(common.EnvLogFormatEnableFullTimestamp+" != 1", func(t *testing.T) { + t.Run(fmt.Sprintf("%s != 1", common.EnvLogFormatEnableFullTimestamp), func(t *testing.T) { t.Setenv(common.EnvLogFormatEnableFullTimestamp, "0") result := CreateFormatter("text") assert.Equal(t, &logrus.TextFormatter{}, result) }) - t.Run(common.EnvLogFormatTimestamp+" is not set", func(t *testing.T) { - result := CreateFormatter("text") - assert.Equal(t, &logrus.TextFormatter{}, result) - }) - t.Run(common.EnvLogFormatTimestamp+" is set", func(t *testing.T) { - t.Setenv(common.EnvLogFormatTimestamp, time.RFC3339Nano) - result := CreateFormatter("text") - assert.Equal(t, &logrus.TextFormatter{TimestampFormat: time.RFC3339Nano}, result) - }) }) t.Run("log format is not json or text", func(t *testing.T) { result := CreateFormatter("xml") - assert.Equal(t, &logrus.JSONFormatter{}, result) + assert.Equal(t, &logrus.TextFormatter{}, result) }) } diff --git a/util/lua/custom_actions_test.go b/util/lua/custom_actions_test.go index 1e52590662..da635af3b0 100644 --- a/util/lua/custom_actions_test.go +++ b/util/lua/custom_actions_test.go @@ -15,9 +15,9 @@ import ( "github.com/argoproj/gitops-engine/pkg/diff" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - appsv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/cli" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/errors" ) type testNormalizer struct{} @@ -26,8 +26,9 @@ func (t testNormalizer) Normalize(un *unstructured.Unstructured) error { if un == nil { return nil } - if un.GetKind() == "Job" { - err := unstructured.SetNestedField(un.Object, map[string]any{"name": "not sure why this works"}, "metadata") + switch un.GetKind() { + case "Job": + err := unstructured.SetNestedField(un.Object, map[string]interface{}{"name": "not sure why this works"}, "metadata") if err != nil { return fmt.Errorf("failed to normalize Job: %w", err) } @@ -96,16 +97,14 @@ type IndividualDiscoveryTest struct { } type IndividualActionTest struct { - Action string `yaml:"action"` - InputPath string `yaml:"inputPath"` - ExpectedOutputPath string `yaml:"expectedOutputPath"` - ExpectedErrorMessage string `yaml:"expectedErrorMessage"` - InputStr string `yaml:"input"` - Parameters map[string]string `yaml:"parameters"` + Action string `yaml:"action"` + InputPath string `yaml:"inputPath"` + ExpectedOutputPath string `yaml:"expectedOutputPath"` + InputStr string `yaml:"input"` } func TestLuaResourceActionsScript(t *testing.T) { - err := filepath.Walk("../../resource_customizations", func(path string, _ os.FileInfo, err error) error { + err := filepath.Walk("../../resource_customizations", func(path string, f os.FileInfo, err error) error { if !strings.Contains(path, "action_test.yaml") { return nil } @@ -118,12 +117,12 @@ func TestLuaResourceActionsScript(t *testing.T) { require.NoError(t, err) for i := range resourceTest.DiscoveryTests { test := resourceTest.DiscoveryTests[i] - testName := "discovery/" + test.InputPath + testName := fmt.Sprintf("discovery/%s", test.InputPath) t.Run(testName, func(t *testing.T) { vm := VM{ UseOpenLibs: true, } - obj := getObj(t, filepath.Join(dir, test.InputPath)) + obj := getObj(filepath.Join(dir, test.InputPath)) discoveryLua, err := vm.GetResourceActionDiscovery(obj) require.NoError(t, err) result, err := vm.ExecuteResourceActionDiscovery(obj, discoveryLua) @@ -144,39 +143,13 @@ func TestLuaResourceActionsScript(t *testing.T) { // privileges that API server has. // UseOpenLibs: true, } - sourceObj := getObj(t, filepath.Join(dir, test.InputPath)) + sourceObj := getObj(filepath.Join(dir, test.InputPath)) action, err := vm.GetResourceAction(sourceObj, test.Action) require.NoError(t, err) - // Log the action Lua script - t.Logf("Action Lua script: %s", action.ActionLua) - - // Parse action parameters - var params []*applicationpkg.ResourceActionParameters - if test.Parameters != nil { - for k, v := range test.Parameters { - params = append(params, &applicationpkg.ResourceActionParameters{ - Name: &k, - Value: &v, - }) - } - } - - if len(params) > 0 { - // Log the parameters - t.Logf("Parameters: %+v", params) - } - require.NoError(t, err) - impactedResources, err := vm.ExecuteResourceAction(sourceObj, action.ActionLua, params) - - // Handle expected errors - if test.ExpectedErrorMessage != "" { - assert.EqualError(t, err, test.ExpectedErrorMessage) - return - } - + impactedResources, err := vm.ExecuteResourceAction(sourceObj, action.ActionLua) require.NoError(t, err) // Treat the Lua expected output as a list @@ -193,8 +166,9 @@ func TestLuaResourceActionsScript(t *testing.T) { // TODO: maybe this should use a normalizer function instead of hard-coding the resource specifics here if (result.GetKind() == "Job" && sourceObj.GetKind() == "CronJob") || (result.GetKind() == "Workflow" && (sourceObj.GetKind() == "CronWorkflow" || sourceObj.GetKind() == "WorkflowTemplate")) { return u.GroupVersionKind() == result.GroupVersionKind() && strings.HasPrefix(u.GetName(), sourceObj.GetName()) && u.GetNamespace() == result.GetNamespace() + } else { + return u.GroupVersionKind() == result.GroupVersionKind() && u.GetName() == result.GetName() && u.GetNamespace() == result.GetNamespace() } - return u.GroupVersionKind() == result.GroupVersionKind() && u.GetName() == result.GetName() && u.GetNamespace() == result.GetNamespace() }) assert.NotNil(t, expectedObj) @@ -203,9 +177,9 @@ func TestLuaResourceActionsScript(t *testing.T) { // No default case since a not supported operation would have failed upon unmarshaling earlier case PatchOperation: // Patching is only allowed for the source resource, so the GVK + name + ns must be the same as the impacted resource - assert.Equal(t, sourceObj.GroupVersionKind(), result.GroupVersionKind()) - assert.Equal(t, sourceObj.GetName(), result.GetName()) - assert.Equal(t, sourceObj.GetNamespace(), result.GetNamespace()) + assert.EqualValues(t, sourceObj.GroupVersionKind(), result.GroupVersionKind()) + assert.EqualValues(t, sourceObj.GetName(), result.GetName()) + assert.EqualValues(t, sourceObj.GetNamespace(), result.GetNamespace()) case CreateOperation: switch result.GetKind() { case "Job": @@ -214,7 +188,6 @@ func TestLuaResourceActionsScript(t *testing.T) { result.SetName(expectedObj.GetName()) } } - // Ideally, we would use a assert.Equal to detect the difference, but the Lua VM returns a object with float64 instead of the original int32. As a result, the assert.Equal is never true despite that the change has been applied. diffResult, err := diff.Diff(expectedObj, result, diff.WithNormalizer(testNormalizer{})) require.NoError(t, err) @@ -237,26 +210,28 @@ func TestLuaResourceActionsScript(t *testing.T) { func getExpectedObjectList(t *testing.T, path string) *unstructured.UnstructuredList { t.Helper() yamlBytes, err := os.ReadFile(path) - require.NoError(t, err) + errors.CheckError(err) unstructuredList := &unstructured.UnstructuredList{} yamlString := bytes.NewBuffer(yamlBytes).String() if yamlString[0] == '-' { // The string represents a new-style action array output, where each member is a wrapper around a k8s unstructured resource - objList := make([]map[string]any, 5) + objList := make([]map[string]interface{}, 5) err = yaml.Unmarshal(yamlBytes, &objList) - require.NoError(t, err) + errors.CheckError(err) unstructuredList.Items = make([]unstructured.Unstructured, len(objList)) // Append each map in objList to the Items field of the new object for i, obj := range objList { - unstructuredObj, ok := obj["unstructuredObj"].(map[string]any) - assert.True(t, ok, "Wrong type of unstructuredObj") + unstructuredObj, ok := obj["unstructuredObj"].(map[string]interface{}) + if !ok { + t.Error("Wrong type of unstructuredObj") + } unstructuredList.Items[i] = unstructured.Unstructured{Object: unstructuredObj} } } else { // The string represents an old-style action object output, which is a k8s unstructured resource - obj := make(map[string]any) + obj := make(map[string]interface{}) err = yaml.Unmarshal(yamlBytes, &obj) - require.NoError(t, err) + errors.CheckError(err) unstructuredList.Items = make([]unstructured.Unstructured, 1) unstructuredList.Items[0] = unstructured.Unstructured{Object: obj} } @@ -264,7 +239,7 @@ func getExpectedObjectList(t *testing.T, path string) *unstructured.Unstructured } func findFirstMatchingItem(items []unstructured.Unstructured, f func(unstructured.Unstructured) bool) *unstructured.Unstructured { - var matching *unstructured.Unstructured + var matching *unstructured.Unstructured = nil for _, item := range items { if f(item) { matching = &item diff --git a/util/lua/health_test.go b/util/lua/health_test.go index a546f80b84..a1fdadafc0 100644 --- a/util/lua/health_test.go +++ b/util/lua/health_test.go @@ -8,9 +8,10 @@ import ( "github.com/argoproj/gitops-engine/pkg/health" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/yaml" + + "github.com/argoproj/argo-cd/v2/util/errors" ) type TestStructure struct { @@ -22,40 +23,39 @@ type IndividualTest struct { HealthStatus health.HealthStatus `yaml:"healthStatus"` } -func getObj(t *testing.T, path string) *unstructured.Unstructured { - t.Helper() +func getObj(path string) *unstructured.Unstructured { yamlBytes, err := os.ReadFile(path) - require.NoError(t, err) - obj := make(map[string]any) + errors.CheckError(err) + obj := make(map[string]interface{}) err = yaml.Unmarshal(yamlBytes, &obj) - require.NoError(t, err) + errors.CheckError(err) return &unstructured.Unstructured{Object: obj} } func TestLuaHealthScript(t *testing.T) { - err := filepath.Walk("../../resource_customizations", func(path string, _ os.FileInfo, err error) error { + err := filepath.Walk("../../resource_customizations", func(path string, f os.FileInfo, err error) error { if !strings.Contains(path, "health.lua") { return nil } - require.NoError(t, err) + errors.CheckError(err) dir := filepath.Dir(path) yamlBytes, err := os.ReadFile(dir + "/health_test.yaml") - require.NoError(t, err) + errors.CheckError(err) var resourceTest TestStructure err = yaml.Unmarshal(yamlBytes, &resourceTest) - require.NoError(t, err) + errors.CheckError(err) for i := range resourceTest.Tests { test := resourceTest.Tests[i] t.Run(test.InputPath, func(t *testing.T) { vm := VM{ UseOpenLibs: true, } - obj := getObj(t, filepath.Join(dir, test.InputPath)) + obj := getObj(filepath.Join(dir, test.InputPath)) script, _, err := vm.GetHealthScript(obj) - require.NoError(t, err) + errors.CheckError(err) result, err := vm.ExecuteHealthLua(obj, script) - require.NoError(t, err) + errors.CheckError(err) assert.Equal(t, &test.HealthStatus, result) }) } diff --git a/util/lua/lua.go b/util/lua/lua.go index abdc88f84a..5babe89874 100644 --- a/util/lua/lua.go +++ b/util/lua/lua.go @@ -6,26 +6,20 @@ import ( "encoding/json" "errors" "fmt" - "io/fs" "os" "path/filepath" "reflect" - "slices" - "strings" - "sync" "time" "github.com/argoproj/gitops-engine/pkg/health" - glob "github.com/bmatcuk/doublestar/v4" lua "github.com/yuin/gopher-lua" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" luajson "layeh.com/gopher-json" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/resource_customizations" - argoglob "github.com/argoproj/argo-cd/v3/util/glob" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/resource_customizations" + "github.com/argoproj/argo-cd/v2/util/glob" ) const ( @@ -36,8 +30,15 @@ const ( actionDiscoveryScriptFile = "discovery.lua" ) -// errScriptDoesNotExist is an error type for when a built-in script does not exist. -var errScriptDoesNotExist = errors.New("built-in script does not exist") +// 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 @@ -69,10 +70,6 @@ type VM struct { } func (vm VM) runLua(obj *unstructured.Unstructured, script string) (*lua.LState, error) { - return vm.runLuaWithResourceActionParameters(obj, script, nil) -} - -func (vm VM) runLuaWithResourceActionParameters(obj *unstructured.Unstructured, script string, resourceActionParameters []*applicationpkg.ResourceActionParameters) (*lua.LState, error) { l := lua.NewState(lua.Options{ SkipOpenLibs: !vm.UseOpenLibs, }) @@ -102,29 +99,9 @@ func (vm VM) runLuaWithResourceActionParameters(obj *unstructured.Unstructured, ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() l.SetContext(ctx) - - // Inject action parameters as a hash table global variable - actionParams := l.CreateTable(0, len(resourceActionParameters)) - for _, resourceActionParameter := range resourceActionParameters { - value := decodeValue(l, resourceActionParameter.GetValue()) - actionParams.RawSetH(lua.LString(resourceActionParameter.GetName()), value) - } - l.SetGlobal("actionParams", actionParams) // Set the actionParams table as a global variable - objectValue := decodeValue(l, obj.Object) l.SetGlobal("obj", objectValue) err := l.DoString(script) - - // Remove the default lua stack trace from execution errors since these - // errors will make it back to the user - var apiErr *lua.ApiError - if errors.As(err, &apiErr) { - if apiErr.Type == lua.ApiErrorRun { - apiErr.StackTrace = "" - err = apiErr - } - } - return l, err } @@ -185,16 +162,8 @@ func (vm VM) GetHealthScript(obj *unstructured.Unstructured) (script string, use // (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 { - if errors.Is(err, errScriptDoesNotExist) { - // Try to find a wildcard built-in health script - builtInScript, err = getWildcardBuiltInHealthOverrideLua(key) - if err != nil { - return "", false, fmt.Errorf("error while fetching built-in health script: %w", err) - } - if builtInScript != "" { - return builtInScript, true, 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 } @@ -204,8 +173,8 @@ func (vm VM) GetHealthScript(obj *unstructured.Unstructured) (script string, use return builtInScript, true, err } -func (vm VM) ExecuteResourceAction(obj *unstructured.Unstructured, script string, resourceActionParameters []*applicationpkg.ResourceActionParameters) ([]ImpactedResource, error) { - l, err := vm.runLuaWithResourceActionParameters(obj, script, resourceActionParameters) +func (vm VM) ExecuteResourceAction(obj *unstructured.Unstructured, script string) ([]ImpactedResource, error) { + l, err := vm.runLua(obj, script) if err != nil { return nil, err } @@ -219,9 +188,8 @@ func (vm VM) ExecuteResourceAction(obj *unstructured.Unstructured, script string var impactedResources []ImpactedResource jsonString := bytes.NewBuffer(jsonBytes).String() - // nolint:staticcheck // Lua is fine to be capitalized. if len(jsonString) < 2 { - return nil, errors.New("Lua output was not a valid json object or array") + return nil, fmt.Errorf("Lua output was not a valid json object or array") } // The output from Lua is either an object (old-style action output) or an array (new-style action output). // Check whether the string starts with an opening square bracket and ends with a closing square bracket, @@ -271,7 +239,7 @@ func UnmarshalToImpactedResources(resources string) ([]ImpactedResource, error) // cleanReturnedObj Lua cannot distinguish an empty table as an array or map, and the library we are using choose to // decoded an empty table into an empty array. This function prevents the lua scripts from unintentionally changing an // empty struct into empty arrays -func cleanReturnedObj(newObj, obj map[string]any) map[string]any { +func cleanReturnedObj(newObj, obj map[string]interface{}) map[string]interface{} { mapToReturn := newObj for key := range obj { if newValueInterface, ok := newObj[key]; ok { @@ -280,19 +248,19 @@ func cleanReturnedObj(newObj, obj map[string]any) map[string]any { continue } switch newValue := newValueInterface.(type) { - case map[string]any: - if oldValue, ok := oldValueInterface.(map[string]any); ok { + case map[string]interface{}: + if oldValue, ok := oldValueInterface.(map[string]interface{}); ok { convertedMap := cleanReturnedObj(newValue, oldValue) mapToReturn[key] = convertedMap } - case []any: + case []interface{}: switch oldValue := oldValueInterface.(type) { - case map[string]any: + case map[string]interface{}: if len(newValue) == 0 { mapToReturn[key] = oldValue } - case []any: + case []interface{}: newArray := cleanReturnedArray(newValue, oldValue) mapToReturn[key] = newArray } @@ -304,17 +272,17 @@ func cleanReturnedObj(newObj, obj map[string]any) map[string]any { // cleanReturnedArray allows Argo CD to recurse into nested arrays when checking for unintentional empty struct to // empty array conversions. -func cleanReturnedArray(newObj, obj []any) []any { +func cleanReturnedArray(newObj, obj []interface{}) []interface{} { arrayToReturn := newObj for i := range newObj { switch newValue := newObj[i].(type) { - case map[string]any: - if oldValue, ok := obj[i].(map[string]any); ok { + case map[string]interface{}: + if oldValue, ok := obj[i].(map[string]interface{}); ok { convertedMap := cleanReturnedObj(newValue, oldValue) arrayToReturn[i] = convertedMap } - case []any: - if oldValue, ok := obj[i].([]any); ok { + case []interface{}: + if oldValue, ok := obj[i].([]interface{}); ok { convertedMap := cleanReturnedArray(newValue, oldValue) arrayToReturn[i] = convertedMap } @@ -325,7 +293,7 @@ func cleanReturnedArray(newObj, obj []any) []any { func (vm VM) ExecuteResourceActionDiscovery(obj *unstructured.Unstructured, scripts []string) ([]appv1.ResourceAction, error) { if len(scripts) == 0 { - return nil, errors.New("no action discovery script provided") + return nil, fmt.Errorf("no action discovery script provided") } availableActionsMap := make(map[string]appv1.ResourceAction) @@ -335,40 +303,41 @@ func (vm VM) ExecuteResourceActionDiscovery(obj *unstructured.Unstructured, scri return nil, err } returnValue := l.Get(-1) - if returnValue.Type() != lua.LTTable { - return nil, fmt.Errorf(incorrectReturnType, "table", returnValue.Type().String()) - } - jsonBytes, err := luajson.Encode(returnValue) - if err != nil { - return nil, fmt.Errorf("error in converting to lua table: %w", err) - } - if noAvailableActions(jsonBytes) { - continue - } - actionsMap := make(map[string]any) - err = json.Unmarshal(jsonBytes, &actionsMap) - if err != nil { - return nil, fmt.Errorf("error unmarshaling action table: %w", err) - } - for key, value := range actionsMap { - resourceAction := appv1.ResourceAction{Name: key, Disabled: isActionDisabled(value)} - if _, exist := availableActionsMap[key]; exist { - continue - } - if emptyResourceActionFromLua(value) { - availableActionsMap[key] = resourceAction - continue - } - resourceActionBytes, err := json.Marshal(value) + if returnValue.Type() == lua.LTTable { + jsonBytes, err := luajson.Encode(returnValue) if err != nil { - return nil, fmt.Errorf("error marshaling resource action: %w", err) + return nil, fmt.Errorf("error in converting to lua table: %w", err) } + if noAvailableActions(jsonBytes) { + continue + } + actionsMap := make(map[string]interface{}) + err = json.Unmarshal(jsonBytes, &actionsMap) + if err != nil { + return nil, fmt.Errorf("error unmarshaling action table: %w", err) + } + for key, value := range actionsMap { + resourceAction := appv1.ResourceAction{Name: key, Disabled: isActionDisabled(value)} + if _, exist := availableActionsMap[key]; exist { + continue + } + if emptyResourceActionFromLua(value) { + availableActionsMap[key] = resourceAction + continue + } + resourceActionBytes, err := json.Marshal(value) + if err != nil { + return nil, fmt.Errorf("error marshaling resource action: %w", err) + } - err = json.Unmarshal(resourceActionBytes, &resourceAction) - if err != nil { - return nil, fmt.Errorf("error unmarshaling resource action: %w", err) + err = json.Unmarshal(resourceActionBytes, &resourceAction) + if err != nil { + return nil, fmt.Errorf("error unmarshaling resource action: %w", err) + } + availableActionsMap[key] = resourceAction } - availableActionsMap[key] = resourceAction + } else { + return nil, fmt.Errorf(incorrectReturnType, "table", returnValue.Type().String()) } } @@ -381,13 +350,14 @@ func (vm VM) ExecuteResourceActionDiscovery(obj *unstructured.Unstructured, scri } // Actions are enabled by default -func isActionDisabled(actionsMap any) bool { - actions, ok := actionsMap.(map[string]any) +func isActionDisabled(actionsMap interface{}) bool { + actions, ok := actionsMap.(map[string]interface{}) if !ok { return false } for key, val := range actions { - if vv, ok := val.(bool); ok { + switch vv := val.(type) { + case bool: if key == "disabled" { return vv } @@ -396,8 +366,8 @@ func isActionDisabled(actionsMap any) bool { return false } -func emptyResourceActionFromLua(i any) bool { - _, ok := i.([]any) +func emptyResourceActionFromLua(i interface{}) bool { + _, ok := i.([]interface{}) return ok } @@ -418,17 +388,19 @@ func (vm VM) GetResourceActionDiscovery(obj *unstructured.Unstructured) ([]strin return nil, err } // Append the action discovery Lua script if built-in actions are to be included - if !actions.MergeBuiltinActions { + if actions.MergeBuiltinActions { + discoveryScripts = append(discoveryScripts, actions.ActionDiscoveryLua) + } else { return []string{actions.ActionDiscoveryLua}, nil } - discoveryScripts = append(discoveryScripts, actions.ActionDiscoveryLua) } // Fetch predefined Lua scripts - discoveryKey := key + "/actions/" + discoveryKey := fmt.Sprintf("%s/actions/", key) discoveryScript, err := vm.getPredefinedLuaScripts(discoveryKey, actionDiscoveryScriptFile) if err != nil { - if errors.Is(err, errScriptDoesNotExist) { + var doesNotExistErr *ScriptDoesNotExistError + if errors.As(err, &doesNotExistErr) { // No worries, just return what we have. return discoveryScripts, nil } @@ -482,7 +454,7 @@ func getWildcardHealthOverrideLua(overrides map[string]appv1.ResourceOverride, g gvkKeyToMatch := GetConfigMapKey(gvk) for key, override := range overrides { - if argoglob.Match(key, gvkKeyToMatch) && override.HealthLua != "" { + if glob.Match(key, gvkKeyToMatch) && override.HealthLua != "" { return override.HealthLua, override.UseOpenLibs } } @@ -493,95 +465,13 @@ func (vm VM) getPredefinedLuaScripts(objKey string, scriptFile string) (string, data, err := resource_customizations.Embedded.ReadFile(filepath.Join(objKey, scriptFile)) if err != nil { if os.IsNotExist(err) { - return "", errScriptDoesNotExist + return "", &ScriptDoesNotExistError{ScriptName: objKey} } return "", err } return string(data), nil } -// globHealthScriptPathsOnce is a sync.Once instance to ensure that the globHealthScriptPaths are only initialized once. -// The globs come from an embedded filesystem, so it won't change at runtime. -var globHealthScriptPathsOnce sync.Once - -// globHealthScriptPaths is a cache for the glob patterns of directories containing health.lua files. Don't use this -// directly, use getGlobHealthScriptPaths() instead. -var globHealthScriptPaths []string - -// getGlobHealthScriptPaths returns the paths of the directories containing health.lua files where the path contains a -// glob pattern. It uses a sync.Once to ensure that the paths are only initialized once. -func getGlobHealthScriptPaths() ([]string, error) { - var err error - globHealthScriptPathsOnce.Do(func() { - // Walk through the embedded filesystem and get the directory names of all directories containing a health.lua. - var patterns []string - err = fs.WalkDir(resource_customizations.Embedded, ".", func(path string, d fs.DirEntry, err error) error { - if err != nil { - return fmt.Errorf("error walking path %q: %w", path, err) - } - - // Skip non-directories at the top level - if d.IsDir() && filepath.Dir(path) == "." { - return nil - } - - // Check if the directory contains a health.lua file - if filepath.Base(path) != healthScriptFile { - return nil - } - - groupKindPath := filepath.Dir(path) - // Check if the path contains a wildcard. If it doesn't, skip it. - if !strings.Contains(groupKindPath, "_") { - return nil - } - - pattern := strings.ReplaceAll(groupKindPath, "_", "*") - // Check that the pattern is valid. - if !glob.ValidatePattern(pattern) { - return fmt.Errorf("invalid glob pattern %q: %w", pattern, err) - } - - patterns = append(patterns, groupKindPath) - return nil - }) - if err != nil { - return - } - - // Sort the patterns to ensure deterministic choice of wildcard directory for a given GK. - slices.Sort(patterns) - - globHealthScriptPaths = patterns - }) - if err != nil { - return nil, fmt.Errorf("error getting health script glob directories: %w", err) - } - return globHealthScriptPaths, nil -} - -func getWildcardBuiltInHealthOverrideLua(objKey string) (string, error) { - // Check if the GVK matches any of the wildcard directories - globs, err := getGlobHealthScriptPaths() - if err != nil { - return "", fmt.Errorf("error getting health script globs: %w", err) - } - for _, g := range globs { - pattern := strings.ReplaceAll(g, "_", "*") - if !glob.PathMatchUnvalidated(pattern, objKey) { - continue - } - - var script []byte - script, err = resource_customizations.Embedded.ReadFile(filepath.Join(g, healthScriptFile)) - if err != nil { - return "", fmt.Errorf("error reading %q file in embedded filesystem: %w", filepath.Join(objKey, healthScriptFile), err) - } - return string(script), nil - } - return "", nil -} - func isValidHealthStatusCode(statusCode health.HealthStatusCode) bool { switch statusCode { case health.HealthStatusUnknown, health.HealthStatusProgressing, health.HealthStatusSuspended, health.HealthStatusHealthy, health.HealthStatusDegraded, health.HealthStatusMissing: @@ -593,7 +483,7 @@ func isValidHealthStatusCode(statusCode health.HealthStatusCode) bool { // Took logic from the link below and added the int, int32, and int64 types since the value would have type int64 // while actually running in the controller and it was not reproducible through testing. // https://github.com/layeh/gopher-json/blob/97fed8db84274c421dbfffbb28ec859901556b97/json.go#L154 -func decodeValue(l *lua.LState, value any) lua.LValue { +func decodeValue(l *lua.LState, value interface{}) lua.LValue { switch converted := value.(type) { case bool: return lua.LBool(converted) @@ -609,13 +499,13 @@ func decodeValue(l *lua.LState, value any) lua.LValue { return lua.LNumber(converted) case int64: return lua.LNumber(converted) - case []any: + case []interface{}: arr := l.CreateTable(len(converted), 0) for _, item := range converted { arr.Append(decodeValue(l, item)) } return arr - case map[string]any: + case map[string]interface{}: tbl := l.CreateTable(0, len(converted)) for key, item := range converted { tbl.RawSetH(lua.LString(key), decodeValue(l, item)) diff --git a/util/lua/lua_test.go b/util/lua/lua_test.go index 9274d279d8..7adc833ab8 100644 --- a/util/lua/lua_test.go +++ b/util/lua/lua_test.go @@ -12,9 +12,8 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/yaml" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/grpc" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/grpc" ) const objJSON = ` @@ -39,7 +38,7 @@ metadata: resourceVersion: "123" ` -const ec2AWSCrossplaneObjJSON = ` +const ec2AWSCrossplaneObjJson = ` apiVersion: ec2.aws.crossplane.io/v1alpha1 kind: Instance metadata: @@ -70,7 +69,7 @@ end return a` func StrToUnstructured(jsonStr string) *unstructured.Unstructured { - obj := make(map[string]any) + obj := make(map[string]interface{}) err := yaml.Unmarshal([]byte(jsonStr), &obj) if err != nil { panic(err) @@ -91,7 +90,7 @@ func TestExecuteNewHealthStatusFunction(t *testing.T) { } func TestExecuteWildcardHealthStatusFunction(t *testing.T) { - testObj := StrToUnstructured(ec2AWSCrossplaneObjJSON) + testObj := StrToUnstructured(ec2AWSCrossplaneObjJson) vm := VM{} status, err := vm.ExecuteHealthLua(testObj, newWildcardHealthStatusFunction) require.NoError(t, err) @@ -108,7 +107,7 @@ func TestFailExternalLibCall(t *testing.T) { testObj := StrToUnstructured(objJSON) vm := VM{} _, err := vm.ExecuteHealthLua(testObj, osLuaScript) - require.Error(t, err) + require.Error(t, err, "") assert.IsType(t, &lua.ApiError{}, err) } @@ -237,7 +236,7 @@ func TestGetHealthScriptWithGroupWildcardOverride(t *testing.T) { } func TestGetHealthScriptWithGroupAndKindWildcardOverride(t *testing.T) { - testObj := StrToUnstructured(ec2AWSCrossplaneObjJSON) + testObj := StrToUnstructured(ec2AWSCrossplaneObjJson) vm := VM{ ResourceOverrides: map[string]appv1.ResourceOverride{ "*.aws.crossplane.io/*": { @@ -268,7 +267,7 @@ func TestGetHealthScriptNoPredefined(t *testing.T) { script, useOpenLibs, err := vm.GetHealthScript(testObj) require.NoError(t, err) assert.False(t, useOpenLibs) - assert.Empty(t, script) + assert.Equal(t, "", script) } func TestGetResourceActionPredefined(t *testing.T) { @@ -284,7 +283,8 @@ func TestGetResourceActionNoPredefined(t *testing.T) { testObj := StrToUnstructured(objWithNoScriptJSON) vm := VM{} action, err := vm.GetResourceAction(testObj, "test") - require.ErrorIs(t, err, errScriptDoesNotExist) + var expectedErr *ScriptDoesNotExistError + require.ErrorAs(t, err, &expectedErr) assert.Empty(t, action.ActionLua) } @@ -477,7 +477,7 @@ func TestExecuteOldStyleResourceAction(t *testing.T) { testObj := StrToUnstructured(objJSON) expectedLuaUpdatedObj := StrToUnstructured(expectedLuaUpdatedResult) vm := VM{} - newObjects, err := vm.ExecuteResourceAction(testObj, validActionLua, nil) + newObjects, err := vm.ExecuteResourceAction(testObj, validActionLua) require.NoError(t, err) assert.Len(t, newObjects, 1) assert.Equal(t, newObjects[0].K8SOperation, K8SOperation("patch")) @@ -516,7 +516,7 @@ const expectedCreatedMultipleJobsObjList = ` kind: Job metadata: name: hello-2 - namespace: test-ns + namespace: test-ns ` const expectedActionMixedOperationObjList = ` @@ -533,9 +533,9 @@ const expectedActionMixedOperationObjList = ` kind: CronJob metadata: name: hello - namespace: test-ns + namespace: test-ns labels: - test: test + test: test ` const createJobActionLua = ` @@ -650,7 +650,7 @@ func TestExecuteNewStyleCreateActionSingleResource(t *testing.T) { expectedObjects, err := UnmarshalToImpactedResources(bytes.NewBuffer(jsonBytes).String()) require.NoError(t, err) vm := VM{} - newObjects, err := vm.ExecuteResourceAction(testObj, createJobActionLua, nil) + newObjects, err := vm.ExecuteResourceAction(testObj, createJobActionLua) require.NoError(t, err) assert.Equal(t, expectedObjects, newObjects) } @@ -663,7 +663,7 @@ func TestExecuteNewStyleCreateActionMultipleResources(t *testing.T) { expectedObjects, err := UnmarshalToImpactedResources(bytes.NewBuffer(jsonBytes).String()) require.NoError(t, err) vm := VM{} - newObjects, err := vm.ExecuteResourceAction(testObj, createMultipleJobsActionLua, nil) + newObjects, err := vm.ExecuteResourceAction(testObj, createMultipleJobsActionLua) require.NoError(t, err) assert.Equal(t, expectedObjects, newObjects) } @@ -676,7 +676,7 @@ func TestExecuteNewStyleActionMixedOperationsOk(t *testing.T) { expectedObjects, err := UnmarshalToImpactedResources(bytes.NewBuffer(jsonBytes).String()) require.NoError(t, err) vm := VM{} - newObjects, err := vm.ExecuteResourceAction(testObj, mixedOperationActionLuaOk, nil) + newObjects, err := vm.ExecuteResourceAction(testObj, mixedOperationActionLuaOk) require.NoError(t, err) assert.Equal(t, expectedObjects, newObjects) } @@ -684,14 +684,14 @@ func TestExecuteNewStyleActionMixedOperationsOk(t *testing.T) { func TestExecuteNewStyleActionMixedOperationsFailure(t *testing.T) { testObj := StrToUnstructured(cronJobObjYaml) vm := VM{} - _, err := vm.ExecuteResourceAction(testObj, createMixedOperationActionLuaFailing, nil) + _, err := vm.ExecuteResourceAction(testObj, createMixedOperationActionLuaFailing) assert.ErrorContains(t, err, "unsupported operation") } func TestExecuteResourceActionNonTableReturn(t *testing.T) { testObj := StrToUnstructured(objJSON) vm := VM{} - _, err := vm.ExecuteResourceAction(testObj, returnInt, nil) + _, err := vm.ExecuteResourceAction(testObj, returnInt) assert.Errorf(t, err, incorrectReturnType, "table", "number") } @@ -703,7 +703,7 @@ return newObj func TestExecuteResourceActionInvalidUnstructured(t *testing.T) { testObj := StrToUnstructured(objJSON) vm := VM{} - _, err := vm.ExecuteResourceAction(testObj, invalidTableReturn, nil) + _, err := vm.ExecuteResourceAction(testObj, invalidTableReturn) require.Error(t, err) } @@ -758,7 +758,7 @@ func TestCleanPatch(t *testing.T) { testObj := StrToUnstructured(objWithEmptyStruct) expectedObj := StrToUnstructured(expectedUpdatedObjWithEmptyStruct) vm := VM{} - newObjects, err := vm.ExecuteResourceAction(testObj, pausedToFalseLua, nil) + newObjects, err := vm.ExecuteResourceAction(testObj, pausedToFalseLua) require.NoError(t, err) assert.Len(t, newObjects, 1) assert.Equal(t, newObjects[0].K8SOperation, K8SOperation("patch")) @@ -841,13 +841,13 @@ return hs` overrides := getHealthOverride(false) status, err := overrides.GetResourceHealth(testObj) assert.IsType(t, &lua.ApiError{}, err) - expectedErr := ":4: attempt to index a non-table object(nil) with key 'find'" + expectedErr := ":4: attempt to index a non-table object(nil) with key 'find'\nstack traceback:\n\t:4: in main chunk\n\t[G]: ?" require.EqualError(t, err, expectedErr) assert.Nil(t, status) }) t.Run("Get resource health for wildcard override", func(t *testing.T) { - testObj := StrToUnstructured(ec2AWSCrossplaneObjJSON) + testObj := StrToUnstructured(ec2AWSCrossplaneObjJson) overrides := getWildcardHealthOverride status, err := overrides.GetResourceHealth(testObj) require.NoError(t, err) @@ -858,7 +858,7 @@ return hs` }) t.Run("Get resource health for wildcard override with non-empty health.lua", func(t *testing.T) { - testObj := StrToUnstructured(ec2AWSCrossplaneObjJSON) + testObj := StrToUnstructured(ec2AWSCrossplaneObjJson) overrides := getMultipleWildcardHealthOverrides status, err := overrides.GetResourceHealth(testObj) require.NoError(t, err) @@ -867,7 +867,7 @@ return hs` }) t.Run("Get resource health for */* override with empty health.lua", func(t *testing.T) { - testObj := StrToUnstructured(objWithNoScriptJSON) + testObj := StrToUnstructured(ec2AWSCrossplaneObjJson) overrides := getBaseWildcardHealthOverrides status, err := overrides.GetResourceHealth(testObj) require.NoError(t, err) @@ -882,83 +882,3 @@ return hs` assert.Nil(t, status) }) } - -func TestExecuteResourceActionWithParams(t *testing.T) { - deploymentObj := createMockResource("Deployment", "test-deployment", 1) - statefulSetObj := createMockResource("StatefulSet", "test-statefulset", 1) - - actionLua := ` - obj.spec.replicas = tonumber(actionParams["replicas"]) - return obj - ` - - params := []*applicationpkg.ResourceActionParameters{ - { - Name: func() *string { s := "replicas"; return &s }(), - Value: func() *string { s := "3"; return &s }(), - }, - } - - vm := VM{} - - // Test with Deployment - t.Run("Test with Deployment", func(t *testing.T) { - impactedResources, err := vm.ExecuteResourceAction(deploymentObj, actionLua, params) - require.NoError(t, err) - - for _, impactedResource := range impactedResources { - modifiedObj := impactedResource.UnstructuredObj - - // Check the replicas in the modified object - actualReplicas, found, err := unstructured.NestedInt64(modifiedObj.Object, "spec", "replicas") - require.NoError(t, err) - assert.True(t, found, "spec.replicas should be found in the modified object") - assert.Equal(t, int64(3), actualReplicas, "replicas should be updated to 3") - } - }) - - // Test with StatefulSet - t.Run("Test with StatefulSet", func(t *testing.T) { - impactedResources, err := vm.ExecuteResourceAction(statefulSetObj, actionLua, params) - require.NoError(t, err) - - for _, impactedResource := range impactedResources { - modifiedObj := impactedResource.UnstructuredObj - - // Check the replicas in the modified object - actualReplicas, found, err := unstructured.NestedInt64(modifiedObj.Object, "spec", "replicas") - require.NoError(t, err) - assert.True(t, found, "spec.replicas should be found in the modified object") - assert.Equal(t, int64(3), actualReplicas, "replicas should be updated to 3") - } - }) -} - -func createMockResource(kind string, name string, replicas int) *unstructured.Unstructured { - return StrToUnstructured(fmt.Sprintf(` - apiVersion: apps/v1 - kind: %s - metadata: - name: %s - namespace: default - spec: - replicas: %d - template: - metadata: - labels: - app: test - spec: - containers: - - name: test-container - image: nginx - `, kind, name, replicas)) -} - -func Test_getHealthScriptPaths(t *testing.T) { - paths, err := getGlobHealthScriptPaths() - require.NoError(t, err) - - // This test will fail any time a glob pattern is added to the health script paths. We don't expect that to happen - // often. - assert.Equal(t, []string{"_.crossplane.io/_", "_.upbound.io/_"}, paths) -} diff --git a/util/lua/oslib_safe.go b/util/lua/oslib_safe.go index 1e9b141800..2d5a94e946 100644 --- a/util/lua/oslib_safe.go +++ b/util/lua/oslib_safe.go @@ -162,21 +162,22 @@ func (fs *flagScanner) Next() (byte, bool) { fs.AppendString(fs.end) } return c, true - } - c = fs.str[fs.Pos] - if c == fs.flag { - if fs.Pos < (fs.Length-1) && fs.str[fs.Pos+1] == fs.flag { - fs.HasFlag = false - fs.AppendChar(fs.flag) - fs.Pos += 2 - return fs.Next() - } else if fs.Pos != fs.Length-1 { - if fs.HasFlag { - fs.AppendString(fs.end) + } else { + c = fs.str[fs.Pos] + if c == fs.flag { + if fs.Pos < (fs.Length-1) && fs.str[fs.Pos+1] == fs.flag { + fs.HasFlag = false + fs.AppendChar(fs.flag) + fs.Pos += 2 + return fs.Next() + } else if fs.Pos != fs.Length-1 { + if fs.HasFlag { + fs.AppendString(fs.end) + } + fs.AppendString(fs.start) + fs.ChangeFlag = true + fs.HasFlag = true } - fs.AppendString(fs.start) - fs.ChangeFlag = true - fs.HasFlag = true } } fs.Pos++ diff --git a/util/manifeststream/stream.go b/util/manifeststream/stream.go index fc1c2503b7..dd02f2570d 100644 --- a/util/manifeststream/stream.go +++ b/util/manifeststream/stream.go @@ -12,10 +12,10 @@ import ( log "github.com/sirupsen/logrus" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/io/files" - "github.com/argoproj/argo-cd/v3/util/tgzstream" + applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/io/files" + "github.com/argoproj/argo-cd/v2/util/tgzstream" ) // Defines the contract for the application sender, i.e. the CLI @@ -45,7 +45,7 @@ func SendApplicationManifestQueryWithFiles(ctx context.Context, stream Applicati return fmt.Errorf("failed to compress files: %w", err) } if filesWritten == 0 { - return errors.New("no files to send") + return fmt.Errorf("no files to send") } err = stream.Send(&applicationpkg.ApplicationManifestQueryWithFilesWrapper{ @@ -107,7 +107,7 @@ func ReceiveApplicationManifestQueryWithFiles(stream ApplicationStreamReceiver) return nil, fmt.Errorf("failed to receive header: %w", err) } if header == nil || header.GetQuery() == nil { - return nil, errors.New("error getting stream query: query is nil") + return nil, fmt.Errorf("error getting stream query: query is nil") } return header.GetQuery(), nil } @@ -142,7 +142,7 @@ func SendRepoStream(repoStream RepoStreamSender, appStream ApplicationStreamRece return fmt.Errorf("stream Recv error: %w", err) } if part == nil || part.GetChunk() == nil { - return errors.New("error getting stream chunk: chunk is nil") + return fmt.Errorf("error getting stream chunk: chunk is nil") } err = repoStream.Send(&apiclient.ManifestRequestWithFiles{ @@ -166,7 +166,7 @@ func ReceiveManifestFileStream(ctx context.Context, receiver RepoStreamReceiver, return nil, nil, fmt.Errorf("failed to receive header: %w", err) } if header == nil || header.GetRequest() == nil { - return nil, nil, errors.New("error getting stream request: request is nil") + return nil, nil, fmt.Errorf("error getting stream request: request is nil") } request := header.GetRequest() @@ -175,7 +175,7 @@ func ReceiveManifestFileStream(ctx context.Context, receiver RepoStreamReceiver, return nil, nil, fmt.Errorf("failed to receive header: %w", err) } if header2 == nil || header2.GetMetadata() == nil { - return nil, nil, errors.New("error getting stream metadata: metadata is nil") + return nil, nil, fmt.Errorf("error getting stream metadata: metadata is nil") } metadata := header2.GetMetadata() @@ -223,7 +223,7 @@ func receiveFile(ctx context.Context, receiver RepoStreamReceiver, checksum stri } c := req.GetChunk() if c == nil { - return nil, errors.New("stream request chunk is nil") + return nil, fmt.Errorf("stream request chunk is nil") } size += len(c.Chunk) if size > int(maxSize) { diff --git a/util/manifeststream/stream_test.go b/util/manifeststream/stream_test.go index 207a82a061..cbb32ed5e9 100644 --- a/util/manifeststream/stream_test.go +++ b/util/manifeststream/stream_test.go @@ -1,7 +1,8 @@ package manifeststream_test import ( - "errors" + "context" + "fmt" "io" "math" "os" @@ -12,11 +13,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/io/files" - "github.com/argoproj/argo-cd/v3/util/manifeststream" + applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/io/files" + "github.com/argoproj/argo-cd/v2/util/manifeststream" ) type applicationStreamMock struct { @@ -31,7 +32,7 @@ func (m *applicationStreamMock) Recv() (*applicationpkg.ApplicationManifestQuery case <-m.done: return nil, io.EOF case <-time.After(500 * time.Millisecond): - return nil, errors.New("timeout receiving message mock") + return nil, fmt.Errorf("timeout receiving message mock") } } @@ -61,7 +62,7 @@ func (m *repoStreamMock) Recv() (*apiclient.ManifestRequestWithFiles, error) { case <-m.done: return nil, io.EOF case <-time.After(500 * time.Millisecond): - return nil, errors.New("timeout receiving message mock") + return nil, fmt.Errorf("timeout receiving message mock") } } @@ -88,7 +89,7 @@ func TestManifestStream(t *testing.T) { appDir := filepath.Join(getTestDataDir(t), "app") go func() { - err := manifeststream.SendApplicationManifestQueryWithFiles(t.Context(), appStreamMock, "test", "test", appDir, nil) + err := manifeststream.SendApplicationManifestQueryWithFiles(context.Background(), appStreamMock, "test", "test", appDir, nil) assert.NoError(t, err) appStreamMock.done <- true }() @@ -105,7 +106,7 @@ func TestManifestStream(t *testing.T) { repoStreamMock.done <- true }() - req2, meta, err := manifeststream.ReceiveManifestFileStream(t.Context(), repoStreamMock, workdir, math.MaxInt64, math.MaxInt64) + req2, meta, err := manifeststream.ReceiveManifestFileStream(context.Background(), repoStreamMock, workdir, math.MaxInt64, math.MaxInt64) require.NoError(t, err) require.NotNil(t, req2) require.NotNil(t, meta) diff --git a/util/metrics/kubectl/kubectl_metrics.go b/util/metrics/kubectl/kubectl_metrics.go deleted file mode 100644 index 0112b650da..0000000000 --- a/util/metrics/kubectl/kubectl_metrics.go +++ /dev/null @@ -1,297 +0,0 @@ -package kubectl - -import ( - "context" - "net/url" - "strconv" - "time" - - "github.com/prometheus/client_golang/prometheus" - "k8s.io/client-go/tools/metrics" -) - -// The label names are meant to match this: https://github.com/kubernetes/component-base/blob/264c1fd30132a3b36b7588e50ac54eb0ff75f26a/metrics/prometheus/restclient/metrics.go -// Even in cases where the label name doesn't align well with Argo CD's other labels, we use the Kubernetes labels to -// make it easier to copy/paste dashboards/alerts/etc. designed for Kubernetes. -const ( - // LabelCallStatus represents the status of the exec plugin call, indicating whether it was successful or failed. - // These are the possible values, as of the current client-go version: - // no_error, plugin_execution_error, plugin_not_found_error, client_internal_error - LabelCallStatus = "call_status" - // LabelCode represents either the HTTP status code returned by the request or the exit code of the command run. - LabelCode = "code" - // LabelHost represents the hostname of the server to which the request was made. - LabelHost = "host" - // LabelMethod represents the HTTP method used for the request (e.g., GET, POST). - LabelMethod = "method" - // LabelResult represents an attempt to get a transport from the transport cache. - // These are the possible values, as of the current client-go version: hit, miss, unreachable - // `unreachable` indicates that the cache was not usable for a given REST config because, for example, TLS files - // couldn't be loaded, or a proxy is being used. - LabelResult = "result" - // LabelVerb represents the Kubernetes API verb used in the request (e.g., list, get, create). - LabelVerb = "verb" -) - -// All metric names below match https://github.com/kubernetes/component-base/blob/264c1fd30132a3b36b7588e50ac54eb0ff75f26a/metrics/prometheus/restclient/metrics.go -// except rest_client_ is replaced with argocd_kubectl_. -// -// We use similar histogram bucket ranges, but reduce cardinality. -// -// We try to use similar labels, but we adjust to more closely match other Argo CD metrics. -// -// The idea is that if we stay close to the Kubernetes metrics, then people can take more advantage of copy/pasting -// dashboards/alerts/etc. designed for Kubernetes. -var ( - clientCertRotationAgeGauge = prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Name: "argocd_kubectl_client_cert_rotation_age_seconds", - Help: "Age of a certificate that has just been rotated", - }, []string{}) - - requestLatencyHistogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{ - Name: "argocd_kubectl_request_duration_seconds", - Help: "Request latency in seconds", - Buckets: []float64{0.005, 0.1, 0.5, 2.0, 8.0, 30.0}, - }, []string{LabelHost, LabelVerb}) - - resolverLatencyHistogram = prometheus.NewHistogramVec( - prometheus.HistogramOpts{ - Name: "argocd_kubectl_dns_resolution_duration_seconds", - Help: "Kubectl resolver latency", - Buckets: []float64{0.005, 0.1, 0.5, 2.0, 8.0, 30.0}, - }, - []string{LabelHost}, - ) - - requestSizeHistogram = prometheus.NewHistogramVec( - prometheus.HistogramOpts{ - Name: "argocd_kubectl_request_size_bytes", - Help: "Size of kubectl requests", - // 64 bytes to 16MB - Buckets: []float64{64, 512, 4096, 65536, 1048576, 16777216}, - }, - []string{LabelHost, LabelMethod}, - ) - - responseSizeHistogram = prometheus.NewHistogramVec( - prometheus.HistogramOpts{ - Name: "argocd_kubectl_response_size_bytes", - Help: "Size of kubectl responses", - // 64 bytes to 16MB - Buckets: []float64{64, 512, 4096, 65536, 1048576, 16777216}, - }, - []string{LabelHost, LabelMethod}, - ) - - rateLimiterLatencyHistogram = prometheus.NewHistogramVec( - prometheus.HistogramOpts{ - Name: "argocd_kubectl_rate_limiter_duration_seconds", - Help: "Kubectl rate limiter latency", - Buckets: []float64{0.005, 0.1, 0.5, 2.0, 8.0, 30.0}, - }, - []string{LabelHost, LabelVerb}, - ) - - requestResultCounter = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "argocd_kubectl_requests_total", - Help: "Number of kubectl request results", - }, - []string{LabelHost, LabelMethod, LabelCode}, - ) - - execPluginCallsCounter = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "argocd_kubectl_exec_plugin_call_total", - Help: "Number of kubectl exec plugin calls", - }, - []string{LabelCode, LabelCallStatus}, - ) - - requestRetryCounter = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "argocd_kubectl_request_retries_total", - Help: "Number of kubectl request retries", - }, - []string{LabelHost, LabelMethod, LabelCode}, - ) - - transportCacheEntriesGauge = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "argocd_kubectl_transport_cache_entries", - Help: "Number of kubectl transport cache entries", - }, - []string{}, - ) - - transportCreateCallsCounter = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "argocd_kubectl_transport_create_calls_total", - Help: "Number of kubectl transport create calls", - }, - []string{LabelResult}, - ) -) - -// RegisterWithPrometheus registers the kubectl metrics with the given prometheus registry. -func RegisterWithPrometheus(registry prometheus.Registerer) { - registry.MustRegister(clientCertRotationAgeGauge) - registry.MustRegister(requestLatencyHistogram) - registry.MustRegister(resolverLatencyHistogram) - registry.MustRegister(requestSizeHistogram) - registry.MustRegister(responseSizeHistogram) - registry.MustRegister(rateLimiterLatencyHistogram) - registry.MustRegister(requestResultCounter) - registry.MustRegister(execPluginCallsCounter) - registry.MustRegister(requestRetryCounter) - registry.MustRegister(transportCacheEntriesGauge) - registry.MustRegister(transportCreateCallsCounter) -} - -// ResetAll resets all kubectl metrics -func ResetAll() { - clientCertRotationAgeGauge.Reset() - requestLatencyHistogram.Reset() - resolverLatencyHistogram.Reset() - requestSizeHistogram.Reset() - responseSizeHistogram.Reset() - rateLimiterLatencyHistogram.Reset() - requestResultCounter.Reset() - execPluginCallsCounter.Reset() - requestRetryCounter.Reset() - transportCacheEntriesGauge.Reset() - transportCreateCallsCounter.Reset() -} - -type KubectlMetrics struct { - clientCertRotationAgeMetric kubectlClientCertRotationAgeMetric - requestLatencyMetric kubectlRequestLatencyMetric - resolverLatencyMetric kubectlResolverLatencyMetric - requestSizeMetric kubectlRequestSizeMetric - responseSizeMetric kubectlResponseSizeMetric - rateLimiterLatencyMetric kubectlRateLimiterLatencyMetric - requestResultMetric kubectlRequestResultMetric - execPluginCallsMetric kubectlExecPluginCallsMetric - requestRetryMetric kubectlRequestRetryMetric - transportCacheEntriesMetric kubectlTransportCacheEntriesMetric - transportCreateCallsMetric kubectlTransportCreateCallsMetric -} - -// NewKubectlMetrics returns a new KubectlMetrics instance with the given initiator, which should be the name of the -// Argo CD component that is producing the metrics. -// -// After initializing the KubectlMetrics instance, you must call RegisterWithClientGo to register the metrics with the -// client-go metrics library. -// -// You must also call RegisterWithPrometheus to register the metrics with the metrics server's prometheus registry. -// -// So these three lines should be enough to set up kubectl metrics in your metrics server: -// -// kubectlMetricsServer := metricsutil.NewKubectlMetrics("your-component-name") -// kubectlMetricsServer.RegisterWithClientGo() -// metricsutil.RegisterWithPrometheus(registry) -// -// Once those functions have been called, everything else should happen automatically. client-go will send observations -// to the handlers in this struct, and your metrics server will collect and expose the metrics. -func NewKubectlMetrics() *KubectlMetrics { - return &KubectlMetrics{ - clientCertRotationAgeMetric: kubectlClientCertRotationAgeMetric{}, - requestLatencyMetric: kubectlRequestLatencyMetric{}, - resolverLatencyMetric: kubectlResolverLatencyMetric{}, - requestSizeMetric: kubectlRequestSizeMetric{}, - responseSizeMetric: kubectlResponseSizeMetric{}, - rateLimiterLatencyMetric: kubectlRateLimiterLatencyMetric{}, - requestResultMetric: kubectlRequestResultMetric{}, - execPluginCallsMetric: kubectlExecPluginCallsMetric{}, - requestRetryMetric: kubectlRequestRetryMetric{}, - transportCacheEntriesMetric: kubectlTransportCacheEntriesMetric{}, - transportCreateCallsMetric: kubectlTransportCreateCallsMetric{}, - } -} - -// RegisterWithClientGo sets the metrics handlers for the go-client library. We do not use the metrics library's `RegisterWithClientGo` method, -// because it is protected by a sync.Once. controller-runtime registers a single handler, which blocks our registration -// of our own handlers. So we must rudely set them all directly. -// -// Since the metrics are global, this function should only be called once for a given Argo CD component. -func (k *KubectlMetrics) RegisterWithClientGo() { - metrics.ClientCertRotationAge = &k.clientCertRotationAgeMetric - metrics.RequestLatency = &k.requestLatencyMetric - metrics.ResolverLatency = &k.resolverLatencyMetric - metrics.RequestSize = &k.requestSizeMetric - metrics.ResponseSize = &k.responseSizeMetric - metrics.RateLimiterLatency = &k.rateLimiterLatencyMetric - metrics.RequestResult = &k.requestResultMetric - metrics.ExecPluginCalls = &k.execPluginCallsMetric - metrics.RequestRetry = &k.requestRetryMetric - metrics.TransportCacheEntries = &k.transportCacheEntriesMetric - metrics.TransportCreateCalls = &k.transportCreateCallsMetric -} - -type kubectlClientCertRotationAgeMetric struct{} - -func (k *kubectlClientCertRotationAgeMetric) Observe(certDuration time.Duration) { - clientCertRotationAgeGauge.WithLabelValues().Set(certDuration.Seconds()) -} - -type kubectlRequestLatencyMetric struct{} - -func (k *kubectlRequestLatencyMetric) Observe(_ context.Context, verb string, u url.URL, latency time.Duration) { - k8sVerb := resolveK8sRequestVerb(u, verb) - requestLatencyHistogram.WithLabelValues(u.Host, k8sVerb).Observe(latency.Seconds()) -} - -type kubectlResolverLatencyMetric struct{} - -func (k *kubectlResolverLatencyMetric) Observe(_ context.Context, host string, latency time.Duration) { - resolverLatencyHistogram.WithLabelValues(host).Observe(latency.Seconds()) -} - -type kubectlRequestSizeMetric struct{} - -func (k *kubectlRequestSizeMetric) Observe(_ context.Context, verb string, host string, size float64) { - requestSizeHistogram.WithLabelValues(host, verb).Observe(size) -} - -type kubectlResponseSizeMetric struct{} - -func (k *kubectlResponseSizeMetric) Observe(_ context.Context, verb string, host string, size float64) { - responseSizeHistogram.WithLabelValues(host, verb).Observe(size) -} - -type kubectlRateLimiterLatencyMetric struct{} - -func (k *kubectlRateLimiterLatencyMetric) Observe(_ context.Context, verb string, u url.URL, latency time.Duration) { - k8sVerb := resolveK8sRequestVerb(u, verb) - rateLimiterLatencyHistogram.WithLabelValues(u.Host, k8sVerb).Observe(latency.Seconds()) -} - -type kubectlRequestResultMetric struct{} - -func (k *kubectlRequestResultMetric) Increment(_ context.Context, code string, method string, host string) { - requestResultCounter.WithLabelValues(host, method, code).Inc() -} - -type kubectlExecPluginCallsMetric struct{} - -func (k *kubectlExecPluginCallsMetric) Increment(exitCode int, callStatus string) { - execPluginCallsCounter.WithLabelValues(strconv.Itoa(exitCode), callStatus).Inc() -} - -type kubectlRequestRetryMetric struct{} - -func (k *kubectlRequestRetryMetric) IncrementRetry(_ context.Context, code string, method string, host string) { - requestRetryCounter.WithLabelValues(host, method, code).Inc() -} - -type kubectlTransportCacheEntriesMetric struct{} - -func (k *kubectlTransportCacheEntriesMetric) Observe(value int) { - transportCacheEntriesGauge.WithLabelValues().Set(float64(value)) -} - -type kubectlTransportCreateCallsMetric struct{} - -func (k *kubectlTransportCreateCallsMetric) Increment(result string) { - transportCreateCallsCounter.WithLabelValues(result).Inc() -} diff --git a/util/metrics/kubectl/util.go b/util/metrics/kubectl/util.go deleted file mode 100644 index 9aa1f82264..0000000000 --- a/util/metrics/kubectl/util.go +++ /dev/null @@ -1,57 +0,0 @@ -package kubectl - -import ( - "net/url" - "regexp" -) - -// The functions here are adapted from: https://github.com/argoproj/pkg/blob/f5a0a066030558f089fa645dc6546ddc5917bad5/kubeclientmetrics/metric.go - -const findPathRegex = `/v\d\w*?(/[a-zA-Z0-9-]*)(/[a-zA-Z0-9-]*)?(/[a-zA-Z0-9-]*)?(/[a-zA-Z0-9-]*)?` - -var processPath = regexp.MustCompile(findPathRegex) - -// discernGetRequest uses a path from a request to determine if the request is a GET, LIST, or WATCH. -// The function tries to find an API version within the path and then calculates how many remaining -// segments are after the API version. A LIST/WATCH request has segments for the kind with a -// namespace and the specific namespace if the kind is a namespaced resource. Meanwhile a GET -// request has an additional segment for resource name. As a result, a LIST/WATCH has an odd number -// of segments while a GET request has an even number of segments. Watch is determined if the query -// parameter watch=true is present in the request. -func discernGetRequest(u url.URL) string { - segments := processPath.FindStringSubmatch(u.Path) - unusedGroup := 0 - for _, str := range segments { - if str == "" { - unusedGroup++ - } - } - if unusedGroup%2 == 1 { - if watchQueryParamValues, ok := u.Query()["watch"]; ok { - if len(watchQueryParamValues) > 0 && watchQueryParamValues[0] == "true" { - return "Watch" - } - } - return "List" - } - return "Get" -} - -func resolveK8sRequestVerb(u url.URL, method string) string { - if method == "POST" { - return "Create" - } - if method == "DELETE" { - return "Delete" - } - if method == "PATCH" { - return "Patch" - } - if method == "PUT" { - return "Update" - } - if method == "GET" { - return discernGetRequest(u) - } - return "Unknown" -} diff --git a/util/metrics/kubectl/util_test.go b/util/metrics/kubectl/util_test.go deleted file mode 100644 index d0d8fabb98..0000000000 --- a/util/metrics/kubectl/util_test.go +++ /dev/null @@ -1,167 +0,0 @@ -package kubectl - -import ( - "net/url" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -// Test_resolveK8sRequestVerb is adapted from: https://github.com/argoproj/pkg/blob/f5a0a066030558f089fa645dc6546ddc5917bad5/kubeclientmetrics/metric_test.go -func Test_resolveK8sRequestVerb(t *testing.T) { - testData := []struct { - testName string - method string - url string - expected string - }{ - { - testName: "Pod LIST", - method: "GET", - url: "https://127.0.0.1/api/v1/namespaces/default/pods", - expected: "List", - }, - { - testName: "Pod Cluster LIST", - method: "GET", - url: "https://127.0.0.1/api/v1/pods", - expected: "List", - }, - { - testName: "Pod GET", - method: "GET", - url: "https://127.0.0.1/api/v1/namespaces/default/pods/pod-name-123456", - expected: "Get", - }, - { - testName: "Namespace LIST", - method: "GET", - url: "https://127.0.0.1/api/v1/namespaces", - expected: "List", - }, - { - testName: "Namespace GET", - method: "GET", - url: "https://127.0.0.1/api/v1/namespaces/default", - expected: "Get", - }, - { - testName: "ReplicaSet LIST", - method: "GET", - url: "https://127.0.0.1/apis/extensions/v1beta1/namespaces/default/replicasets", - expected: "List", - }, - { - testName: "ReplicaSet Cluster LIST", - method: "GET", - url: "https://127.0.0.1/apis/apps/v1/replicasets", - expected: "List", - }, - { - testName: "ReplicaSet GET", - method: "GET", - url: "https://127.0.0.1/apis/extensions/v1beta1/namespaces/default/replicasets/rs-abc123", - expected: "Get", - }, - { - testName: "VirtualService LIST", - method: "GET", - url: "https://127.0.0.1/apis/networking.istio.io/v1alpha3/namespaces/default/virtualservices", - expected: "List", - }, - { - testName: "VirtualService GET", - method: "GET", - url: "https://127.0.0.1/apis/networking.istio.io/v1alpha3/namespaces/default/virtualservices/virtual-service", - expected: "Get", - }, - { - testName: "ClusterRole LIST", - method: "GET", - url: "https://127.0.0.1/apis/rbac.authorization.k8s.io/v1/clusterroles", - expected: "List", - }, - { - testName: "ClusterRole Get", - method: "GET", - url: "https://127.0.0.1/apis/rbac.authorization.k8s.io/v1/clusterroles/argo-rollouts-clusterrole", - expected: "Get", - }, - { - testName: "CRD List", - method: "GET", - url: "https://127.0.0.1/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions", - expected: "List", - }, - { - testName: "CRD Get", - method: "GET", - url: "https://127.0.0.1/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions/dummies.argoproj.io", - expected: "Get", - }, - { - testName: "Resource With Periods Get", - method: "GET", - url: "https://127.0.0.1/apis/argoproj.io/v1alpha1/namespaces/argocd/applications/my-cluster.cluster.k8s.local", - expected: "Get", - }, - { - testName: "Watch cluster resources", - method: "GET", - url: "https://127.0.0.1/api/v1/namespaces?resourceVersion=343003&watch=true", - expected: "Watch", - }, - { - testName: "Watch single cluster resource", - method: "GET", - url: "https://127.0.0.1/api/v1/namespaces?fieldSelector=metadata.name%3Ddefault&resourceVersion=0&watch=true", - expected: "Watch", - }, - { - testName: "Watch namespace resources", - method: "GET", - url: "https://127.0.0.1/api/v1/namespaces/kube-system/serviceaccounts?resourceVersion=343091&watch=true", - expected: "Watch", - }, - { - testName: "Watch single namespace resource", - method: "GET", - url: "https://127.0.0.1/api/v1/namespaces/kube-system/serviceaccounts?fieldSelector=metadata.name%3Ddefault&resourceVersion=0&watch=true", - expected: "Watch", - }, - { - testName: "Create single namespace resource", - method: "POST", - url: "https://127.0.0.1/api/v1/namespaces", - expected: "Create", - }, - { - testName: "Delete single namespace resource", - method: "DELETE", - url: "https://127.0.0.1/api/v1/namespaces/test", - expected: "Delete", - }, - { - testName: "Patch single namespace resource", - method: "PATCH", - url: "https://127.0.0.1/api/v1/namespaces/test", - expected: "Patch", - }, - { - testName: "Update single namespace resource", - method: "PUT", - url: "https://127.0.0.1/api/v1/namespaces/test", - expected: "Update", - }, - } - - for _, td := range testData { - t.Run(td.testName, func(t *testing.T) { - u, err := url.Parse(td.url) - require.NoError(t, err) - info := resolveK8sRequestVerb(*u, td.method) - assert.Equal(t, td.expected, info) - }) - } -} diff --git a/util/notification/argocd/mocks/Service.go b/util/notification/argocd/mocks/Service.go index 2ab2eefc89..1147ece069 100644 --- a/util/notification/argocd/mocks/Service.go +++ b/util/notification/argocd/mocks/Service.go @@ -1,17 +1,82 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" + context "context" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/notification/expression/shared" mock "github.com/stretchr/testify/mock" + + shared "github.com/argoproj/argo-cd/v2/util/notification/expression/shared" + + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) +// Service is an autogenerated mock type for the Service type +type Service struct { + mock.Mock +} + +// GetAppDetails provides a mock function with given fields: ctx, app +func (_m *Service) GetAppDetails(ctx context.Context, app *v1alpha1.Application) (*shared.AppDetail, error) { + ret := _m.Called(ctx, app) + + if len(ret) == 0 { + panic("no return value specified for GetAppDetails") + } + + var r0 *shared.AppDetail + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Application) (*shared.AppDetail, error)); ok { + return rf(ctx, app) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Application) *shared.AppDetail); ok { + r0 = rf(ctx, app) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*shared.AppDetail) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Application) error); ok { + r1 = rf(ctx, app) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCommitMetadata provides a mock function with given fields: ctx, repoURL, commitSHA, project +func (_m *Service) GetCommitMetadata(ctx context.Context, repoURL string, commitSHA string, project string) (*shared.CommitMetadata, error) { + ret := _m.Called(ctx, repoURL, commitSHA, project) + + if len(ret) == 0 { + panic("no return value specified for GetCommitMetadata") + } + + var r0 *shared.CommitMetadata + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string, string) (*shared.CommitMetadata, error)); ok { + return rf(ctx, repoURL, commitSHA, project) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string, string) *shared.CommitMetadata); ok { + r0 = rf(ctx, repoURL, commitSHA, project) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*shared.CommitMetadata) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string, string) error); ok { + r1 = rf(ctx, repoURL, commitSHA, project) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewService creates a new instance of Service. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewService(t interface { @@ -25,132 +90,3 @@ func NewService(t interface { return mock } - -// Service is an autogenerated mock type for the Service type -type Service struct { - mock.Mock -} - -type Service_Expecter struct { - mock *mock.Mock -} - -func (_m *Service) EXPECT() *Service_Expecter { - return &Service_Expecter{mock: &_m.Mock} -} - -// GetAppDetails provides a mock function for the type Service -func (_mock *Service) GetAppDetails(ctx context.Context, app *v1alpha1.Application) (*shared.AppDetail, error) { - ret := _mock.Called(ctx, app) - - if len(ret) == 0 { - panic("no return value specified for GetAppDetails") - } - - var r0 *shared.AppDetail - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Application) (*shared.AppDetail, error)); ok { - return returnFunc(ctx, app) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *v1alpha1.Application) *shared.AppDetail); ok { - r0 = returnFunc(ctx, app) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*shared.AppDetail) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *v1alpha1.Application) error); ok { - r1 = returnFunc(ctx, app) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Service_GetAppDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAppDetails' -type Service_GetAppDetails_Call struct { - *mock.Call -} - -// GetAppDetails is a helper method to define mock.On call -// - ctx -// - app -func (_e *Service_Expecter) GetAppDetails(ctx interface{}, app interface{}) *Service_GetAppDetails_Call { - return &Service_GetAppDetails_Call{Call: _e.mock.On("GetAppDetails", ctx, app)} -} - -func (_c *Service_GetAppDetails_Call) Run(run func(ctx context.Context, app *v1alpha1.Application)) *Service_GetAppDetails_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*v1alpha1.Application)) - }) - return _c -} - -func (_c *Service_GetAppDetails_Call) Return(appDetail *shared.AppDetail, err error) *Service_GetAppDetails_Call { - _c.Call.Return(appDetail, err) - return _c -} - -func (_c *Service_GetAppDetails_Call) RunAndReturn(run func(ctx context.Context, app *v1alpha1.Application) (*shared.AppDetail, error)) *Service_GetAppDetails_Call { - _c.Call.Return(run) - return _c -} - -// GetCommitMetadata provides a mock function for the type Service -func (_mock *Service) GetCommitMetadata(ctx context.Context, repoURL string, commitSHA string, project string) (*shared.CommitMetadata, error) { - ret := _mock.Called(ctx, repoURL, commitSHA, project) - - if len(ret) == 0 { - panic("no return value specified for GetCommitMetadata") - } - - var r0 *shared.CommitMetadata - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string, string) (*shared.CommitMetadata, error)); ok { - return returnFunc(ctx, repoURL, commitSHA, project) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string, string, string) *shared.CommitMetadata); ok { - r0 = returnFunc(ctx, repoURL, commitSHA, project) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*shared.CommitMetadata) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string, string, string) error); ok { - r1 = returnFunc(ctx, repoURL, commitSHA, project) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// Service_GetCommitMetadata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCommitMetadata' -type Service_GetCommitMetadata_Call struct { - *mock.Call -} - -// GetCommitMetadata is a helper method to define mock.On call -// - ctx -// - repoURL -// - commitSHA -// - project -func (_e *Service_Expecter) GetCommitMetadata(ctx interface{}, repoURL interface{}, commitSHA interface{}, project interface{}) *Service_GetCommitMetadata_Call { - return &Service_GetCommitMetadata_Call{Call: _e.mock.On("GetCommitMetadata", ctx, repoURL, commitSHA, project)} -} - -func (_c *Service_GetCommitMetadata_Call) Run(run func(ctx context.Context, repoURL string, commitSHA string, project string)) *Service_GetCommitMetadata_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(string)) - }) - return _c -} - -func (_c *Service_GetCommitMetadata_Call) Return(commitMetadata *shared.CommitMetadata, err error) *Service_GetCommitMetadata_Call { - _c.Call.Return(commitMetadata, err) - return _c -} - -func (_c *Service_GetCommitMetadata_Call) RunAndReturn(run func(ctx context.Context, repoURL string, commitSHA string, project string) (*shared.CommitMetadata, error)) *Service_GetCommitMetadata_Call { - _c.Call.Return(run) - return _c -} diff --git a/util/notification/argocd/service.go b/util/notification/argocd/service.go index 8108205260..acb355a8d2 100644 --- a/util/notification/argocd/service.go +++ b/util/notification/argocd/service.go @@ -3,15 +3,15 @@ package service import ( "context" - "github.com/argoproj/argo-cd/v3/util/notification/expression/shared" + "github.com/argoproj/argo-cd/v2/util/notification/expression/shared" log "github.com/sirupsen/logrus" "k8s.io/client-go/kubernetes" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/settings" ) type Service interface { diff --git a/util/notification/expression/expr.go b/util/notification/expression/expr.go index d34a83d434..f00f245dc9 100644 --- a/util/notification/expression/expr.go +++ b/util/notification/expression/expr.go @@ -3,27 +3,27 @@ package expression import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - service "github.com/argoproj/argo-cd/v3/util/notification/argocd" + service "github.com/argoproj/argo-cd/v2/util/notification/argocd" - "github.com/argoproj/argo-cd/v3/util/notification/expression/repo" - "github.com/argoproj/argo-cd/v3/util/notification/expression/strings" - "github.com/argoproj/argo-cd/v3/util/notification/expression/time" + "github.com/argoproj/argo-cd/v2/util/notification/expression/repo" + "github.com/argoproj/argo-cd/v2/util/notification/expression/strings" + "github.com/argoproj/argo-cd/v2/util/notification/expression/time" ) -var helpers = map[string]any{} +var helpers = map[string]interface{}{} func init() { - helpers = make(map[string]any) + helpers = make(map[string]interface{}) register("time", time.NewExprs()) register("strings", strings.NewExprs()) } -func register(namespace string, entry map[string]any) { +func register(namespace string, entry map[string]interface{}) { helpers[namespace] = entry } -func Spawn(app *unstructured.Unstructured, argocdService service.Service, vars map[string]any) map[string]any { - clone := make(map[string]any) +func Spawn(app *unstructured.Unstructured, argocdService service.Service, vars map[string]interface{}) map[string]interface{} { + clone := make(map[string]interface{}) for k := range vars { clone[k] = vars[k] } diff --git a/util/notification/expression/repo/repo.go b/util/notification/expression/repo/repo.go index 8bfeace6df..df9943d41b 100644 --- a/util/notification/expression/repo/repo.go +++ b/util/notification/expression/repo/repo.go @@ -8,15 +8,15 @@ import ( "regexp" "strings" - service "github.com/argoproj/argo-cd/v3/util/notification/argocd" + service "github.com/argoproj/argo-cd/v2/util/notification/argocd" - "github.com/argoproj/argo-cd/v3/util/notification/expression/shared" + "github.com/argoproj/argo-cd/v2/util/notification/expression/shared" "github.com/argoproj/notifications-engine/pkg/util/text" giturls "github.com/chainguard-dev/git-urls" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) var gitSuffix = regexp.MustCompile(`\.git$`) @@ -93,12 +93,12 @@ func repoURLToHTTPS(rawURL string) string { return parsed.String() } -func NewExprs(argocdService service.Service, app *unstructured.Unstructured) map[string]any { - return map[string]any{ +func NewExprs(argocdService service.Service, app *unstructured.Unstructured) map[string]interface{} { + return map[string]interface{}{ "RepoURLToHTTPS": repoURLToHTTPS, "FullNameByRepoURL": FullNameByRepoURL, "QueryEscape": url.QueryEscape, - "GetCommitMetadata": func(commitSHA string) any { + "GetCommitMetadata": func(commitSHA string) interface{} { meta, err := getCommitMetadata(commitSHA, app, argocdService) if err != nil { panic(err) @@ -106,7 +106,7 @@ func NewExprs(argocdService service.Service, app *unstructured.Unstructured) map return *meta }, - "GetAppDetails": func() any { + "GetAppDetails": func() interface{} { appDetails, err := getAppDetails(app, argocdService) if err != nil { panic(err) diff --git a/util/notification/expression/shared/appdetail.go b/util/notification/expression/shared/appdetail.go index 642ff6af04..e3156ff4a0 100644 --- a/util/notification/expression/shared/appdetail.go +++ b/util/notification/expression/shared/appdetail.go @@ -3,9 +3,9 @@ package shared import ( "time" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" ) type CommitMetadata struct { diff --git a/util/notification/expression/shared/appdetail_test.go b/util/notification/expression/shared/appdetail_test.go index 2f64d84b0e..08d6deff61 100644 --- a/util/notification/expression/shared/appdetail_test.go +++ b/util/notification/expression/shared/appdetail_test.go @@ -5,8 +5,8 @@ import ( "github.com/stretchr/testify/assert" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" ) func TestGetParameterValueByName(t *testing.T) { diff --git a/util/notification/expression/strings/strings.go b/util/notification/expression/strings/strings.go index de0617fca1..8b29430dde 100644 --- a/util/notification/expression/strings/strings.go +++ b/util/notification/expression/strings/strings.go @@ -4,8 +4,8 @@ import ( "strings" ) -func NewExprs() map[string]any { - return map[string]any{ +func NewExprs() map[string]interface{} { + return map[string]interface{}{ "ReplaceAll": replaceAll, "ToUpper": toUpper, "ToLower": toLower, diff --git a/util/notification/expression/strings/strings_test.go b/util/notification/expression/strings/strings_test.go index c84ba4f374..660ec66aa4 100644 --- a/util/notification/expression/strings/strings_test.go +++ b/util/notification/expression/strings/strings_test.go @@ -1,6 +1,7 @@ package strings import ( + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -49,7 +50,7 @@ func TestUpperAndLower(t *testing.T) { exprs := NewExprs() for _, testCase := range testCases { - t.Run("With success case: Func: "+testCase.fn, func(t *testing.T) { + t.Run(fmt.Sprintf("With success case: Func: %s", testCase.fn), func(tc *testing.T) { toUpperFn, ok := exprs[testCase.fn].(func(s string) string) assert.True(t, ok) diff --git a/util/notification/expression/time/time.go b/util/notification/expression/time/time.go index 24b79f57e3..63aa31c3d3 100644 --- a/util/notification/expression/time/time.go +++ b/util/notification/expression/time/time.go @@ -6,8 +6,8 @@ import ( var now = time.Now -func NewExprs() map[string]any { - return map[string]any{ +func NewExprs() map[string]interface{} { + return map[string]interface{}{ // Functions "Parse": parse, "Now": now, diff --git a/util/notification/expression/time/time_test.go b/util/notification/expression/time/time_test.go index 41c27b6f5f..a450260bea 100644 --- a/util/notification/expression/time/time_test.go +++ b/util/notification/expression/time/time_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/expr-lang/expr" + "github.com/antonmedv/expr" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -54,7 +54,7 @@ func Test_NewExprs_Now(t *testing.T) { vm, err := expr.Compile("time.Now().Truncate(time.Hour).Format(time.RFC3339)") require.NoError(t, err) - val, err := expr.Run(vm, map[string]any{"time": NewExprs()}) + val, err := expr.Run(vm, map[string]interface{}{"time": NewExprs()}) require.NoError(t, err) assert.Equal(t, "2022-09-26T11:00:00Z", val) diff --git a/util/notification/k8s/informers.go b/util/notification/k8s/informers.go index 2980ccfb38..4289df21e0 100644 --- a/util/notification/k8s/informers.go +++ b/util/notification/k8s/informers.go @@ -1,10 +1,11 @@ package k8s import ( + "fmt" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - informersv1 "k8s.io/client-go/informers/core/v1" + corev1 "k8s.io/client-go/informers/core/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" ) @@ -14,13 +15,13 @@ const ( ) func NewSecretInformer(clientset kubernetes.Interface, namespace string, secretName string) cache.SharedIndexInformer { - return informersv1.NewFilteredSecretInformer(clientset, namespace, settingsResyncDuration, cache.Indexers{}, func(options *metav1.ListOptions) { - options.FieldSelector = "metadata.name=" + secretName + return corev1.NewFilteredSecretInformer(clientset, namespace, settingsResyncDuration, cache.Indexers{}, func(options *metav1.ListOptions) { + options.FieldSelector = fmt.Sprintf("metadata.name=%s", secretName) }) } func NewConfigMapInformer(clientset kubernetes.Interface, namespace string, configMapName string) cache.SharedIndexInformer { - return informersv1.NewFilteredConfigMapInformer(clientset, namespace, settingsResyncDuration, cache.Indexers{}, func(options *metav1.ListOptions) { - options.FieldSelector = "metadata.name=" + configMapName + return corev1.NewFilteredConfigMapInformer(clientset, namespace, settingsResyncDuration, cache.Indexers{}, func(options *metav1.ListOptions) { + options.FieldSelector = fmt.Sprintf("metadata.name=%s", configMapName) }) } diff --git a/util/notification/settings/legacy.go b/util/notification/settings/legacy.go index 6f373ee5d0..04ade75159 100644 --- a/util/notification/settings/legacy.go +++ b/util/notification/settings/legacy.go @@ -12,7 +12,7 @@ import ( "github.com/argoproj/notifications-engine/pkg/util/text" jsonpatch "github.com/evanphx/json-patch" log "github.com/sirupsen/logrus" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "sigs.k8s.io/yaml" ) @@ -51,7 +51,7 @@ type legacyServicesConfig struct { Webhook []legacyWebhookOptions `json:"webhook"` } -func mergePatch(orig any, other any) error { +func mergePatch(orig interface{}, other interface{}) error { origData, err := json.Marshal(orig) if err != nil { return fmt.Errorf("error marshaling json for original: %w", err) @@ -88,13 +88,13 @@ func (legacy legacyConfig) merge(cfg *api.Config, context map[string]string) err } } if template.Title != "" { - if template.Email == nil { - template.Email = &services.EmailNotification{} + if template.Notification.Email == nil { + template.Notification.Email = &services.EmailNotification{} } - template.Email.Subject = template.Title + template.Notification.Email.Subject = template.Title } if template.Body != "" { - template.Message = template.Body + template.Notification.Message = template.Body } cfg.Templates[template.Name] = template.Notification } @@ -157,7 +157,7 @@ func (c *legacyServicesConfig) merge(cfg *api.Config) { } // ApplyLegacyConfig settings specified using deprecated config map and secret keys -func ApplyLegacyConfig(cfg *api.Config, context map[string]string, cm *corev1.ConfigMap, secret *corev1.Secret) error { +func ApplyLegacyConfig(cfg *api.Config, context map[string]string, cm *v1.ConfigMap, secret *v1.Secret) error { if notifiersData, ok := secret.Data["notifiers.yaml"]; ok && len(notifiersData) > 0 { log.Warn("Key 'notifiers.yaml' in Secret is deprecated, please migrate to new settings") legacyServices := &legacyServicesConfig{} diff --git a/util/notification/settings/legacy_test.go b/util/notification/settings/legacy_test.go index 1a77f87410..00565767c3 100644 --- a/util/notification/settings/legacy_test.go +++ b/util/notification/settings/legacy_test.go @@ -9,7 +9,7 @@ import ( "github.com/argoproj/notifications-engine/pkg/triggers" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/labels" ) @@ -36,8 +36,8 @@ triggers: ` err := ApplyLegacyConfig(&cfg, context, - &corev1.ConfigMap{Data: map[string]string{"config.yaml": configYAML}}, - &corev1.Secret{Data: map[string][]byte{}}, + &v1.ConfigMap{Data: map[string]string{"config.yaml": configYAML}}, + &v1.Secret{Data: map[string][]byte{}}, ) require.NoError(t, err) assert.Equal(t, []string{"my-trigger1"}, cfg.DefaultTriggers) @@ -82,8 +82,8 @@ slack: token: my-token ` err := ApplyLegacyConfig(&cfg, context, - &corev1.ConfigMap{Data: map[string]string{"config.yaml": configYAML}}, - &corev1.Secret{Data: map[string][]byte{"notifiers.yaml": []byte(notifiersYAML)}}, + &v1.ConfigMap{Data: map[string]string{"config.yaml": configYAML}}, + &v1.Secret{Data: map[string][]byte{"notifiers.yaml": []byte(notifiersYAML)}}, ) require.NoError(t, err) diff --git a/util/notification/settings/settings.go b/util/notification/settings/settings.go index 9fa67167ad..0e14dc60a7 100644 --- a/util/notification/settings/settings.go +++ b/util/notification/settings/settings.go @@ -1,24 +1,24 @@ package settings import ( - "errors" + "fmt" "github.com/argoproj/notifications-engine/pkg/api" "github.com/argoproj/notifications-engine/pkg/services" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/util/notification/expression" + "github.com/argoproj/argo-cd/v2/util/notification/expression" - service "github.com/argoproj/argo-cd/v3/util/notification/argocd" + service "github.com/argoproj/argo-cd/v2/util/notification/argocd" ) func GetFactorySettings(argocdService service.Service, secretName, configMapName string, selfServiceNotificationEnabled bool) api.Settings { return api.Settings{ SecretName: secretName, ConfigMapName: configMapName, - InitGetVars: func(cfg *api.Config, configMap *corev1.ConfigMap, secret *corev1.Secret) (api.GetVars, error) { + InitGetVars: func(cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (api.GetVars, error) { if selfServiceNotificationEnabled { return initGetVarsWithoutSecret(argocdService, cfg, configMap, secret) } @@ -32,9 +32,9 @@ func GetFactorySettingsForCLI(argocdService *service.Service, secretName, config return api.Settings{ SecretName: secretName, ConfigMapName: configMapName, - InitGetVars: func(cfg *api.Config, configMap *corev1.ConfigMap, secret *corev1.Secret) (api.GetVars, error) { + InitGetVars: func(cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (api.GetVars, error) { if *argocdService == nil { - return nil, errors.New("argocdService is not initialized") + return nil, fmt.Errorf("argocdService is not initialized") } if selfServiceNotificationEnabled { @@ -45,7 +45,7 @@ func GetFactorySettingsForCLI(argocdService *service.Service, secretName, config } } -func getContext(cfg *api.Config, configMap *corev1.ConfigMap, secret *corev1.Secret) (map[string]string, error) { +func getContext(cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (map[string]string, error) { context := map[string]string{} if contextYaml, ok := configMap.Data["context"]; ok { if err := yaml.Unmarshal([]byte(contextYaml), &context); err != nil { @@ -58,28 +58,28 @@ func getContext(cfg *api.Config, configMap *corev1.ConfigMap, secret *corev1.Sec return context, nil } -func initGetVarsWithoutSecret(argocdService service.Service, cfg *api.Config, configMap *corev1.ConfigMap, secret *corev1.Secret) (api.GetVars, error) { +func initGetVarsWithoutSecret(argocdService service.Service, cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (api.GetVars, error) { context, err := getContext(cfg, configMap, secret) if err != nil { return nil, err } - return func(obj map[string]any, dest services.Destination) map[string]any { - return expression.Spawn(&unstructured.Unstructured{Object: obj}, argocdService, map[string]any{ + return func(obj map[string]interface{}, dest services.Destination) map[string]interface{} { + return expression.Spawn(&unstructured.Unstructured{Object: obj}, argocdService, map[string]interface{}{ "app": obj, "context": injectLegacyVar(context, dest.Service), }) }, nil } -func initGetVars(argocdService service.Service, cfg *api.Config, configMap *corev1.ConfigMap, secret *corev1.Secret) (api.GetVars, error) { +func initGetVars(argocdService service.Service, cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (api.GetVars, error) { context, err := getContext(cfg, configMap, secret) if err != nil { return nil, err } - return func(obj map[string]any, dest services.Destination) map[string]any { - return expression.Spawn(&unstructured.Unstructured{Object: obj}, argocdService, map[string]any{ + return func(obj map[string]interface{}, dest services.Destination) map[string]interface{} { + return expression.Spawn(&unstructured.Unstructured{Object: obj}, argocdService, map[string]interface{}{ "app": obj, "context": injectLegacyVar(context, dest.Service), "secrets": secret.Data, diff --git a/util/notification/settings/settings_test.go b/util/notification/settings/settings_test.go index 35c91ac977..8c3a8c5bf9 100644 --- a/util/notification/settings/settings_test.go +++ b/util/notification/settings/settings_test.go @@ -9,11 +9,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/reposerver/apiclient/mocks" - service "github.com/argoproj/argo-cd/v3/util/notification/argocd" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" + service "github.com/argoproj/argo-cd/v2/util/notification/argocd" ) const ( @@ -24,7 +24,7 @@ const ( func TestInitGetVars(t *testing.T) { notificationsCm := corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-notifications-cm", }, @@ -36,7 +36,7 @@ func TestInitGetVars(t *testing.T) { }, } notificationsSecret := corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "argocd-notifications-secret", Namespace: testNamespace, }, @@ -45,14 +45,14 @@ func TestInitGetVars(t *testing.T) { }, } kubeclientset := fake.NewClientset(&corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-notifications-cm", }, Data: notificationsCm.Data, }, &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "argocd-notifications-secret", Namespace: testNamespace, }, @@ -66,12 +66,12 @@ func TestInitGetVars(t *testing.T) { testDestination := services.Destination{ Service: "webhook", } - emptyAppData := map[string]any{} + emptyAppData := map[string]interface{}{} varsProvider, _ := initGetVars(argocdService, &config, ¬ificationsCm, ¬ificationsSecret) t.Run("Vars provider serves Application data on app key", func(t *testing.T) { - appData := map[string]any{ + appData := map[string]interface{}{ "name": "app-name", } result := varsProvider(appData, testDestination) diff --git a/util/oidc/oidc.go b/util/oidc/oidc.go index 2ff4e0ef4f..2f01dc167e 100644 --- a/util/oidc/oidc.go +++ b/util/oidc/oidc.go @@ -1,7 +1,6 @@ package oidc import ( - "context" "encoding/hex" "encoding/json" "errors" @@ -15,27 +14,26 @@ import ( "os" "path" "strings" - "sync" "time" gooidc "github.com/coreos/go-oidc/v3/oidc" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" log "github.com/sirupsen/logrus" "golang.org/x/oauth2" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/server/settings/oidc" - "github.com/argoproj/argo-cd/v3/util/cache" - "github.com/argoproj/argo-cd/v3/util/crypto" - "github.com/argoproj/argo-cd/v3/util/dex" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/server/settings/oidc" + "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/argoproj/argo-cd/v2/util/crypto" + "github.com/argoproj/argo-cd/v2/util/dex" - httputil "github.com/argoproj/argo-cd/v3/util/http" - jwtutil "github.com/argoproj/argo-cd/v3/util/jwt" - "github.com/argoproj/argo-cd/v3/util/rand" - "github.com/argoproj/argo-cd/v3/util/settings" + httputil "github.com/argoproj/argo-cd/v2/util/http" + jwtutil "github.com/argoproj/argo-cd/v2/util/jwt" + "github.com/argoproj/argo-cd/v2/util/rand" + "github.com/argoproj/argo-cd/v2/util/settings" ) -var ErrInvalidRedirectURL = errors.New("invalid return URL") +var InvalidRedirectURLError = fmt.Errorf("invalid return URL") const ( GrantTypeAuthorizationCode = "authorization_code" @@ -62,8 +60,6 @@ type ClientApp struct { clientID string // OAuth2 client secret of this application clientSecret string - // Use Azure Workload Identity for clientID auth instead of clientSecret - useAzureWorkloadIdentity bool // Callback URL for OAuth2 responses (e.g. https://argocd.example.com/auth/callback) redirectURI string // URL of the issuer (e.g. https://argocd.example.com/api/dex) @@ -85,17 +81,6 @@ type ClientApp struct { provider Provider // clientCache represent a cache of sso artifact clientCache cache.CacheClient - // properties for azure workload identity. - azure azureApp -} - -type azureApp struct { - // federated azure token for the service account - assertion string - // expiry of the token - expires time.Time - // mutex for parallelism for reading the token - mtx *sync.RWMutex } func GetScopesOrDefault(scopes []string) []string { @@ -107,7 +92,7 @@ func GetScopesOrDefault(scopes []string) []string { // NewClientApp will register the Argo CD client app (either via Dex or external OIDC) and return an // object which has HTTP handlers for handling the HTTP responses for login and callback -func NewClientApp(settings *settings.ArgoCDSettings, dexServerAddr string, dexTLSConfig *dex.DexTLSConfig, baseHRef string, cacheClient cache.CacheClient) (*ClientApp, error) { +func NewClientApp(settings *settings.ArgoCDSettings, dexServerAddr string, dexTlsConfig *dex.DexTLSConfig, baseHRef string, cacheClient cache.CacheClient) (*ClientApp, error) { redirectURL, err := settings.RedirectURL() if err != nil { return nil, err @@ -117,16 +102,14 @@ func NewClientApp(settings *settings.ArgoCDSettings, dexServerAddr string, dexTL return nil, err } a := ClientApp{ - clientID: settings.OAuth2ClientID(), - clientSecret: settings.OAuth2ClientSecret(), - useAzureWorkloadIdentity: settings.UseAzureWorkloadIdentity(), - redirectURI: redirectURL, - issuerURL: settings.IssuerURL(), - userInfoPath: settings.UserInfoPath(), - baseHRef: baseHRef, - encryptionKey: encryptionKey, - clientCache: cacheClient, - azure: azureApp{mtx: &sync.RWMutex{}}, + clientID: settings.OAuth2ClientID(), + clientSecret: settings.OAuth2ClientSecret(), + redirectURI: redirectURL, + issuerURL: settings.IssuerURL(), + userInfoPath: settings.UserInfoPath(), + baseHRef: baseHRef, + encryptionKey: encryptionKey, + clientCache: cacheClient, } log.Infof("Creating client app (%s)", a.clientID) u, err := url.Parse(settings.URL) @@ -148,8 +131,8 @@ func NewClientApp(settings *settings.ArgoCDSettings, dexServerAddr string, dexTL } if settings.DexConfig != "" && settings.OIDCConfigRAW == "" { - transport.TLSClientConfig = dex.TLSConfig(dexTLSConfig) - addrWithProto := dex.DexServerAddressWithProtocol(dexServerAddr, dexTLSConfig) + transport.TLSClientConfig = dex.TLSConfig(dexTlsConfig) + addrWithProto := dex.DexServerAddressWithProtocol(dexServerAddr, dexTlsConfig) a.client.Transport = dex.NewDexRewriteURLRoundTripper(addrWithProto, a.client.Transport) } else { transport.TLSClientConfig = settings.OIDCTLSConfig() @@ -175,7 +158,6 @@ func (a *ClientApp) oauth2Config(request *http.Request, scopes []string) (*oauth log.Warnf("Unable to find ArgoCD URL from request, falling back to configured redirect URI: %v", err) redirectURL = a.redirectURI } - return &oauth2.Config{ ClientID: a.clientID, ClientSecret: a.clientSecret, @@ -233,12 +215,12 @@ func (a *ClientApp) verifyAppState(r *http.Request, w http.ResponseWriter, state if len(parts) == 2 && parts[1] != "" { if !isValidRedirectURL(parts[1], append([]string{a.settings.URL, a.baseHRef}, a.settings.AdditionalURLs...)) { - sanitizedURL := parts[1] - if len(sanitizedURL) > 100 { - sanitizedURL = sanitizedURL[:100] + sanitizedUrl := parts[1] + if len(sanitizedUrl) > 100 { + sanitizedUrl = sanitizedUrl[:100] } - log.Warnf("Failed to verify app state - got invalid redirectURL %q", sanitizedURL) - return "", fmt.Errorf("failed to verify app state: %w", ErrInvalidRedirectURL) + log.Warnf("Failed to verify app state - got invalid redirectURL %q", sanitizedUrl) + return "", fmt.Errorf("failed to verify app state: %w", InvalidRedirectURLError) } redirectURL = parts[1] } @@ -290,9 +272,9 @@ func isValidRedirectURL(redirectURL string, allowedURLs []string) bool { // scheme and host are mandatory to match. if b.Scheme == r.Scheme && b.Host == r.Host { // If path of redirectURL and allowedURL match, redirectURL is allowed - // if b.Path == r.Path { - // return true - // } + //if b.Path == r.Path { + // return true + //} // If path of redirectURL is within allowed URL's path, redirectURL is allowed if strings.HasPrefix(path.Clean(r.Path), b.Path) { return true @@ -314,13 +296,10 @@ func (a *ClientApp) HandleLogin(w http.ResponseWriter, r *http.Request) { scopes := make([]string, 0) var opts []oauth2.AuthCodeOption if config := a.settings.OIDCConfig(); config != nil { - scopes = GetScopesOrDefault(config.RequestedScopes) + scopes = config.RequestedScopes opts = AppendClaimsAuthenticationRequestParameter(opts, config.RequestedIDTokenClaims) - } else if a.settings.IsDexConfigured() { - scopes = append(GetScopesOrDefault(nil), common.DexFederatedScope) } - - oauth2Config, err := a.oauth2Config(r, scopes) + oauth2Config, err := a.oauth2Config(r, GetScopesOrDefault(scopes)) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -357,44 +336,6 @@ func (a *ClientApp) HandleLogin(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, url, http.StatusSeeOther) } -// getFederatedServiceAccountToken returns the specified file's content, which is expected to be Federated Kubernetes service account token. -// Kubernetes is responsible for updating the file as service account tokens expire. -// Azure Workload Identity mutation webhook will set the environment variable AZURE_FEDERATED_TOKEN_FILE -// Content of this file will contain a federated token which can be used in assertion with Microsoft Entra Application. -func (a *azureApp) getFederatedServiceAccountToken(context.Context) (string, error) { - file, ok := os.LookupEnv("AZURE_FEDERATED_TOKEN_FILE") - if file == "" || !ok { - return "", errors.New("AZURE_FEDERATED_TOKEN_FILE env variable not found, make sure workload identity is enabled on the cluster") - } - - if _, err := os.Stat(file); errors.Is(err, os.ErrNotExist) { - return "", errors.New("AZURE_FEDERATED_TOKEN_FILE specified file does not exist") - } - - a.mtx.RLock() - if a.expires.Before(time.Now()) { - // ensure only one goroutine at a time updates the assertion - a.mtx.RUnlock() - a.mtx.Lock() - defer a.mtx.Unlock() - // double check because another goroutine may have acquired the write lock first and done the update - if now := time.Now(); a.expires.Before(now) { - content, err := os.ReadFile(file) - if err != nil { - return "", err - } - a.assertion = string(content) - // Kubernetes rotates service account tokens when they reach 80% of their total TTL. The shortest TTL - // is 1 hour. That implies the token we just read is valid for at least 12 minutes (20% of 1 hour), - // but we add some margin for safety. - a.expires = now.Add(10 * time.Minute) - } - } else { - defer a.mtx.RUnlock() - } - return a.assertion, nil -} - // HandleCallback is the callback handler for an OAuth2 login flow func (a *ClientApp) HandleCallback(w http.ResponseWriter, r *http.Request) { oauth2Config, err := a.oauth2Config(r, nil) @@ -420,29 +361,12 @@ func (a *ClientApp) HandleCallback(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - ctx := gooidc.ClientContext(r.Context(), a.client) - options := []oauth2.AuthCodeOption{} - - if a.useAzureWorkloadIdentity { - clientAssertion, err := a.azure.getFederatedServiceAccountToken(ctx) - if err != nil { - http.Error(w, fmt.Sprintf("failed to generate client assertion: %v", err), http.StatusInternalServerError) - return - } - - options = []oauth2.AuthCodeOption{ - oauth2.SetAuthURLParam("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"), - oauth2.SetAuthURLParam("client_assertion", clientAssertion), - } - } - - token, err := oauth2Config.Exchange(ctx, code, options...) + token, err := oauth2Config.Exchange(ctx, code) if err != nil { http.Error(w, fmt.Sprintf("failed to get token: %v", err), http.StatusInternalServerError) return } - idTokenRAW, ok := token.Extra("id_token").(string) if !ok { http.Error(w, "no id_token in token response", http.StatusInternalServerError) @@ -459,7 +383,7 @@ func (a *ClientApp) HandleCallback(w http.ResponseWriter, r *http.Request) { if a.baseHRef != "" { path = strings.TrimRight(strings.TrimLeft(a.baseHRef, "/"), "/") } - cookiePath := "path=/" + path + cookiePath := fmt.Sprintf("path=/%s", path) flags := []string{cookiePath, "SameSite=lax", "httpOnly"} if a.secureCookie { flags = append(flags, "Secure") @@ -640,11 +564,12 @@ func (a *ClientApp) GetUserInfo(actualClaims jwt.MapClaims, issuerURL, userInfoP log.Errorf("decrypting the cached claims failed (sub=%s): %s", sub, err) } else { err = json.Unmarshal(claimsRaw, &claims) - if err == nil { + if err != nil { + log.Errorf("cannot unmarshal cached claims structure: %s", err) + } else { // return the cached claims since they are not yet expired, were successfully decrypted and unmarshaled return claims, false, err } - log.Errorf("cannot unmarshal cached claims structure: %s", err) } } @@ -718,12 +643,11 @@ func (a *ClientApp) GetUserInfo(actualClaims jwt.MapClaims, issuerURL, userInfoP // only use configured expiry if the token lives longer and the expiry is configured // if the token has no expiry, use the expiry of the actual token // otherwise use the expiry of the token - switch { - case settingExpiry < tokenExpiry && settingExpiry != 0: + if settingExpiry < tokenExpiry && settingExpiry != 0 { cacheExpiry = settingExpiry - case tokenExpiry < 0: + } else if tokenExpiry < 0 { cacheExpiry = getTokenExpiration(actualClaims) - default: + } else { cacheExpiry = tokenExpiry } diff --git a/util/oidc/oidc_test.go b/util/oidc/oidc_test.go index 749b661d7b..40c606dcd9 100644 --- a/util/oidc/oidc_test.go +++ b/util/oidc/oidc_test.go @@ -9,41 +9,26 @@ import ( "net/http/httptest" "net/url" "os" - "path/filepath" "strings" - "sync" "testing" "time" gooidc "github.com/coreos/go-oidc/v3/oidc" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/oauth2" - "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/server/settings/oidc" - "github.com/argoproj/argo-cd/v3/util" - "github.com/argoproj/argo-cd/v3/util/cache" - "github.com/argoproj/argo-cd/v3/util/crypto" - "github.com/argoproj/argo-cd/v3/util/dex" - "github.com/argoproj/argo-cd/v3/util/settings" - "github.com/argoproj/argo-cd/v3/util/test" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/server/settings/oidc" + "github.com/argoproj/argo-cd/v2/util" + "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/argoproj/argo-cd/v2/util/crypto" + "github.com/argoproj/argo-cd/v2/util/dex" + "github.com/argoproj/argo-cd/v2/util/settings" + "github.com/argoproj/argo-cd/v2/util/test" ) -func setupAzureIdentity(t *testing.T) { - t.Helper() - - tempDir := t.TempDir() - tokenFilePath := filepath.Join(tempDir, "token.txt") - tempFile, err := os.Create(tokenFilePath) - require.NoError(t, err) - _, err = tempFile.Write([]byte("serviceAccountToken")) - require.NoError(t, err) - t.Setenv("AZURE_FEDERATED_TOKEN_FILE", tokenFilePath) -} - func TestInferGrantType(t *testing.T) { for _, path := range []string{"dex", "okta", "auth0", "onelogin"} { t.Run(path, func(t *testing.T) { @@ -152,7 +137,9 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), app.HandleLogin(w, req) - assert.Contains(t, w.Body.String(), "certificate signed by unknown authority") + if !strings.Contains(w.Body.String(), "certificate signed by unknown authority") && !strings.Contains(w.Body.String(), "certificate is not trusted") { + t.Fatal("did not receive expected certificate verification failure error") + } cdSettings.OIDCTLSInsecureSkipVerify = true @@ -180,6 +167,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), cert, err := tls.X509KeyPair(test.Cert, test.PrivateKey) require.NoError(t, err) cdSettings.Certificate = &cert + app, err := NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) @@ -204,108 +192,6 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), assert.NotContains(t, w.Body.String(), "certificate signed by unknown authority") }) - t.Run("OIDC auth", func(t *testing.T) { - cdSettings := &settings.ArgoCDSettings{ - URL: "https://argocd.example.com", - OIDCTLSInsecureSkipVerify: true, - } - oidcConfig := settings.OIDCConfig{ - Name: "Test", - Issuer: oidcTestServer.URL, - ClientID: "xxx", - ClientSecret: "yyy", - } - oidcConfigRaw, err := yaml.Marshal(oidcConfig) - require.NoError(t, err) - cdSettings.OIDCConfigRAW = string(oidcConfigRaw) - - app, err := NewClientApp(cdSettings, dexTestServer.URL, &dex.DexTLSConfig{StrictValidation: false}, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) - require.NoError(t, err) - - req := httptest.NewRequest(http.MethodGet, "https://argocd.example.com/auth/login", nil) - w := httptest.NewRecorder() - app.HandleLogin(w, req) - - assert.Equal(t, http.StatusSeeOther, w.Code) - location, err := url.Parse(w.Header().Get("Location")) - require.NoError(t, err) - values, err := url.ParseQuery(location.RawQuery) - require.NoError(t, err) - assert.Equal(t, []string{"openid", "profile", "email", "groups"}, strings.Split(values.Get("scope"), " ")) - assert.Equal(t, "xxx", values.Get("client_id")) - assert.Equal(t, "code", values.Get("response_type")) - }) - - t.Run("OIDC auth with custom scopes", func(t *testing.T) { - cdSettings := &settings.ArgoCDSettings{ - URL: "https://argocd.example.com", - OIDCTLSInsecureSkipVerify: true, - } - oidcConfig := settings.OIDCConfig{ - Name: "Test", - Issuer: oidcTestServer.URL, - ClientID: "xxx", - ClientSecret: "yyy", - RequestedScopes: []string{"oidc"}, - } - oidcConfigRaw, err := yaml.Marshal(oidcConfig) - require.NoError(t, err) - cdSettings.OIDCConfigRAW = string(oidcConfigRaw) - - app, err := NewClientApp(cdSettings, dexTestServer.URL, &dex.DexTLSConfig{StrictValidation: false}, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) - require.NoError(t, err) - - req := httptest.NewRequest(http.MethodGet, "https://argocd.example.com/auth/login", nil) - w := httptest.NewRecorder() - app.HandleLogin(w, req) - - assert.Equal(t, http.StatusSeeOther, w.Code) - location, err := url.Parse(w.Header().Get("Location")) - require.NoError(t, err) - values, err := url.ParseQuery(location.RawQuery) - require.NoError(t, err) - assert.Equal(t, []string{"oidc"}, strings.Split(values.Get("scope"), " ")) - assert.Equal(t, "xxx", values.Get("client_id")) - assert.Equal(t, "code", values.Get("response_type")) - }) - - t.Run("Dex auth", func(t *testing.T) { - cdSettings := &settings.ArgoCDSettings{ - URL: dexTestServer.URL, - } - dexConfig := map[string]any{ - "connectors": []map[string]any{ - { - "type": "github", - "name": "GitHub", - "config": map[string]any{ - "clientId": "aabbccddeeff00112233", - "clientSecret": "aabbccddeeff00112233", - }, - }, - }, - } - dexConfigRaw, err := yaml.Marshal(dexConfig) - require.NoError(t, err) - cdSettings.DexConfig = string(dexConfigRaw) - - app, err := NewClientApp(cdSettings, dexTestServer.URL, &dex.DexTLSConfig{StrictValidation: false}, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) - require.NoError(t, err) - - req := httptest.NewRequest(http.MethodGet, "https://argocd.example.com/auth/login", nil) - w := httptest.NewRecorder() - app.HandleLogin(w, req) - - assert.Equal(t, http.StatusSeeOther, w.Code) - location, err := url.Parse(w.Header().Get("Location")) - require.NoError(t, err) - values, err := url.ParseQuery(location.RawQuery) - require.NoError(t, err) - assert.Equal(t, []string{"openid", "profile", "email", "groups", common.DexFederatedScope}, strings.Split(values.Get("scope"), " ")) - assert.Equal(t, common.ArgoCDClientAppID, values.Get("client_id")) - assert.Equal(t, "code", values.Get("response_type")) - }) - t.Run("with additional base URL", func(t *testing.T) { cdSettings := &settings.ArgoCDSettings{ URL: "https://argocd.example.com", @@ -327,6 +213,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), cert, err := tls.X509KeyPair(test.Cert, test.PrivateKey) require.NoError(t, err) cdSettings.Certificate = &cert + app, err := NewClientApp(cdSettings, dexTestServer.URL, &dex.DexTLSConfig{StrictValidation: false}, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) @@ -421,6 +308,7 @@ clientSecret: yyy requestedScopes: ["oidc"]`, oidcTestServer.URL), OIDCTLSInsecureSkipVerify: true, } + // The base href (the last argument for NewClientApp) is what HandleLogin will fall back to when no explicit // redirect URL is given. app, err := NewClientApp(cdSettings, "", nil, "/", cache.NewInMemoryCache(24*time.Hour)) @@ -432,10 +320,10 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), app.HandleLogin(w, req) - redirectURL, err := w.Result().Location() + redirectUrl, err := w.Result().Location() require.NoError(t, err) - state := redirectURL.Query()["state"] + state := redirectUrl.Query()["state"] req = httptest.NewRequest(http.MethodGet, fmt.Sprintf("https://argocd.example.com/auth/callback?state=%s&code=abc", state), nil) for _, cookie := range w.Result().Cookies() { @@ -446,7 +334,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), app.HandleCallback(w, req) - assert.NotContains(t, w.Body.String(), ErrInvalidRedirectURL.Error()) + assert.NotContains(t, w.Body.String(), InvalidRedirectURLError.Error()) } func TestClientApp_HandleCallback(t *testing.T) { @@ -505,6 +393,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), cert, err := tls.X509KeyPair(test.Cert, test.PrivateKey) require.NoError(t, err) cdSettings.Certificate = &cert + app, err := NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) @@ -530,144 +419,6 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), }) } -func Test_azureApp_getFederatedServiceAccountToken(t *testing.T) { - app := azureApp{mtx: &sync.RWMutex{}} - - setupAzureIdentity(t) - - t.Run("before the method call assertion should be empty.", func(t *testing.T) { - assert.Empty(t, app.assertion) - }) - - t.Run("Fetch the token value from the file", func(t *testing.T) { - _, err := app.getFederatedServiceAccountToken(t.Context()) - require.NoError(t, err) - assert.Equal(t, "serviceAccountToken", app.assertion) - }) - - t.Run("Workload Identity Not enabled.", func(t *testing.T) { - t.Setenv("AZURE_FEDERATED_TOKEN_FILE", "") - _, err := app.getFederatedServiceAccountToken(t.Context()) - assert.ErrorContains(t, err, "AZURE_FEDERATED_TOKEN_FILE env variable not found, make sure workload identity is enabled on the cluster") - }) - - t.Run("Workload Identity invalid file", func(t *testing.T) { - t.Setenv("AZURE_FEDERATED_TOKEN_FILE", filepath.Join(t.TempDir(), "invalid.txt")) - _, err := app.getFederatedServiceAccountToken(t.Context()) - assert.ErrorContains(t, err, "AZURE_FEDERATED_TOKEN_FILE specified file does not exist") - }) - - t.Run("Concurrent access to the function", func(t *testing.T) { - currentExpiryTime := app.expires - - var wg sync.WaitGroup - numGoroutines := 10 - wg.Add(numGoroutines) - for i := 0; i < numGoroutines; i++ { - go func() { - defer wg.Done() - _, err := app.getFederatedServiceAccountToken(t.Context()) - require.NoError(t, err) - assert.Equal(t, "serviceAccountToken", app.assertion) - }() - } - wg.Wait() - - // Event with multiple concurrent calls the expiry time should not change untile it passes. - assert.Equal(t, currentExpiryTime, app.expires) - }) - - t.Run("Concurrent access to the function when the current token expires", func(t *testing.T) { - var wg sync.WaitGroup - currentExpiryTime := app.expires - app.expires = time.Now() - numGoroutines := 10 - wg.Add(numGoroutines) - for i := 0; i < numGoroutines; i++ { - go func() { - defer wg.Done() - _, err := app.getFederatedServiceAccountToken(t.Context()) - require.NoError(t, err) - assert.Equal(t, "serviceAccountToken", app.assertion) - }() - } - wg.Wait() - - assert.NotEqual(t, currentExpiryTime, app.expires) - }) -} - -func TestClientAppWithAzureWorkloadIdentity_HandleCallback(t *testing.T) { - tokenRequestAssertions := func(r *http.Request) { - err := r.ParseForm() - require.NoError(t, err) - - formData := r.Form - clientAssertion := formData.Get("client_assertion") - clientAssertionType := formData.Get("client_assertion_type") - assert.Equal(t, "serviceAccountToken", clientAssertion) - assert.Equal(t, "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", clientAssertionType) - } - - oidcTestServer := test.GetAzureOIDCTestServer(t, tokenRequestAssertions) - t.Cleanup(oidcTestServer.Close) - - dexTestServer := test.GetDexTestServer(t) - t.Cleanup(dexTestServer.Close) - signature, err := util.MakeSignature(32) - require.NoError(t, err) - - setupAzureIdentity(t) - - t.Run("oidc certificate checking during oidc callback should toggle on config", func(t *testing.T) { - cdSettings := &settings.ArgoCDSettings{ - URL: "https://argocd.example.com", - ServerSignature: signature, - OIDCConfigRAW: fmt.Sprintf(` -name: Test -issuer: %s -clientID: xxx -azure: - useWorkloadIdentity: true -skipAudienceCheckWhenTokenHasNoAudience: true -requestedScopes: ["oidc"]`, oidcTestServer.URL), - } - - app, err := NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) - require.NoError(t, err) - - req := httptest.NewRequest(http.MethodGet, "https://argocd.example.com/auth/callback", nil) - req.Form = url.Values{ - "code": {"abc"}, - "state": {"123"}, - } - w := httptest.NewRecorder() - - app.HandleCallback(w, req) - - if !strings.Contains(w.Body.String(), "certificate signed by unknown authority") && !strings.Contains(w.Body.String(), "certificate is not trusted") { - t.Fatal("did not receive expected certificate verification failure error") - } - - cdSettings.OIDCTLSInsecureSkipVerify = true - - app, err = NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) - require.NoError(t, err) - - w = httptest.NewRecorder() - - key, err := cdSettings.GetServerEncryptionKey() - require.NoError(t, err) - encrypted, _ := crypto.Encrypt([]byte("123"), key) - req.AddCookie(&http.Cookie{Name: common.StateCookieName, Value: hex.EncodeToString(encrypted)}) - - app.HandleCallback(w, req) - - assert.NotContains(t, w.Body.String(), "certificate is not trusted") - assert.NotContains(t, w.Body.String(), "certificate signed by unknown authority") - }) -} - func TestIsValidRedirect(t *testing.T) { tests := []struct { name string @@ -812,7 +563,7 @@ func TestGenerateAppState_XSS(t *testing.T) { } returnURL, err := app.verifyAppState(req, httptest.NewRecorder(), state) - require.ErrorIs(t, err, ErrInvalidRedirectURL) + require.ErrorIs(t, err, InvalidRedirectURLError) assert.Empty(t, returnURL) }) @@ -843,6 +594,7 @@ func TestGenerateAppState_NoReturnURL(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "/", nil) encrypted, err := crypto.Encrypt([]byte("123"), key) require.NoError(t, err) + app, err := NewClientApp(cdSettings, "", nil, "/argo-cd", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) @@ -856,7 +608,7 @@ func TestGetUserInfo(t *testing.T) { tests := []struct { name string userInfoPath string - expectedOutput any + expectedOutput interface{} expectError bool expectUnauthenticated bool expectedCacheItems []struct { // items to check in cache after function call @@ -892,7 +644,7 @@ func TestGetUserInfo(t *testing.T) { }, }, idpClaims: jwt.MapClaims{"sub": "randomUser", "exp": float64(time.Now().Add(5 * time.Minute).Unix())}, - idpHandler: func(w http.ResponseWriter, _ *http.Request) { + idpHandler: func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) }, cache: cache.NewInMemoryCache(24 * time.Hour), @@ -926,7 +678,7 @@ func TestGetUserInfo(t *testing.T) { }, }, idpClaims: jwt.MapClaims{"sub": "randomUser", "exp": float64(time.Now().Add(5 * time.Minute).Unix())}, - idpHandler: func(w http.ResponseWriter, _ *http.Request) { + idpHandler: func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusUnauthorized) }, cache: cache.NewInMemoryCache(24 * time.Hour), @@ -960,9 +712,9 @@ func TestGetUserInfo(t *testing.T) { }, }, idpClaims: jwt.MapClaims{"sub": "randomUser", "exp": float64(time.Now().Add(5 * time.Minute).Unix())}, - idpHandler: func(w http.ResponseWriter, _ *http.Request) { + idpHandler: func(w http.ResponseWriter, r *http.Request) { userInfoBytes := ` - notevenJsongarbage + notevenJsongarbage ` _, err := w.Write([]byte(userInfoBytes)) if err != nil { @@ -1002,7 +754,7 @@ func TestGetUserInfo(t *testing.T) { }, }, idpClaims: jwt.MapClaims{"sub": "randomUser", "exp": float64(time.Now().Add(5 * time.Minute).Unix())}, - idpHandler: func(w http.ResponseWriter, _ *http.Request) { + idpHandler: func(w http.ResponseWriter, r *http.Request) { userInfoBytes := ` { "groups":["githubOrg:engineers"] @@ -1020,7 +772,7 @@ func TestGetUserInfo(t *testing.T) { { name: "call UserInfo with valid accessToken in cache", userInfoPath: "/user-info", - expectedOutput: jwt.MapClaims{"groups": []any{"githubOrg:engineers"}}, + expectedOutput: jwt.MapClaims{"groups": []interface{}{"githubOrg:engineers"}}, expectError: false, expectUnauthenticated: false, expectedCacheItems: []struct { @@ -1037,7 +789,7 @@ func TestGetUserInfo(t *testing.T) { }, }, idpClaims: jwt.MapClaims{"sub": "randomUser", "exp": float64(time.Now().Add(5 * time.Minute).Unix())}, - idpHandler: func(w http.ResponseWriter, _ *http.Request) { + idpHandler: func(w http.ResponseWriter, r *http.Request) { userInfoBytes := ` { "groups":["githubOrg:engineers"] diff --git a/util/oidc/provider.go b/util/oidc/provider.go index e3131b85a0..36601314d0 100644 --- a/util/oidc/provider.go +++ b/util/oidc/provider.go @@ -11,8 +11,8 @@ import ( log "github.com/sirupsen/logrus" "golang.org/x/oauth2" - "github.com/argoproj/argo-cd/v3/util/security" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/util/security" + "github.com/argoproj/argo-cd/v2/util/settings" ) // Provider is a wrapper around go-oidc provider to also provide the following features: @@ -66,7 +66,7 @@ func (p *providerImpl) newGoOIDCProvider() (*gooidc.Provider, error) { ctx := gooidc.ClientContext(context.Background(), p.client) prov, err := gooidc.NewProvider(ctx, p.issuerURL) if err != nil { - return nil, fmt.Errorf("failed to query provider %q: %w", p.issuerURL, err) + return nil, fmt.Errorf("Failed to query provider %q: %w", p.issuerURL, err) } s, _ := ParseConfig(prov) log.Infof("OIDC supported scopes: %v", s.ScopesSupported) @@ -82,7 +82,7 @@ func (t tokenVerificationError) Error() string { for aud, err := range t.errorsByAudience { errorStrings = append(errorStrings, fmt.Sprintf("error for aud %q: %v", aud, err)) } - return "token verification failed for all audiences: " + strings.Join(errorStrings, ", ") + return fmt.Sprintf("token verification failed for all audiences: %s", strings.Join(errorStrings, ", ")) } func (p *providerImpl) Verify(tokenString string, argoSettings *settings.ArgoCDSettings) (*gooidc.IDToken, error) { diff --git a/util/oidc/templates.go b/util/oidc/templates.go index 1a57d375d6..4b013edea0 100644 --- a/util/oidc/templates.go +++ b/util/oidc/templates.go @@ -51,7 +51,7 @@ func renderToken(w http.ResponseWriter, redirectURL, idToken, refreshToken strin }) } -func renderTemplate(w http.ResponseWriter, tmpl *template.Template, data any) { +func renderTemplate(w http.ResponseWriter, tmpl *template.Template, data interface{}) { err := tmpl.Execute(w, data) if err == nil { return diff --git a/util/password/password.go b/util/password/password.go index 6faeaf9412..5544a4fc84 100644 --- a/util/password/password.go +++ b/util/password/password.go @@ -2,7 +2,7 @@ package password import ( "crypto/subtle" - "errors" + "fmt" "golang.org/x/crypto/bcrypt" ) @@ -35,7 +35,7 @@ var preferredHashers = []PasswordHasher{ func hashPasswordWithHashers(password string, hashers []PasswordHasher) (string, error) { // Even though good hashers will disallow blank passwords, let's be explicit that ALL BLANK PASSWORDS ARE INVALID. Full stop. if password == "" { - return "", errors.New("blank passwords are not allowed") + return "", fmt.Errorf("blank passwords are not allowed") } return hashers[0].HashPassword(password) } @@ -80,7 +80,7 @@ func (h DummyPasswordHasher) HashPassword(password string) (string, error) { // VerifyPassword validates whether a one-way digest ("hash") of a password was created from a given plaintext password. func (h DummyPasswordHasher) VerifyPassword(password, hashedPassword string) bool { - return subtle.ConstantTimeCompare([]byte(password), []byte(hashedPassword)) == 1 + return 1 == subtle.ConstantTimeCompare([]byte(password), []byte(hashedPassword)) } // HashPassword creates a one-way digest ("hash") of a password. In the case of Bcrypt, a pseudorandom salt is included automatically by the underlying library. For security reasons, the work factor is always at _least_ bcrypt.DefaultCost. diff --git a/util/password/password_test.go b/util/password/password_test.go index 06d2d16b77..bbdf1ebb51 100644 --- a/util/password/password_test.go +++ b/util/password/password_test.go @@ -2,9 +2,6 @@ package password import ( "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func testPasswordHasher(t *testing.T, h PasswordHasher) { @@ -15,8 +12,12 @@ func testPasswordHasher(t *testing.T, h PasswordHasher) { pollution = "extradata12345" ) hashedPassword, _ := h.HashPassword(defaultPassword) - assert.True(t, h.VerifyPassword(defaultPassword, hashedPassword), "Password %q should have validated against hash %q", defaultPassword, hashedPassword) - assert.False(t, h.VerifyPassword(defaultPassword, pollution+hashedPassword), "Password %q should NOT have validated against hash %q", defaultPassword, pollution+hashedPassword) + if !h.VerifyPassword(defaultPassword, hashedPassword) { + t.Errorf("Password %q should have validated against hash %q", defaultPassword, hashedPassword) + } + if h.VerifyPassword(defaultPassword, pollution+hashedPassword) { + t.Errorf("Password %q should NOT have validated against hash %q", defaultPassword, pollution+hashedPassword) + } } func TestBcryptPasswordHasher(t *testing.T) { @@ -42,15 +43,27 @@ func TestPasswordHashing(t *testing.T) { hashedPassword, _ := hashPasswordWithHashers(defaultPassword, hashers) valid, stale := verifyPasswordWithHashers(defaultPassword, hashedPassword, hashers) - assert.True(t, valid, "Password %q should have validated against hash %q", defaultPassword, hashedPassword) - assert.False(t, stale, "Password %q should not have been marked stale against hash %q", defaultPassword, hashedPassword) + if !valid { + t.Errorf("Password %q should have validated against hash %q", defaultPassword, hashedPassword) + } + if stale { + t.Errorf("Password %q should not have been marked stale against hash %q", defaultPassword, hashedPassword) + } valid, stale = verifyPasswordWithHashers(defaultPassword, defaultPassword, hashers) - assert.True(t, valid, "Password %q should have validated against itself with dummy hasher", defaultPassword) - assert.True(t, stale, "Password %q should have been acknowledged stale against itself with dummy hasher", defaultPassword) + if !valid { + t.Errorf("Password %q should have validated against itself with dummy hasher", defaultPassword) + } + if !stale { + t.Errorf("Password %q should have been acknowledged stale against itself with dummy hasher", defaultPassword) + } hashedPassword, err := hashPasswordWithHashers(blankPassword, hashers) - require.Error(t, err, "Blank password should have produced error, rather than hash %q", hashedPassword) + if err == nil { + t.Errorf("Blank password should have produced error, rather than hash %q", hashedPassword) + } valid, _ = verifyPasswordWithHashers(blankPassword, "", hashers) - assert.False(t, valid, "Blank password should have failed verification") + if valid != false { + t.Errorf("Blank password should have failed verification") + } } diff --git a/util/profile/profile.go b/util/profile/profile.go index ef3c71b03c..5a31cc306f 100644 --- a/util/profile/profile.go +++ b/util/profile/profile.go @@ -5,7 +5,7 @@ import ( "net/http/pprof" "os" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/util/env" ) var enableProfilerFilePath = env.StringFromEnv("ARGOCD_ENABLE_PROFILER_FILE_PATH", "/home/argocd/params/profiler.enabled") diff --git a/util/profile/profile_test.go b/util/profile/profile_test.go index 3bb43badf8..3af520af64 100644 --- a/util/profile/profile_test.go +++ b/util/profile/profile_test.go @@ -28,7 +28,7 @@ func TestRegisterProfile_FileExist(t *testing.T) { srv := httptest.NewServer(mux) defer srv.Close() - f, err := os.CreateTemp(t.TempDir(), "test") + f, err := os.CreateTemp("", "test") require.NoError(t, err) _, err = f.WriteString("true") require.NoError(t, err) diff --git a/util/proxy/proxy.go b/util/proxy/proxy.go index c4349e8ad4..bef4ce47b8 100644 --- a/util/proxy/proxy.go +++ b/util/proxy/proxy.go @@ -1,6 +1,7 @@ package proxy import ( + "fmt" "net/http" "net/url" "os/exec" @@ -46,13 +47,13 @@ func GetCallback(proxy string, noProxy string) func(*http.Request) (*url.URL, er } func httpProxy(url string) string { - return "http_proxy=" + url + return fmt.Sprintf("http_proxy=%s", url) } func httpsProxy(url string) string { - return "https_proxy=" + url + return fmt.Sprintf("https_proxy=%s", url) } func noProxyVar(noProxy string) string { - return "no_proxy=" + noProxy + return fmt.Sprintf("no_proxy=%s", noProxy) } diff --git a/util/proxy/proxy_test.go b/util/proxy/proxy_test.go index 657b83efe6..85e31685c9 100644 --- a/util/proxy/proxy_test.go +++ b/util/proxy/proxy_test.go @@ -18,7 +18,7 @@ func TestAddProxyEnvIfAbsent(t *testing.T) { cmd := exec.Command("test") cmd.Env = []string{`http_proxy="https_proxy=https://env-proxy:8888"`, "key=val", "no_proxy=.argoproj.io"} got := UpsertEnv(cmd, proxy, noProxy) - assert.Equal(t, []string{"key=val", httpProxy(proxy), httpsProxy(proxy), noProxyVar(noProxy)}, got) + assert.EqualValues(t, []string{"key=val", httpProxy(proxy), httpsProxy(proxy), noProxyVar(noProxy)}, got) }) t.Run("proxy env variables not found", func(t *testing.T) { proxy := "http://proxy:5000" @@ -26,7 +26,7 @@ func TestAddProxyEnvIfAbsent(t *testing.T) { cmd := exec.Command("test") cmd.Env = []string{"key=val"} got := UpsertEnv(cmd, proxy, noProxy) - assert.Equal(t, []string{"key=val", httpProxy(proxy), httpsProxy(proxy), noProxyVar(noProxy)}, got) + assert.EqualValues(t, []string{"key=val", httpProxy(proxy), httpsProxy(proxy), noProxyVar(noProxy)}, got) }) } diff --git a/util/rand/rand.go b/util/rand/rand.go index 82603da176..1e748bf93b 100644 --- a/util/rand/rand.go +++ b/util/rand/rand.go @@ -2,7 +2,6 @@ package rand import ( "crypto/rand" - "encoding/hex" "fmt" "math/big" ) @@ -29,12 +28,3 @@ func StringFromCharset(n int, charset string) (string, error) { } return string(b), nil } - -// RandHex returns a cryptographically-secure pseudo-random alpha-numeric string of a given length -func RandHex(n int) (string, error) { - bytes := make([]byte, n/2+1) // we need one extra letter to discard - if _, err := rand.Read(bytes); err != nil { - return "", err - } - return hex.EncodeToString(bytes)[0:n], nil -} diff --git a/util/rand/rand_test.go b/util/rand/rand_test.go index 09366f8652..d696c0e22c 100644 --- a/util/rand/rand_test.go +++ b/util/rand/rand_test.go @@ -16,12 +16,3 @@ func TestRandString(t *testing.T) { require.NoError(t, err) assert.Len(t, ss, 5) } - -func TestRandHex(t *testing.T) { - ss, err := RandHex(10) - require.NoError(t, err) - assert.Len(t, ss, 10) - ss, err = RandHex(5) - require.NoError(t, err) - assert.Len(t, ss, 5) -} diff --git a/util/rbac/rbac.go b/util/rbac/rbac.go index 2da3495e6e..14bc91bd0a 100644 --- a/util/rbac/rbac.go +++ b/util/rbac/rbac.go @@ -10,25 +10,24 @@ import ( "sync" "time" - "github.com/argoproj/argo-cd/v3/util/assets" - claimsutil "github.com/argoproj/argo-cd/v3/util/claims" - "github.com/argoproj/argo-cd/v3/util/glob" - jwtutil "github.com/argoproj/argo-cd/v3/util/jwt" + "github.com/argoproj/argo-cd/v2/util/assets" + "github.com/argoproj/argo-cd/v2/util/glob" + jwtutil "github.com/argoproj/argo-cd/v2/util/jwt" "github.com/casbin/casbin/v2" "github.com/casbin/casbin/v2/model" "github.com/casbin/casbin/v2/util" "github.com/casbin/govaluate" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" gocache "github.com/patrickmn/go-cache" log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + apiv1 "k8s.io/api/core/v1" + apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" - informersv1 "k8s.io/client-go/informers/core/v1" + v1 "k8s.io/client-go/informers/core/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" ) @@ -47,13 +46,11 @@ const ( // CasbinEnforcer represents methods that must be implemented by a Casbin enforces type CasbinEnforcer interface { EnableLog(bool) - Enforce(rvals ...any) (bool, error) + Enforce(rvals ...interface{}) (bool, error) LoadPolicy() error EnableEnforce(bool) AddFunction(name string, function govaluate.ExpressionFunction) GetGroupingPolicy() ([][]string, error) - GetAllRoles() ([]string, error) - GetImplicitPermissionsForUser(user string, domain ...string) ([][]string, error) } const ( @@ -156,16 +153,16 @@ func (e *Enforcer) invalidateCache(actions ...func()) { e.enforcerCache.Flush() } -func (e *Enforcer) getCasbinEnforcer(project string, policy string) CasbinEnforcer { - res, err := e.tryGetCasbinEnforcer(project, policy) +func (e *Enforcer) getCabinEnforcer(project string, policy string) CasbinEnforcer { + res, err := e.tryGetCabinEnforcer(project, policy) if err != nil { panic(err) } return res } -// tryGetCasbinEnforcer returns the cached enforcer for the given optional project and project policy. -func (e *Enforcer) tryGetCasbinEnforcer(project string, policy string) (CasbinEnforcer, error) { +// tryGetCabinEnforcer returns the cached enforcer for the given optional project and project policy. +func (e *Enforcer) tryGetCabinEnforcer(project string, policy string) (CasbinEnforcer, error) { e.lock.Lock() defer e.lock.Unlock() var cached *cachedEnforcer @@ -206,9 +203,9 @@ func (e *Enforcer) tryGetCasbinEnforcer(project string, policy string) (CasbinEn } // ClaimsEnforcerFunc is func template to enforce a JWT claims. The subject is replaced -type ClaimsEnforcerFunc func(claims jwt.Claims, rvals ...any) bool +type ClaimsEnforcerFunc func(claims jwt.Claims, rvals ...interface{}) bool -func newEnforcerSafe(matchFunction govaluate.ExpressionFunction, params ...any) (e CasbinEnforcer, err error) { +func newEnforcerSafe(matchFunction govaluate.ExpressionFunction, params ...interface{}) (e CasbinEnforcer, err error) { defer func() { if r := recover(); r != nil { err = fmt.Errorf("%v", r) @@ -254,34 +251,12 @@ func (e *Enforcer) EnableEnforce(s bool) { // LoadPolicy executes casbin.Enforcer functionality and will invalidate cache if required. func (e *Enforcer) LoadPolicy() error { - _, err := e.tryGetCasbinEnforcer("", "") + _, err := e.tryGetCabinEnforcer("", "") return err } -// CheckUserDefinedRoleReferentialIntegrity iterates over roles and policies to validate the existence of a matching policy subject for every defined role -func CheckUserDefinedRoleReferentialIntegrity(e CasbinEnforcer) error { - allRoles, err := e.GetAllRoles() - if err != nil { - return err - } - notFound := make([]string, 0) - for _, roleName := range allRoles { - permissions, err := e.GetImplicitPermissionsForUser(roleName) - if err != nil { - return err - } - if len(permissions) == 0 { - notFound = append(notFound, roleName) - } - } - if len(notFound) > 0 { - return fmt.Errorf("user defined roles not found in policies: %s", strings.Join(notFound, ",")) - } - return nil -} - // Glob match func -func globMatchFunc(args ...any) (any, error) { +func globMatchFunc(args ...interface{}) (interface{}, error) { if len(args) < 2 { return false, nil } @@ -324,37 +299,34 @@ func (e *Enforcer) SetClaimsEnforcerFunc(claimsEnforcer ClaimsEnforcerFunc) { // Enforce is a wrapper around casbin.Enforce to additionally enforce a default role and a custom // claims function -func (e *Enforcer) Enforce(rvals ...any) bool { - return enforce(e.getCasbinEnforcer("", ""), e.defaultRole, e.claimsEnforcerFunc, rvals...) +func (e *Enforcer) Enforce(rvals ...interface{}) bool { + return enforce(e.getCabinEnforcer("", ""), e.defaultRole, e.claimsEnforcerFunc, rvals...) } // EnforceErr is a convenience helper to wrap a failed enforcement with a detailed error about the request -func (e *Enforcer) EnforceErr(rvals ...any) error { +func (e *Enforcer) EnforceErr(rvals ...interface{}) error { if !e.Enforce(rvals...) { errMsg := "permission denied" - if len(rvals) > 0 { rvalsStrs := make([]string, len(rvals)-1) for i, rval := range rvals[1:] { rvalsStrs[i] = fmt.Sprintf("%s", rval) } - if s, ok := rvals[0].(jwt.Claims); ok { + switch s := rvals[0].(type) { + case jwt.Claims: claims, err := jwtutil.MapClaims(s) - if err == nil { - argoClaims, err := claimsutil.MapClaimsToArgoClaims(claims) - if err == nil { - if argoClaims.GetUserIdentifier() != "" { - rvalsStrs = append(rvalsStrs, "sub: "+argoClaims.GetUserIdentifier()) - } - if issuedAtTime, err := jwtutil.IssuedAtTime(claims); err == nil { - rvalsStrs = append(rvalsStrs, "iat: "+issuedAtTime.Format(time.RFC3339)) - } - } + if err != nil { + break + } + if sub := jwtutil.StringField(claims, "sub"); sub != "" { + rvalsStrs = append(rvalsStrs, fmt.Sprintf("sub: %s", sub)) + } + if issuedAtTime, err := jwtutil.IssuedAtTime(claims); err == nil { + rvalsStrs = append(rvalsStrs, fmt.Sprintf("iat: %s", issuedAtTime.Format(time.RFC3339))) } } errMsg = fmt.Sprintf("%s: %s", errMsg, strings.Join(rvalsStrs, ", ")) } - return status.Error(codes.PermissionDenied, errMsg) } return nil @@ -363,7 +335,7 @@ func (e *Enforcer) EnforceErr(rvals ...any) error { // EnforceRuntimePolicy enforces a policy defined at run-time which augments the built-in and // user-defined policy. This allows any explicit denies of the built-in, and user-defined policies // to override the run-time policy. Runs normal enforcement if run-time policy is empty. -func (e *Enforcer) EnforceRuntimePolicy(project string, policy string, rvals ...any) bool { +func (e *Enforcer) EnforceRuntimePolicy(project string, policy string, rvals ...interface{}) bool { enf := e.CreateEnforcerWithRuntimePolicy(project, policy) return e.EnforceWithCustomEnforcer(enf, rvals...) } @@ -372,19 +344,19 @@ func (e *Enforcer) EnforceRuntimePolicy(project string, policy string, rvals ... // user-defined policy. This allows any explicit denies of the built-in, and user-defined policies // to override the run-time policy. Runs normal enforcement if run-time policy is empty. func (e *Enforcer) CreateEnforcerWithRuntimePolicy(project string, policy string) CasbinEnforcer { - return e.getCasbinEnforcer(project, policy) + return e.getCabinEnforcer(project, policy) } // EnforceWithCustomEnforcer wraps enforce with an custom enforcer -func (e *Enforcer) EnforceWithCustomEnforcer(enf CasbinEnforcer, rvals ...any) bool { +func (e *Enforcer) EnforceWithCustomEnforcer(enf CasbinEnforcer, rvals ...interface{}) bool { return enforce(enf, e.defaultRole, e.claimsEnforcerFunc, rvals...) } // enforce is a helper to additionally check a default role and invoke a custom claims enforcement function -func enforce(enf CasbinEnforcer, defaultRole string, claimsEnforcerFunc ClaimsEnforcerFunc, rvals ...any) bool { +func enforce(enf CasbinEnforcer, defaultRole string, claimsEnforcerFunc ClaimsEnforcerFunc, rvals ...interface{}) bool { // check the default role if defaultRole != "" && len(rvals) >= 2 { - if ok, err := enf.Enforce(append([]any{defaultRole}, rvals[1:]...)...); ok && err == nil { + if ok, err := enf.Enforce(append([]interface{}{defaultRole}, rvals[1:]...)...); ok && err == nil { return true } } @@ -401,9 +373,9 @@ func enforce(enf CasbinEnforcer, defaultRole string, claimsEnforcerFunc ClaimsEn if claimsEnforcerFunc != nil && claimsEnforcerFunc(s, rvals...) { return true } - rvals = append([]any{""}, rvals[1:]...) + rvals = append([]interface{}{""}, rvals[1:]...) default: - rvals = append([]any{""}, rvals[1:]...) + rvals = append([]interface{}{""}, rvals[1:]...) } ok, err := enf.Enforce(rvals...) return ok && err == nil @@ -428,18 +400,18 @@ func (e *Enforcer) SetUserPolicy(policy string) error { // newInformers returns an informer which watches updates on the rbac configmap func (e *Enforcer) newInformer() cache.SharedIndexInformer { tweakConfigMap := func(options *metav1.ListOptions) { - cmFieldSelector := fields.ParseSelectorOrDie("metadata.name=" + e.configmap) + cmFieldSelector := fields.ParseSelectorOrDie(fmt.Sprintf("metadata.name=%s", e.configmap)) options.FieldSelector = cmFieldSelector.String() } indexers := cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc} - return informersv1.NewFilteredConfigMapInformer(e.clientset, e.namespace, defaultRBACSyncPeriod, indexers, tweakConfigMap) + return v1.NewFilteredConfigMapInformer(e.clientset, e.namespace, defaultRBACSyncPeriod, indexers, tweakConfigMap) } // RunPolicyLoader runs the policy loader which watches policy updates from the configmap and reloads them -func (e *Enforcer) RunPolicyLoader(ctx context.Context, onUpdated func(cm *corev1.ConfigMap) error) error { +func (e *Enforcer) RunPolicyLoader(ctx context.Context, onUpdated func(cm *apiv1.ConfigMap) error) error { cm, err := e.clientset.CoreV1().ConfigMaps(e.namespace).Get(ctx, e.configmap, metav1.GetOptions{}) if err != nil { - if !apierrors.IsNotFound(err) { + if !apierr.IsNotFound(err) { return err } } else { @@ -452,12 +424,12 @@ func (e *Enforcer) RunPolicyLoader(ctx context.Context, onUpdated func(cm *corev return nil } -func (e *Enforcer) runInformer(ctx context.Context, onUpdated func(cm *corev1.ConfigMap) error) { +func (e *Enforcer) runInformer(ctx context.Context, onUpdated func(cm *apiv1.ConfigMap) error) { cmInformer := e.newInformer() _, err := cmInformer.AddEventHandler( cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj any) { - if cm, ok := obj.(*corev1.ConfigMap); ok { + AddFunc: func(obj interface{}) { + if cm, ok := obj.(*apiv1.ConfigMap); ok { err := e.syncUpdate(cm, onUpdated) if err != nil { log.Error(err) @@ -466,9 +438,9 @@ func (e *Enforcer) runInformer(ctx context.Context, onUpdated func(cm *corev1.Co } } }, - UpdateFunc: func(old, new any) { - oldCM := old.(*corev1.ConfigMap) - newCM := new.(*corev1.ConfigMap) + UpdateFunc: func(old, new interface{}) { + oldCM := old.(*apiv1.ConfigMap) + newCM := new.(*apiv1.ConfigMap) if oldCM.ResourceVersion == newCM.ResourceVersion { return } @@ -521,7 +493,7 @@ func PolicyCSV(data map[string]string) string { } // syncUpdate updates the enforcer -func (e *Enforcer) syncUpdate(cm *corev1.ConfigMap, onUpdated func(cm *corev1.ConfigMap) error) error { +func (e *Enforcer) syncUpdate(cm *apiv1.ConfigMap, onUpdated func(cm *apiv1.ConfigMap) error) error { e.SetDefaultRole(cm.Data[ConfigMapPolicyDefaultKey]) e.SetMatchMode(cm.Data[ConfigMapMatchModeKey]) policyCSV := PolicyCSV(cm.Data) @@ -533,15 +505,10 @@ func (e *Enforcer) syncUpdate(cm *corev1.ConfigMap, onUpdated func(cm *corev1.Co // ValidatePolicy verifies a policy string is acceptable to casbin func ValidatePolicy(policy string) error { - casbinEnforcer, err := newEnforcerSafe(globMatchFunc, newBuiltInModel(), newAdapter("", "", policy)) + _, err := newEnforcerSafe(globMatchFunc, newBuiltInModel(), newAdapter("", "", policy)) if err != nil { return fmt.Errorf("policy syntax error: %s", policy) } - - // Check for referential integrity - if err := CheckUserDefinedRoleReferentialIntegrity(casbinEnforcer); err != nil { - log.Warning(err.Error()) - } return nil } @@ -617,18 +584,18 @@ func loadPolicyLine(line string, model model.Model) error { return nil } -func (a *argocdAdapter) SavePolicy(_ model.Model) error { +func (a *argocdAdapter) SavePolicy(model model.Model) error { return errors.New("not implemented") } -func (a *argocdAdapter) AddPolicy(_ string, _ string, _ []string) error { +func (a *argocdAdapter) AddPolicy(sec string, ptype string, rule []string) error { return errors.New("not implemented") } -func (a *argocdAdapter) RemovePolicy(_ string, _ string, _ []string) error { +func (a *argocdAdapter) RemovePolicy(sec string, ptype string, rule []string) error { return errors.New("not implemented") } -func (a *argocdAdapter) RemoveFilteredPolicy(_ string, _ string, _ int, _ ...string) error { +func (a *argocdAdapter) RemoveFilteredPolicy(sec string, ptype string, fieldIndex int, fieldValues ...string) error { return errors.New("not implemented") } diff --git a/util/rbac/rbac_norace_test.go b/util/rbac/rbac_norace_test.go index 2192ad8113..80314d04f3 100644 --- a/util/rbac/rbac_norace_test.go +++ b/util/rbac/rbac_norace_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + apiv1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes/fake" ) @@ -29,10 +29,10 @@ func TestPolicyInformer(t *testing.T) { kubeclientset := fake.NewClientset(cm) enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) - ctx := t.Context() + ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() - go enf.runInformer(ctx, func(_ *corev1.ConfigMap) error { + go enf.runInformer(ctx, func(cm *apiv1.ConfigMap) error { return nil }) diff --git a/util/rbac/rbac_test.go b/util/rbac/rbac_test.go index 210b91918c..8bf1b780af 100644 --- a/util/rbac/rbac_test.go +++ b/util/rbac/rbac_test.go @@ -2,21 +2,20 @@ package rbac import ( "context" + "fmt" "strings" "testing" "time" - "github.com/argoproj/argo-cd/v3/util/test" - - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + apiv1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/util/assets" + "github.com/argoproj/argo-cd/v2/util/assets" ) const ( @@ -24,12 +23,12 @@ const ( fakeNamespace = "fake-ns" ) -var noOpUpdate = func(_ *corev1.ConfigMap) error { +var noOpUpdate = func(cm *apiv1.ConfigMap) error { return nil } -func fakeConfigMap() *corev1.ConfigMap { - cm := corev1.ConfigMap{ +func fakeConfigMap() *apiv1.ConfigMap { + cm := apiv1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", APIVersion: "v1", @@ -52,7 +51,7 @@ func TestPolicyCSV(t *testing.T) { policy := PolicyCSV(data) // then - assert.Empty(t, policy) + assert.Equal(t, "", policy) }) t.Run("will return just policy defined with default key", func(t *testing.T) { // given @@ -117,7 +116,7 @@ func TestBuiltinPolicyEnforcer(t *testing.T) { // now set builtin policy _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) - allowed := [][]any{ + allowed := [][]interface{}{ {"admin", "applications", "get", "foo/bar"}, {"admin", "applications", "delete", "foo/bar"}, {"role:readonly", "applications", "get", "foo/bar"}, @@ -130,7 +129,7 @@ func TestBuiltinPolicyEnforcer(t *testing.T) { } } - disallowed := [][]any{ + disallowed := [][]interface{}{ {"role:readonly", "applications", "create", "foo/bar"}, {"role:readonly", "applications", "delete", "foo/bar"}, } @@ -217,7 +216,7 @@ p, alice, *, get, foo/obj, allow p, mike, *, get, foo/obj, deny ` _ = enf.SetUserPolicy(policy) - enf.SetClaimsEnforcerFunc(func(_ jwt.Claims, _ ...any) bool { + enf.SetClaimsEnforcerFunc(func(claims jwt.Claims, rvals ...interface{}) bool { return false }) @@ -273,44 +272,6 @@ func TestNoPolicy(t *testing.T) { assert.False(t, enf.Enforce("admin", "applications", "delete", "foo/bar")) } -// TestValidatePolicyCheckUserDefinedPolicyReferentialIntegrity adds a hook into logrus.StandardLogger and validates -// policies with and without referential integrity issues. Log entries are searched to verify expected outcomes. -func TestValidatePolicyCheckUserDefinedPolicyReferentialIntegrity(t *testing.T) { - // Policy with referential integrity - policy := ` -p, role:depA, *, get, foo/obj, allow -p, role:depB, *, get, foo/obj, deny -g, depA, role:depA -g, depB, role:depB -` - hook := test.LogHook{} - log.AddHook(&hook) - t.Cleanup(func() { - log.StandardLogger().ReplaceHooks(log.LevelHooks{}) - }) - require.NoError(t, ValidatePolicy(policy)) - assert.Empty(t, hook.GetRegexMatchesInEntries("user defined roles not found in policies")) - - // Policy with a role reference which transitively associates to policies - policy = ` -p, role:depA, *, get, foo/obj, allow -p, role:depB, *, get, foo/obj, deny -g, depC, role:depC -g, role:depC, role:depA -` - require.NoError(t, ValidatePolicy(policy)) - assert.Empty(t, hook.GetRegexMatchesInEntries("user defined roles not found in policies")) - - // Policy with a role reference which has no associated policies - policy = ` -p, role:depA, *, get, foo/obj, allow -p, role:depB, *, get, foo/obj, deny -g, depC, role:depC -` - require.NoError(t, ValidatePolicy(policy)) - assert.Len(t, hook.GetRegexMatchesInEntries("user defined roles not found in policies: role:depC"), 1) -} - // TestClaimsEnforcerFunc tests func TestClaimsEnforcerFunc(t *testing.T) { kubeclientset := fake.NewClientset() @@ -319,7 +280,7 @@ func TestClaimsEnforcerFunc(t *testing.T) { Subject: "foo", } assert.False(t, enf.Enforce(&claims, "applications", "get", "foo/bar")) - enf.SetClaimsEnforcerFunc(func(_ jwt.Claims, _ ...any) bool { + enf.SetClaimsEnforcerFunc(func(claims jwt.Claims, rvals ...interface{}) bool { return true }) assert.True(t, enf.Enforce(&claims, "applications", "get", "foo/bar")) @@ -348,7 +309,7 @@ func TestClaimsEnforcerFuncWithRuntimePolicy(t *testing.T) { Subject: "foo", } assert.False(t, enf.EnforceRuntimePolicy("", runtimePolicy, claims, "applications", "get", "foo/bar")) - enf.SetClaimsEnforcerFunc(func(_ jwt.Claims, _ ...any) bool { + enf.SetClaimsEnforcerFunc(func(claims jwt.Claims, rvals ...interface{}) bool { return true }) assert.True(t, enf.EnforceRuntimePolicy("", runtimePolicy, claims, "applications", "get", "foo/bar")) @@ -395,27 +356,39 @@ func TestEnforceErrorMessage(t *testing.T) { err := enf.syncUpdate(fakeConfigMap(), noOpUpdate) require.NoError(t, err) - require.EqualError(t, enf.EnforceErr("admin", "applications", "get", "foo/bar"), "rpc error: code = PermissionDenied desc = permission denied: applications, get, foo/bar") + err = enf.EnforceErr("admin", "applications", "get", "foo/bar") + require.Error(t, err) + assert.Equal(t, "rpc error: code = PermissionDenied desc = permission denied: applications, get, foo/bar", err.Error()) - require.EqualError(t, enf.EnforceErr(), "rpc error: code = PermissionDenied desc = permission denied") + err = enf.EnforceErr() + require.Error(t, err) + assert.Equal(t, "rpc error: code = PermissionDenied desc = permission denied", err.Error()) - //nolint:staticcheck - ctx := context.WithValue(t.Context(), "claims", &jwt.RegisteredClaims{Subject: "proj:default:admin"}) - require.EqualError(t, enf.EnforceErr(ctx.Value("claims"), "project"), "rpc error: code = PermissionDenied desc = permission denied: project, sub: proj:default:admin") + // nolint:staticcheck + ctx := context.WithValue(context.Background(), "claims", &jwt.RegisteredClaims{Subject: "proj:default:admin"}) + err = enf.EnforceErr(ctx.Value("claims"), "project") + require.Error(t, err) + assert.Equal(t, "rpc error: code = PermissionDenied desc = permission denied: project, sub: proj:default:admin", err.Error()) iat := time.Unix(int64(1593035962), 0).Format(time.RFC3339) - exp := "rpc error: code = PermissionDenied desc = permission denied: project, sub: proj:default:admin, iat: " + iat - //nolint:staticcheck - ctx = context.WithValue(t.Context(), "claims", &jwt.RegisteredClaims{Subject: "proj:default:admin", IssuedAt: jwt.NewNumericDate(time.Unix(int64(1593035962), 0))}) - require.EqualError(t, enf.EnforceErr(ctx.Value("claims"), "project"), exp) + exp := fmt.Sprintf("rpc error: code = PermissionDenied desc = permission denied: project, sub: proj:default:admin, iat: %s", iat) + // nolint:staticcheck + ctx = context.WithValue(context.Background(), "claims", &jwt.RegisteredClaims{Subject: "proj:default:admin", IssuedAt: jwt.NewNumericDate(time.Unix(int64(1593035962), 0))}) + err = enf.EnforceErr(ctx.Value("claims"), "project") + require.Error(t, err) + assert.Equal(t, exp, err.Error()) - //nolint:staticcheck - ctx = context.WithValue(t.Context(), "claims", &jwt.RegisteredClaims{ExpiresAt: jwt.NewNumericDate(time.Now())}) - require.EqualError(t, enf.EnforceErr(ctx.Value("claims"), "project"), "rpc error: code = PermissionDenied desc = permission denied: project") + // nolint:staticcheck + ctx = context.WithValue(context.Background(), "claims", &jwt.RegisteredClaims{ExpiresAt: jwt.NewNumericDate(time.Now())}) + err = enf.EnforceErr(ctx.Value("claims"), "project") + require.Error(t, err) + assert.Equal(t, "rpc error: code = PermissionDenied desc = permission denied: project", err.Error()) - //nolint:staticcheck - ctx = context.WithValue(t.Context(), "claims", &jwt.RegisteredClaims{Subject: "proj:default:admin", IssuedAt: nil}) - assert.EqualError(t, enf.EnforceErr(ctx.Value("claims"), "project"), "rpc error: code = PermissionDenied desc = permission denied: project, sub: proj:default:admin") + // nolint:staticcheck + ctx = context.WithValue(context.Background(), "claims", &jwt.RegisteredClaims{Subject: "proj:default:admin", IssuedAt: nil}) + err = enf.EnforceErr(ctx.Value("claims"), "project") + require.Error(t, err) + assert.Equal(t, "rpc error: code = PermissionDenied desc = permission denied: project, sub: proj:default:admin", err.Error()) } func TestDefaultGlobMatchMode(t *testing.T) { diff --git a/util/resource/revision_test.go b/util/resource/revision_test.go index 38927fa397..b6bd395ad7 100644 --- a/util/resource/revision_test.go +++ b/util/resource/revision_test.go @@ -4,10 +4,9 @@ import ( "testing" . "github.com/argoproj/gitops-engine/pkg/utils/testing" - "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/v3/test" + "github.com/argoproj/argo-cd/v2/test" ) func TestGetRevision(t *testing.T) { @@ -29,7 +28,9 @@ func TestGetRevision(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, GetRevision(tt.args.obj), "GetRevision()") + if got := GetRevision(tt.args.obj); got != tt.want { + t.Errorf("GetRevision() = %v, want %v", got, tt.want) + } }) } } diff --git a/util/security/application_namespaces.go b/util/security/application_namespaces.go index 43594fd938..89019beb6f 100644 --- a/util/security/application_namespaces.go +++ b/util/security/application_namespaces.go @@ -3,7 +3,7 @@ package security import ( "fmt" - "github.com/argoproj/argo-cd/v3/util/glob" + "github.com/argoproj/argo-cd/v2/util/glob" ) func IsNamespaceEnabled(namespace string, serverNamespace string, enabledNamespaces []string) bool { diff --git a/util/security/jwt_test.go b/util/security/jwt_test.go index c164dfc14a..f8131259c1 100644 --- a/util/security/jwt_test.go +++ b/util/security/jwt_test.go @@ -4,11 +4,11 @@ import ( "testing" "time" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - utiltest "github.com/argoproj/argo-cd/v3/util/test" + utiltest "github.com/argoproj/argo-cd/v2/util/test" ) func Test_UnverifiedHasAudClaim(t *testing.T) { diff --git a/util/security/rbac.go b/util/security/rbac.go index dbb56eeb12..d80cbbadb3 100644 --- a/util/security/rbac.go +++ b/util/security/rbac.go @@ -8,6 +8,7 @@ import ( func RBACName(defaultNS string, project string, namespace string, name string) string { if defaultNS != "" && namespace != defaultNS && namespace != "" { return fmt.Sprintf("%s/%s/%s", project, namespace, name) + } else { + return fmt.Sprintf("%s/%s", project, name) } - return fmt.Sprintf("%s/%s", project, name) } diff --git a/util/session/sessionmanager.go b/util/session/sessionmanager.go index f2335d1240..2813443fa1 100644 --- a/util/session/sessionmanager.go +++ b/util/session/sessionmanager.go @@ -14,25 +14,23 @@ import ( "time" "github.com/coreos/go-oidc/v3/oidc" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" "github.com/google/uuid" log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/argoproj/argo-cd/v3/server/rbacpolicy" - - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/util/cache/appstate" - claimsutil "github.com/argoproj/argo-cd/v3/util/claims" - "github.com/argoproj/argo-cd/v3/util/dex" - "github.com/argoproj/argo-cd/v3/util/env" - httputil "github.com/argoproj/argo-cd/v3/util/http" - jwtutil "github.com/argoproj/argo-cd/v3/util/jwt" - oidcutil "github.com/argoproj/argo-cd/v3/util/oidc" - passwordutil "github.com/argoproj/argo-cd/v3/util/password" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/server/rbacpolicy" + "github.com/argoproj/argo-cd/v2/util/cache/appstate" + "github.com/argoproj/argo-cd/v2/util/dex" + "github.com/argoproj/argo-cd/v2/util/env" + httputil "github.com/argoproj/argo-cd/v2/util/http" + jwtutil "github.com/argoproj/argo-cd/v2/util/jwt" + oidcutil "github.com/argoproj/argo-cd/v2/util/oidc" + passwordutil "github.com/argoproj/argo-cd/v2/util/password" + "github.com/argoproj/argo-cd/v2/util/settings" ) // SessionManager generates and validates JWT tokens for login sessions. @@ -158,15 +156,15 @@ func NewSessionManager(settingsMgr *settings.SettingsManager, projectsLister v1a // Passing a value of `0` for secondsBeforeExpiry creates a token that never expires. // The id parameter holds an optional unique JWT token identifier and stored as a standard claim "jti" in the JWT token. func (mgr *SessionManager) Create(subject string, secondsBeforeExpiry int64, id string) (string, error) { + // Create a new token object, specifying signing method and the claims + // you would like it to contain. now := time.Now().UTC() - claims := claimsutil.ArgoClaims{ - RegisteredClaims: jwt.RegisteredClaims{ - IssuedAt: jwt.NewNumericDate(now), - Issuer: SessionManagerClaimsIssuer, - NotBefore: jwt.NewNumericDate(now), - Subject: subject, - ID: id, - }, + claims := jwt.RegisteredClaims{ + IssuedAt: jwt.NewNumericDate(now), + Issuer: SessionManagerClaimsIssuer, + NotBefore: jwt.NewNumericDate(now), + Subject: subject, + ID: id, } if secondsBeforeExpiry > 0 { expires := now.Add(time.Duration(secondsBeforeExpiry) * time.Second) @@ -222,17 +220,13 @@ func (mgr *SessionManager) Parse(tokenString string) (jwt.Claims, string, error) if err != nil { return nil, "", err } - argoClaims, err := claimsutil.MapClaimsToArgoClaims(claims) - if err != nil { - return nil, "", err - } issuedAt, err := jwtutil.IssuedAtTime(claims) if err != nil { return nil, "", err } - subject := argoClaims.GetUserIdentifier() + subject := jwtutil.StringField(claims, "sub") id := jwtutil.StringField(claims, "jti") if projName, role, ok := rbacpolicy.GetProjectRoleFromSubject(subject); ok { @@ -509,7 +503,7 @@ func WithAuthMiddleware(disabled bool, authn TokenVerifier, next http.Handler) h } ctx := r.Context() // Add claims to the context to inspect for RBAC - //nolint:staticcheck + // nolint:staticcheck ctx = context.WithValue(ctx, "claims", claims) r = r.WithContext(ctx) } @@ -521,14 +515,12 @@ func WithAuthMiddleware(disabled bool, authn TokenVerifier, next http.Handler) h // We choose how to verify based on the issuer. func (mgr *SessionManager) VerifyToken(tokenString string) (jwt.Claims, string, error) { parser := jwt.NewParser(jwt.WithoutClaimsValidation()) - claims := jwt.MapClaims{} + var claims jwt.RegisteredClaims _, _, err := parser.ParseUnverified(tokenString, &claims) if err != nil { return nil, "", err } - // Get issuer from MapClaims - issuer, _ := claims["iss"].(string) - switch issuer { + switch claims.Issuer { case SessionManagerClaimsIssuer: // Argo CD signed token return mgr.Parse(tokenString) @@ -555,12 +547,12 @@ func (mgr *SessionManager) VerifyToken(tokenString string) (jwt.Claims, string, log.Warnf("Failed to verify token: %s", err) tokenExpiredError := &oidc.TokenExpiredError{} if errors.As(err, &tokenExpiredError) { - claims = jwt.MapClaims{ - "iss": "sso", + claims = jwt.RegisteredClaims{ + Issuer: "sso", } - return claims, "", common.ErrTokenVerification + return claims, "", common.TokenVerificationErr } - return nil, "", common.ErrTokenVerification + return nil, "", common.TokenVerificationErr } var claims jwt.MapClaims @@ -592,23 +584,20 @@ func (mgr *SessionManager) RevokeToken(ctx context.Context, id string, expiringA } func LoggedIn(ctx context.Context) bool { - return GetUserIdentifier(ctx) != "" && ctx.Value(AuthErrorCtxKey) == nil + return Sub(ctx) != "" && ctx.Value(AuthErrorCtxKey) == nil } // Username is a helper to extract a human readable username from a context func Username(ctx context.Context) string { - argoClaims, ok := argoClaims(ctx) + mapClaims, ok := mapClaims(ctx) if !ok { return "" } - switch argoClaims.Issuer { + switch jwtutil.StringField(mapClaims, "iss") { case SessionManagerClaimsIssuer: - return argoClaims.GetUserIdentifier() + return jwtutil.StringField(mapClaims, "sub") default: - if argoClaims.Email != "" { - return argoClaims.Email - } - return argoClaims.GetUserIdentifier() + return jwtutil.StringField(mapClaims, "email") } } @@ -628,17 +617,12 @@ func Iat(ctx context.Context) (time.Time, error) { return jwtutil.IssuedAtTime(mapClaims) } -// GetUserIdentifier returns the user identifier from context, prioritizing federated claims over subject -func GetUserIdentifier(ctx context.Context) string { +func Sub(ctx context.Context) string { mapClaims, ok := mapClaims(ctx) if !ok { return "" } - argoClaims, err := claimsutil.MapClaimsToArgoClaims(mapClaims) - if err != nil { - return "" - } - return argoClaims.GetUserIdentifier() + return jwtutil.StringField(mapClaims, "sub") } func Groups(ctx context.Context, scopes []string) []string { @@ -660,15 +644,3 @@ func mapClaims(ctx context.Context) (jwt.MapClaims, bool) { } return mapClaims, true } - -func argoClaims(ctx context.Context) (*claimsutil.ArgoClaims, bool) { - mapClaims, ok := mapClaims(ctx) - if !ok { - return nil, false - } - argoClaims, err := claimsutil.MapClaimsToArgoClaims(mapClaims) - if err != nil { - return nil, false - } - return argoClaims, true -} diff --git a/util/session/sessionmanager_norace_test.go b/util/session/sessionmanager_norace_test.go index 083074fae1..ae6e22b030 100644 --- a/util/session/sessionmanager_norace_test.go +++ b/util/session/sessionmanager_norace_test.go @@ -4,24 +4,25 @@ package session import ( + "context" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/util/settings" ) func TestRandomPasswordVerificationDelay(t *testing.T) { // !race: - // `SessionManager.VerifyUsernamePassword` uses bcrypt to prevent against time-based attacks + //`SessionManager.VerifyUsernamePassword` uses bcrypt to prevent against time-based attacks // and verify the hashed password; however this is a CPU intensive algorithm that is made // significantly slower due to data race detection being enabled, which breaks through // the maximum time limit required by `TestRandomPasswordVerificationDelay`. var sleptFor time.Duration - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClient(t, "password", true), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("password", true), "argocd") mgr := newSessionManager(settingsMgr, getProjLister(), NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = true mgr.sleep = func(d time.Duration) { diff --git a/util/session/sessionmanager_test.go b/util/session/sessionmanager_test.go index 7df377b14c..73d8fdb8ea 100644 --- a/util/session/sessionmanager_test.go +++ b/util/session/sessionmanager_test.go @@ -14,7 +14,7 @@ import ( "testing" "time" - "github.com/golang-jwt/jwt/v5" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" @@ -24,28 +24,26 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/fake" - "github.com/argoproj/argo-cd/v3/common" - appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - apps "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/test" - claimsutil "github.com/argoproj/argo-cd/v3/util/claims" - jwtutil "github.com/argoproj/argo-cd/v3/util/jwt" - "github.com/argoproj/argo-cd/v3/util/password" - "github.com/argoproj/argo-cd/v3/util/settings" - utiltest "github.com/argoproj/argo-cd/v3/util/test" + "github.com/argoproj/argo-cd/v2/common" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + apps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/password" + "github.com/argoproj/argo-cd/v2/util/settings" + utiltest "github.com/argoproj/argo-cd/v2/util/test" ) func getProjLister(objects ...runtime.Object) v1alpha1.AppProjectNamespaceLister { return test.NewFakeProjListerFromInterface(apps.NewSimpleClientset(objects...).ArgoprojV1alpha1().AppProjects("argocd")) } -func getKubeClient(t *testing.T, pass string, enabled bool, capabilities ...settings.AccountCapability) *fake.Clientset { - t.Helper() +func getKubeClient(pass string, enabled bool, capabilities ...settings.AccountCapability) *fake.Clientset { const defaultSecretKey = "Hello, world!" bcrypt, err := password.HashPassword(pass) - require.NoError(t, err) + errors.CheckError(err) if len(capabilities) == 0 { capabilities = []settings.AccountCapability{settings.AccountCapabilityLogin, settings.AccountCapabilityApiKey} } @@ -88,33 +86,36 @@ func TestSessionManager_AdminToken(t *testing.T) { redisClient, closer := test.NewInMemoryRedis() defer closer() - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClient(t, "pass", true), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("pass", true), "argocd") mgr := newSessionManager(settingsMgr, getProjLister(), NewUserStateStorage(redisClient)) token, err := mgr.Create("admin:login", 0, "123") - require.NoError(t, err, "Could not create token") + if err != nil { + t.Errorf("Could not create token: %v", err) + } claims, newToken, err := mgr.Parse(token) require.NoError(t, err) assert.Empty(t, newToken) - mapClaims, err := jwtutil.MapClaims(claims) - require.NoError(t, err) - argoClaims, err := claimsutil.MapClaimsToArgoClaims(mapClaims) - require.NoError(t, err) - - assert.Equal(t, "admin", argoClaims.Subject) + mapClaims := *(claims.(*jwt.MapClaims)) + subject := mapClaims["sub"].(string) + if subject != "admin" { + t.Errorf("Token claim subject %q does not match expected subject %q.", subject, "admin") + } } func TestSessionManager_AdminToken_ExpiringSoon(t *testing.T) { redisClient, closer := test.NewInMemoryRedis() defer closer() - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClient(t, "pass", true), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("pass", true), "argocd") mgr := newSessionManager(settingsMgr, getProjLister(), NewUserStateStorage(redisClient)) token, err := mgr.Create("admin:login", int64(autoRegenerateTokenDuration.Seconds()-1), "123") - require.NoError(t, err) + if err != nil { + t.Errorf("Could not create token: %v", err) + } // verify new token is generated is login token is expiring soon _, newToken, err := mgr.Parse(token) @@ -124,21 +125,16 @@ func TestSessionManager_AdminToken_ExpiringSoon(t *testing.T) { // verify that new token is valid and for the same user claims, _, err := mgr.Parse(newToken) require.NoError(t, err) - - mapClaims, err := jwtutil.MapClaims(claims) - require.NoError(t, err) - - argoClaims, err := claimsutil.MapClaimsToArgoClaims(mapClaims) - require.NoError(t, err) - - assert.Equal(t, "admin", argoClaims.Subject) + mapClaims := *(claims.(*jwt.MapClaims)) + subject := mapClaims["sub"].(string) + assert.Equal(t, "admin", subject) } func TestSessionManager_AdminToken_Revoked(t *testing.T) { redisClient, closer := test.NewInMemoryRedis() defer closer() - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClient(t, "pass", true), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("pass", true), "argocd") storage := NewUserStateStorage(redisClient) mgr := newSessionManager(settingsMgr, getProjLister(), storage) @@ -146,37 +142,42 @@ func TestSessionManager_AdminToken_Revoked(t *testing.T) { token, err := mgr.Create("admin:login", 0, "123") require.NoError(t, err) - err = storage.RevokeToken(t.Context(), "123", time.Hour) + err = storage.RevokeToken(context.Background(), "123", time.Hour) require.NoError(t, err) _, _, err = mgr.Parse(token) - assert.EqualError(t, err, "token is revoked, please re-login") + require.Error(t, err) + assert.Equal(t, "token is revoked, please re-login", err.Error()) } func TestSessionManager_AdminToken_Deactivated(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClient(t, "pass", false), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("pass", false), "argocd") mgr := newSessionManager(settingsMgr, getProjLister(), NewUserStateStorage(nil)) token, err := mgr.Create("admin:login", 0, "abc") - require.NoError(t, err, "Could not create token") + if err != nil { + t.Errorf("Could not create token: %v", err) + } _, _, err = mgr.Parse(token) assert.ErrorContains(t, err, "account admin is disabled") } func TestSessionManager_AdminToken_LoginCapabilityDisabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClient(t, "pass", true, settings.AccountCapabilityLogin), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("pass", true, settings.AccountCapabilityLogin), "argocd") mgr := newSessionManager(settingsMgr, getProjLister(), NewUserStateStorage(nil)) token, err := mgr.Create("admin", 0, "abc") - require.NoError(t, err, "Could not create token") + if err != nil { + t.Errorf("Could not create token: %v", err) + } _, _, err = mgr.Parse(token) assert.ErrorContains(t, err, "account admin does not have 'apiKey' capability") } func TestSessionManager_ProjectToken(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClient(t, "pass", true), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("pass", true), "argocd") t.Run("Valid Token", func(t *testing.T) { proj := appv1.AppProject{ @@ -196,16 +197,8 @@ func TestSessionManager_ProjectToken(t *testing.T) { jwtToken, err := mgr.Create("proj:default:test", 100, "abc") require.NoError(t, err) - claims, _, err := mgr.Parse(jwtToken) + _, _, err = mgr.Parse(jwtToken) require.NoError(t, err) - - mapClaims, err := jwtutil.MapClaims(claims) - require.NoError(t, err) - - argoClaims, err := claimsutil.MapClaimsToArgoClaims(mapClaims) - require.NoError(t, err) - - assert.Equal(t, "proj:default:test", argoClaims.Subject) }) t.Run("Token Revoked", func(t *testing.T) { @@ -227,12 +220,20 @@ func TestSessionManager_ProjectToken(t *testing.T) { }) } +type claimsMock struct { + err error +} + +func (cm *claimsMock) Valid() error { + return cm.err +} + type tokenVerifierMock struct { - claims jwt.Claims + claims *claimsMock err error } -func (tm *tokenVerifierMock) VerifyToken(_ string) (jwt.Claims, string, error) { +func (tm *tokenVerifierMock) VerifyToken(token string) (jwt.Claims, string, error) { if tm.claims == nil { return nil, "", tm.err } @@ -245,7 +246,7 @@ func strPointer(str string) *string { func TestSessionManager_WithAuthMiddleware(t *testing.T) { handlerFunc := func() func(http.ResponseWriter, *http.Request) { - return func(w http.ResponseWriter, _ *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { t.Helper() w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/text") @@ -257,7 +258,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { name string authDisabled bool cookieHeader bool - verifiedClaims *jwt.RegisteredClaims + verifiedClaims *claimsMock verifyTokenErr error expectedStatusCode int expectedResponseBody *string @@ -268,7 +269,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { name: "will authenticate successfully", authDisabled: false, cookieHeader: true, - verifiedClaims: &jwt.RegisteredClaims{}, + verifiedClaims: &claimsMock{}, verifyTokenErr: nil, expectedStatusCode: http.StatusOK, expectedResponseBody: strPointer("Ok"), @@ -286,7 +287,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { name: "will return 400 if no cookie header", authDisabled: false, cookieHeader: false, - verifiedClaims: &jwt.RegisteredClaims{}, + verifiedClaims: &claimsMock{}, verifyTokenErr: nil, expectedStatusCode: http.StatusBadRequest, expectedResponseBody: nil, @@ -295,7 +296,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { name: "will return 401 verify token fails", authDisabled: false, cookieHeader: true, - verifiedClaims: &jwt.RegisteredClaims{}, + verifiedClaims: &claimsMock{}, verifyTokenErr: stderrors.New("token error"), expectedStatusCode: http.StatusUnauthorized, expectedResponseBody: nil, @@ -345,36 +346,29 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { } } -var ( - loggedOutContext = context.Background() - //nolint:staticcheck - loggedInContext = context.WithValue(context.Background(), "claims", &jwt.MapClaims{"iss": "qux", "sub": "foo", "email": "bar", "groups": []string{"baz"}}) - //nolint:staticcheck - loggedInContextFederated = context.WithValue(context.Background(), "claims", &jwt.MapClaims{"iss": "qux", "sub": "not-foo", "email": "bar", "groups": []string{"baz"}, "federated_claims": map[string]any{"user_id": "foo"}}) -) +var loggedOutContext = context.Background() + +// nolint:staticcheck +var loggedInContext = context.WithValue(context.Background(), "claims", &jwt.MapClaims{"iss": "qux", "sub": "foo", "email": "bar", "groups": []string{"baz"}}) func TestIss(t *testing.T) { assert.Empty(t, Iss(loggedOutContext)) assert.Equal(t, "qux", Iss(loggedInContext)) - assert.Equal(t, "qux", Iss(loggedInContextFederated)) } func TestLoggedIn(t *testing.T) { assert.False(t, LoggedIn(loggedOutContext)) assert.True(t, LoggedIn(loggedInContext)) - assert.True(t, LoggedIn(loggedInContextFederated)) } func TestUsername(t *testing.T) { assert.Empty(t, Username(loggedOutContext)) assert.Equal(t, "bar", Username(loggedInContext)) - assert.Equal(t, "bar", Username(loggedInContextFederated)) } -func TestGetUserIdentifier(t *testing.T) { - assert.Empty(t, GetUserIdentifier(loggedOutContext)) - assert.Equal(t, "foo", GetUserIdentifier(loggedInContext)) - assert.Equal(t, "foo", GetUserIdentifier(loggedInContextFederated)) +func TestSub(t *testing.T) { + assert.Empty(t, Sub(loggedOutContext)) + assert.Equal(t, "foo", Sub(loggedInContext)) } func TestGroups(t *testing.T) { @@ -422,7 +416,7 @@ func TestVerifyUsernamePassword(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClient(t, password, !tc.disabled), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient(password, !tc.disabled), "argocd") mgr := newSessionManager(settingsMgr, getProjLister(), NewUserStateStorage(nil)) @@ -492,7 +486,7 @@ func TestCacheValueGetters(t *testing.T) { } func TestLoginRateLimiter(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClient(t, "password", true), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("password", true), "argocd") storage := NewUserStateStorage(nil) mgr := newSessionManager(settingsMgr, getProjLister(), storage) @@ -533,14 +527,14 @@ func TestMaxUsernameLength(t *testing.T) { for i := 0; i < maxUsernameLength+1; i++ { username += "a" } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClient(t, "password", true), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("password", true), "argocd") mgr := newSessionManager(settingsMgr, getProjLister(), NewUserStateStorage(nil)) err := mgr.VerifyUsernamePassword(username, "password") assert.ErrorContains(t, err, fmt.Sprintf(usernameTooLongError, maxUsernameLength)) } func TestMaxCacheSize(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClient(t, "password", true), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("password", true), "argocd") mgr := newSessionManager(settingsMgr, getProjLister(), NewUserStateStorage(nil)) invalidUsers := []string{"invalid1", "invalid2", "invalid3", "invalid4", "invalid5", "invalid6", "invalid7"} @@ -556,7 +550,7 @@ func TestMaxCacheSize(t *testing.T) { } func TestFailedAttemptsExpiry(t *testing.T) { - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClient(t, "password", true), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("password", true), "argocd") mgr := newSessionManager(settingsMgr, getProjLister(), NewUserStateStorage(nil)) invalidUsers := []string{"invalid1", "invalid2", "invalid3", "invalid4", "invalid5", "invalid6", "invalid7"} @@ -619,7 +613,7 @@ clientSecret: yyy requestedScopes: ["oidc"]`, oidcTestServer.URL), } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(dexConfig, nil), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(dexConfig, nil), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false // Use test server's client to avoid TLS issues. @@ -653,7 +647,7 @@ rootCA: | `, oidcTestServer.URL, strings.ReplaceAll(string(cert), "\n", "\n ")), } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(dexConfig, nil), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(dexConfig, nil), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -690,12 +684,12 @@ rootCA: | "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(dexConfig, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(dexConfig, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), dexTestServer.URL, nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false claims := jwt.RegisteredClaims{Audience: jwt.ClaimStrings{"test-client"}, Subject: "admin", ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 24))} - claims.Issuer = dexTestServer.URL + "/api/dex" + claims.Issuer = fmt.Sprintf("%s/api/dex", dexTestServer.URL) token := jwt.NewWithClaims(jwt.SigningMethodRS512, claims) key, err := jwt.ParseRSAPrivateKeyFromPEM(utiltest.PrivateKey) require.NoError(t, err) @@ -704,7 +698,7 @@ rootCA: | _, _, err = mgr.VerifyToken(tokenString) require.Error(t, err) - assert.ErrorIs(t, err, common.ErrTokenVerification) + assert.ErrorIs(t, err, common.TokenVerificationErr) }) t.Run("OIDC provider is external, TLS is configured", func(t *testing.T) { @@ -725,7 +719,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(dexConfig, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(dexConfig, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -739,7 +733,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), _, _, err = mgr.VerifyToken(tokenString) require.Error(t, err) - assert.ErrorIs(t, err, common.ErrTokenVerification) + assert.ErrorIs(t, err, common.TokenVerificationErr) }) t.Run("OIDC provider is Dex, TLS is configured", func(t *testing.T) { @@ -760,12 +754,12 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(dexConfig, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(dexConfig, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), dexTestServer.URL, nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false claims := jwt.RegisteredClaims{Audience: jwt.ClaimStrings{"test-client"}, Subject: "admin", ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 24))} - claims.Issuer = dexTestServer.URL + "/api/dex" + claims.Issuer = fmt.Sprintf("%s/api/dex", dexTestServer.URL) token := jwt.NewWithClaims(jwt.SigningMethodRS512, claims) key, err := jwt.ParseRSAPrivateKeyFromPEM(utiltest.PrivateKey) require.NoError(t, err) @@ -774,7 +768,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), _, _, err = mgr.VerifyToken(tokenString) require.Error(t, err) - assert.ErrorIs(t, err, common.ErrTokenVerification) + assert.ErrorIs(t, err, common.TokenVerificationErr) }) t.Run("OIDC provider is external, TLS is configured, OIDCTLSInsecureSkipVerify is true", func(t *testing.T) { @@ -796,7 +790,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(dexConfig, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(dexConfig, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -825,7 +819,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), "oidc.tls.insecure.skip.verify": "true", } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(dexConfig, nil), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(dexConfig, nil), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -862,7 +856,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(config, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(config, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -898,7 +892,7 @@ skipAudienceCheckWhenTokenHasNoAudience: true`, oidcTestServer.URL), "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(config, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(config, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -934,7 +928,7 @@ skipAudienceCheckWhenTokenHasNoAudience: false`, oidcTestServer.URL), "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(config, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(config, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -948,7 +942,7 @@ skipAudienceCheckWhenTokenHasNoAudience: false`, oidcTestServer.URL), _, _, err = mgr.VerifyToken(tokenString) require.Error(t, err) - assert.ErrorIs(t, err, common.ErrTokenVerification) + assert.ErrorIs(t, err, common.TokenVerificationErr) }) t.Run("OIDC provider is external, audience is client ID, no allowed list specified", func(t *testing.T) { @@ -970,7 +964,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(config, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(config, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -1007,7 +1001,7 @@ allowedAudiences: "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(config, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(config, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -1044,7 +1038,7 @@ allowedAudiences: "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(config, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(config, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -1058,7 +1052,7 @@ allowedAudiences: _, _, err = mgr.VerifyToken(tokenString) require.Error(t, err) - assert.ErrorIs(t, err, common.ErrTokenVerification) + assert.ErrorIs(t, err, common.TokenVerificationErr) }) t.Run("OIDC provider is external, audience is not client ID, and there is no allow list", func(t *testing.T) { @@ -1080,7 +1074,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(config, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(config, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -1094,7 +1088,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), _, _, err = mgr.VerifyToken(tokenString) require.Error(t, err) - assert.ErrorIs(t, err, common.ErrTokenVerification) + assert.ErrorIs(t, err, common.TokenVerificationErr) }) t.Run("OIDC provider is external, audience is specified, but allow list is empty", func(t *testing.T) { @@ -1117,7 +1111,7 @@ allowedAudiences: []`, oidcTestServer.URL), "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(config, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(config, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -1131,7 +1125,7 @@ allowedAudiences: []`, oidcTestServer.URL), _, _, err = mgr.VerifyToken(tokenString) require.Error(t, err) - assert.ErrorIs(t, err, common.ErrTokenVerification) + assert.ErrorIs(t, err, common.TokenVerificationErr) }) // Make sure the logic works to allow any of the allowed audiences, not just the first one. @@ -1155,7 +1149,7 @@ allowedAudiences: ["aud-a", "aud-b"]`, oidcTestServer.URL), "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(config, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(config, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -1190,7 +1184,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), "tls.key": utiltest.PrivateKey, } - settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(config, secretConfig), "argocd") + settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(config, secretConfig), "argocd") mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil)) mgr.verificationDelayNoiseEnabled = false @@ -1204,7 +1198,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), _, _, err = mgr.VerifyToken(tokenString) require.Error(t, err) - assert.ErrorIs(t, err, common.ErrTokenVerification) + assert.ErrorIs(t, err, common.TokenVerificationErr) }) } diff --git a/util/session/state.go b/util/session/state.go index ff121733b6..db8eda5020 100644 --- a/util/session/state.go +++ b/util/session/state.go @@ -9,7 +9,7 @@ import ( "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" - utilio "github.com/argoproj/argo-cd/v3/util/io" + util "github.com/argoproj/argo-cd/v2/util/io" ) const ( @@ -18,23 +18,21 @@ const ( ) type userStateStorage struct { - attempts map[string]LoginAttempts - redis *redis.Client - revokedTokens map[string]bool - recentRevokedTokens map[string]bool - lock sync.RWMutex - resyncDuration time.Duration + attempts map[string]LoginAttempts + redis *redis.Client + revokedTokens map[string]bool + lock sync.RWMutex + resyncDuration time.Duration } var _ UserStateStorage = &userStateStorage{} func NewUserStateStorage(redis *redis.Client) *userStateStorage { return &userStateStorage{ - attempts: map[string]LoginAttempts{}, - revokedTokens: map[string]bool{}, - recentRevokedTokens: map[string]bool{}, - resyncDuration: time.Second * 15, - redis: redis, + attempts: map[string]LoginAttempts{}, + revokedTokens: map[string]bool{}, + resyncDuration: time.Hour, + redis: redis, } } @@ -55,7 +53,7 @@ func (storage *userStateStorage) Init(ctx context.Context) { func (storage *userStateStorage) watchRevokedTokens(ctx context.Context) { pubsub := storage.redis.Subscribe(ctx, newRevokedTokenKey) - defer utilio.Close(pubsub) + defer util.Close(pubsub) ch := pubsub.Channel() for { @@ -65,7 +63,6 @@ func (storage *userStateStorage) watchRevokedTokens(ctx context.Context) { case val := <-ch: storage.lock.Lock() storage.revokedTokens[val.Payload] = true - storage.recentRevokedTokens[val.Payload] = true storage.lock.Unlock() } } @@ -81,8 +78,10 @@ func (storage *userStateStorage) loadRevokedTokensSafe() { } func (storage *userStateStorage) loadRevokedTokens() error { - redisRevokedTokens := map[string]bool{} - iterator := storage.redis.Scan(context.Background(), 0, revokedTokenPrefix+"*", 10000).Iterator() + storage.lock.Lock() + defer storage.lock.Unlock() + storage.revokedTokens = map[string]bool{} + iterator := storage.redis.Scan(context.Background(), 0, revokedTokenPrefix+"*", -1).Iterator() for iterator.Next(context.Background()) { parts := strings.Split(iterator.Val(), "|") if len(parts) != 2 { @@ -91,20 +90,12 @@ func (storage *userStateStorage) loadRevokedTokens() error { iterator.Val()) continue } - redisRevokedTokens[parts[1]] = true + storage.revokedTokens[parts[1]] = true } if iterator.Err() != nil { return iterator.Err() } - storage.lock.Lock() - defer storage.lock.Unlock() - storage.revokedTokens = redisRevokedTokens - for recentRevokedToken := range storage.recentRevokedTokens { - storage.revokedTokens[recentRevokedToken] = true - } - storage.recentRevokedTokens = map[string]bool{} - return nil } @@ -121,7 +112,6 @@ func (storage *userStateStorage) SetLoginAttempts(attempts map[string]LoginAttem func (storage *userStateStorage) RevokeToken(ctx context.Context, id string, expiringAt time.Duration) error { storage.lock.Lock() storage.revokedTokens[id] = true - storage.recentRevokedTokens[id] = true storage.lock.Unlock() if err := storage.redis.Set(ctx, revokedTokenPrefix+id, "", expiringAt).Err(); err != nil { return err diff --git a/util/session/state_test.go b/util/session/state_test.go index 2b0b9c99e2..35c2dbcc71 100644 --- a/util/session/state_test.go +++ b/util/session/state_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/argoproj/argo-cd/v3/test" + "github.com/argoproj/argo-cd/v2/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -15,10 +15,10 @@ func TestUserStateStorage_LoadRevokedTokens(t *testing.T) { redis, closer := test.NewInMemoryRedis() defer closer() - err := redis.Set(t.Context(), revokedTokenPrefix+"abc", "", time.Hour).Err() + err := redis.Set(context.Background(), revokedTokenPrefix+"abc", "", time.Hour).Err() require.NoError(t, err) - ctx, cancel := context.WithCancel(t.Context()) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() storage := NewUserStateStorage(redis) diff --git a/util/settings/accounts.go b/util/settings/accounts.go index cb99dee438..2972d1911e 100644 --- a/util/settings/accounts.go +++ b/util/settings/accounts.go @@ -10,10 +10,10 @@ import ( log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/client-go/util/retry" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) const ( @@ -38,7 +38,7 @@ const ( // AccountCapabilityLogin represents capability to create UI session tokens. AccountCapabilityLogin AccountCapability = "login" // AccountCapabilityLogin represents capability to generate API auth tokens. - AccountCapabilityApiKey AccountCapability = "apiKey" //nolint:revive //FIXME(var-naming) + AccountCapabilityApiKey AccountCapability = "apiKey" ) // Token holds the information about the generated auth token. @@ -95,8 +95,8 @@ func (a *Account) HasCapability(capability AccountCapability) bool { } func (mgr *SettingsManager) saveAccount(name string, account Account) error { - return mgr.updateSecret(func(secret *corev1.Secret) error { - return mgr.updateConfigMap(func(cm *corev1.ConfigMap) error { + return mgr.updateSecret(func(secret *v1.Secret) error { + return mgr.updateConfigMap(func(cm *v1.ConfigMap) error { return saveAccount(secret, cm, name, account) }) }) @@ -145,18 +145,22 @@ func (mgr *SettingsManager) UpdateAccount(name string, callback func(account *Ac // GetAccounts returns list of configured accounts func (mgr *SettingsManager) GetAccounts() (map[string]Account, error) { - cm, err := mgr.getConfigMap() + err := mgr.ensureSynced(false) if err != nil { return nil, err } - secret, err := mgr.getSecret() + secret, err := mgr.secrets.Secrets(mgr.namespace).Get(common.ArgoCDSecretName) + if err != nil { + return nil, err + } + cm, err := mgr.configmaps.ConfigMaps(mgr.namespace).Get(common.ArgoCDConfigMapName) if err != nil { return nil, err } return parseAccounts(secret, cm) } -func updateAccountMap(cm *corev1.ConfigMap, key string, val string, defVal string) { +func updateAccountMap(cm *v1.ConfigMap, key string, val string, defVal string) { existingVal := cm.Data[key] if existingVal != val { if val == "" || val == defVal { @@ -167,7 +171,7 @@ func updateAccountMap(cm *corev1.ConfigMap, key string, val string, defVal strin } } -func updateAccountSecret(secret *corev1.Secret, key string, val string, defVal string) { +func updateAccountSecret(secret *v1.Secret, key string, val string, defVal string) { existingVal := string(secret.Data[key]) if existingVal != val { if val == "" || val == defVal { @@ -178,7 +182,7 @@ func updateAccountSecret(secret *corev1.Secret, key string, val string, defVal s } } -func saveAccount(secret *corev1.Secret, cm *corev1.ConfigMap, name string, account Account) error { +func saveAccount(secret *v1.Secret, cm *v1.ConfigMap, name string, account Account) error { tokens, err := json.Marshal(account.Tokens) if err != nil { return err @@ -198,7 +202,7 @@ func saveAccount(secret *corev1.Secret, cm *corev1.ConfigMap, name string, accou return nil } -func parseAdminAccount(secret *corev1.Secret, cm *corev1.ConfigMap) (*Account, error) { +func parseAdminAccount(secret *v1.Secret, cm *v1.ConfigMap) (*Account, error) { adminAccount := &Account{Enabled: true, Capabilities: []AccountCapability{AccountCapabilityLogin}} if adminPasswordHash, ok := secret.Data[settingAdminPasswordHashKey]; ok { adminAccount.PasswordHash = string(adminPasswordHash) @@ -227,7 +231,7 @@ func parseAdminAccount(secret *corev1.Secret, cm *corev1.ConfigMap) (*Account, e return adminAccount, nil } -func parseAccounts(secret *corev1.Secret, cm *corev1.ConfigMap) (map[string]Account, error) { +func parseAccounts(secret *v1.Secret, cm *v1.ConfigMap) (map[string]Account, error) { adminAccount, err := parseAdminAccount(secret, cm) if err != nil { return nil, err @@ -237,7 +241,7 @@ func parseAccounts(secret *corev1.Secret, cm *corev1.ConfigMap) (map[string]Acco } for key, v := range cm.Data { - if !strings.HasPrefix(key, accountsKeyPrefix+".") { + if !strings.HasPrefix(key, fmt.Sprintf("%s.", accountsKeyPrefix)) { continue } @@ -296,11 +300,11 @@ func parseAccounts(secret *corev1.Secret, cm *corev1.ConfigMap) (map[string]Acco account.PasswordHash = string(passwordHash) } if passwordMtime, ok := secret.Data[fmt.Sprintf("%s.%s.%s", accountsKeyPrefix, name, accountPasswordMtimeSuffix)]; ok { - mTime, err := time.Parse(time.RFC3339, string(passwordMtime)) - if err != nil { + if mTime, err := time.Parse(time.RFC3339, string(passwordMtime)); err != nil { return nil, err + } else { + account.PasswordMtime = &mTime } - account.PasswordMtime = &mTime } if tokensStr, ok := secret.Data[fmt.Sprintf("%s.%s.%s", accountsKeyPrefix, name, accountTokensSuffix)]; ok { account.Tokens = make([]Token, 0) diff --git a/util/settings/accounts_test.go b/util/settings/accounts_test.go index 1b00aa3594..2ab477ba6a 100644 --- a/util/settings/accounts_test.go +++ b/util/settings/accounts_test.go @@ -1,6 +1,7 @@ package settings import ( + "context" "testing" "time" @@ -8,10 +9,10 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/common" + "github.com/argoproj/argo-cd/v2/common" ) func TestGetAccounts_NoAccountsConfigured(t *testing.T) { @@ -21,11 +22,11 @@ func TestGetAccounts_NoAccountsConfigured(t *testing.T) { adminAccount, ok := accounts[common.ArgoCDAdminUsername] assert.True(t, ok) - assert.Equal(t, []AccountCapability{AccountCapabilityLogin}, adminAccount.Capabilities) + assert.EqualValues(t, []AccountCapability{AccountCapabilityLogin}, adminAccount.Capabilities) } func TestGetAccounts_HasConfiguredAccounts(t *testing.T) { - _, settingsManager := fixtures(map[string]string{"accounts.test": "apiKey"}, func(secret *corev1.Secret) { + _, settingsManager := fixtures(map[string]string{"accounts.test": "apiKey"}, func(secret *v1.Secret) { secret.Data["accounts.test.tokens"] = []byte(`[{"id":"123","iat":1583789194,"exp":1583789194}]`) }) accounts, err := settingsManager.GetAccounts() @@ -76,13 +77,13 @@ func TestGetAccount_WithInvalidToken(t *testing.T) { "accounts.invaliduser": "apiKey", "accounts.user2": "apiKey", }, - func(secret *corev1.Secret) { + func(secret *v1.Secret) { secret.Data["accounts.user1.tokens"] = []byte(`[{"id":"1","iat":158378932,"exp":1583789194}]`) }, - func(secret *corev1.Secret) { + func(secret *v1.Secret) { secret.Data["accounts.invaliduser.tokens"] = []byte("Invalid token") }, - func(secret *corev1.Secret) { + func(secret *v1.Secret) { secret.Data["accounts.user2.tokens"] = []byte(`[{"id":"2","iat":1583789194,"exp":1583784545}]`) }, ) @@ -93,7 +94,7 @@ func TestGetAccount_WithInvalidToken(t *testing.T) { func TestGetAdminAccount(t *testing.T) { mTime := time.Now().Format(time.RFC3339) - _, settingsManager := fixtures(nil, func(secret *corev1.Secret) { + _, settingsManager := fixtures(nil, func(secret *v1.Secret) { secret.Data["admin.password"] = []byte("admin-password") secret.Data["admin.passwordMtime"] = []byte(mTime) }) @@ -113,7 +114,7 @@ func TestFormatPasswordMtime_SuccessfullyFormatted(t *testing.T) { func TestFormatPasswordMtime_NoMtime(t *testing.T) { acc := Account{} - assert.Empty(t, acc.FormatPasswordMtime()) + assert.Equal(t, "", acc.FormatPasswordMtime()) } func TestHasCapability(t *testing.T) { @@ -152,13 +153,13 @@ func TestAddAccount_AccountAdded(t *testing.T) { err := settingsManager.AddAccount("test", addedAccount) require.NoError(t, err) - cm, err := clientset.CoreV1().ConfigMaps("default").Get(t.Context(), common.ArgoCDConfigMapName, metav1.GetOptions{}) + cm, err := clientset.CoreV1().ConfigMaps("default").Get(context.Background(), common.ArgoCDConfigMapName, metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, "login", cm.Data["accounts.test"]) assert.Equal(t, "false", cm.Data["accounts.test.enabled"]) - secret, err := clientset.CoreV1().Secrets("default").Get(t.Context(), common.ArgoCDSecretName, metav1.GetOptions{}) + secret, err := clientset.CoreV1().Secrets("default").Get(context.Background(), common.ArgoCDSecretName, metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, "hash", string(secret.Data["accounts.test.password"])) @@ -192,13 +193,13 @@ func TestUpdateAccount_SuccessfullyUpdated(t *testing.T) { }) require.NoError(t, err) - cm, err := clientset.CoreV1().ConfigMaps("default").Get(t.Context(), common.ArgoCDConfigMapName, metav1.GetOptions{}) + cm, err := clientset.CoreV1().ConfigMaps("default").Get(context.Background(), common.ArgoCDConfigMapName, metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, "login", cm.Data["accounts.test"]) assert.Equal(t, "false", cm.Data["accounts.test.enabled"]) - secret, err := clientset.CoreV1().Secrets("default").Get(t.Context(), common.ArgoCDSecretName, metav1.GetOptions{}) + secret, err := clientset.CoreV1().Secrets("default").Get(context.Background(), common.ArgoCDSecretName, metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, "hash", string(secret.Data["accounts.test.password"])) @@ -217,7 +218,7 @@ func TestUpdateAccount_UpdateAdminPassword(t *testing.T) { }) require.NoError(t, err) - secret, err := clientset.CoreV1().Secrets("default").Get(t.Context(), common.ArgoCDSecretName, metav1.GetOptions{}) + secret, err := clientset.CoreV1().Secrets("default").Get(context.Background(), common.ArgoCDSecretName, metav1.GetOptions{}) require.NoError(t, err) assert.Equal(t, "newPassword", string(secret.Data["admin.password"])) diff --git a/util/settings/filtered_resource.go b/util/settings/filtered_resource.go index 5094555d59..29c5d5cef5 100644 --- a/util/settings/filtered_resource.go +++ b/util/settings/filtered_resource.go @@ -1,6 +1,6 @@ package settings -import "github.com/argoproj/argo-cd/v3/util/glob" +import "github.com/argoproj/argo-cd/v2/util/glob" type FilteredResource struct { APIGroups []string `json:"apiGroups,omitempty"` @@ -9,8 +9,8 @@ type FilteredResource struct { } func (r FilteredResource) matchGroup(apiGroup string) bool { - for _, excludedAPIGroup := range r.APIGroups { - if glob.Match(excludedAPIGroup, apiGroup) { + for _, excludedApiGroup := range r.APIGroups { + if glob.Match(excludedApiGroup, apiGroup) { return true } } diff --git a/util/settings/settings.go b/util/settings/settings.go index 9982928a8d..37057418a9 100644 --- a/util/settings/settings.go +++ b/util/settings/settings.go @@ -20,28 +20,29 @@ import ( "time" log "github.com/sirupsen/logrus" - corev1 "k8s.io/api/core/v1" + apiv1 "k8s.io/api/core/v1" + apierr "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" - informersv1 "k8s.io/client-go/informers/core/v1" + v1 "k8s.io/client-go/informers/core/v1" "k8s.io/client-go/kubernetes" v1listers "k8s.io/client-go/listers/core/v1" "k8s.io/client-go/tools/cache" "sigs.k8s.io/yaml" enginecache "github.com/argoproj/gitops-engine/pkg/cache" - timeutil "github.com/argoproj/pkg/v2/time" + timeutil "github.com/argoproj/pkg/time" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v3/server/settings/oidc" - "github.com/argoproj/argo-cd/v3/util" - "github.com/argoproj/argo-cd/v3/util/crypto" - "github.com/argoproj/argo-cd/v3/util/kube" - "github.com/argoproj/argo-cd/v3/util/password" - tlsutil "github.com/argoproj/argo-cd/v3/util/tls" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/server/settings/oidc" + "github.com/argoproj/argo-cd/v2/util" + "github.com/argoproj/argo-cd/v2/util/crypto" + "github.com/argoproj/argo-cd/v2/util/kube" + "github.com/argoproj/argo-cd/v2/util/password" + tlsutil "github.com/argoproj/argo-cd/v2/util/tls" ) // ArgoCDSettings holds in-memory runtime configuration options. @@ -55,7 +56,7 @@ type ArgoCDSettings struct { // Indicates if status badge is enabled or not. StatusBadgeEnabled bool `json:"statusBadgeEnable"` // Indicates if status badge custom root URL should be used. - StatusBadgeRootUrl string `json:"statusBadgeRootUrl,omitempty"` //nolint:revive //FIXME(var-naming) + StatusBadgeRootUrl string `json:"statusBadgeRootUrl,omitempty"` // DexConfig contains portions of a dex config yaml DexConfig string `json:"dexConfig,omitempty"` // OIDCConfigRAW holds OIDC configuration as a raw string @@ -90,15 +91,15 @@ type ArgoCDSettings struct { // Specifies token expiration duration UserSessionDuration time.Duration `json:"userSessionDuration,omitempty"` // UiCssURL local or remote path to user-defined CSS to customize ArgoCD UI - UiCssURL string `json:"uiCssURL,omitempty"` //nolint:revive //FIXME(var-naming) + UiCssURL string `json:"uiCssURL,omitempty"` // Content of UI Banner - UiBannerContent string `json:"uiBannerContent,omitempty"` //nolint:revive //FIXME(var-naming) + UiBannerContent string `json:"uiBannerContent,omitempty"` // URL for UI Banner - UiBannerURL string `json:"uiBannerURL,omitempty"` //nolint:revive //FIXME(var-naming) + UiBannerURL string `json:"uiBannerURL,omitempty"` // Make Banner permanent and not closeable - UiBannerPermanent bool `json:"uiBannerPermanent,omitempty"` //nolint:revive //FIXME(var-naming) + UiBannerPermanent bool `json:"uiBannerPermanent,omitempty"` // Position of UI Banner - UiBannerPosition string `json:"uiBannerPosition,omitempty"` //nolint:revive //FIXME(var-naming) + UiBannerPosition string `json:"uiBannerPosition,omitempty"` // PasswordPattern for password regular expression PasswordPattern string `json:"passwordPattern,omitempty"` // BinaryUrls contains the URLs for downloading argocd binaries @@ -169,7 +170,6 @@ func (o *oidcConfig) toExported() *OIDCConfig { Issuer: o.Issuer, ClientID: o.ClientID, ClientSecret: o.ClientSecret, - Azure: o.Azure, CLIClientID: o.CLIClientID, UserInfoPath: o.UserInfoPath, EnableUserInfoGroups: o.EnableUserInfoGroups, @@ -198,21 +198,16 @@ type OIDCConfig struct { RootCA string `json:"rootCA,omitempty"` EnablePKCEAuthentication bool `json:"enablePKCEAuthentication,omitempty"` DomainHint string `json:"domainHint,omitempty"` - Azure *AzureOIDCConfig `json:"azure,omitempty"` -} - -type AzureOIDCConfig struct { - UseWorkloadIdentity bool `json:"useWorkloadIdentity,omitempty"` } // DEPRECATED. Helm repository credentials are now managed using RepoCredentials type HelmRepoCredentials struct { - URL string `json:"url,omitempty"` - Name string `json:"name,omitempty"` - UsernameSecret *corev1.SecretKeySelector `json:"usernameSecret,omitempty"` - PasswordSecret *corev1.SecretKeySelector `json:"passwordSecret,omitempty"` - CertSecret *corev1.SecretKeySelector `json:"certSecret,omitempty"` - KeySecret *corev1.SecretKeySelector `json:"keySecret,omitempty"` + URL string `json:"url,omitempty"` + Name string `json:"name,omitempty"` + UsernameSecret *apiv1.SecretKeySelector `json:"usernameSecret,omitempty"` + PasswordSecret *apiv1.SecretKeySelector `json:"passwordSecret,omitempty"` + CertSecret *apiv1.SecretKeySelector `json:"certSecret,omitempty"` + KeySecret *apiv1.SecretKeySelector `json:"keySecret,omitempty"` } // KustomizeVersion holds information about additional Kustomize version @@ -233,8 +228,8 @@ type KustomizeSettings struct { var ( ByClusterURLIndexer = "byClusterURL" - byClusterURLIndexerFunc = func(obj any) ([]string, error) { - s, ok := obj.(*corev1.Secret) + byClusterURLIndexerFunc = func(obj interface{}) ([]string, error) { + s, ok := obj.(*apiv1.Secret) if !ok { return nil, nil } @@ -250,8 +245,8 @@ var ( return nil, nil } ByClusterNameIndexer = "byClusterName" - byClusterNameIndexerFunc = func(obj any) ([]string, error) { - s, ok := obj.(*corev1.Secret) + byClusterNameIndexerFunc = func(obj interface{}) ([]string, error) { + s, ok := obj.(*apiv1.Secret) if !ok { return nil, nil } @@ -269,9 +264,9 @@ var ( ByProjectClusterIndexer = "byProjectCluster" ByProjectRepoIndexer = "byProjectRepo" ByProjectRepoWriteIndexer = "byProjectRepoWrite" - byProjectIndexerFunc = func(secretType string) func(obj any) ([]string, error) { - return func(obj any) ([]string, error) { - s, ok := obj.(*corev1.Secret) + byProjectIndexerFunc = func(secretType string) func(obj interface{}) ([]string, error) { + return func(obj interface{}) ([]string, error) { + s, ok := obj.(*apiv1.Secret) if !ok { return nil, nil } @@ -323,11 +318,11 @@ type Repository struct { // helm only Name string `json:"name,omitempty"` // Name of the secret storing the username used to access the repo - UsernameSecret *corev1.SecretKeySelector `json:"usernameSecret,omitempty"` + UsernameSecret *apiv1.SecretKeySelector `json:"usernameSecret,omitempty"` // Name of the secret storing the password used to access the repo - PasswordSecret *corev1.SecretKeySelector `json:"passwordSecret,omitempty"` + PasswordSecret *apiv1.SecretKeySelector `json:"passwordSecret,omitempty"` // Name of the secret storing the SSH private key used to access the repo. Git only - SSHPrivateKeySecret *corev1.SecretKeySelector `json:"sshPrivateKeySecret,omitempty"` + SSHPrivateKeySecret *apiv1.SecretKeySelector `json:"sshPrivateKeySecret,omitempty"` // Whether to connect the repository in an insecure way (deprecated) InsecureIgnoreHostKey bool `json:"insecureIgnoreHostKey,omitempty"` // Whether to connect the repository in an insecure way @@ -335,13 +330,13 @@ type Repository struct { // Whether the repo is git-lfs enabled. Git only. EnableLFS bool `json:"enableLfs,omitempty"` // Name of the secret storing the TLS client cert data - TLSClientCertDataSecret *corev1.SecretKeySelector `json:"tlsClientCertDataSecret,omitempty"` + TLSClientCertDataSecret *apiv1.SecretKeySelector `json:"tlsClientCertDataSecret,omitempty"` // Name of the secret storing the TLS client cert's key data - TLSClientCertKeySecret *corev1.SecretKeySelector `json:"tlsClientCertKeySecret,omitempty"` + TLSClientCertKeySecret *apiv1.SecretKeySelector `json:"tlsClientCertKeySecret,omitempty"` // Whether the repo is helm-oci enabled. Git only. EnableOci bool `json:"enableOci,omitempty"` // Github App Private Key PEM data - GithubAppPrivateKeySecret *corev1.SecretKeySelector `json:"githubAppPrivateKeySecret,omitempty"` + GithubAppPrivateKeySecret *apiv1.SecretKeySelector `json:"githubAppPrivateKeySecret,omitempty"` // Github App ID of the app used to access the repo GithubAppId int64 `json:"githubAppID,omitempty"` // Github App Installation ID of the installed GitHub App @@ -353,11 +348,9 @@ type Repository struct { // NoProxy specifies a list of targets where the proxy isn't used, applies only in cases where the proxy is applied NoProxy string `json:"noProxy,omitempty"` // GCPServiceAccountKey specifies the service account key in JSON format to be used for getting credentials to Google Cloud Source repos - GCPServiceAccountKey *corev1.SecretKeySelector `json:"gcpServiceAccountKey,omitempty"` + GCPServiceAccountKey *apiv1.SecretKeySelector `json:"gcpServiceAccountKey,omitempty"` // ForceHttpBasicAuth determines whether Argo CD should force use of basic auth for HTTP connected repositories - ForceHttpBasicAuth bool `json:"forceHttpBasicAuth,omitempty"` //nolint:revive //FIXME(var-naming) - // UseAzureWorkloadIdentity specifies whether to use Azure Workload Identity for authentication - UseAzureWorkloadIdentity bool `json:"useAzureWorkloadIdentity,omitempty"` + ForceHttpBasicAuth bool `json:"forceHttpBasicAuth,omitempty"` } // Credential template for accessing repositories @@ -365,17 +358,17 @@ type RepositoryCredentials struct { // The URL pattern the repository URL has to match URL string `json:"url,omitempty"` // Name of the secret storing the username used to access the repo - UsernameSecret *corev1.SecretKeySelector `json:"usernameSecret,omitempty"` + UsernameSecret *apiv1.SecretKeySelector `json:"usernameSecret,omitempty"` // Name of the secret storing the password used to access the repo - PasswordSecret *corev1.SecretKeySelector `json:"passwordSecret,omitempty"` + PasswordSecret *apiv1.SecretKeySelector `json:"passwordSecret,omitempty"` // Name of the secret storing the SSH private key used to access the repo. Git only - SSHPrivateKeySecret *corev1.SecretKeySelector `json:"sshPrivateKeySecret,omitempty"` + SSHPrivateKeySecret *apiv1.SecretKeySelector `json:"sshPrivateKeySecret,omitempty"` // Name of the secret storing the TLS client cert data - TLSClientCertDataSecret *corev1.SecretKeySelector `json:"tlsClientCertDataSecret,omitempty"` + TLSClientCertDataSecret *apiv1.SecretKeySelector `json:"tlsClientCertDataSecret,omitempty"` // Name of the secret storing the TLS client cert's key data - TLSClientCertKeySecret *corev1.SecretKeySelector `json:"tlsClientCertKeySecret,omitempty"` + TLSClientCertKeySecret *apiv1.SecretKeySelector `json:"tlsClientCertKeySecret,omitempty"` // Github App Private Key PEM data - GithubAppPrivateKeySecret *corev1.SecretKeySelector `json:"githubAppPrivateKeySecret,omitempty"` + GithubAppPrivateKeySecret *apiv1.SecretKeySelector `json:"githubAppPrivateKeySecret,omitempty"` // Github App ID of the app used to access the repo GithubAppId int64 `json:"githubAppID,omitempty"` // Github App Installation ID of the installed GitHub App @@ -387,11 +380,9 @@ type RepositoryCredentials struct { // the type of the repositoryCredentials, "git" or "helm", assumed to be "git" if empty or absent Type string `json:"type,omitempty"` // GCPServiceAccountKey specifies the service account key in JSON format to be used for getting credentials to Google Cloud Source repos - GCPServiceAccountKey *corev1.SecretKeySelector `json:"gcpServiceAccountKey,omitempty"` + GCPServiceAccountKey *apiv1.SecretKeySelector `json:"gcpServiceAccountKey,omitempty"` // ForceHttpBasicAuth determines whether Argo CD should force use of basic auth for HTTP connected repositories - ForceHttpBasicAuth bool `json:"forceHttpBasicAuth,omitempty"` //nolint:revive //FIXME(var-naming) - // UseAzureWorkloadIdentity specifies whether to use Azure Workload Identity for authentication - UseAzureWorkloadIdentity bool `json:"useAzureWorkloadIdentity,omitempty"` + ForceHttpBasicAuth bool `json:"forceHttpBasicAuth,omitempty"` } // DeepLink structure @@ -427,14 +418,20 @@ const ( settingURLKey = "url" // settingAdditionalUrlsKey designates the key where Argo CD's additional external URLs are set settingAdditionalUrlsKey = "additionalUrls" + // repositoriesKey designates the key where ArgoCDs repositories list is set + repositoriesKey = "repositories" + // repositoryCredentialsKey designates the key where ArgoCDs repositories credentials list is set + repositoryCredentialsKey = "repository.credentials" + // helmRepositoriesKey designates the key where list of helm repositories is set + helmRepositoriesKey = "helm.repositories" // settingDexConfigKey designates the key for the dex config settingDexConfigKey = "dex.config" // settingsOIDCConfigKey designates the key for OIDC config settingsOIDCConfigKey = "oidc.config" // statusBadgeEnabledKey holds the key which enables of disables status badge feature statusBadgeEnabledKey = "statusbadge.enabled" - // statusBadgeRootURLKey holds the key for the root badge URL override - statusBadgeRootURLKey = "statusbadge.url" + // statusBadgeRootUrlKey holds the key for the root badge URL override + statusBadgeRootUrlKey = "statusbadge.url" // settingsWebhookGitHubSecret is the key for the GitHub shared webhook secret settingsWebhookGitHubSecretKey = "webhook.github.secret" // settingsWebhookGitLabSecret is the key for the GitLab shared webhook secret @@ -485,16 +482,16 @@ const ( userSessionDurationKey = "users.session.duration" // diffOptions is the key where diff options are configured resourceCompareOptionsKey = "resource.compareoptions" - // settingUICSSURLKey designates the key for user-defined CSS URL for UI customization - settingUICSSURLKey = "ui.cssurl" - // settingUIBannerContentKey designates the key for content of user-defined info banner for UI - settingUIBannerContentKey = "ui.bannercontent" - // settingUIBannerURLKey designates the key for the link for user-defined info banner for UI - settingUIBannerURLKey = "ui.bannerurl" - // settingUIBannerPermanentKey designates the key for whether the banner is permanent and not closeable - settingUIBannerPermanentKey = "ui.bannerpermanent" - // settingUIBannerPositionKey designates the key for the position of the banner - settingUIBannerPositionKey = "ui.bannerposition" + // settingUiCssURLKey designates the key for user-defined CSS URL for UI customization + settingUiCssURLKey = "ui.cssurl" + // settingUiBannerContentKey designates the key for content of user-defined info banner for UI + settingUiBannerContentKey = "ui.bannercontent" + // settingUiBannerURLKey designates the key for the link for user-defined info banner for UI + settingUiBannerURLKey = "ui.bannerurl" + // settingUiBannerPermanentKey designates the key for whether the banner is permanent and not closeable + settingUiBannerPermanentKey = "ui.bannerpermanent" + // settingUiBannerPositionKey designates the key for the position of the banner + settingUiBannerPositionKey = "ui.bannerposition" // settingsBinaryUrlsKey designates the key for the argocd binary URLs settingsBinaryUrlsKey = "help.download" // globalProjectsKey designates the key for global project settings @@ -513,6 +510,8 @@ const ( settingsPasswordPatternKey = "passwordPattern" // inClusterEnabledKey is the key to configure whether to allow in-cluster server address inClusterEnabledKey = "cluster.inClusterEnabled" + // settingsServerRBACLogEnforceEnable is the key to configure whether logs RBAC enforcement is enabled + settingsServerRBACLogEnforceEnableKey = "server.rbac.log.enforce.enable" // settingsServerRBACEDisableFineGrainedInheritance is the key to configure find-grained RBAC inheritance settingsServerRBACDisableFineGrainedInheritance = "server.rbac.disableApplicationFineGrainedRBACInheritance" // MaxPodLogsToRender the maximum number of pod logs to render @@ -584,7 +583,7 @@ const ( // IgnoreResourceStatusInAll ignores status changes for all resources IgnoreResourceStatusInAll IgnoreStatus = "all" // IgnoreResourceStatusInNone ignores status changes for no resources - IgnoreResourceStatusInNone IgnoreStatus = "none" + IgnoreResourceStatusInNone IgnoreStatus = "off" ) type ArgoCDDiffOptions struct { @@ -641,14 +640,18 @@ func (mgr *SettingsManager) GetSecretsInformer() (cache.SharedIndexInformer, err return mgr.secretsInformer, nil } -func (mgr *SettingsManager) updateSecret(callback func(*corev1.Secret) error) error { - argoCDSecret, err := mgr.getSecret() +func (mgr *SettingsManager) updateSecret(callback func(*apiv1.Secret) error) error { + err := mgr.ensureSynced(false) + if err != nil { + return err + } + argoCDSecret, err := mgr.secrets.Secrets(mgr.namespace).Get(common.ArgoCDSecretName) createSecret := false if err != nil { - if !apierrors.IsNotFound(err) { + if !apierr.IsNotFound(err) { return err } - argoCDSecret = &corev1.Secret{ + argoCDSecret = &apiv1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, }, @@ -656,21 +659,24 @@ func (mgr *SettingsManager) updateSecret(callback func(*corev1.Secret) error) er } createSecret = true } + if argoCDSecret.Data == nil { + argoCDSecret.Data = make(map[string][]byte) + } - beforeUpdate := argoCDSecret.DeepCopy() - err = callback(argoCDSecret) + updatedSecret := argoCDSecret.DeepCopy() + err = callback(updatedSecret) if err != nil { return err } - if !createSecret && reflect.DeepEqual(beforeUpdate.Data, argoCDSecret.Data) { + if !createSecret && reflect.DeepEqual(argoCDSecret.Data, updatedSecret.Data) { return nil } if createSecret { - _, err = mgr.clientset.CoreV1().Secrets(mgr.namespace).Create(context.Background(), argoCDSecret, metav1.CreateOptions{}) + _, err = mgr.clientset.CoreV1().Secrets(mgr.namespace).Create(context.Background(), updatedSecret, metav1.CreateOptions{}) } else { - _, err = mgr.clientset.CoreV1().Secrets(mgr.namespace).Update(context.Background(), argoCDSecret, metav1.UpdateOptions{}) + _, err = mgr.clientset.CoreV1().Secrets(mgr.namespace).Update(context.Background(), updatedSecret, metav1.UpdateOptions{}) } if err != nil { return err @@ -679,28 +685,29 @@ func (mgr *SettingsManager) updateSecret(callback func(*corev1.Secret) error) er return mgr.ResyncInformers() } -func (mgr *SettingsManager) updateConfigMap(callback func(*corev1.ConfigMap) error) error { +func (mgr *SettingsManager) updateConfigMap(callback func(*apiv1.ConfigMap) error) error { argoCDCM, err := mgr.getConfigMap() createCM := false if err != nil { - if !apierrors.IsNotFound(err) { + if !apierr.IsNotFound(err) { return err } - argoCDCM = &corev1.ConfigMap{ + argoCDCM = &apiv1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, }, - Data: make(map[string]string), } createCM = true } - + if argoCDCM.Data == nil { + argoCDCM.Data = make(map[string]string) + } beforeUpdate := argoCDCM.DeepCopy() err = callback(argoCDCM) if err != nil { return err } - if !createCM && reflect.DeepEqual(beforeUpdate.Data, argoCDCM.Data) { + if reflect.DeepEqual(beforeUpdate.Data, argoCDCM.Data) { return nil } @@ -719,14 +726,25 @@ func (mgr *SettingsManager) updateConfigMap(callback func(*corev1.ConfigMap) err return mgr.ResyncInformers() } -func (mgr *SettingsManager) getConfigMap() (*corev1.ConfigMap, error) { - return mgr.GetConfigMapByName(common.ArgoCDConfigMapName) +func (mgr *SettingsManager) getConfigMap() (*apiv1.ConfigMap, error) { + err := mgr.ensureSynced(false) + if err != nil { + return nil, err + } + argoCDCM, err := mgr.configmaps.ConfigMaps(mgr.namespace).Get(common.ArgoCDConfigMapName) + if err != nil { + return nil, err + } + if argoCDCM.Data == nil { + argoCDCM.Data = make(map[string]string) + } + return argoCDCM, err } // Returns the ConfigMap with the given name from the cluster. // The ConfigMap must be labeled with "app.kubernetes.io/part-of: argocd" in // order to be retrievable. -func (mgr *SettingsManager) GetConfigMapByName(configMapName string) (*corev1.ConfigMap, error) { +func (mgr *SettingsManager) GetConfigMapByName(configMapName string) (*apiv1.ConfigMap, error) { err := mgr.ensureSynced(false) if err != nil { return nil, err @@ -735,53 +753,7 @@ func (mgr *SettingsManager) GetConfigMapByName(configMapName string) (*corev1.Co if err != nil { return nil, err } - cmCopy := configMap.DeepCopy() - if cmCopy.Data == nil { - cmCopy.Data = make(map[string]string) - } - return cmCopy, err -} - -func (mgr *SettingsManager) getSecret() (*corev1.Secret, error) { - return mgr.GetSecretByName(common.ArgoCDSecretName) -} - -// Returns the Secret with the given name from the cluster. -func (mgr *SettingsManager) GetSecretByName(secretName string) (*corev1.Secret, error) { - err := mgr.ensureSynced(false) - if err != nil { - return nil, err - } - secret, err := mgr.secrets.Secrets(mgr.namespace).Get(secretName) - if err != nil { - return nil, err - } - secretCopy := secret.DeepCopy() - if secretCopy.Data == nil { - secretCopy.Data = make(map[string][]byte) - } - return secretCopy, err -} - -func (mgr *SettingsManager) getSecrets() ([]*corev1.Secret, error) { - err := mgr.ensureSynced(false) - if err != nil { - return nil, err - } - - selector, err := labels.Parse(partOfArgoCDSelector) - if err != nil { - return nil, fmt.Errorf("error parsing Argo CD selector %w", err) - } - secrets, err := mgr.secrets.Secrets(mgr.namespace).List(selector) - if err != nil { - return nil, err - } - // SecretNamespaceLister lists all Secrets in the indexer for a given namespace. - // Objects returned by the lister must be treated as read-only. - // To allow us to modify the secrets, make a copy - secrets = util.SliceCopy(secrets) - return secrets, nil + return configMap, err } func (mgr *SettingsManager) GetResourcesFilter() (*ResourcesFilter, error) { @@ -827,11 +799,7 @@ func (mgr *SettingsManager) GetTrackingMethod() (string, error) { if err != nil { return "", err } - tm := argoCDCM.Data[settingsResourceTrackingMethodKey] - if tm == "" { - return string(v1alpha1.TrackingMethodAnnotation), nil - } - return tm, nil + return argoCDCM.Data[settingsResourceTrackingMethodKey], nil } func (mgr *SettingsManager) GetInstallationID() (string, error) { @@ -854,6 +822,19 @@ func (mgr *SettingsManager) GetPasswordPattern() (string, error) { return label, nil } +func (mgr *SettingsManager) GetServerRBACLogEnforceEnable() (bool, error) { + argoCDCM, err := mgr.getConfigMap() + if err != nil { + return false, err + } + + if argoCDCM.Data[settingsServerRBACLogEnforceEnableKey] == "" { + return false, nil + } + + return strconv.ParseBool(argoCDCM.Data[settingsServerRBACLogEnforceEnableKey]) +} + func (mgr *SettingsManager) ApplicationFineGrainedRBACInheritanceDisabled() (bool, error) { argoCDCM, err := mgr.getConfigMap() if err != nil { @@ -861,7 +842,7 @@ func (mgr *SettingsManager) ApplicationFineGrainedRBACInheritanceDisabled() (boo } if argoCDCM.Data[settingsServerRBACDisableFineGrainedInheritance] == "" { - return true, nil + return false, nil } return strconv.ParseBool(argoCDCM.Data[settingsServerRBACDisableFineGrainedInheritance]) @@ -981,28 +962,31 @@ func (mgr *SettingsManager) GetResourceOverrides() (map[string]v1alpha1.Resource return nil, err } - diffOptions, err := mgr.GetResourceCompareOptions() - if err != nil { - return nil, fmt.Errorf("failed to get compare options: %w", err) + var diffOptions ArgoCDDiffOptions + if value, ok := argoCDCM.Data[resourceCompareOptionsKey]; ok { + err := yaml.Unmarshal([]byte(value), &diffOptions) + if err != nil { + return nil, err + } } crdGK := "apiextensions.k8s.io/CustomResourceDefinition" + crdPrsvUnkn := "/spec/preserveUnknownFields" switch diffOptions.IgnoreResourceStatusField { - case "", IgnoreResourceStatusInAll: + case "", "crd": + addStatusOverrideToGK(resourceOverrides, crdGK) + addIgnoreDiffItemOverrideToGK(resourceOverrides, crdGK, crdPrsvUnkn) + case "all": addStatusOverrideToGK(resourceOverrides, "*/*") log.Info("Ignore status for all objects") - case IgnoreResourceStatusInCRD: - addStatusOverrideToGK(resourceOverrides, crdGK) - case IgnoreResourceStatusInNone, "off", "false": - // Yaml 'off' non-string value can be converted to 'false' - // Support these cases because compareoptions is a yaml string in the config - // and this misconfiguration can be hard to catch for users. - // To prevent this, the default value has been changed to none + + case "off", "false": log.Info("Not ignoring status for any object") + default: - addStatusOverrideToGK(resourceOverrides, "*/*") - log.Warnf("Unrecognized value for ignoreResourceStatusField - %s, ignore status for all resources", diffOptions.IgnoreResourceStatusField) + addStatusOverrideToGK(resourceOverrides, crdGK) + log.Warnf("Unrecognized value for ignoreResourceStatusField - %s, ignore status for CustomResourceDefinitions", diffOptions.IgnoreResourceStatusField) } return resourceOverrides, nil @@ -1036,7 +1020,7 @@ func (mgr *SettingsManager) appendResourceOverridesFromSplitKeys(cmData map[stri continue } - // config map key should be of format resource.customizations.. + // config map key should be of format resource.customizations.. parts := strings.SplitN(k, ".", 4) if len(parts) < 4 { continue @@ -1097,7 +1081,7 @@ func (mgr *SettingsManager) appendResourceOverridesFromSplitKeys(cmData map[stri return nil } -// Convert group_kind format to , allowed key format examples +// Convert group-kind format to , allowed key format examples // resource.customizations.health.cert-manager.io_Certificate // resource.customizations.health.Certificate func convertToOverrideKey(groupKind string) (string, error) { @@ -1111,7 +1095,7 @@ func convertToOverrideKey(groupKind string) (string, error) { } func GetDefaultDiffOptions() ArgoCDDiffOptions { - return ArgoCDDiffOptions{IgnoreAggregatedRoles: false, IgnoreResourceStatusField: IgnoreResourceStatusInAll, IgnoreDifferencesOnResourceUpdates: true} + return ArgoCDDiffOptions{IgnoreAggregatedRoles: false, IgnoreDifferencesOnResourceUpdates: false} } // GetResourceCompareOptions loads the resource compare options settings from the ConfigMap @@ -1213,6 +1197,111 @@ func addKustomizeVersion(prefix, name, path string, kvMap map[string]KustomizeVe return nil } +// DEPRECATED. Helm repository credentials are now managed using RepoCredentials +func (mgr *SettingsManager) GetHelmRepositories() ([]HelmRepoCredentials, error) { + argoCDCM, err := mgr.getConfigMap() + if err != nil { + return nil, fmt.Errorf("error retrieving config map: %w", err) + } + helmRepositories := make([]HelmRepoCredentials, 0) + helmRepositoriesStr := argoCDCM.Data[helmRepositoriesKey] + if helmRepositoriesStr != "" { + err := yaml.Unmarshal([]byte(helmRepositoriesStr), &helmRepositories) + if err != nil { + return nil, fmt.Errorf("error unmarshalling helm repositories: %w", err) + } + } + return helmRepositories, nil +} + +func (mgr *SettingsManager) GetRepositories() ([]Repository, error) { + mgr.mutex.Lock() + reposCache := mgr.reposCache + mgr.mutex.Unlock() + if reposCache != nil { + return reposCache, nil + } + + // Get the config map outside of the lock + argoCDCM, err := mgr.getConfigMap() + if err != nil { + return nil, fmt.Errorf("failed to get argo-cd config map: %w", err) + } + + mgr.mutex.Lock() + defer mgr.mutex.Unlock() + repositories := make([]Repository, 0) + repositoriesStr := argoCDCM.Data[repositoriesKey] + if repositoriesStr != "" { + err := yaml.Unmarshal([]byte(repositoriesStr), &repositories) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal repositories from config map key %q: %w", repositoriesKey, err) + } + } + mgr.reposCache = repositories + + return mgr.reposCache, nil +} + +func (mgr *SettingsManager) SaveRepositories(repos []Repository) error { + return mgr.updateConfigMap(func(argoCDCM *apiv1.ConfigMap) error { + if len(repos) > 0 { + yamlStr, err := yaml.Marshal(repos) + if err != nil { + return err + } + argoCDCM.Data[repositoriesKey] = string(yamlStr) + } else { + delete(argoCDCM.Data, repositoriesKey) + } + return nil + }) +} + +func (mgr *SettingsManager) SaveRepositoryCredentials(creds []RepositoryCredentials) error { + return mgr.updateConfigMap(func(argoCDCM *apiv1.ConfigMap) error { + if len(creds) > 0 { + yamlStr, err := yaml.Marshal(creds) + if err != nil { + return err + } + argoCDCM.Data[repositoryCredentialsKey] = string(yamlStr) + } else { + delete(argoCDCM.Data, repositoryCredentialsKey) + } + return nil + }) +} + +func (mgr *SettingsManager) GetRepositoryCredentials() ([]RepositoryCredentials, error) { + mgr.mutex.Lock() + repoCredsCache := mgr.repoCredsCache + mgr.mutex.Unlock() + if repoCredsCache != nil { + return repoCredsCache, nil + } + + // Get the config map outside of the lock + argoCDCM, err := mgr.getConfigMap() + if err != nil { + return nil, fmt.Errorf("error retrieving config map: %w", err) + } + + mgr.mutex.Lock() + defer mgr.mutex.Unlock() + creds := make([]RepositoryCredentials, 0) + credsStr := argoCDCM.Data[repositoryCredentialsKey] + if credsStr != "" { + err := yaml.Unmarshal([]byte(credsStr), &creds) + if err != nil { + return nil, err + } + } + mgr.repoCredsCache = creds + + return mgr.repoCredsCache, nil +} + func (mgr *SettingsManager) GetGoogleAnalytics() (*GoogleAnalytics, error) { argoCDCM, err := mgr.getConfigMap() if err != nil { @@ -1246,19 +1335,30 @@ func (mgr *SettingsManager) GetHelp() (*Help, error) { // GetSettings retrieves settings from the ArgoCDConfigMap and secret. func (mgr *SettingsManager) GetSettings() (*ArgoCDSettings, error) { - argoCDCM, err := mgr.getConfigMap() + err := mgr.ensureSynced(false) + if err != nil { + return nil, err + } + argoCDCM, err := mgr.configmaps.ConfigMaps(mgr.namespace).Get(common.ArgoCDConfigMapName) if err != nil { return nil, fmt.Errorf("error retrieving argocd-cm: %w", err) } - argoCDSecret, err := mgr.getSecret() + argoCDSecret, err := mgr.secrets.Secrets(mgr.namespace).Get(common.ArgoCDSecretName) if err != nil { return nil, fmt.Errorf("error retrieving argocd-secret: %w", err) } - secrets, err := mgr.getSecrets() + selector, err := labels.Parse(partOfArgoCDSelector) if err != nil { - return nil, fmt.Errorf("error retrieving argocd secrets: %w", err) + return nil, fmt.Errorf("error parsing Argo CD selector %w", err) } - + secrets, err := mgr.secrets.Secrets(mgr.namespace).List(selector) + if err != nil { + return nil, err + } + // SecretNamespaceLister lists all Secrets in the indexer for a given namespace. + // Objects returned by the lister must be treated as read-only. + // To allow us to modify the secrets, make a copy + secrets = util.SliceCopy(secrets) var settings ArgoCDSettings var errs []error updateSettingsFromConfigMap(&settings, argoCDCM) @@ -1266,7 +1366,7 @@ func (mgr *SettingsManager) GetSettings() (*ArgoCDSettings, error) { errs = append(errs, err) } if len(errs) > 0 { - return &settings, errors.Join(errs...) + return &settings, errs[0] } return &settings, nil @@ -1288,14 +1388,14 @@ func (mgr *SettingsManager) initialize(ctx context.Context) error { } eventHandler := cache.ResourceEventHandlerFuncs{ - UpdateFunc: func(_, _ any) { + UpdateFunc: func(oldObj, newObj interface{}) { mgr.invalidateCache() mgr.onRepoOrClusterChanged() }, - AddFunc: func(_ any) { + AddFunc: func(obj interface{}) { mgr.onRepoOrClusterChanged() }, - DeleteFunc: func(_ any) { + DeleteFunc: func(obj interface{}) { mgr.onRepoOrClusterChanged() }, } @@ -1307,8 +1407,8 @@ func (mgr *SettingsManager) initialize(ctx context.Context) error { ByProjectRepoIndexer: byProjectIndexerFunc(common.LabelValueSecretTypeRepository), ByProjectRepoWriteIndexer: byProjectIndexerFunc(common.LabelValueSecretTypeRepositoryWrite), } - cmInformer := informersv1.NewFilteredConfigMapInformer(mgr.clientset, mgr.namespace, 3*time.Minute, indexers, tweakConfigMap) - secretsInformer := informersv1.NewSecretInformer(mgr.clientset, mgr.namespace, 3*time.Minute, indexers) + cmInformer := v1.NewFilteredConfigMapInformer(mgr.clientset, mgr.namespace, 3*time.Minute, indexers, tweakConfigMap) + secretsInformer := v1.NewSecretInformer(mgr.clientset, mgr.namespace, 3*time.Minute, indexers) _, err := cmInformer.AddEventHandler(eventHandler) if err != nil { log.Error(err) @@ -1330,7 +1430,7 @@ func (mgr *SettingsManager) initialize(ctx context.Context) error { }() if !cache.WaitForCacheSync(ctx.Done(), cmInformer.HasSynced, secretsInformer.HasSynced) { - return errors.New("timed out waiting for settings cache to sync") + return fmt.Errorf("Timed out waiting for settings cache to sync") } log.Info("Configmap/secret informer synced") @@ -1344,14 +1444,14 @@ func (mgr *SettingsManager) initialize(ctx context.Context) error { } now := time.Now() handler := cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj any) { + AddFunc: func(obj interface{}) { if metaObj, ok := obj.(metav1.Object); ok { if metaObj.GetCreationTimestamp().After(now) { tryNotify() } } }, - UpdateFunc: func(oldObj, newObj any) { + UpdateFunc: func(oldObj, newObj interface{}) { oldMeta, oldOk := oldObj.(metav1.Common) newMeta, newOk := newObj.(metav1.Common) if oldOk && newOk && oldMeta.GetResourceVersion() != newMeta.GetResourceVersion() { @@ -1388,7 +1488,7 @@ func (mgr *SettingsManager) ensureSynced(forceResync bool) error { return mgr.initialize(ctx) } -func getDownloadBinaryUrlsFromConfigMap(argoCDCM *corev1.ConfigMap) map[string]string { +func getDownloadBinaryUrlsFromConfigMap(argoCDCM *apiv1.ConfigMap) map[string]string { binaryUrls := map[string]string{} for _, archType := range []string{"darwin-amd64", "darwin-arm64", "windows-amd64", "linux-amd64", "linux-arm64", "linux-ppc64le", "linux-s390x"} { if val, ok := argoCDCM.Data[settingsBinaryUrlsKey+"."+archType]; ok { @@ -1399,23 +1499,24 @@ func getDownloadBinaryUrlsFromConfigMap(argoCDCM *corev1.ConfigMap) map[string]s } // updateSettingsFromConfigMap transfers settings from a Kubernetes configmap into an ArgoCDSettings struct. -func updateSettingsFromConfigMap(settings *ArgoCDSettings, argoCDCM *corev1.ConfigMap) { +func updateSettingsFromConfigMap(settings *ArgoCDSettings, argoCDCM *apiv1.ConfigMap) { settings.DexConfig = argoCDCM.Data[settingDexConfigKey] settings.OIDCConfigRAW = argoCDCM.Data[settingsOIDCConfigKey] settings.KustomizeBuildOptions = argoCDCM.Data[kustomizeBuildOptionsKey] settings.StatusBadgeEnabled = argoCDCM.Data[statusBadgeEnabledKey] == "true" - settings.StatusBadgeRootUrl = argoCDCM.Data[statusBadgeRootURLKey] + settings.StatusBadgeRootUrl = argoCDCM.Data[statusBadgeRootUrlKey] settings.AnonymousUserEnabled = argoCDCM.Data[anonymousUserEnabledKey] == "true" - settings.UiCssURL = argoCDCM.Data[settingUICSSURLKey] - settings.UiBannerContent = argoCDCM.Data[settingUIBannerContentKey] - settings.UiBannerPermanent = argoCDCM.Data[settingUIBannerPermanentKey] == "true" - settings.UiBannerPosition = argoCDCM.Data[settingUIBannerPositionKey] + settings.UiCssURL = argoCDCM.Data[settingUiCssURLKey] + settings.UiBannerContent = argoCDCM.Data[settingUiBannerContentKey] + settings.UiBannerPermanent = argoCDCM.Data[settingUiBannerPermanentKey] == "true" + settings.UiBannerPosition = argoCDCM.Data[settingUiBannerPositionKey] + settings.ServerRBACLogEnforceEnable = argoCDCM.Data[settingsServerRBACLogEnforceEnableKey] == "true" settings.BinaryUrls = getDownloadBinaryUrlsFromConfigMap(argoCDCM) if err := validateExternalURL(argoCDCM.Data[settingURLKey]); err != nil { log.Warnf("Failed to validate URL in configmap: %v", err) } settings.URL = argoCDCM.Data[settingURLKey] - if err := validateExternalURL(argoCDCM.Data[settingUIBannerURLKey]); err != nil { + if err := validateExternalURL(argoCDCM.Data[settingUiBannerURLKey]); err != nil { log.Warnf("Failed to validate UI banner URL in configmap: %v", err) } if argoCDCM.Data[settingAdditionalUrlsKey] != "" { @@ -1428,7 +1529,7 @@ func updateSettingsFromConfigMap(settings *ArgoCDSettings, argoCDCM *corev1.Conf log.Warnf("Failed to validate external URL in configmap: %v", err) } } - settings.UiBannerURL = argoCDCM.Data[settingUIBannerURLKey] + settings.UiBannerURL = argoCDCM.Data[settingUiBannerURLKey] settings.UserSessionDuration = time.Hour * 24 if userSessionDurationStr, ok := argoCDCM.Data[userSessionDurationKey]; ok { if val, err := timeutil.ParseDuration(userSessionDurationStr); err != nil { @@ -1481,16 +1582,16 @@ func validateExternalURL(u string) error { } URL, err := url.Parse(u) if err != nil { - return fmt.Errorf("failed to parse URL: %w", err) + return fmt.Errorf("Failed to parse URL: %w", err) } if URL.Scheme != "http" && URL.Scheme != "https" { - return errors.New("URL must include http or https protocol") + return fmt.Errorf("URL must include http or https protocol") } return nil } // updateSettingsFromSecret transfers settings from a Kubernetes secret into an ArgoCDSettings struct. -func (mgr *SettingsManager) updateSettingsFromSecret(settings *ArgoCDSettings, argoCDSecret *corev1.Secret, secrets []*corev1.Secret) error { +func (mgr *SettingsManager) updateSettingsFromSecret(settings *ArgoCDSettings, argoCDSecret *apiv1.Secret, secrets []*apiv1.Secret) error { var errs []error secretKey, ok := argoCDSecret.Data[settingServerSignatureKey] if ok { @@ -1535,7 +1636,7 @@ func (mgr *SettingsManager) updateSettingsFromSecret(settings *ArgoCDSettings, a } settings.Secrets = secretValues if len(errs) > 0 { - return errors.Join(errs...) + return errs[0] } settings.WebhookGitHubSecret = ReplaceStringSecret(string(argoCDSecret.Data[settingsWebhookGitHubSecretKey]), settings.Secrets) @@ -1554,9 +1655,9 @@ func (mgr *SettingsManager) updateSettingsFromSecret(settings *ArgoCDSettings, a // return values are nil, no external secret has been configured. func (mgr *SettingsManager) externalServerTLSCertificate() (*tls.Certificate, error) { var cert tls.Certificate - secret, err := mgr.GetSecretByName(externalServerTLSSecretName) + secret, err := mgr.secrets.Secrets(mgr.namespace).Get(externalServerTLSSecretName) if err != nil { - if apierrors.IsNotFound(err) { + if apierr.IsNotFound(err) { return nil, nil } } @@ -1573,7 +1674,7 @@ func (mgr *SettingsManager) externalServerTLSCertificate() (*tls.Certificate, er // SaveSettings serializes ArgoCDSettings and upserts it into K8s secret/configmap func (mgr *SettingsManager) SaveSettings(settings *ArgoCDSettings) error { - err := mgr.updateConfigMap(func(argoCDCM *corev1.ConfigMap) error { + err := mgr.updateConfigMap(func(argoCDCM *apiv1.ConfigMap) error { if settings.URL != "" { argoCDCM.Data[settingURLKey] = settings.URL } else { @@ -1590,17 +1691,17 @@ func (mgr *SettingsManager) SaveSettings(settings *ArgoCDSettings) error { delete(argoCDCM.Data, settingsOIDCConfigKey) } if settings.UiCssURL != "" { - argoCDCM.Data[settingUICSSURLKey] = settings.UiCssURL + argoCDCM.Data[settingUiCssURLKey] = settings.UiCssURL } if settings.UiBannerContent != "" { - argoCDCM.Data[settingUIBannerContentKey] = settings.UiBannerContent + argoCDCM.Data[settingUiBannerContentKey] = settings.UiBannerContent } else { - delete(argoCDCM.Data, settingUIBannerContentKey) + delete(argoCDCM.Data, settingUiBannerContentKey) } if settings.UiBannerURL != "" { - argoCDCM.Data[settingUIBannerURLKey] = settings.UiBannerURL + argoCDCM.Data[settingUiBannerURLKey] = settings.UiBannerURL } else { - delete(argoCDCM.Data, settingUIBannerURLKey) + delete(argoCDCM.Data, settingUiBannerURLKey) } return nil }) @@ -1608,7 +1709,7 @@ func (mgr *SettingsManager) SaveSettings(settings *ArgoCDSettings) error { return err } - return mgr.updateSecret(func(argoCDSecret *corev1.Secret) error { + return mgr.updateSecret(func(argoCDSecret *apiv1.Secret) error { argoCDSecret.Data[settingServerSignatureKey] = settings.ServerSignature if settings.WebhookGitHubSecret != "" { argoCDSecret.Data[settingsWebhookGitHubSecretKey] = []byte(settings.WebhookGitHubSecret) @@ -1647,11 +1748,20 @@ func (mgr *SettingsManager) SaveSettings(settings *ArgoCDSettings) error { // Save the SSH known host data into the corresponding ConfigMap func (mgr *SettingsManager) SaveSSHKnownHostsData(ctx context.Context, knownHostsList []string) error { + err := mgr.ensureSynced(false) + if err != nil { + return err + } + certCM, err := mgr.GetConfigMapByName(common.ArgoCDKnownHostsConfigMapName) if err != nil { return err } + if certCM.Data == nil { + certCM.Data = make(map[string]string) + } + sshKnownHostsData := strings.Join(knownHostsList, "\n") + "\n" certCM.Data["ssh_known_hosts"] = sshKnownHostsData _, err = mgr.clientset.CoreV1().ConfigMaps(mgr.namespace).Update(ctx, certCM, metav1.UpdateOptions{}) @@ -1663,6 +1773,11 @@ func (mgr *SettingsManager) SaveSSHKnownHostsData(ctx context.Context, knownHost } func (mgr *SettingsManager) SaveTLSCertificateData(ctx context.Context, tlsCertificates map[string]string) error { + err := mgr.ensureSynced(false) + if err != nil { + return err + } + certCM, err := mgr.GetConfigMapByName(common.ArgoCDTLSCertsConfigMapName) if err != nil { return err @@ -1678,6 +1793,11 @@ func (mgr *SettingsManager) SaveTLSCertificateData(ctx context.Context, tlsCerti } func (mgr *SettingsManager) SaveGPGPublicKeyData(ctx context.Context, gpgPublicKeys map[string]string) error { + err := mgr.ensureSynced(false) + if err != nil { + return err + } + keysCM, err := mgr.GetConfigMapByName(common.ArgoCDGPGKeysConfigMapName) if err != nil { return err @@ -1747,8 +1867,8 @@ func (a *ArgoCDSettings) GetServerEncryptionKey() ([]byte, error) { return crypto.KeyFromPassphrase(string(a.ServerSignature)) } -func UnmarshalDexConfig(config string) (map[string]any, error) { - var dexCfg map[string]any +func UnmarshalDexConfig(config string) (map[string]interface{}, error) { + var dexCfg map[string]interface{} err := yaml.Unmarshal([]byte(config), &dexCfg) return dexCfg, err } @@ -1757,7 +1877,7 @@ func (a *ArgoCDSettings) oidcConfig() *oidcConfig { if a.OIDCConfigRAW == "" { return nil } - configMap := map[string]any{} + configMap := map[string]interface{}{} err := yaml.Unmarshal([]byte(a.OIDCConfigRAW), &configMap) if err != nil { log.Warnf("invalid oidc config: %v", err) @@ -1904,13 +2024,6 @@ func (a *ArgoCDSettings) OAuth2ClientSecret() string { return "" } -func (a *ArgoCDSettings) UseAzureWorkloadIdentity() bool { - if oidcConfig := a.OIDCConfig(); oidcConfig != nil && oidcConfig.Azure != nil { - return oidcConfig.Azure.UseWorkloadIdentity - } - return false -} - // OIDCTLSConfig returns the TLS config for the OIDC provider. If an external provider is configured, returns a TLS // config using the root CAs (if any) specified in the OIDC config. If an external OIDC provider is not configured, // returns the API server TLS config, because the API server proxies requests to Dex. @@ -2082,7 +2195,7 @@ func (mgr *SettingsManager) InitializeSettings(insecureModeEnabled bool) (*ArgoC if err != nil { return err } - ku := kube.NewKubeUtil(mgr.ctx, mgr.clientset) + ku := kube.NewKubeUtil(mgr.clientset, mgr.ctx) err = ku.CreateOrUpdateSecretField(mgr.namespace, initialPasswordSecretName, initialPasswordSecretField, initialPassword) if err != nil { return err @@ -2109,7 +2222,7 @@ func (mgr *SettingsManager) InitializeSettings(insecureModeEnabled bool) (*ArgoC hosts := []string{ "localhost", "argocd-server", - "argocd-server." + mgr.namespace, + fmt.Sprintf("argocd-server.%s", mgr.namespace), fmt.Sprintf("argocd-server.%s.svc", mgr.namespace), fmt.Sprintf("argocd-server.%s.svc.cluster.local", mgr.namespace), } @@ -2137,13 +2250,13 @@ func (mgr *SettingsManager) InitializeSettings(insecureModeEnabled bool) (*ArgoC // ReplaceMapSecrets takes a json object and recursively looks for any secret key references in the // object and replaces the value with the secret value -func ReplaceMapSecrets(obj map[string]any, secretValues map[string]string) map[string]any { - newObj := make(map[string]any) +func ReplaceMapSecrets(obj map[string]interface{}, secretValues map[string]string) map[string]interface{} { + newObj := make(map[string]interface{}) for k, v := range obj { switch val := v.(type) { - case map[string]any: + case map[string]interface{}: newObj[k] = ReplaceMapSecrets(val, secretValues) - case []any: + case []interface{}: newObj[k] = replaceListSecrets(val, secretValues) case string: newObj[k] = ReplaceStringSecret(val, secretValues) @@ -2154,13 +2267,13 @@ func ReplaceMapSecrets(obj map[string]any, secretValues map[string]string) map[s return newObj } -func replaceListSecrets(obj []any, secretValues map[string]string) []any { - newObj := make([]any, len(obj)) +func replaceListSecrets(obj []interface{}, secretValues map[string]string) []interface{} { + newObj := make([]interface{}, len(obj)) for i, v := range obj { switch val := v.(type) { - case map[string]any: + case map[string]interface{}: newObj[i] = ReplaceMapSecrets(val, secretValues) - case []any: + case []interface{}: newObj[i] = replaceListSecrets(val, secretValues) case string: newObj[i] = ReplaceStringSecret(val, secretValues) diff --git a/util/settings/settings_test.go b/util/settings/settings_test.go index 16614bd0ff..d76234b8ae 100644 --- a/util/settings/settings_test.go +++ b/util/settings/settings_test.go @@ -12,21 +12,22 @@ import ( "testing" "time" + "k8s.io/apimachinery/pkg/util/yaml" + + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + testutil "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/test" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/client-go/kubernetes/fake" - - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - testutil "github.com/argoproj/argo-cd/v3/test" - "github.com/argoproj/argo-cd/v3/util/test" ) -func fixtures(data map[string]string, opts ...func(secret *corev1.Secret)) (*fake.Clientset, *SettingsManager) { - cm := &corev1.ConfigMap{ +func fixtures(data map[string]string, opts ...func(secret *v1.Secret)) (*fake.Clientset, *SettingsManager) { + cm := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -36,7 +37,7 @@ func fixtures(data map[string]string, opts ...func(secret *corev1.Secret)) (*fak }, Data: data, } - secret := &corev1.Secret{ + secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -56,7 +57,7 @@ func fixtures(data map[string]string, opts ...func(secret *corev1.Secret)) (*fak } func TestDocumentedArgoCDConfigMapIsValid(t *testing.T) { - var argocdCM *corev1.ConfigMap + var argocdCM *v1.ConfigMap settings := ArgoCDSettings{} data, err := os.ReadFile("../../docs/operator-manual/argocd-cm.yaml") require.NoError(t, err) @@ -65,40 +66,13 @@ func TestDocumentedArgoCDConfigMapIsValid(t *testing.T) { updateSettingsFromConfigMap(&settings, argocdCM) } -func TestGetConfigMapByName(t *testing.T) { - t.Run("data is never nil", func(t *testing.T) { - _, settingsManager := fixtures(nil) - cm, err := settingsManager.GetConfigMapByName(common.ArgoCDConfigMapName) - require.NoError(t, err) - assert.NotNil(t, cm.Data) - }) - t.Run("cannot update informer value", func(t *testing.T) { - _, settingsManager := fixtures(nil) - cm1, err := settingsManager.GetConfigMapByName(common.ArgoCDConfigMapName) - require.NoError(t, err) - cm1.Data["test"] = "invalid" - cm2, err := settingsManager.GetConfigMapByName(common.ArgoCDConfigMapName) - require.NoError(t, err) - assert.NotContains(t, cm2.Data, "test") - }) -} - -func TestGetSecretByName(t *testing.T) { - t.Run("data is never nil", func(t *testing.T) { - _, settingsManager := fixtures(nil, func(secret *corev1.Secret) { secret.Data = nil }) - secret, err := settingsManager.GetSecretByName(common.ArgoCDSecretName) - require.NoError(t, err) - assert.NotNil(t, secret.Data) - }) - t.Run("cannot update informer value", func(t *testing.T) { - _, settingsManager := fixtures(nil) - s1, err := settingsManager.GetSecretByName(common.ArgoCDSecretName) - require.NoError(t, err) - s1.Data["test"] = []byte("invalid") - s2, err := settingsManager.GetSecretByName(common.ArgoCDSecretName) - require.NoError(t, err) - assert.NotContains(t, s2.Data, "test") +func TestGetRepositories(t *testing.T) { + _, settingsManager := fixtures(map[string]string{ + "repositories": "\n - url: http://foo\n", }) + filter, err := settingsManager.GetRepositories() + require.NoError(t, err) + assert.Equal(t, []Repository{{URL: "http://foo"}}, filter) } func TestGetExtensionConfigs(t *testing.T) { @@ -124,8 +98,8 @@ func TestGetExtensionConfigs(t *testing.T) { name: "will return main and additional config successfully", expectedLen: 2, input: map[string]string{ - extensionConfig: "main config", - extensionConfig + ".anotherExtension": "another config", + extensionConfig: "main config", + fmt.Sprintf("%s.anotherExtension", extensionConfig): "another config", }, expected: map[string]string{ "": "main config", @@ -147,6 +121,52 @@ func TestGetExtensionConfigs(t *testing.T) { } } +func TestSaveRepositories(t *testing.T) { + kubeClient, settingsManager := fixtures(nil) + err := settingsManager.SaveRepositories([]Repository{{URL: "http://foo"}}) + require.NoError(t, err) + cm, err := kubeClient.CoreV1().ConfigMaps("default").Get(context.Background(), common.ArgoCDConfigMapName, metav1.GetOptions{}) + require.NoError(t, err) + assert.Equal(t, "- url: http://foo\n", cm.Data["repositories"]) + + repos, err := settingsManager.GetRepositories() + require.NoError(t, err) + assert.ElementsMatch(t, repos, []Repository{{URL: "http://foo"}}) +} + +func TestSaveRepositoriesNoConfigMap(t *testing.T) { + kubeClient := fake.NewClientset() + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") + + err := settingsManager.SaveRepositories([]Repository{{URL: "http://foo"}}) + require.NoError(t, err) + cm, err := kubeClient.CoreV1().ConfigMaps("default").Get(context.Background(), common.ArgoCDConfigMapName, metav1.GetOptions{}) + require.NoError(t, err) + assert.Equal(t, "- url: http://foo\n", cm.Data["repositories"]) +} + +func TestSaveRepositoryCredentials(t *testing.T) { + kubeClient, settingsManager := fixtures(nil) + err := settingsManager.SaveRepositoryCredentials([]RepositoryCredentials{{URL: "http://foo"}}) + require.NoError(t, err) + cm, err := kubeClient.CoreV1().ConfigMaps("default").Get(context.Background(), common.ArgoCDConfigMapName, metav1.GetOptions{}) + require.NoError(t, err) + assert.Equal(t, "- url: http://foo\n", cm.Data["repository.credentials"]) + + creds, err := settingsManager.GetRepositoryCredentials() + require.NoError(t, err) + assert.ElementsMatch(t, creds, []RepositoryCredentials{{URL: "http://foo"}}) +} + +func TestGetRepositoryCredentials(t *testing.T) { + _, settingsManager := fixtures(map[string]string{ + "repository.credentials": "\n - url: http://foo\n", + }) + filter, err := settingsManager.GetRepositoryCredentials() + require.NoError(t, err) + assert.Equal(t, []RepositoryCredentials{{URL: "http://foo"}}, filter) +} + func TestGetResourceFilter(t *testing.T) { data := map[string]string{ "resource.exclusions": "\n - apiGroups: [\"group1\"]\n kinds: [\"kind1\"]\n clusters: [\"cluster1\"]\n", @@ -179,7 +199,7 @@ func TestInClusterServerAddressEnabled(t *testing.T) { func TestInClusterServerAddressEnabledByDefault(t *testing.T) { kubeClient := fake.NewClientset( - &corev1.ConfigMap{ + &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -189,7 +209,7 @@ func TestInClusterServerAddressEnabledByDefault(t *testing.T) { }, Data: map[string]string{}, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -203,62 +223,51 @@ func TestInClusterServerAddressEnabledByDefault(t *testing.T) { }, }, ) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") settings, err := settingsManager.GetSettings() require.NoError(t, err) assert.True(t, settings.InClusterEnabled) } func TestGetAppInstanceLabelKey(t *testing.T) { - t.Run("should get custom instanceLabelKey", func(t *testing.T) { - _, settingsManager := fixtures(map[string]string{ - "application.instanceLabelKey": "testLabel", - }) - label, err := settingsManager.GetAppInstanceLabelKey() - require.NoError(t, err) - assert.Equal(t, "testLabel", label) - }) - - t.Run("should get default instanceLabelKey if custom not defined", func(t *testing.T) { - _, settingsManager := fixtures(map[string]string{}) - label, err := settingsManager.GetAppInstanceLabelKey() - require.NoError(t, err) - assert.Equal(t, common.LabelKeyAppInstance, label) + _, settingsManager := fixtures(map[string]string{ + "application.instanceLabelKey": "testLabel", }) + label, err := settingsManager.GetAppInstanceLabelKey() + require.NoError(t, err) + assert.Equal(t, "testLabel", label) } -func TestGetTrackingMethod(t *testing.T) { - t.Run("should get custom trackingMethod", func(t *testing.T) { - _, settingsManager := fixtures(map[string]string{ - "application.resourceTrackingMethod": string(v1alpha1.TrackingMethodLabel), - }) - label, err := settingsManager.GetTrackingMethod() - require.NoError(t, err) - assert.Equal(t, string(v1alpha1.TrackingMethodLabel), label) - }) +func TestGetServerRBACLogEnforceEnableKeyDefaultFalse(t *testing.T) { + _, settingsManager := fixtures(nil) + serverRBACLogEnforceEnable, err := settingsManager.GetServerRBACLogEnforceEnable() + require.NoError(t, err) + assert.False(t, serverRBACLogEnforceEnable) +} - t.Run("should get default trackingMethod if custom not defined", func(t *testing.T) { - _, settingsManager := fixtures(map[string]string{}) - label, err := settingsManager.GetTrackingMethod() - require.NoError(t, err) - assert.Equal(t, string(v1alpha1.TrackingMethodAnnotation), label) +func TestGetServerRBACLogEnforceEnableKey(t *testing.T) { + _, settingsManager := fixtures(map[string]string{ + "server.rbac.log.enforce.enable": "true", }) + serverRBACLogEnforceEnable, err := settingsManager.GetServerRBACLogEnforceEnable() + require.NoError(t, err) + assert.True(t, serverRBACLogEnforceEnable) } func TestApplicationFineGrainedRBACInheritanceDisabledDefault(t *testing.T) { _, settingsManager := fixtures(nil) flag, err := settingsManager.ApplicationFineGrainedRBACInheritanceDisabled() require.NoError(t, err) - assert.True(t, flag) + assert.False(t, flag) } func TestApplicationFineGrainedRBACInheritanceDisabled(t *testing.T) { _, settingsManager := fixtures(map[string]string{ - "server.rbac.disableApplicationFineGrainedRBACInheritance": "false", + "server.rbac.disableApplicationFineGrainedRBACInheritance": "true", }) flag, err := settingsManager.ApplicationFineGrainedRBACInheritanceDisabled() require.NoError(t, err) - assert.False(t, flag) + assert.True(t, flag) } func TestGetIsIgnoreResourceUpdatesEnabled(t *testing.T) { @@ -288,6 +297,9 @@ func TestGetResourceOverrides(t *testing.T) { ignoreStatus := v1alpha1.ResourceOverride{IgnoreDifferences: v1alpha1.OverrideIgnoreDiff{ JSONPointers: []string{"/status"}, }} + ignoreCRDFields := v1alpha1.ResourceOverride{IgnoreDifferences: v1alpha1.OverrideIgnoreDiff{ + JSONPointers: []string{"/status", "/spec/preserveUnknownFields"}, + }} crdGK := "apiextensions.k8s.io/CustomResourceDefinition" _, settingsManager := fixtures(map[string]string{ @@ -321,10 +333,10 @@ func TestGetResourceOverrides(t *testing.T) { }, }, webHookOverrides) - // by default, all status should be ignored - globalOverrides := overrides["*/*"] - assert.NotNil(t, globalOverrides) - assert.Equal(t, ignoreStatus, globalOverrides) + // by default, crd status should be ignored + crdOverrides := overrides[crdGK] + assert.NotNil(t, crdOverrides) + assert.Equal(t, ignoreCRDFields, crdOverrides) // with value all, status of all objects should be ignored _, settingsManager = fixtures(map[string]string{ @@ -334,7 +346,7 @@ func TestGetResourceOverrides(t *testing.T) { overrides, err = settingsManager.GetResourceOverrides() require.NoError(t, err) - globalOverrides = overrides["*/*"] + globalOverrides := overrides["*/*"] assert.NotNil(t, globalOverrides) assert.Equal(t, ignoreStatus, globalOverrides) @@ -354,14 +366,14 @@ func TestGetResourceOverrides(t *testing.T) { overrides, err = settingsManager.GetResourceOverrides() require.NoError(t, err) - crdOverrides := overrides[crdGK] + crdOverrides = overrides[crdGK] assert.NotNil(t, crdOverrides) assert.Equal(t, v1alpha1.ResourceOverride{IgnoreDifferences: v1alpha1.OverrideIgnoreDiff{ - JSONPointers: []string{"/webhooks/0/clientConfig/caBundle", "/status"}, + JSONPointers: []string{"/webhooks/0/clientConfig/caBundle", "/status", "/spec/preserveUnknownFields"}, JQPathExpressions: []string{".webhooks[0].clientConfig.caBundle"}, }}, crdOverrides) - // with incorrect value, status of all objects should be ignored + // with incorrect value, status of crd objects should be ignored _, settingsManager = fixtures(map[string]string{ "resource.compareoptions": ` ignoreResourceStatusField: foobar`, @@ -369,11 +381,12 @@ func TestGetResourceOverrides(t *testing.T) { overrides, err = settingsManager.GetResourceOverrides() require.NoError(t, err) - globalOverrides = overrides["*/*"] - assert.NotNil(t, globalOverrides) - assert.Equal(t, ignoreStatus, globalOverrides) + defaultOverrides := overrides[crdGK] + assert.NotNil(t, defaultOverrides) + assert.Equal(t, ignoreStatus, defaultOverrides) + assert.Equal(t, ignoreStatus, defaultOverrides) - // with value non-string off, status of no objects should be ignored + // with value off, status of no objects should be ignored _, settingsManager = fixtures(map[string]string{ "resource.compareoptions": ` ignoreResourceStatusField: off`, @@ -381,24 +394,6 @@ func TestGetResourceOverrides(t *testing.T) { overrides, err = settingsManager.GetResourceOverrides() require.NoError(t, err) assert.Empty(t, overrides) - - // with value non-string false, status of no objects should be ignored - _, settingsManager = fixtures(map[string]string{ - "resource.compareoptions": ` - ignoreResourceStatusField: false`, - }) - overrides, err = settingsManager.GetResourceOverrides() - require.NoError(t, err) - assert.Empty(t, overrides) - - // with value none, status of no objects should be ignored - _, settingsManager = fixtures(map[string]string{ - "resource.compareoptions": ` - ignoreResourceStatusField: none`, - }) - overrides, err = settingsManager.GetResourceOverrides() - require.NoError(t, err) - assert.Empty(t, overrides) } func TestGetResourceOverridesHealthWithWildcard(t *testing.T) { @@ -431,8 +426,6 @@ func TestSettingsManager_GetResourceOverrides_with_empty_string(t *testing.T) { func TestGetResourceOverrides_with_splitted_keys(t *testing.T) { data := map[string]string{ - "resource.compareoptions": `ignoreResourceStatusField: none`, - "resource.customizations": ` admissionregistration.k8s.io/MutatingWebhookConfiguration: ignoreDifferences: | @@ -454,11 +447,13 @@ func TestGetResourceOverrides_with_splitted_keys(t *testing.T) { } t.Run("MergedKey", func(t *testing.T) { + crdGK := "apiextensions.k8s.io/CustomResourceDefinition" _, settingsManager := fixtures(data) overrides, err := settingsManager.GetResourceOverrides() require.NoError(t, err) - assert.Len(t, overrides, 4) + assert.Len(t, overrides, 5) + assert.Len(t, overrides[crdGK].IgnoreDifferences.JSONPointers, 2) assert.Len(t, overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"].IgnoreDifferences.JSONPointers, 1) assert.Equal(t, "foo", overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"].IgnoreDifferences.JSONPointers[0]) assert.Len(t, overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"].IgnoreResourceUpdates.JSONPointers, 1) @@ -472,8 +467,6 @@ func TestGetResourceOverrides_with_splitted_keys(t *testing.T) { t.Run("SplitKeys", func(t *testing.T) { newData := map[string]string{ - "resource.compareoptions": `ignoreResourceStatusField: none`, - "resource.customizations.health.admissionregistration.k8s.io_MutatingWebhookConfiguration": "bar", "resource.customizations.ignoreDifferences.admissionregistration.k8s.io_MutatingWebhookConfiguration": `jsonPointers: - bar`, @@ -502,12 +495,16 @@ func TestGetResourceOverrides_with_splitted_keys(t *testing.T) { "resource.customizations.ignoreResourceUpdates.apps_Deployment": `jqPathExpressions: - bar`, } + crdGK := "apiextensions.k8s.io/CustomResourceDefinition" _, settingsManager := fixtures(mergemaps(data, newData)) overrides, err := settingsManager.GetResourceOverrides() require.NoError(t, err) - assert.Len(t, overrides, 8) + assert.Len(t, overrides, 9) + assert.Len(t, overrides[crdGK].IgnoreDifferences.JSONPointers, 2) + assert.Equal(t, "/status", overrides[crdGK].IgnoreDifferences.JSONPointers[0]) + assert.Equal(t, "/spec/preserveUnknownFields", overrides[crdGK].IgnoreDifferences.JSONPointers[1]) assert.Len(t, overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"].IgnoreDifferences.JSONPointers, 1) assert.Equal(t, "bar", overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"].IgnoreDifferences.JSONPointers[0]) assert.Len(t, overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"].IgnoreResourceUpdates.JSONPointers, 1) @@ -533,6 +530,41 @@ func TestGetResourceOverrides_with_splitted_keys(t *testing.T) { assert.Len(t, overrides["apps/Deployment"].IgnoreResourceUpdates.JQPathExpressions, 1) assert.Equal(t, "bar", overrides["apps/Deployment"].IgnoreResourceUpdates.JQPathExpressions[0]) }) + + t.Run("SplitKeysCompareOptionsAll", func(t *testing.T) { + newData := map[string]string{ + "resource.customizations.health.cert-manager.io_Certificate": "bar", + "resource.customizations.actions.apps_Deployment": "bar", + "resource.compareoptions": `ignoreResourceStatusField: all`, + } + _, settingsManager := fixtures(mergemaps(data, newData)) + + overrides, err := settingsManager.GetResourceOverrides() + require.NoError(t, err) + assert.Len(t, overrides, 5) + assert.Len(t, overrides["*/*"].IgnoreDifferences.JSONPointers, 1) + assert.Len(t, overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"].IgnoreDifferences.JSONPointers, 1) + assert.Equal(t, "foo\n", overrides["certmanager.k8s.io/Certificate"].HealthLua) + assert.Equal(t, "bar", overrides["cert-manager.io/Certificate"].HealthLua) + assert.Equal(t, "bar", overrides["apps/Deployment"].Actions) + }) + + t.Run("SplitKeysCompareOptionsOff", func(t *testing.T) { + newData := map[string]string{ + "resource.customizations.health.cert-manager.io_Certificate": "bar", + "resource.customizations.actions.apps_Deployment": "bar", + "resource.compareoptions": `ignoreResourceStatusField: off`, + } + _, settingsManager := fixtures(mergemaps(data, newData)) + + overrides, err := settingsManager.GetResourceOverrides() + require.NoError(t, err) + assert.Len(t, overrides, 4) + assert.Len(t, overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"].IgnoreDifferences.JSONPointers, 1) + assert.Equal(t, "foo\n", overrides["certmanager.k8s.io/Certificate"].HealthLua) + assert.Equal(t, "bar", overrides["cert-manager.io/Certificate"].HealthLua) + assert.Equal(t, "bar", overrides["apps/Deployment"].Actions) + }) } func mergemaps(mapA map[string]string, mapB map[string]string) map[string]string { @@ -549,10 +581,6 @@ func TestGetIgnoreResourceUpdatesOverrides(t *testing.T) { allGK := "*/*" testCustomizations := map[string]string{ - "resource.compareoptions": ` - ignoreResourceStatusField: none - ignoreDifferencesOnResourceUpdates: true`, - "resource.customizations": ` admissionregistration.k8s.io/MutatingWebhookConfiguration: ignoreDifferences: | @@ -576,24 +604,7 @@ func TestGetIgnoreResourceUpdatesOverrides(t *testing.T) { assert.NotNil(t, allOverrides) assert.Equal(t, allDefault, allOverrides) - // with ignoreDifferencesOnResourceUpdates, ignoreDifferences should be added - assert.NotNil(t, overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"]) - assert.Equal(t, v1alpha1.ResourceOverride{ - IgnoreDifferences: v1alpha1.OverrideIgnoreDiff{ - JSONPointers: []string{"/webhooks/1/clientConfig/caBundle", "/webhooks/0/clientConfig/caBundle"}, - JQPathExpressions: []string{".webhooks[1].clientConfig.caBundle", ".webhooks[0].clientConfig.caBundle"}, - }, - IgnoreResourceUpdates: v1alpha1.OverrideIgnoreDiff{}, - }, overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"]) - // without ignoreDifferencesOnResourceUpdates, only ignoreResourceUpdates should be added - _, settingsManager = fixtures(mergemaps(map[string]string{ - "resource.compareoptions": ` - ignoreResourceStatusField: none - ignoreDifferencesOnResourceUpdates: false`, - }, testCustomizations)) - overrides, err = settingsManager.GetIgnoreResourceUpdatesOverrides() - require.NoError(t, err) assert.NotNil(t, overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"]) assert.Equal(t, v1alpha1.ResourceOverride{ IgnoreDifferences: v1alpha1.OverrideIgnoreDiff{ @@ -602,6 +613,23 @@ func TestGetIgnoreResourceUpdatesOverrides(t *testing.T) { }, IgnoreResourceUpdates: v1alpha1.OverrideIgnoreDiff{}, }, overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"]) + + // with ignoreDifferencesOnResourceUpdates, ignoreDifferences should be added + _, settingsManager = fixtures(mergemaps(testCustomizations, map[string]string{ + "resource.compareoptions": ` + ignoreDifferencesOnResourceUpdates: true`, + })) + overrides, err = settingsManager.GetIgnoreResourceUpdatesOverrides() + require.NoError(t, err) + + assert.NotNil(t, overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"]) + assert.Equal(t, v1alpha1.ResourceOverride{ + IgnoreDifferences: v1alpha1.OverrideIgnoreDiff{ + JSONPointers: []string{"/webhooks/1/clientConfig/caBundle", "/webhooks/0/clientConfig/caBundle"}, + JQPathExpressions: []string{".webhooks[1].clientConfig.caBundle", ".webhooks[0].clientConfig.caBundle"}, + }, + IgnoreResourceUpdates: v1alpha1.OverrideIgnoreDiff{}, + }, overrides["admissionregistration.k8s.io/MutatingWebhookConfiguration"]) } func TestConvertToOverrideKey(t *testing.T) { @@ -737,7 +765,7 @@ func TestSettingsManager_GetKustomizeBuildOptions(t *testing.T) { } sortVersionsByName(want.Versions) sortVersionsByName(got.Versions) - assert.Equal(t, want, got) + assert.EqualValues(t, want, got) }) t.Run("Kustomize settings per-version with duplicate versions", func(t *testing.T) { @@ -792,10 +820,10 @@ func TestSettingsManager_GetEventLabelKeys(t *testing.T) { } inKeys := settingsManager.GetIncludeEventLabelKeys() - assert.Len(t, inKeys, len(tt.expectedKeys)) + assert.Equal(t, len(tt.expectedKeys), len(inKeys)) exKeys := settingsManager.GetExcludeEventLabelKeys() - assert.Len(t, exKeys, len(tt.expectedKeys)) + assert.Equal(t, len(tt.expectedKeys), len(exKeys)) for i := range tt.expectedKeys { assert.Equal(t, tt.expectedKeys[i], inKeys[i]) @@ -825,7 +853,7 @@ func TestKustomizeSettings_GetOptions(t *testing.T) { t.Run("DefaultBuildOptions", func(t *testing.T) { ver, err := settings.GetOptions(v1alpha1.ApplicationSource{}) require.NoError(t, err) - assert.Empty(t, ver.BinaryPath) + assert.Equal(t, "", ver.BinaryPath) assert.Equal(t, "--opt1 val1", ver.BuildOptions) }) @@ -835,7 +863,7 @@ func TestKustomizeSettings_GetOptions(t *testing.T) { }) require.NoError(t, err) assert.Equal(t, "path_v2", ver.BinaryPath) - assert.Empty(t, ver.BuildOptions) + assert.Equal(t, "", ver.BuildOptions) }) t.Run("VersionExistsWithBuildOption", func(t *testing.T) { @@ -909,7 +937,7 @@ func TestSettingsManager_GetHelp(t *testing.T) { func TestSettingsManager_GetSettings(t *testing.T) { t.Run("UserSessionDurationNotProvided", func(t *testing.T) { kubeClient := fake.NewClientset( - &corev1.ConfigMap{ + &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -919,7 +947,7 @@ func TestSettingsManager_GetSettings(t *testing.T) { }, Data: nil, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -932,14 +960,14 @@ func TestSettingsManager_GetSettings(t *testing.T) { }, }, ) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") s, err := settingsManager.GetSettings() require.NoError(t, err) assert.Equal(t, time.Hour*24, s.UserSessionDuration) }) t.Run("UserSessionDurationInvalidFormat", func(t *testing.T) { kubeClient := fake.NewClientset( - &corev1.ConfigMap{ + &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -951,7 +979,7 @@ func TestSettingsManager_GetSettings(t *testing.T) { "users.session.duration": "10hh", }, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -964,14 +992,14 @@ func TestSettingsManager_GetSettings(t *testing.T) { }, }, ) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") s, err := settingsManager.GetSettings() require.NoError(t, err) assert.Equal(t, time.Hour*24, s.UserSessionDuration) }) t.Run("UserSessionDurationProvided", func(t *testing.T) { kubeClient := fake.NewClientset( - &corev1.ConfigMap{ + &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -983,7 +1011,7 @@ func TestSettingsManager_GetSettings(t *testing.T) { "users.session.duration": "10h", }, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -996,7 +1024,7 @@ func TestSettingsManager_GetSettings(t *testing.T) { }, }, ) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") s, err := settingsManager.GetSettings() require.NoError(t, err) assert.Equal(t, time.Hour*10, s.UserSessionDuration) @@ -1005,7 +1033,7 @@ func TestSettingsManager_GetSettings(t *testing.T) { func TestGetOIDCConfig(t *testing.T) { kubeClient := fake.NewClientset( - &corev1.ConfigMap{ + &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -1017,7 +1045,7 @@ func TestGetOIDCConfig(t *testing.T) { "oidc.config": "\n requestedIDTokenClaims: {\"groups\": {\"essential\": true}}\n", }, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -1031,7 +1059,7 @@ func TestGetOIDCConfig(t *testing.T) { }, }, ) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") settings, err := settingsManager.GetSettings() require.NoError(t, err) @@ -1085,7 +1113,7 @@ func Test_validateExternalURL(t *testing.T) { func TestGetOIDCSecretTrim(t *testing.T) { kubeClient := fake.NewClientset( - &corev1.ConfigMap{ + &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -1097,7 +1125,7 @@ func TestGetOIDCSecretTrim(t *testing.T) { "oidc.config": "\n name: Okta\n clientSecret: test-secret\r\n \n clientID: aaaabbbbccccddddeee\n", }, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -1111,7 +1139,7 @@ func TestGetOIDCSecretTrim(t *testing.T) { }, }, ) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") settings, err := settingsManager.GetSettings() require.NoError(t, err) @@ -1131,7 +1159,7 @@ func getCNFromCertificate(cert *tls.Certificate) string { func Test_GetTLSConfiguration(t *testing.T) { t.Run("Valid external TLS secret with success", func(t *testing.T) { kubeClient := fake.NewClientset( - &corev1.ConfigMap{ + &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -1143,7 +1171,7 @@ func Test_GetTLSConfiguration(t *testing.T) { "oidc.config": "\n name: Okta\n clientSecret: test-secret\r\n \n clientID: aaaabbbbccccddddeee\n", }, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -1156,7 +1184,7 @@ func Test_GetTLSConfiguration(t *testing.T) { "server.secretkey": nil, }, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: externalServerTLSSecretName, Namespace: "default", @@ -1167,7 +1195,7 @@ func Test_GetTLSConfiguration(t *testing.T) { }, }, ) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") settings, err := settingsManager.GetSettings() require.NoError(t, err) assert.True(t, settings.CertificateIsExternal) @@ -1177,7 +1205,7 @@ func Test_GetTLSConfiguration(t *testing.T) { t.Run("Valid external TLS secret overrides argocd-secret", func(t *testing.T) { kubeClient := fake.NewClientset( - &corev1.ConfigMap{ + &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -1189,7 +1217,7 @@ func Test_GetTLSConfiguration(t *testing.T) { "oidc.config": "\n name: Okta\n clientSecret: test-secret\r\n \n clientID: aaaabbbbccccddddeee\n", }, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -1204,7 +1232,7 @@ func Test_GetTLSConfiguration(t *testing.T) { "tls.key": []byte(testutil.MustLoadFileToString("../../test/fixture/certs/argocd-e2e-server.key")), }, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: externalServerTLSSecretName, Namespace: "default", @@ -1215,7 +1243,7 @@ func Test_GetTLSConfiguration(t *testing.T) { }, }, ) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") settings, err := settingsManager.GetSettings() require.NoError(t, err) assert.True(t, settings.CertificateIsExternal) @@ -1224,7 +1252,7 @@ func Test_GetTLSConfiguration(t *testing.T) { }) t.Run("Invalid external TLS secret", func(t *testing.T) { kubeClient := fake.NewClientset( - &corev1.ConfigMap{ + &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -1236,7 +1264,7 @@ func Test_GetTLSConfiguration(t *testing.T) { "oidc.config": "\n name: Okta\n clientSecret: test-secret\r\n \n clientID: aaaabbbbccccddddeee\n", }, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -1249,7 +1277,7 @@ func Test_GetTLSConfiguration(t *testing.T) { "server.secretkey": nil, }, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: externalServerTLSSecretName, Namespace: "default", @@ -1260,14 +1288,14 @@ func Test_GetTLSConfiguration(t *testing.T) { }, }, ) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") settings, err := settingsManager.GetSettings() require.ErrorContains(t, err, "could not read from secret") assert.NotNil(t, settings) }) t.Run("No external TLS secret", func(t *testing.T) { kubeClient := fake.NewClientset( - &corev1.ConfigMap{ + &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -1279,7 +1307,7 @@ func Test_GetTLSConfiguration(t *testing.T) { "oidc.config": "\n name: Okta\n clientSecret: test-secret\r\n \n clientID: aaaabbbbccccddddeee\n", }, }, - &corev1.Secret{ + &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -1295,7 +1323,7 @@ func Test_GetTLSConfiguration(t *testing.T) { }, }, ) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") settings, err := settingsManager.GetSettings() require.NoError(t, err) assert.False(t, settings.CertificateIsExternal) @@ -1338,7 +1366,7 @@ requestedScopes: ["openid", "profile", "email"] # Optional set of OIDC claims to request on the ID token. requestedIDTokenClaims: {"groups": {"essential": true}}`, } - cm := &corev1.ConfigMap{ + cm := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -1348,7 +1376,7 @@ requestedIDTokenClaims: {"groups": {"essential": true}}`, }, Data: data, } - argocdSecret := &corev1.Secret{ + argocdSecret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -1359,7 +1387,7 @@ requestedIDTokenClaims: {"groups": {"essential": true}}`, "webhook.github.secret": []byte("$ext:webhook.github.secret"), }, } - secret := &corev1.Secret{ + secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "ext", Namespace: "default", @@ -1374,7 +1402,7 @@ requestedIDTokenClaims: {"groups": {"essential": true}}`, }, } kubeClient := fake.NewClientset(cm, secret, argocdSecret) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") settings, err := settingsManager.GetSettings() require.NoError(t, err) @@ -1410,7 +1438,7 @@ func TestGetEnableManifestGeneration(t *testing.T) { for i := range testCases { tc := testCases[i] t.Run(tc.name, func(t *testing.T) { - cm := &corev1.ConfigMap{ + cm := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -1420,7 +1448,7 @@ func TestGetEnableManifestGeneration(t *testing.T) { }, Data: tc.data, } - argocdSecret := &corev1.Secret{ + argocdSecret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -1432,7 +1460,7 @@ func TestGetEnableManifestGeneration(t *testing.T) { } kubeClient := fake.NewClientset(cm, argocdSecret) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") enableManifestGeneration, err := settingsManager.GetEnabledSourceTypes() require.NoError(t, err) @@ -1468,7 +1496,7 @@ func TestGetHelmSettings(t *testing.T) { for i := range testCases { tc := testCases[i] t.Run(tc.name, func(t *testing.T) { - cm := &corev1.ConfigMap{ + cm := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, Namespace: "default", @@ -1478,7 +1506,7 @@ func TestGetHelmSettings(t *testing.T) { }, Data: tc.data, } - argocdSecret := &corev1.Secret{ + argocdSecret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDSecretName, Namespace: "default", @@ -1488,7 +1516,7 @@ func TestGetHelmSettings(t *testing.T) { "server.secretkey": nil, }, } - secret := &corev1.Secret{ + secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "acme", Namespace: "default", @@ -1501,7 +1529,7 @@ func TestGetHelmSettings(t *testing.T) { }, } kubeClient := fake.NewClientset(cm, secret, argocdSecret) - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") helmSettings, err := settingsManager.GetHelmSettings() require.NoError(t, err) @@ -1651,7 +1679,7 @@ func TestReplaceStringSecret(t *testing.T) { assert.Equal(t, "$invalid-secret-key", result) result = ReplaceStringSecret("", secretValues) - assert.Empty(t, result) + assert.Equal(t, "", result) result = ReplaceStringSecret("my-value", secretValues) assert.Equal(t, "my-value", result) @@ -1766,60 +1794,11 @@ func TestRedirectAdditionalURLs(t *testing.T) { } } -func TestUseAzureWorkloadIdentity(t *testing.T) { - testCases := []struct { - Name string - Settings *ArgoCDSettings - ExpectedResult bool - }{ - { - Name: "UseAzureWorkloadIdentity defined and set to true", - Settings: &ArgoCDSettings{ - OIDCConfigRAW: "{ \"azure\": {\"useWorkloadIdentity\": true }}", - }, - ExpectedResult: true, - }, - { - Name: "UseAzureWorkloadIdentity defined and set to false", - Settings: &ArgoCDSettings{ - OIDCConfigRAW: "{ \"azure\": {\"useWorkloadIdentity\": false }}", - }, - ExpectedResult: false, - }, - { - Name: "UseAzureWorkloadIdentity not defined, with azure key present", - Settings: &ArgoCDSettings{ - OIDCConfigRAW: "{ \"azure\": {}}", - }, - ExpectedResult: false, - }, - { - Name: "UseAzureWorkloadIdentity not defined", - Settings: &ArgoCDSettings{ - OIDCConfigRAW: "{}", - }, - ExpectedResult: false, - }, - { - Name: "OIDC config isnot defined", - Settings: &ArgoCDSettings{}, - ExpectedResult: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.Name, func(t *testing.T) { - result := tc.Settings.UseAzureWorkloadIdentity() - require.Equal(t, tc.ExpectedResult, result) - }) - } -} - func TestIsImpersonationEnabled(t *testing.T) { // When there is no argocd-cm itself, // Then IsImpersonationEnabled() must return false (default value) and an error with appropriate error message. kubeClient := fake.NewClientset() - settingsManager := NewSettingsManager(t.Context(), kubeClient, "default") + 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)") @@ -1886,7 +1865,7 @@ func TestSettingsManager_GetHideSecretAnnotations(t *testing.T) { resourceSensitiveAnnotationsKey: tt.input, }) keys := settingsManager.GetSensitiveAnnotations() - assert.Len(t, keys, len(tt.output)) + assert.Equal(t, len(tt.output), len(keys)) assert.Equal(t, tt.output, keys) }) } diff --git a/util/swagger/swagger.go b/util/swagger/swagger.go index 0509939129..44cf8b0a52 100644 --- a/util/swagger/swagger.go +++ b/util/swagger/swagger.go @@ -15,7 +15,7 @@ const redocScriptName = "redoc.standalone.js" func ServeSwaggerUI(mux *http.ServeMux, swaggerJSON string, uiPath string, rootPath string) { prefix := path.Dir(uiPath) swaggerPath := path.Join(prefix, "swagger.json") - mux.HandleFunc(swaggerPath, func(w http.ResponseWriter, _ *http.Request) { + mux.HandleFunc(swaggerPath, func(w http.ResponseWriter, r *http.Request) { _, _ = fmt.Fprint(w, swaggerJSON) }) diff --git a/util/swagger/swagger_test.go b/util/swagger/swagger_test.go index 31facdae13..4c6e26c739 100644 --- a/util/swagger/swagger_test.go +++ b/util/swagger/swagger_test.go @@ -9,7 +9,7 @@ import ( "github.com/go-openapi/loads" "github.com/stretchr/testify/require" - "github.com/argoproj/argo-cd/v3/util/assets" + "github.com/argoproj/argo-cd/v2/util/assets" ) func TestSwaggerUI(t *testing.T) { diff --git a/util/test/testutil.go b/util/test/testutil.go index 177421dbc3..a8e5063008 100644 --- a/util/test/testutil.go +++ b/util/test/testutil.go @@ -6,14 +6,10 @@ import ( "io" "net/http" "net/http/httptest" - "regexp" "testing" - "time" - log "github.com/sirupsen/logrus" - - "github.com/go-jose/go-jose/v4" - "github.com/golang-jwt/jwt/v5" + "github.com/go-jose/go-jose/v3" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/require" ) @@ -143,7 +139,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(_ http.ResponseWriter, _ *http.Request) { + 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. })) ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -152,7 +148,7 @@ func GetDexTestServer(t *testing.T) *httptest.Server { return ts } -func oidcMockHandler(t *testing.T, url string, tokenRequestPreHandler func(r *http.Request)) func(http.ResponseWriter, *http.Request) { +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") @@ -200,16 +196,6 @@ func oidcMockHandler(t *testing.T, url string, tokenRequestPreHandler func(r *ht require.NoError(t, err) _, err = w.Write(out) require.NoError(t, err) - case "/token": - if tokenRequestPreHandler != nil { - tokenRequestPreHandler(r) - } - response, err := mockTokenEndpointResponse(url) - require.NoError(t, err) - out, err := json.Marshal(response) - require.NoError(t, err) - _, err = w.Write(out) - require.NoError(t, err) default: w.WriteHeader(http.StatusNotFound) } @@ -218,81 +204,11 @@ func oidcMockHandler(t *testing.T, url string, tokenRequestPreHandler func(r *ht func GetOIDCTestServer(t *testing.T) *httptest.Server { t.Helper() - ts := httptest.NewTLSServer(http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) { + 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. })) ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - oidcMockHandler(t, ts.URL, nil)(w, r) + oidcMockHandler(t, ts.URL)(w, r) }) return ts } - -func GetAzureOIDCTestServer(t *testing.T, tokenRequestPreHandler func(r *http.Request)) *httptest.Server { - t.Helper() - ts := httptest.NewTLSServer(http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) { - // Start with a placeholder. We need the server URL before setting up the real handler. - })) - ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - oidcMockHandler(t, ts.URL, tokenRequestPreHandler)(w, r) - }) - return ts -} - -type TokenResponse struct { - AccessToken string `json:"access_token"` - TokenType string `json:"token_type"` - ExpiresIn int `json:"expires_in"` - IDToken string `json:"id_token"` - RefreshToken string `json:"refresh_token"` -} - -func mockTokenEndpointResponse(issuer string) (TokenResponse, error) { - token, err := generateJWTToken(issuer) - return TokenResponse{ - AccessToken: token, - TokenType: "Bearer", - ExpiresIn: 3600, - IDToken: token, - RefreshToken: token, - }, err -} - -// Helper function to generate a JWT token -func generateJWTToken(issuer string) (string, error) { - token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ - "sub": "1234567890", - "name": "John Doe", - "iat": time.Now().Unix(), - "iss": issuer, - "exp": time.Now().Add(time.Hour).Unix(), // Set the expiration time - }) - tokenString, err := token.SignedString([]byte("secret")) - if err != nil { - return "", err - } - return tokenString, nil -} - -type LogHook struct { - Entries []log.Entry -} - -func (h *LogHook) Levels() []log.Level { - return []log.Level{log.WarnLevel} -} - -func (h *LogHook) Fire(entry *log.Entry) error { - h.Entries = append(h.Entries, *entry) - return nil -} - -func (h *LogHook) GetRegexMatchesInEntries(match string) []string { - re := regexp.MustCompile(match) - matches := make([]string, 0) - for _, entry := range h.Entries { - if re.Match([]byte(entry.Message)) { - matches = append(matches, entry.Message) - } - } - return matches -} diff --git a/util/text/text_test.go b/util/text/text_test.go index bcce240f1f..8640df01c8 100644 --- a/util/text/text_test.go +++ b/util/text/text_test.go @@ -23,7 +23,9 @@ func TestTrunc(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, Trunc(tt.args.message, tt.args.n), "Trunc()") + if got := Trunc(tt.args.message, tt.args.n); got != tt.want { + t.Errorf("Trunc() = %v, want %v", got, tt.want) + } }) } } diff --git a/util/tgzstream/stream.go b/util/tgzstream/stream.go index 4f8680e86a..220a3eed0e 100644 --- a/util/tgzstream/stream.go +++ b/util/tgzstream/stream.go @@ -10,7 +10,7 @@ import ( log "github.com/sirupsen/logrus" - "github.com/argoproj/argo-cd/v3/util/io/files" + "github.com/argoproj/argo-cd/v2/util/io/files" ) func CloseAndDelete(f *os.File) { diff --git a/util/tls/tls.go b/util/tls/tls.go index e45d7ea3a6..24c659d274 100644 --- a/util/tls/tls.go +++ b/util/tls/tls.go @@ -21,7 +21,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v3/util/env" + "github.com/argoproj/argo-cd/v2/util/env" ) const ( @@ -89,10 +89,11 @@ func getTLSCipherSuitesByString(cipherSuites string) ([]uint16, error) { allowedSuites := make([]uint16, 0) for _, s := range strings.Split(cipherSuites, ":") { id, ok := suiteMap[strings.TrimSpace(s)] - if !ok { + if ok { + allowedSuites = append(allowedSuites, id) + } else { return nil, fmt.Errorf("invalid cipher suite specified: %s", s) } - allowedSuites = append(allowedSuites, id) } return allowedSuites, nil } @@ -127,7 +128,7 @@ func getTLSConfigCustomizer(minVersionStr, maxVersionStr, tlsCiphersStr string) return nil, fmt.Errorf("error retrieving TLS version by max version %q: %w", maxVersionStr, err) } if minVersion > maxVersion { - return nil, fmt.Errorf("minimum TLS version %s must not be higher than maximum TLS version %s", minVersionStr, maxVersionStr) + return nil, fmt.Errorf("Minimum TLS version %s must not be higher than maximum TLS version %s", minVersionStr, maxVersionStr) } // Cipher suites for TLSv1.3 are not configurable @@ -178,7 +179,7 @@ func AddTLSFlagsToCmd(cmd *cobra.Command) func() (ConfigCustomizer, error) { } } -func publicKey(priv any) any { +func publicKey(priv interface{}) interface{} { switch k := priv.(type) { case *rsa.PrivateKey: return &k.PublicKey @@ -189,9 +190,14 @@ func publicKey(priv any) any { } } -func pemBlockForKey(priv any) *pem.Block { +func pemBlockForKey(priv interface{}) *pem.Block { switch k := priv.(type) { case *rsa.PrivateKey: + // In Go 1.24+, MarshalPKCS1PrivateKey calls Precompute() which can panic + // if the key is invalid. Validate the key first. + if k == nil || k.Validate() != nil { + return nil + } return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)} case *ecdsa.PrivateKey: b, err := x509.MarshalECPrivateKey(k) @@ -207,7 +213,7 @@ func pemBlockForKey(priv any) *pem.Block { func generate(opts CertOptions) ([]byte, crypto.PrivateKey, error) { if len(opts.Hosts) == 0 { - return nil, nil, errors.New("hosts not supplied") + return nil, nil, fmt.Errorf("hosts not supplied") } var privateKey crypto.PrivateKey @@ -228,7 +234,7 @@ func generate(opts CertOptions) ([]byte, crypto.PrivateKey, error) { case "P521": privateKey, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) default: - return nil, nil, fmt.Errorf("unrecognized elliptic curve: %q", opts.ECDSACurve) + return nil, nil, fmt.Errorf("Unrecognized elliptic curve: %q", opts.ECDSACurve) } if err != nil { return nil, nil, fmt.Errorf("failed to generate private key: %w", err) @@ -255,7 +261,7 @@ func generate(opts CertOptions) ([]byte, crypto.PrivateKey, error) { } if opts.Organization == "" { - return nil, nil, errors.New("organization not supplied") + return nil, nil, fmt.Errorf("organization not supplied") } template := x509.Certificate{ SerialNumber: serialNumber, @@ -285,7 +291,7 @@ func generate(opts CertOptions) ([]byte, crypto.PrivateKey, error) { certBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(privateKey), privateKey) if err != nil { - return nil, nil, fmt.Errorf("failed to create certificate: %w", err) + return nil, nil, fmt.Errorf("Failed to create certificate: %w", err) } return certBytes, privateKey, nil } @@ -297,7 +303,11 @@ func generatePEM(opts CertOptions) ([]byte, []byte, error) { return nil, nil, err } certpem := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certBytes}) - keypem := pem.EncodeToMemory(pemBlockForKey(privateKey)) + keyBlock := pemBlockForKey(privateKey) + if keyBlock == nil { + return nil, nil, errors.New("failed to encode private key") + } + keypem := pem.EncodeToMemory(keyBlock) return certpem, keypem, nil } @@ -320,7 +330,11 @@ func EncodeX509KeyPair(cert tls.Certificate) ([]byte, []byte) { for _, certtmp := range cert.Certificate { certpem = append(certpem, pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certtmp})...) } - keypem := pem.EncodeToMemory(pemBlockForKey(cert.PrivateKey)) + keyBlock := pemBlockForKey(cert.PrivateKey) + if keyBlock == nil { + return certpem, []byte{} + } + keypem := pem.EncodeToMemory(keyBlock) return certpem, keypem } @@ -344,13 +358,14 @@ func LoadX509CertPool(paths ...string) (*x509.CertPool, error) { } // ...but everything else is considered an error return nil, fmt.Errorf("could not load TLS certificate: %w", err) - } - f, err := os.ReadFile(path) - if err != nil { - return nil, fmt.Errorf("failure to load TLS certificates from %s: %w", path, err) - } - if ok := pool.AppendCertsFromPEM(f); !ok { - return nil, fmt.Errorf("invalid cert data in %s", path) + } else { + f, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("failure to load TLS certificates from %s: %w", path, err) + } + if ok := pool.AppendCertsFromPEM(f); !ok { + return nil, fmt.Errorf("invalid cert data in %s", path) + } } } return pool, nil @@ -364,7 +379,7 @@ func LoadX509Cert(path string) (*x509.Certificate, error) { } block, _ := pem.Decode(bytes) if block == nil { - return nil, errors.New("could not decode PEM") + return nil, fmt.Errorf("could not decode PEM") } cert, err := x509.ParseCertificate(block.Bytes) if err != nil { @@ -421,7 +436,7 @@ func CreateServerTLSConfig(tlsCertPath, tlsKeyPath string, hosts []string) (*tls log.Infof("Loading TLS configuration from cert=%s and key=%s", tlsCertPath, tlsKeyPath) c, err := tls.LoadX509KeyPair(tlsCertPath, tlsKeyPath) if err != nil { - return nil, fmt.Errorf("unable to initialize TLS configuration with cert=%s and key=%s: %w", tlsCertPath, tlsKeyPath, err) + return nil, fmt.Errorf("Unable to initialize TLS configuration with cert=%s and key=%s: %w", tlsCertPath, tlsKeyPath, err) } cert = &c } diff --git a/util/tls/tls_test.go b/util/tls/tls_test.go index 08686b8e3f..2b989516fe 100644 --- a/util/tls/tls_test.go +++ b/util/tls/tls_test.go @@ -1,11 +1,13 @@ package tls import ( + "crypto/rsa" "crypto/tls" "crypto/x509" "encoding/pem" "errors" "fmt" + "math/big" "os" "strings" "testing" @@ -79,22 +81,19 @@ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep -----END CERTIFICATE-----` var privateKey = `-----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQCJ35XKYxJtCy9on9TYqOZB2tvpcW5VCU7Y+cn8Ls7xtuYcA4ye -1FAWqCd71k15QTcGinCelTI/Oyy8jxpwJmAbrEU5xQfcpY8N2G1jdhZ4zA0vUrIa -ofCVQrk0DK1RxaijCrQeO+y+jhhsZkSX8SnzTJB/opdzIrZcFiXogMhVyQIDAQAB -AoGAWCUck86xGgvbnG0K3BVnWFT+4YlGe5E+2pMf4l1eqsQ+60wNnAGqzkFlNNP2 -pf3emwzpIUnLXQeM+2QWB/tQ149oZg8ZeOU7024WWhwP0lEjmcP36KtnKa6z/Y6L -YkItQifsQ8mOD06yQea/IeuIlcrvvDjYGTYOWAfHoMekeYECQQDKxWy1/ML8CMrO -iRH6ijBEEhlSbbF22DuGOA52iccvrITwBwSjd2MXEKWxk9q0VMjPTmiyTasx9aZr -2UgjF3YZAkEArhDqRf4qYXpUy2zeMRlRCVQbtEk++KPs3tNyLWP6VtXl35cveF64 -iG2R8lCgPF8Qq/DgHFUuiydIWgkF0dnzMQJAOajiPO3fVGP7p7d6kU/yYajz4mim -6jCa3JPcKQEMzxWzx713KDSuzMRDGbf9nQHvCGQ3iVxkrhQ4erqStMfbIQJBAJ7O -r+7LxL7KbTJrUQxanKR2KBCEAv+2DxX8s97VqEAxRliIBrc7NADEdrMs/AQYd41n -ZhBzZtNuM4RxVu3uewECQQDEJoPoXFXGyEAySPY8NJYPUHrY4tmue2L3CB+sdcgI -NPQCy08ABN5ro6GjeZimdvtHnXeiLYVKGtKsmTq4iTQG +MIIBsAIBAAKBgQCgF35rHhOWi9+r4n9xM/ejvMEsQ8h6lams962k4U0WSdfySUev +hyI1bd3FRIb5fFqSBt6qPTiiiIw0KXte5dANB6lPe6HdUPTA/U4xHWi2FB/BfAyP +sOlUBfFp6dtkEEcEKt+Z8KTJYJEerRie24y+nsfZMnLBst6tsEBfx/U75wIBAwKB +gGq6VEdpYmRdHGzsbmP7vDiYe2zYHLwQ0AKnPKNErq6KQyQC5eEngbgT4WpWl+J2 +Xn+R9m0vwNbaiDam0uD3p5192BaN2tdaW5P5JjfGa95ytRBCQ/cr+z03FjG9C6zQ +QZG5eyOoMloHAfnYiJMV5SZarfTiF9BGFvtcfrjhbterAgkDBMoUFjHxL0ECeDUI +f9nbOl1O2AgI/51gfHGo/NKv+kcQenM8RO7dy9+hUAulwqMlyszSq+0GdZdgQL/i +Lz8NclSgyuUtptmaSWtjB5Tdc8boaBApGKac7vB4M1AfTkng1+SplKbkdFlCVg4n +6EvCOrUFFsLp308JSbkv2240Q93JJwIJAgMxYrl2oMorAgcDNY7r7ttvAggOb9tA +6WMDHQ== -----END RSA PRIVATE KEY-----` -func decodePem(certInput string) (*tls.Certificate, error) { +func decodePem(certInput string) tls.Certificate { var cert tls.Certificate certPEMBlock := []byte(certInput) var certDERBlock *pem.Block @@ -111,20 +110,17 @@ func decodePem(certInput string) (*tls.Certificate, error) { var keyDERBlock *pem.Block keyPEMBlock := []byte(privateKey) keyDERBlock, _ = pem.Decode(keyPEMBlock) - privateKey, err := x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes) - if err != nil { - return nil, err - } - cert.PrivateKey = privateKey - return &cert, nil + cert.PrivateKey, _ = x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes) + return cert } func TestEncodeX509KeyPairString(t *testing.T) { - certChain, err := decodePem(chain) - require.NoError(t, err) - cert, _ := EncodeX509KeyPairString(*certChain) + certChain := decodePem(chain) + cert, _ := EncodeX509KeyPairString(certChain) - assert.Equal(t, strings.TrimSpace(chain), strings.TrimSpace(cert)) + if strings.TrimSpace(chain) != strings.TrimSpace(cert) { + t.Errorf("Incorrect, got: %s, want: %s", cert, chain) + } } func TestGetTLSVersionByString(t *testing.T) { @@ -151,7 +147,7 @@ func TestGetTLSVersionByString(t *testing.T) { func TestGetTLSCipherSuitesByString(t *testing.T) { suites := make([]string, 0) for _, s := range tls.CipherSuites() { - t.Run("Test for valid suite "+s.Name, func(t *testing.T) { + t.Run(fmt.Sprintf("Test for valid suite %s", s.Name), func(t *testing.T) { ids, err := getTLSCipherSuitesByString(s.Name) require.NoError(t, err) assert.Len(t, ids, 1) @@ -205,11 +201,11 @@ func TestGenerate(t *testing.T) { 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) - assert.ErrorContains(t, err, "unrecognized elliptic curve") + assert.ErrorContains(t, err, "Unrecognized elliptic curve") }) for _, curve := range []string{"P224", "P256", "P384", "P521"} { - t.Run("Create certificate with curve "+curve, func(t *testing.T) { + t.Run(fmt.Sprintf("Create certificate with curve %s", curve), func(t *testing.T) { opts := CertOptions{Hosts: []string{"localhost"}, Organization: "Acme", ECDSACurve: curve} _, _, err := generate(opts) require.NoError(t, err) @@ -458,3 +454,74 @@ func TestLoadX509CertPool(t *testing.T) { require.Nil(t, p) }) } + +func TestEncodeX509KeyPair_InvalidRSAKey(t *testing.T) { + t.Run("Nil RSA private key", func(t *testing.T) { + cert := tls.Certificate{ + Certificate: [][]byte{{0x30, 0x82}}, // minimal DER certificate bytes + PrivateKey: (*rsa.PrivateKey)(nil), + } + certPEM, keyPEM := EncodeX509KeyPair(cert) + assert.NotEmpty(t, certPEM) + assert.Empty(t, keyPEM) + }) + + t.Run("RSA private key that fails validation", func(t *testing.T) { + // Create an RSA key with invalid parameters that will fail Validate() + invalidKey := &rsa.PrivateKey{ + PublicKey: rsa.PublicKey{ + N: big.NewInt(1), // Too small modulus, will fail validation + E: 65537, + }, + D: big.NewInt(1), // Invalid private exponent + } + cert := tls.Certificate{ + Certificate: [][]byte{{0x30, 0x82}}, // minimal DER certificate bytes + PrivateKey: invalidKey, + } + certPEM, keyPEM := EncodeX509KeyPair(cert) + assert.NotEmpty(t, certPEM) + assert.Empty(t, keyPEM) + }) + + t.Run("RSA private key with inconsistent parameters", func(t *testing.T) { + invalidKey := &rsa.PrivateKey{ + PublicKey: rsa.PublicKey{ + N: big.NewInt(35), + E: 65537, + }, + D: big.NewInt(99999), + } + cert := tls.Certificate{ + Certificate: [][]byte{{0x30, 0x82}}, // minimal DER certificate bytes + PrivateKey: invalidKey, + } + certPEM, keyPEM := EncodeX509KeyPair(cert) + assert.NotEmpty(t, certPEM) + assert.Empty(t, keyPEM) + }) + + t.Run("Unsupported private key type", func(t *testing.T) { + // Use a type that's not *rsa.PrivateKey or *ecdsa.PrivateKey + cert := tls.Certificate{ + Certificate: [][]byte{{0x30, 0x82}}, // minimal DER certificate bytes + PrivateKey: "not a private key", // Unsupported type + } + certPEM, keyPEM := EncodeX509KeyPair(cert) + assert.NotEmpty(t, certPEM) + assert.Empty(t, keyPEM) + }) + + t.Run("Valid RSA private key should work", func(t *testing.T) { + // Generate a valid RSA key for testing + opts := CertOptions{Hosts: []string{"localhost"}, Organization: "Test"} + validCert, err := GenerateX509KeyPair(opts) + require.NoError(t, err) + + certPEM, keyPEM := EncodeX509KeyPair(*validCert) + assert.NotEmpty(t, certPEM) + assert.NotEmpty(t, keyPEM) + assert.Contains(t, string(keyPEM), "-----BEGIN RSA PRIVATE KEY-----") + assert.Contains(t, string(keyPEM), "-----END RSA PRIVATE KEY-----") + }) +} diff --git a/util/util.go b/util/util.go index 4deb0e6a63..e816bf4878 100644 --- a/util/util.go +++ b/util/util.go @@ -2,10 +2,7 @@ package util import ( "crypto/rand" - "crypto/sha256" "encoding/base64" - "encoding/hex" - "fmt" "k8s.io/apimachinery/pkg/runtime" ) @@ -30,15 +27,3 @@ func SliceCopy[T runtime.Object](items []T) []T { } return itemsCopy } - -// GenerateCacheKey generates a cache key based on a format string and arguments -func GenerateCacheKey(format string, args ...any) (string, error) { - h := sha256.New() - _, err := fmt.Fprintf(h, format, args...) - if err != nil { - return "", err - } - - key := hex.EncodeToString(h.Sum(nil)) - return key, nil -} diff --git a/util/util_test.go b/util/util_test.go index 18d382a4d2..5999541004 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -1,22 +1,22 @@ package util_test import ( - "fmt" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" + apiv1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/util" - "github.com/argoproj/argo-cd/v3/util/webhook" + "github.com/argoproj/argo-cd/v2/util" + "github.com/argoproj/argo-cd/v2/util/webhook" ) func TestMakeSignature(t *testing.T) { for size := 1; size <= 64; size++ { s, err := util.MakeSignature(size) - require.NoError(t, err, "Could not generate signature of size %d: %v", size, err) + if err != nil { + t.Errorf("Could not generate signature of size %d: %v", size, err) + } t.Logf("Generated token: %v", s) } } @@ -44,31 +44,31 @@ func TestParseRevision(t *testing.T) { func TestSliceCopy(t *testing.T) { type args struct { - secrets []*corev1.Secret + secrets []*apiv1.Secret } tests := []struct { name string args args - want []*corev1.Secret + want []*apiv1.Secret }{ - {name: "nil", args: args{secrets: nil}, want: []*corev1.Secret{}}, + {name: "nil", args: args{secrets: nil}, want: []*apiv1.Secret{}}, { - name: "Three", args: args{secrets: []*corev1.Secret{ + name: "Three", args: args{secrets: []*apiv1.Secret{ {ObjectMeta: metav1.ObjectMeta{Name: "one"}}, {ObjectMeta: metav1.ObjectMeta{Name: "two"}}, {ObjectMeta: metav1.ObjectMeta{Name: "three"}}, }}, - want: []*corev1.Secret{ + want: []*apiv1.Secret{ {ObjectMeta: metav1.ObjectMeta{Name: "one"}}, {ObjectMeta: metav1.ObjectMeta{Name: "two"}}, {ObjectMeta: metav1.ObjectMeta{Name: "three"}}, }, }, { - name: "One", args: args{secrets: []*corev1.Secret{{ObjectMeta: metav1.ObjectMeta{Name: "one"}}}}, - want: []*corev1.Secret{{ObjectMeta: metav1.ObjectMeta{Name: "one"}}}, + name: "One", args: args{secrets: []*apiv1.Secret{{ObjectMeta: metav1.ObjectMeta{Name: "one"}}}}, + want: []*apiv1.Secret{{ObjectMeta: metav1.ObjectMeta{Name: "one"}}}, }, - {name: "Zero", args: args{secrets: []*corev1.Secret{}}, want: []*corev1.Secret{}}, + {name: "Zero", args: args{secrets: []*apiv1.Secret{}}, want: []*apiv1.Secret{}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -80,46 +80,3 @@ func TestSliceCopy(t *testing.T) { }) } } - -// TestGenerateCacheKey tests the GenerateCacheKey function -func TestGenerateCacheKey(t *testing.T) { - // Define test cases - testCases := []struct { - format string - args []any - expected string - shouldErr bool - }{ - { - format: "Hello %s", - args: []any{"World"}, - expected: "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e", - shouldErr: false, - }, - { - format: "", - args: []any{}, - expected: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - shouldErr: false, - }, - { - format: "Number: %d", - args: []any{123}, - expected: "665fb090bf37fa3cbba9b92b9f82e6fa4bb851bad4c0a0a6edfb0aefa542150b", - shouldErr: false, - }, - // Add more test cases as needed - } - - for _, tc := range testCases { - t.Run(fmt.Sprintf("format=%s args=%v", tc.format, tc.args), func(t *testing.T) { - key, err := util.GenerateCacheKey(tc.format, tc.args...) - if tc.shouldErr { - require.Errorf(t, err, "expected error but got none") - return - } - require.NoErrorf(t, err, "unexpected error: %v", err) - require.Equalf(t, tc.expected, key, "expected %s but got %s", tc.expected, key) - }) - } -} diff --git a/util/versions/tags.go b/util/versions/tags.go deleted file mode 100644 index 4bb2c2f152..0000000000 --- a/util/versions/tags.go +++ /dev/null @@ -1,64 +0,0 @@ -package versions - -import ( - "errors" - "fmt" - - log "github.com/sirupsen/logrus" - - "github.com/Masterminds/semver/v3" -) - -// MaxVersion takes a revision and a list of tags. -// If the revision is a version, it returns that version, even if it is not in the list of tags. -// If the revision is not a version, but is also not a constraint, it returns that revision, even if it is not in the list of tags. -// If the revision is a constraint, it iterates over the list of tags to find the "maximum" tag which satisfies that -// constraint. -// If the revision is a constraint, but no tag satisfies that constraint, then it returns an error. -func MaxVersion(revision string, tags []string) (string, error) { - if v, 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 and return the original value. - // For example, the following are considered valid versions, and therefore should match an exact tag: - // - "v1.0.0"/"1.0.0" - // - "v1.0"/"1.0" - return v.Original(), nil - } - - constraints, err := semver.NewConstraint(revision) - if err != nil { - log.Debugf("Revision '%s' is not a valid semver constraint, resolving via basic string equality.", revision) - // If this is also an invalid constraint, we just iterate over available tags to determine if it is valid/invalid. - for _, tag := range tags { - if tag == revision { - return revision, nil - } - } - return "", fmt.Errorf("failed to determine semver constraint: %w", err) - } - - var maxVersion *semver.Version - for _, tag := range tags { - v, err := semver.NewVersion(tag) - - // Invalid semantic version ignored - if errors.Is(err, semver.ErrInvalidSemVer) { - log.Debugf("Invalid semantic version: %s", tag) - continue - } - if err != nil { - return "", fmt.Errorf("invalid semver version in tags: %w", err) - } - if constraints.Check(v) { - if maxVersion == nil || v.GreaterThan(maxVersion) { - maxVersion = v - } - } - } - if maxVersion == nil { - return "", fmt.Errorf("version matching constraint not found in %d tags", len(tags)) - } - - log.Debugf("Semver constraint '%s' resolved to version '%s'", constraints.String(), maxVersion.Original()) - return maxVersion.Original(), nil -} diff --git a/util/versions/tags_test.go b/util/versions/tags_test.go deleted file mode 100644 index 80f164c754..0000000000 --- a/util/versions/tags_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package versions - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -var tags = []string{ - "0.7.1", - "0.5.4", - "0.5.3", - "0.7.2", - "0.5.2", - "0.5.1", - "0.5.0", - "2024.03-LTS-RC19", -} - -func TestTags_MaxVersion(t *testing.T) { - t.Run("Exact", func(t *testing.T) { - version, err := MaxVersion("0.5.3", tags) - require.NoError(t, err) - assert.Equal(t, "0.5.3", version) - }) - t.Run("Exact nonsemver", func(t *testing.T) { - version, err := MaxVersion("2024.03-LTS-RC19", tags) - require.NoError(t, err) - assert.Equal(t, "2024.03-LTS-RC19", version) - }) - t.Run("Exact missing", func(t *testing.T) { - // Passing an exact version which is not in the list of tags still returns that version - version, err := MaxVersion("99.99", []string{}) - require.NoError(t, err) - assert.Equal(t, "99.99", version) - }) - t.Run("Constraint", func(t *testing.T) { - version, err := MaxVersion("> 0.5.3", tags) - require.NoError(t, err) - assert.Equal(t, "0.7.2", version) - }) - t.Run("Constraint", func(t *testing.T) { - version, err := MaxVersion("> 0.0.0", tags) - require.NoError(t, err) - assert.Equal(t, "0.7.2", version) - }) - t.Run("Constraint", func(t *testing.T) { - version, err := MaxVersion(">0.5.0,<0.7.0", tags) - require.NoError(t, err) - assert.Equal(t, "0.5.4", version) - }) - t.Run("Constraint", func(t *testing.T) { - version, err := MaxVersion("0.7.*", tags) - require.NoError(t, err) - assert.Equal(t, "0.7.2", version) - }) - t.Run("Constraint", func(t *testing.T) { - version, err := MaxVersion("*", tags) - require.NoError(t, err) - assert.Equal(t, "0.7.2", version) - }) - t.Run("Constraint missing", func(t *testing.T) { - _, err := MaxVersion("0.7.*", []string{}) - require.Error(t, err) - }) -} diff --git a/util/webhook/testdata/gitlab-event.json b/util/webhook/testdata/gitlab-event.json index 9371005e18..bede10363a 100644 --- a/util/webhook/testdata/gitlab-event.json +++ b/util/webhook/testdata/gitlab-event.json @@ -16,26 +16,26 @@ "id": 1, "name": "project", "description": "", - "web_url": "https://gitlab.com/group/name", + "web_url": "https://gitlab/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", - "git_http_url": "https://gitlab.com/group/name.git", + "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", + "git_http_url": "https://gitlab/group/name.git", "namespace": "group", "visibility_level": 1, "path_with_namespace": "group/name", "default_branch": "master", "ci_config_path": null, - "homepage": "https://gitlab.com/group/name", - "url": "ssh://git@gitlab.com:2222/group/name.git", - "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", - "http_url": "https://gitlab.com/group/name.git" + "homepage": "https://gitlab/group/name", + "url": "ssh://git@gitlab:2222/group/name.git", + "ssh_url": "ssh://git@gitlab:2222/group/name.git", + "http_url": "https://gitlab/group/name.git" }, "commits": [ { "id": "bb0748feaa336d841c251017e4e374c22d0c8a98", "message": "Test commit message\n", "timestamp": "2020-01-06T03:47:55Z", - "url": "https://gitlab.com/group/name/commit/bb0748feaa336d841c251017e4e374c22d0c8a98", + "url": "https://gitlab/group/name/commit/bb0748feaa336d841c251017e4e374c22d0c8a98", "author": { "name": "User", "email": "user@example.com" @@ -55,11 +55,11 @@ }, "repository": { "name": "name", - "url": "ssh://git@gitlab.com:2222/group/name.git", + "url": "ssh://git@gitlab:2222/group/name.git", "description": "", - "homepage": "https://gitlab.com/group/name", - "git_http_url": "https://gitlab.com/group/name.git", - "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "homepage": "https://gitlab/group/name", + "git_http_url": "https://gitlab/group/name.git", + "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", "visibility_level": 10 } -} +} \ No newline at end of file diff --git a/util/webhook/webhook.go b/util/webhook/webhook.go index 43ab603dd1..40c3eac5d8 100644 --- a/util/webhook/webhook.go +++ b/util/webhook/webhook.go @@ -10,9 +10,6 @@ import ( "regexp" "strings" "sync" - "time" - - bb "github.com/ktrysmt/go-bitbucket" "github.com/Masterminds/semver/v3" "github.com/go-playground/webhooks/v6/azuredevops" @@ -25,17 +22,16 @@ import ( log "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/common" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned" - "github.com/argoproj/argo-cd/v3/reposerver/cache" - servercache "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/util/app/path" - "github.com/argoproj/argo-cd/v3/util/argo" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/git" - "github.com/argoproj/argo-cd/v3/util/glob" - "github.com/argoproj/argo-cd/v3/util/settings" + "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" + "github.com/argoproj/argo-cd/v2/reposerver/cache" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/util/app/path" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/glob" + "github.com/argoproj/argo-cd/v2/util/settings" ) type settingsSource interface { @@ -46,7 +42,7 @@ type settingsSource interface { // https://www.rfc-editor.org/rfc/rfc3986#section-3.2.1 // https://github.com/shadow-maint/shadow/blob/master/libmisc/chkname.c#L36 -const usernameRegex = `[\w\.][\w\.-]{0,30}[\w\.\$-]?` +const usernameRegex = `[a-zA-Z0-9_\.][a-zA-Z0-9_\.-]{0,30}[a-zA-Z0-9_\.\$-]?` const payloadQueueSize = 50000 @@ -66,9 +62,8 @@ type ArgoCDWebhookHandler struct { bitbucketserver *bitbucketserver.Webhook azuredevops *azuredevops.Webhook gogs *gogs.Webhook - settings *settings.ArgoCDSettings settingsSrc settingsSource - queue chan any + queue chan interface{} maxWebhookPayloadSizeB int64 } @@ -111,9 +106,8 @@ func NewHandler(namespace string, applicationNamespaces []string, webhookParalle settingsSrc: settingsSrc, repoCache: repoCache, serverCache: serverCache, - settings: set, db: argoDB, - queue: make(chan any, payloadQueueSize), + queue: make(chan interface{}, payloadQueueSize), maxWebhookPayloadSizeB: maxWebhookPayloadSizeB, } @@ -144,8 +138,8 @@ func ParseRevision(ref string) string { } // affectedRevisionInfo examines a payload from a webhook event, and extracts the repo web URL, -// the revision, and whether, or not this affected origin/HEAD (the default branch of the repository) -func (a *ArgoCDWebhookHandler) affectedRevisionInfo(payloadIf any) (webURLs []string, revision string, change changeInfo, touchedHead bool, changedFiles []string) { +// the revision, and whether or not this affected origin/HEAD (the default branch of the repository) +func affectedRevisionInfo(payloadIf interface{}) (webURLs []string, revision string, change changeInfo, touchedHead bool, changedFiles []string) { switch payload := payloadIf.(type) { case azuredevops.GitPushEvent: // See: https://learn.microsoft.com/en-us/azure/devops/service-hooks/events?view=azure-devops#git.push @@ -196,63 +190,24 @@ func (a *ArgoCDWebhookHandler) affectedRevisionInfo(payloadIf any) (webURLs []st // See: https://confluence.atlassian.com/bitbucket/event-payloads-740262817.html#EventPayloads-Push // NOTE: this is untested webURLs = append(webURLs, payload.Repository.Links.HTML.Href) - for _, changes := range payload.Push.Changes { - revision = changes.New.Name - change.shaBefore = changes.Old.Target.Hash - change.shaAfter = changes.New.Target.Hash + // TODO: bitbucket includes multiple changes as part of a single event. + // We only pick the first but need to consider how to handle multiple + for _, change := range payload.Push.Changes { + revision = change.New.Name break } // Not actually sure how to check if the incoming change affected HEAD just by examining the // payload alone. To be safe, we just return true and let the controller check for himself. touchedHead = true - // Get DiffSet only for authenticated webhooks. - // when WebhookBitbucketUUID is set in argocd-secret, then the payload must be signed and - // signature is validated before payload is parsed. - if len(a.settings.WebhookBitbucketUUID) > 0 { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - argoRepo, err := a.lookupRepository(ctx, webURLs[0]) - if err != nil { - log.Warnf("error trying to find a matching repo for URL %s: %v", payload.Repository.Links.HTML.Href, err) - break - } - if argoRepo == nil { - // it could be a public repository with no repo creds stored. - // initialize with empty bearer token to use the no auth bitbucket client. - log.Debugf("no bitbucket repository configured for URL %s, initializing with empty bearer token", webURLs[0]) - argoRepo = &v1alpha1.Repository{BearerToken: "", Repo: webURLs[0]} - } - apiBaseURL := strings.ReplaceAll(payload.Repository.Links.Self.Href, "/repositories/"+payload.Repository.FullName, "") - bbClient, err := newBitbucketClient(ctx, argoRepo, apiBaseURL) - if err != nil { - log.Warnf("error creating Bitbucket client for repo %s: %v", payload.Repository.Name, err) - break - } - log.Debugf("created bitbucket client with base URL '%s'", apiBaseURL) - owner := strings.ReplaceAll(payload.Repository.FullName, "/"+payload.Repository.Name, "") - spec := change.shaBefore + ".." + change.shaAfter - diffStatChangedFiles, err := fetchDiffStatFromBitbucket(ctx, bbClient, owner, payload.Repository.Name, spec) - if err != nil { - log.Warnf("error fetching changed files using bitbucket diffstat api: %v", err) - } - changedFiles = append(changedFiles, diffStatChangedFiles...) - touchedHead, err = isHeadTouched(ctx, bbClient, owner, payload.Repository.Name, revision) - if err != nil { - log.Warnf("error fetching bitbucket repo details: %v", err) - // To be safe, we just return true and let the controller check for himself. - touchedHead = true - } - } - // Bitbucket does not include a list of changed files anywhere in it's payload // so we cannot update changedFiles for this type of payload case bitbucketserver.RepositoryReferenceChangedPayload: // Webhook module does not parse the inner links if payload.Repository.Links != nil { - for _, l := range payload.Repository.Links["clone"].([]any) { - link := l.(map[string]any) + for _, l := range payload.Repository.Links["clone"].([]interface{}) { + link := l.(map[string]interface{}) if link["name"] == "http" { webURLs = append(webURLs, link["href"].(string)) } @@ -296,8 +251,8 @@ type changeInfo struct { } // HandleEvent handles webhook events for repo push events -func (a *ArgoCDWebhookHandler) HandleEvent(payload any) { - webURLs, revision, change, touchedHead, changedFiles := a.affectedRevisionInfo(payload) +func (a *ArgoCDWebhookHandler) HandleEvent(payload interface{}) { + webURLs, revision, change, touchedHead, changedFiles := affectedRevisionInfo(payload) // NOTE: the webURL does not include the .git extension if len(webURLs) == 0 { log.Info("Ignoring webhook event") @@ -346,7 +301,7 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload any) { } for _, webURL := range webURLs { - repoRegexp, err := GetWebURLRegex(webURL) + repoRegexp, err := getWebUrlRegex(webURL) if err != nil { log.Warnf("Failed to get repoRegexp: %s", err) continue @@ -357,11 +312,11 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload any) { if sourceRevisionHasChanged(drySource, revision, touchedHead) && sourceUsesURL(drySource, webURL, repoRegexp) { refreshPaths := path.GetAppRefreshPaths(&app) if path.AppFilesHaveChanged(refreshPaths, changedFiles) { - namespacedAppInterface := a.appClientset.ArgoprojV1alpha1().Applications(app.Namespace) - log.Infof("webhook trigger refresh app to hydrate '%s'", app.Name) - _, err = argo.RefreshApp(namespacedAppInterface, app.Name, v1alpha1.RefreshTypeNormal, true) + namespacedAppInterface := a.appClientset.ArgoprojV1alpha1().Applications(app.ObjectMeta.Namespace) + log.Infof("webhook trigger refresh app to hydrate '%s'", app.ObjectMeta.Name) + _, err = argo.RefreshApp(namespacedAppInterface, app.ObjectMeta.Name, v1alpha1.RefreshTypeNormal, true) if err != nil { - log.Warnf("Failed to hydrate app '%s' for controller reprocessing: %v", app.Name, err) + log.Warnf("Failed to hydrate app '%s' for controller reprocessing: %v", app.ObjectMeta.Name, err) continue } } @@ -372,10 +327,10 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload any) { if sourceRevisionHasChanged(source, revision, touchedHead) && sourceUsesURL(source, webURL, repoRegexp) { refreshPaths := path.GetAppRefreshPaths(&app) if path.AppFilesHaveChanged(refreshPaths, changedFiles) { - namespacedAppInterface := a.appClientset.ArgoprojV1alpha1().Applications(app.Namespace) - _, err = argo.RefreshApp(namespacedAppInterface, app.Name, v1alpha1.RefreshTypeNormal, true) + namespacedAppInterface := a.appClientset.ArgoprojV1alpha1().Applications(app.ObjectMeta.Namespace) + _, err = argo.RefreshApp(namespacedAppInterface, app.ObjectMeta.Name, v1alpha1.RefreshTypeNormal, true) if err != nil { - log.Warnf("Failed to refresh app '%s' for controller reprocessing: %v", app.Name, err) + log.Warnf("Failed to refresh app '%s' for controller reprocessing: %v", app.ObjectMeta.Name, err) continue } // No need to refresh multiple times if multiple sources match. @@ -391,58 +346,34 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload any) { } } -// GetWebURLRegex compiles a regex that will match any targetRevision referring to the same repo as -// the given webURL. webURL is expected to be a URL from an SCM webhook payload pointing to the web -// page for the repo. -func GetWebURLRegex(webURL string) (*regexp.Regexp, error) { - // 1. Optional: protocol (`http`, `https`, or `ssh`) followed by `://` - // 2. Optional: username followed by `@` - // 3. Optional: `ssh` or `altssh` subdomain - // 4. Required: hostname parsed from `webURL` - // 5. Optional: `:` followed by port number - // 6. Required: `:` or `/` - // 7. Required: path parsed from `webURL` - // 8. Optional: `.git` extension - return getURLRegex(webURL, `(?i)^((https?|ssh)://)?(%[1]s@)?((alt)?ssh\.)?%[2]s(:\d+)?[:/]%[3]s(\.git)?$`) -} - -// GetAPIURLRegex compiles a regex that will match any targetRevision referring to the same repo as -// the given apiURL. -func GetAPIURLRegex(apiURL string) (*regexp.Regexp, error) { - // 1. Optional: protocol (`http` or `https`) followed by `://` - // 2. Optional: username followed by `@` - // 3. Required: hostname parsed from `webURL` - // 4. Optional: `:` followed by port number - // 5. Optional: `/` - return getURLRegex(apiURL, `(?i)^(https?://)?(%[1]s@)?%[2]s(:\d+)?/?$`) -} - -func getURLRegex(originalURL string, regexpFormat string) (*regexp.Regexp, error) { - urlObj, err := url.Parse(originalURL) +// getWebUrlRegex compiles a regex that will match any targetRevision referring to the same repo as the given webURL. +// webURL is expected to be a URL from an SCM webhook payload pointing to the web page for the repo. +func getWebUrlRegex(webURL string) (*regexp.Regexp, error) { + urlObj, err := url.Parse(webURL) if err != nil { - return nil, fmt.Errorf("failed to parse URL '%s'", originalURL) + return nil, fmt.Errorf("failed to parse repoURL '%s'", webURL) } regexEscapedHostname := regexp.QuoteMeta(urlObj.Hostname()) - const urlPathSeparator = "/" - regexEscapedPath := regexp.QuoteMeta(strings.TrimPrefix(urlObj.EscapedPath(), urlPathSeparator)) - regexpStr := fmt.Sprintf(regexpFormat, usernameRegex, regexEscapedHostname, regexEscapedPath) + regexEscapedPath := regexp.QuoteMeta(urlObj.EscapedPath()[1:]) + regexpStr := fmt.Sprintf(`(?i)^(http://|https://|%s@|ssh://(%s@)?)%s(:[0-9]+|)[:/]%s(\.git)?$`, + usernameRegex, usernameRegex, regexEscapedHostname, regexEscapedPath) repoRegexp, err := regexp.Compile(regexpStr) if err != nil { - return nil, fmt.Errorf("failed to compile regexp for URL '%s'", originalURL) + return nil, fmt.Errorf("failed to compile regexp for repoURL '%s'", webURL) } return repoRegexp, nil } func (a *ArgoCDWebhookHandler) storePreviouslyCachedManifests(app *v1alpha1.Application, change changeInfo, trackingMethod string, appInstanceLabelKey string, installationID string) error { - destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, a.db) + err := argo.ValidateDestination(context.Background(), &app.Spec.Destination, a.db) if err != nil { return fmt.Errorf("error validating destination: %w", err) } var clusterInfo v1alpha1.ClusterInfo - err = a.serverCache.GetClusterInfo(destCluster.Server, &clusterInfo) + err = a.serverCache.GetClusterInfo(app.Spec.Destination.Server, &clusterInfo) if err != nil { return fmt.Errorf("error getting cluster info: %w", err) } @@ -468,23 +399,6 @@ func (a *ArgoCDWebhookHandler) storePreviouslyCachedManifests(app *v1alpha1.Appl return nil } -// lookupRepository returns a repository with its credentials for a given URL. If there are no matching repository secret found, -// then nil repository is returned. -func (a *ArgoCDWebhookHandler) lookupRepository(ctx context.Context, repoURL string) (*v1alpha1.Repository, error) { - repositories, err := a.db.ListRepositories(ctx) - if err != nil { - return nil, fmt.Errorf("error listing repositories: %w", err) - } - var repository *v1alpha1.Repository - for _, repo := range repositories { - if git.SameURL(repo.Repo, repoURL) { - log.Debugf("found a matching repository for URL %s", repoURL) - return repo, nil - } - } - return repository, nil -} - func sourceRevisionHasChanged(source v1alpha1.ApplicationSource, revision string, touchedHead bool) bool { targetRev := ParseRevision(source.TargetRevision) if targetRev == "HEAD" || targetRev == "" { // revision is head @@ -532,78 +446,8 @@ func sourceUsesURL(source v1alpha1.ApplicationSource, webURL string, repoRegexp return true } -// newBitbucketClient creates a new bitbucket client for the given repository and uses the provided apiURL to connect -// to the bitbucket server. If the repository uses basic auth, then a basic auth client is created or if bearer token -// is provided, then oauth based client is created. -func newBitbucketClient(_ context.Context, repository *v1alpha1.Repository, apiBaseURL string) (*bb.Client, error) { - var bbClient *bb.Client - if repository.Username != "" && repository.Password != "" { - log.Debugf("fetched user/password for repository URL '%s', initializing basic auth client", repository.Repo) - if repository.Username == "x-token-auth" { - bbClient = bb.NewOAuthbearerToken(repository.Password) - } else { - bbClient = bb.NewBasicAuth(repository.Username, repository.Password) - } - } else { - if repository.BearerToken != "" { - log.Debugf("fetched bearer token for repository URL '%s', initializing bearer token auth based client", repository.Repo) - } else { - log.Debugf("no credentials available for repository URL '%s', initializing no auth client", repository.Repo) - } - bbClient = bb.NewOAuthbearerToken(repository.BearerToken) - } - // parse and set the target URL of the Bitbucket server in the client - repoBaseURL, err := url.Parse(apiBaseURL) - if err != nil { - return nil, fmt.Errorf("failed to parse bitbucket api base URL '%s'", apiBaseURL) - } - bbClient.SetApiBaseURL(*repoBaseURL) - return bbClient, nil -} - -// fetchDiffStatFromBitbucket gets the list of files changed between two commits, by making a diffstat api callback to the -// bitbucket server from where the webhook orignated. -func fetchDiffStatFromBitbucket(_ context.Context, bbClient *bb.Client, owner, repoSlug, spec string) ([]string, error) { - // Getting the files changed from diff API: - // https://developer.atlassian.com/cloud/bitbucket/rest/api-group-commits/#api-repositories-workspace-repo-slug-diffstat-spec-get - - // invoke the diffstat api call to get the list of changed files between two commit shas - log.Debugf("invoking diffstat call with parameters: [Owner:%s, RepoSlug:%s, Spec:%s]", owner, repoSlug, spec) - diffStatResp, err := bbClient.Repositories.Diff.GetDiffStat(&bb.DiffStatOptions{ - Owner: owner, - RepoSlug: repoSlug, - Spec: spec, - Renames: true, - }) - if err != nil { - return nil, fmt.Errorf("error getting the diffstat: %w", err) - } - changedFiles := make([]string, len(diffStatResp.DiffStats)) - for i, value := range diffStatResp.DiffStats { - changedFilePath := value.New["path"] - if changedFilePath != nil { - changedFiles[i] = changedFilePath.(string) - } - } - log.Debugf("changed files for spec %s: %v", spec, changedFiles) - return changedFiles, nil -} - -// isHeadTouched returns true if the repository's main branch is modified, false otherwise -func isHeadTouched(ctx context.Context, bbClient *bb.Client, owner, repoSlug, revision string) (bool, error) { - bbRepoOptions := &bb.RepositoryOptions{ - Owner: owner, - RepoSlug: repoSlug, - } - bbRepo, err := bbClient.Repositories.Repository.Get(bbRepoOptions.WithContext(ctx)) - if err != nil { - return false, err - } - return bbRepo.Mainbranch.Name == revision, nil -} - func (a *ArgoCDWebhookHandler) Handler(w http.ResponseWriter, r *http.Request) { - var payload any + var payload interface{} var err error r.Body = http.MaxBytesReader(w, r.Body, a.maxWebhookPayloadSizeB) @@ -660,7 +504,7 @@ func (a *ArgoCDWebhookHandler) Handler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { status = http.StatusMethodNotAllowed } - http.Error(w, "Webhook processing failed: "+html.EscapeString(err.Error()), status) + http.Error(w, fmt.Sprintf("Webhook processing failed: %s", html.EscapeString(err.Error())), status) return } diff --git a/util/webhook/webhook_test.go b/util/webhook/webhook_test.go index 699d5f2acf..599b7dae00 100644 --- a/util/webhook/webhook_test.go +++ b/util/webhook/webhook_test.go @@ -2,21 +2,15 @@ package webhook import ( "bytes" - "context" "encoding/json" - "errors" "fmt" "io" "net/http" "net/http/httptest" "os" - "strings" "testing" - "text/template" "time" - bb "github.com/ktrysmt/go-bitbucket" - "github.com/stretchr/testify/mock" "k8s.io/apimachinery/pkg/types" "github.com/go-playground/webhooks/v6/bitbucket" @@ -24,25 +18,25 @@ import ( "github.com/go-playground/webhooks/v6/github" "github.com/go-playground/webhooks/v6/gitlab" gogsclient "github.com/gogits/go-gogs-client" - "github.com/jarcoal/httpmock" "k8s.io/apimachinery/pkg/runtime" kubetesting "k8s.io/client-go/testing" - servercache "github.com/argoproj/argo-cd/v3/server/cache" - "github.com/argoproj/argo-cd/v3/util/cache/appstate" - "github.com/argoproj/argo-cd/v3/util/db" - "github.com/argoproj/argo-cd/v3/util/db/mocks" + "github.com/argoproj/argo-cd/v2/util/cache/appstate" + + "github.com/argoproj/argo-cd/v2/util/db/mocks" + + servercache "github.com/argoproj/argo-cd/v2/server/cache" "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake" - "github.com/argoproj/argo-cd/v3/reposerver/cache" - cacheutil "github.com/argoproj/argo-cd/v3/util/cache" - "github.com/argoproj/argo-cd/v3/util/settings" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + "github.com/argoproj/argo-cd/v2/reposerver/cache" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/argoproj/argo-cd/v2/util/settings" ) type fakeSettingsSrc struct{} @@ -71,34 +65,6 @@ func NewMockHandler(reactor *reactorDef, applicationNamespaces []string, objects } func NewMockHandlerWithPayloadLimit(reactor *reactorDef, applicationNamespaces []string, maxPayloadSize int64, objects ...runtime.Object) *ArgoCDWebhookHandler { - return newMockHandler(reactor, applicationNamespaces, maxPayloadSize, &mocks.ArgoDB{}, &settings.ArgoCDSettings{}, objects...) -} - -func NewMockHandlerForBitbucketCallback(reactor *reactorDef, applicationNamespaces []string, objects ...runtime.Object) *ArgoCDWebhookHandler { - mockDB := mocks.ArgoDB{} - mockDB.On("ListRepositories", mock.Anything).Return( - []*v1alpha1.Repository{ - { - Repo: "https://bitbucket.org/test/argocd-examples-pub.git", - Username: "test", - Password: "test", - }, - { - Repo: "https://bitbucket.org/test-owner/test-repo.git", - Username: "test", - Password: "test", - }, - { - Repo: "git@bitbucket.org:test/argocd-examples-pub.git", - SSHPrivateKey: "test-ssh-key", - }, - }, nil) - argoSettings := settings.ArgoCDSettings{WebhookBitbucketUUID: "abcd-efgh-ijkl-mnop"} - defaultMaxPayloadSize := int64(50) * 1024 * 1024 - return newMockHandler(reactor, applicationNamespaces, defaultMaxPayloadSize, &mockDB, &argoSettings, objects...) -} - -func newMockHandler(reactor *reactorDef, applicationNamespaces []string, maxPayloadSize int64, argoDB db.ArgoDB, argoSettings *settings.ArgoCDSettings, objects ...runtime.Object) *ArgoCDWebhookHandler { appClientset := appclientset.NewSimpleClientset(objects...) if reactor != nil { defaultReactor := appClientset.ReactionChain[0] @@ -110,12 +76,12 @@ func newMockHandler(reactor *reactorDef, applicationNamespaces []string, maxPayl } cacheClient := cacheutil.NewCache(cacheutil.NewInMemoryCache(1 * time.Hour)) - return NewHandler("argocd", applicationNamespaces, 10, appClientset, argoSettings, &fakeSettingsSrc{}, cache.NewCache( + return NewHandler("argocd", applicationNamespaces, 10, appClientset, &settings.ArgoCDSettings{}, &fakeSettingsSrc{}, cache.NewCache( cacheClient, 1*time.Minute, 1*time.Minute, 10*time.Second, - ), servercache.NewCache(appstate.NewCache(cacheClient, time.Minute), time.Minute, time.Minute, time.Minute), argoDB, maxPayloadSize) + ), servercache.NewCache(appstate.NewCache(cacheClient, time.Minute), time.Minute, time.Minute, time.Minute), &mocks.ArgoDB{}, maxPayloadSize) } func TestGitHubCommitEvent(t *testing.T) { @@ -425,10 +391,10 @@ func TestBitbucketServerRepositoryReferenceChangedEvent(t *testing.T) { close(h.queue) h.Wait() assert.Equal(t, http.StatusOK, w.Code) - expectedLogResultSSH := "Received push event repo: ssh://git@bitbucketserver:7999/myproject/test-repo.git, revision: master, touchedHead: true" - assert.Equal(t, expectedLogResultSSH, hook.AllEntries()[len(hook.AllEntries())-2].Message) - expectedLogResultHTTPS := "Received push event repo: https://bitbucketserver/scm/myproject/test-repo.git, revision: master, touchedHead: true" - assert.Equal(t, expectedLogResultHTTPS, hook.LastEntry().Message) + expectedLogResultSsh := "Received push event repo: ssh://git@bitbucketserver:7999/myproject/test-repo.git, revision: master, touchedHead: true" + assert.Equal(t, expectedLogResultSsh, hook.AllEntries()[len(hook.AllEntries())-2].Message) + expectedLogResultHttps := "Received push event repo: https://bitbucketserver/scm/myproject/test-repo.git, revision: master, touchedHead: true" + assert.Equal(t, expectedLogResultHttps, hook.LastEntry().Message) hook.Reset() } @@ -479,7 +445,7 @@ func TestGitLabPushEvent(t *testing.T) { close(h.queue) h.Wait() assert.Equal(t, http.StatusOK, w.Code) - expectedLogResult := "Received push event repo: https://gitlab.com/group/name, revision: master, touchedHead: true" + expectedLogResult := "Received push event repo: https://gitlab/group/name, revision: master, touchedHead: true" assert.Equal(t, expectedLogResult, hook.LastEntry().Message) hook.Reset() } @@ -497,7 +463,7 @@ func TestGitLabSystemEvent(t *testing.T) { close(h.queue) h.Wait() assert.Equal(t, http.StatusOK, w.Code) - expectedLogResult := "Received push event repo: https://gitlab.com/group/name, revision: master, touchedHead: true" + expectedLogResult := "Received push event repo: https://gitlab/group/name, revision: master, touchedHead: true" assert.Equal(t, expectedLogResult, hook.LastEntry().Message) hook.Reset() } @@ -625,7 +591,7 @@ func Test_affectedRevisionInfo_appRevisionHasChanged(t *testing.T) { Changes: []bitbucketserver.RepositoryChange{ {Reference: bitbucketserver.RepositoryReference{ID: "refs/heads/" + branchName}}, }, - Repository: bitbucketserver.Repository{Links: map[string]any{"clone": []any{}}}, + Repository: bitbucketserver.Repository{Links: map[string]interface{}{"clone": []interface{}{}}}, } } @@ -638,7 +604,7 @@ func Test_affectedRevisionInfo_appRevisionHasChanged(t *testing.T) { tests := []struct { hasChanged bool targetRevision string - hookPayload any + hookPayload interface{} name string }{ // Edge cases for bitbucket. @@ -703,8 +669,7 @@ func Test_affectedRevisionInfo_appRevisionHasChanged(t *testing.T) { testCopy := testCase t.Run(testCopy.name, func(t *testing.T) { t.Parallel() - h := NewMockHandler(nil, []string{}) - _, revisionFromHook, _, _, _ := h.affectedRevisionInfo(testCopy.hookPayload) + _, revisionFromHook, _, _, _ := affectedRevisionInfo(testCopy.hookPayload) if got := sourceRevisionHasChanged(sourceWithRevision(testCopy.targetRevision), revisionFromHook, false); got != testCopy.hasChanged { t.Errorf("sourceRevisionHasChanged() = %v, want %v", got, testCopy.hasChanged) } @@ -712,7 +677,7 @@ func Test_affectedRevisionInfo_appRevisionHasChanged(t *testing.T) { } } -func Test_GetWebURLRegex(t *testing.T) { +func Test_getWebUrlRegex(t *testing.T) { tests := []struct { shouldMatch bool webURL string @@ -728,79 +693,26 @@ func Test_GetWebURLRegex(t *testing.T) { {false, "https://example.com/org/repo", "https://example.com/org/repo-2", "partial match should not match"}, {true, "https://example.com/org/repo", "https://example.com/org/repo.git", "no .git should match with .git"}, {true, "https://example.com/org/repo", "git@example.com:org/repo", "git without protocol should match"}, - {true, "https://example.com/org/repo", "user@example.com:org/repo", "git with non-git username should match"}, + {true, "https://example.com/org/repo", "user@example.com:org/repo", "git with non-git username shout match"}, {true, "https://example.com/org/repo", "ssh://git@example.com/org/repo", "git with protocol should match"}, {true, "https://example.com/org/repo", "ssh://git@example.com:22/org/repo", "git with port number should match"}, {true, "https://example.com:443/org/repo", "ssh://git@example.com:22/org/repo", "https and ssh w/ different port numbers should match"}, - {true, "https://example.com:443/org/repo", "ssh://git@ssh.example.com:443/org/repo", "https and ssh w/ ssh subdomain should match"}, - {true, "https://example.com:443/org/repo", "ssh://git@altssh.example.com:443/org/repo", "https and ssh w/ altssh subdomain should match"}, - {false, "https://example.com:443/org/repo", "ssh://git@unknown.example.com:443/org/repo", "https and ssh w/ unknown subdomain should not match"}, {true, "https://example.com/org/repo", "ssh://user-name@example.com/org/repo", "valid usernames with hyphens in repo should match"}, {false, "https://example.com/org/repo", "ssh://-user-name@example.com/org/repo", "invalid usernames with hyphens in repo should not match"}, {true, "https://example.com:443/org/repo", "GIT@EXAMPLE.COM:22:ORG/REPO", "matches aren't case-sensitive"}, {true, "https://example.com/org/repo%20", "https://example.com/org/repo%20", "escape codes in path are preserved"}, - {true, "https://user@example.com/org/repo", "http://example.com/org/repo", "https+username should match http"}, - {true, "https://user@example.com/org/repo", "https://example.com/org/repo", "https+username should match https"}, - {true, "http://example.com/org/repo", "https://user@example.com/org/repo", "http should match https+username"}, - {true, "https://example.com/org/repo", "https://user@example.com/org/repo", "https should match https+username"}, - {true, "https://user@example.com/org/repo", "ssh://example.com/org/repo", "https+username should match ssh"}, - - {false, "", "", "empty URLs should not panic"}, } - for _, testCase := range tests { testCopy := testCase t.Run(testCopy.name, func(t *testing.T) { t.Parallel() - regexp, err := GetWebURLRegex(testCopy.webURL) + regexp, err := getWebUrlRegex(testCopy.webURL) require.NoError(t, err) if matches := regexp.MatchString(testCopy.repo); matches != testCopy.shouldMatch { t.Errorf("sourceRevisionHasChanged() = %v, want %v", matches, testCopy.shouldMatch) } }) } - - t.Run("bad URL should error", func(t *testing.T) { - _, err := GetWebURLRegex("%%") - require.Error(t, err) - }) -} - -func Test_GetAPIURLRegex(t *testing.T) { - tests := []struct { - shouldMatch bool - apiURL string - repo string - name string - }{ - // Ensure input is regex-escaped. - {false, "https://an.example.com/", "https://an-example.com/", "dots in domain names should not be treated as wildcards"}, - - // Standard cases. - {true, "https://example.com/", "https://example.com/", "exact match should match"}, - {false, "https://example.com/", "ssh://example.com/", "should not match ssh"}, - {true, "https://user@example.com/", "http://example.com/", "https+username should match http"}, - {true, "https://user@example.com/", "https://example.com/", "https+username should match https"}, - {true, "http://example.com/", "https://user@example.com/", "http should match https+username"}, - {true, "https://example.com/", "https://user@example.com/", "https should match https+username"}, - } - - for _, testCase := range tests { - testCopy := testCase - t.Run(testCopy.name, func(t *testing.T) { - t.Parallel() - regexp, err := GetAPIURLRegex(testCopy.apiURL) - require.NoError(t, err) - if matches := regexp.MatchString(testCopy.repo); matches != testCopy.shouldMatch { - t.Errorf("sourceRevisionHasChanged() = %v, want %v", matches, testCopy.shouldMatch) - } - }) - } - - t.Run("bad URL should error", func(t *testing.T) { - _, err := GetAPIURLRegex("%%") - require.Error(t, err) - }) } func TestGitHubCommitEventMaxPayloadSize(t *testing.T) { @@ -821,364 +733,3 @@ func TestGitHubCommitEventMaxPayloadSize(t *testing.T) { assert.Equal(t, expectedLogResult, hook.LastEntry().Message) hook.Reset() } - -func Test_affectedRevisionInfo_bitbucket_changed_files(t *testing.T) { - httpmock.Activate() - defer httpmock.DeactivateAndReset() - httpmock.RegisterResponder("GET", - "https://api.bitbucket.org/2.0/repositories/test-owner/test-repo/diffstat/abcdef..ghijkl", - getDiffstatResponderFn()) - httpmock.RegisterResponder("GET", - "https://api.bitbucket.org/2.0/repositories/test-owner/test-repo", - getRepositoryResponderFn()) - const payloadTemplateString = ` -{ - "push":{ - "changes":[ - {"new":{"name":"{{.branch}}", "target": {"hash": "{{.newHash}}"}}, "old": {"name":"{{.branch}}", "target": {"hash": "{{.oldHash}}"}}} - ] - }, - "repository":{ - "type": "repository", - "full_name": "{{.owner}}/{{.repo}}", - "name": "{{.repo}}", - "scm": "git", - "links": { - "self": {"href": "https://api.bitbucket.org/2.0/repositories/{{.owner}}/{{.repo}}"}, - "html": {"href": "https://bitbucket.org/{{.owner}}/{{.repo}}"} - } - } -}` - tmpl, err := template.New("test").Parse(payloadTemplateString) - if err != nil { - panic(err) - } - - bitbucketPushPayload := func(branchName, owner, repo string) bitbucket.RepoPushPayload { - // The payload's "push.changes[0].new.name" member seems to only have the branch name (based on the example payload). - // https://support.atlassian.com/bitbucket-cloud/docs/event-payloads/#EventPayloads-Push - var pl bitbucket.RepoPushPayload - var doc bytes.Buffer - err = tmpl.Execute(&doc, map[string]string{ - "branch": branchName, - "owner": owner, - "repo": repo, - "oldHash": "abcdef", - "newHash": "ghijkl", - }) - if err != nil { - require.NoError(t, err) - } - _ = json.Unmarshal(doc.Bytes(), &pl) - return pl - } - - tests := []struct { - name string - hasChanged bool - revision string - hookPayload bitbucket.RepoPushPayload - expectedTouchHead bool - expectedChangedFiles []string - expectedChangeInfo changeInfo - }{ - { - "bitbucket branch name containing 'refs/heads/'", - false, - "release-0.0", - bitbucketPushPayload("release-0.0", "test-owner", "test-repo"), - false, - []string{"guestbook/guestbook-ui-deployment.yaml"}, - changeInfo{ - shaBefore: "abcdef", - shaAfter: "ghijkl", - }, - }, - { - "bitbucket branch name containing 'main'", - false, - "main", - bitbucketPushPayload("main", "test-owner", "test-repo"), - true, - []string{"guestbook/guestbook-ui-deployment.yaml"}, - changeInfo{ - shaBefore: "abcdef", - shaAfter: "ghijkl", - }, - }, - } - for _, testCase := range tests { - t.Run(testCase.name, func(t *testing.T) { - h := NewMockHandlerForBitbucketCallback(nil, []string{}) - _, revisionFromHook, change, touchHead, changedFiles := h.affectedRevisionInfo(testCase.hookPayload) - require.Equal(t, testCase.revision, revisionFromHook) - require.Equal(t, testCase.expectedTouchHead, touchHead) - require.Equal(t, testCase.expectedChangedFiles, changedFiles) - require.Equal(t, testCase.expectedChangeInfo, change) - }) - } -} - -func TestLookupRepository(t *testing.T) { - mockCtx, cancel := context.WithDeadline(t.Context(), time.Now().Add(10*time.Second)) - defer cancel() - h := NewMockHandlerForBitbucketCallback(nil, []string{}) - data := []string{ - "https://bitbucket.org/test/argocd-examples-pub.git", - "https://bitbucket.org/test/argocd-examples-pub", - "https://BITBUCKET.org/test/argocd-examples-pub", - "https://BITBUCKET.org/test/argocd-examples-pub.git", - "\thttps://bitbucket.org/test/argocd-examples-pub\n", - "\thttps://bitbucket.org/test/argocd-examples-pub.git\n", - "git@BITBUCKET.org:test/argocd-examples-pub", - "git@BITBUCKET.org:test/argocd-examples-pub.git", - "git@bitbucket.org:test/argocd-examples-pub", - "git@bitbucket.org:test/argocd-examples-pub.git", - } - for _, url := range data { - repository, err := h.lookupRepository(mockCtx, url) - require.NoError(t, err) - require.NotNil(t, repository) - require.Contains(t, strings.ToLower(repository.Repo), strings.Trim(strings.ToLower(url), "\t\n")) - require.True(t, repository.Username == "test" || repository.SSHPrivateKey == "test-ssh-key") - } - // when no matching repository is found, then it should return nil error and nil repository - repository, err := h.lookupRepository(t.Context(), "https://bitbucket.org/test/argocd-examples-not-found.git") - require.NoError(t, err) - require.Nil(t, repository) -} - -func TestCreateBitbucketClient(t *testing.T) { - tests := []struct { - name string - apiURL string - repository *v1alpha1.Repository - expectedAuth string - expectedErr error - }{ - { - "client creation with username and password", - "https://api.bitbucket.org/2.0/", - &v1alpha1.Repository{ - Repo: "https://bitbucket.org/test", - Username: "test", - Password: "test", - }, - "user:\"test\", password:\"test\"", - nil, - }, - { - "client creation for user x-token-auth and token in password", - "https://api.bitbucket.org/2.0/", - &v1alpha1.Repository{ - Repo: "https://bitbucket.org/test", - Username: "x-token-auth", - Password: "test-token", - }, - "bearerToken:\"test-token\"", - nil, - }, - { - "client creation with oauth bearer token", - "https://api.bitbucket.org/2.0/", - &v1alpha1.Repository{ - Repo: "https://bitbucket.org/test", - BearerToken: "test-token", - }, - "bearerToken:\"test-token\"", - nil, - }, - { - "client creation with no auth", - "https://api.bitbucket.org/2.0/", - &v1alpha1.Repository{ - Repo: "https://bitbucket.org/test", - }, - "bearerToken:\"\"", - nil, - }, - { - "client creation with invalid api URL", - "api.bitbucket.org%%/2.0/", - &v1alpha1.Repository{}, - "", - errors.New("failed to parse bitbucket api base URL 'api.bitbucket.org%%/2.0/'"), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - client, err := newBitbucketClient(t.Context(), tt.repository, tt.apiURL) - if tt.expectedErr == nil { - require.NoError(t, err) - require.NotNil(t, client) - require.Equal(t, tt.apiURL, client.GetApiBaseURL()) - require.Contains(t, fmt.Sprintf("%#v", *client.Auth), tt.expectedAuth) - } else { - require.Error(t, err) - require.Nil(t, client) - require.Equal(t, tt.expectedErr, err) - } - }) - } -} - -func TestFetchDiffStatBitbucketClient(t *testing.T) { - httpmock.Activate() - defer httpmock.DeactivateAndReset() - httpmock.RegisterResponder("GET", - "https://api.bitbucket.org/2.0/repositories/test-owner/test-repo/diffstat/abcdef..ghijkl", - getDiffstatResponderFn()) - client := bb.NewOAuthbearerToken("") - tt := []struct { - name string - owner string - repo string - spec string - expectedLen int - expectedFileChanged string - expectedErrString string - }{ - { - name: "valid repo and spec", - owner: "test-owner", - repo: "test-repo", - spec: "abcdef..ghijkl", - expectedLen: 1, - expectedFileChanged: "guestbook/guestbook-ui-deployment.yaml", - }, - { - name: "invalid spec", - owner: "test-owner", - repo: "test-repo", - spec: "abcdef..", - expectedErrString: "error getting the diffstat", - }, - } - - for _, test := range tt { - t.Run(test.name, func(t *testing.T) { - changedFiles, err := fetchDiffStatFromBitbucket(t.Context(), client, test.owner, test.repo, test.spec) - if test.expectedErrString == "" { - require.NoError(t, err) - require.NotNil(t, changedFiles) - require.Len(t, changedFiles, test.expectedLen) - require.Equal(t, test.expectedFileChanged, changedFiles[0]) - } else { - require.Error(t, err) - require.Contains(t, err.Error(), test.expectedErrString) - } - }) - } -} - -func TestIsHeadTouched(t *testing.T) { - httpmock.Activate() - defer httpmock.DeactivateAndReset() - httpmock.RegisterResponder("GET", - "https://api.bitbucket.org/2.0/repositories/test-owner/test-repo", - getRepositoryResponderFn()) - client := bb.NewOAuthbearerToken("") - tt := []struct { - name string - owner string - repo string - revision string - expectedErrString string - expectedTouchHead bool - }{ - { - name: "valid repo with main branch in revision", - owner: "test-owner", - repo: "test-repo", - revision: "main", - expectedErrString: "", - expectedTouchHead: true, - }, - { - name: "valid repo with main branch in revision", - owner: "test-owner", - repo: "test-repo", - revision: "release-0.0", - expectedErrString: "", - expectedTouchHead: false, - }, - { - name: "valid repo with main branch in revision", - owner: "test-owner", - repo: "unknown-repo", - revision: "master", - expectedErrString: "Get \"https://api.bitbucket.org/2.0/repositories/test-owner/unknown-repo\"", - expectedTouchHead: false, - }, - } - for _, test := range tt { - t.Run(test.name, func(t *testing.T) { - touchedHead, err := isHeadTouched(t.Context(), client, test.owner, test.repo, test.revision) - if test.expectedErrString == "" { - require.NoError(t, err) - require.Equal(t, test.expectedTouchHead, touchedHead) - } else { - require.Error(t, err) - require.False(t, touchedHead) - } - }) - } -} - -// getRepositoryResponderFn return a httpmock responder function to mock a get repository api call to bitbucket server -func getRepositoryResponderFn() func(req *http.Request) (*http.Response, error) { - return func(_ *http.Request) (*http.Response, error) { - // sample response: https://api.bitbucket.org/2.0/repositories/anandjoseph/argocd-examples-pub - repository := &bb.Repository{ - Type: "repository", - Full_name: "test-owner/test-repo", - Name: "test-repo", - Is_private: false, - Fork_policy: "allow_forks", - Mainbranch: bb.RepositoryBranch{ - Name: "main", - Type: "branch", - }, - } - resp, err := httpmock.NewJsonResponse(200, repository) - if err != nil { - return httpmock.NewStringResponse(500, ""), nil - } - return resp, nil - } -} - -// getDiffstatResponderFn return a httpmock responder function to mock a diffstat api call to bitbucket server -func getDiffstatResponderFn() func(req *http.Request) (*http.Response, error) { - return func(_ *http.Request) (*http.Response, error) { - // sample response : https://api.bitbucket.org/2.0/repositories/anandjoseph/argocd-examples-pub/diffstat/3a53cee247fc820fbae0a9cf463a6f4a18369f90..3d0965f36fcc07e88130b2d5c917a37c2876c484 - diffStatRes := &bb.DiffStatRes{ - Page: 1, - Size: 1, - Pagelen: 500, - DiffStats: []*bb.DiffStat{ - { - Type: "diffstat", - Status: "added", - LinedAdded: 20, - LinesRemoved: 0, - New: map[string]any{ - "path": "guestbook/guestbook-ui-deployment.yaml", - "type": "commit_file", - "escaped_path": "guestbook/guestbook-ui-deployment.yaml", - "links": map[string]any{ - "self": map[string]any{ - "href": "https://bitbucket.org/guestbook/guestbook-ui-deployment.yaml", - }, - }, - }, - }, - }, - } - resp, err := httpmock.NewJsonResponse(200, diffStatRes) - if err != nil { - return httpmock.NewStringResponse(500, ""), nil - } - return resp, nil - } -} diff --git a/util/workloadidentity/mocks/TokenProvider.go b/util/workloadidentity/mocks/TokenProvider.go deleted file mode 100644 index 008b45c6f4..0000000000 --- a/util/workloadidentity/mocks/TokenProvider.go +++ /dev/null @@ -1,90 +0,0 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify - -package mocks - -import ( - mock "github.com/stretchr/testify/mock" -) - -// NewTokenProvider creates a new instance of TokenProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewTokenProvider(t interface { - mock.TestingT - Cleanup(func()) -}) *TokenProvider { - mock := &TokenProvider{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} - -// TokenProvider is an autogenerated mock type for the TokenProvider type -type TokenProvider struct { - mock.Mock -} - -type TokenProvider_Expecter struct { - mock *mock.Mock -} - -func (_m *TokenProvider) EXPECT() *TokenProvider_Expecter { - return &TokenProvider_Expecter{mock: &_m.Mock} -} - -// GetToken provides a mock function for the type TokenProvider -func (_mock *TokenProvider) GetToken(scope string) (string, error) { - ret := _mock.Called(scope) - - if len(ret) == 0 { - panic("no return value specified for GetToken") - } - - var r0 string - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) (string, error)); ok { - return returnFunc(scope) - } - if returnFunc, ok := ret.Get(0).(func(string) string); ok { - r0 = returnFunc(scope) - } else { - r0 = ret.Get(0).(string) - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(scope) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// TokenProvider_GetToken_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetToken' -type TokenProvider_GetToken_Call struct { - *mock.Call -} - -// GetToken is a helper method to define mock.On call -// - scope -func (_e *TokenProvider_Expecter) GetToken(scope interface{}) *TokenProvider_GetToken_Call { - return &TokenProvider_GetToken_Call{Call: _e.mock.On("GetToken", scope)} -} - -func (_c *TokenProvider_GetToken_Call) Run(run func(scope string)) *TokenProvider_GetToken_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *TokenProvider_GetToken_Call) Return(s string, err error) *TokenProvider_GetToken_Call { - _c.Call.Return(s, err) - return _c -} - -func (_c *TokenProvider_GetToken_Call) RunAndReturn(run func(scope string) (string, error)) *TokenProvider_GetToken_Call { - _c.Call.Return(run) - return _c -} diff --git a/util/workloadidentity/workloadidentity.go b/util/workloadidentity/workloadidentity.go deleted file mode 100644 index 24aef2ffa5..0000000000 --- a/util/workloadidentity/workloadidentity.go +++ /dev/null @@ -1,45 +0,0 @@ -package workloadidentity - -import ( - "context" - - "github.com/Azure/azure-sdk-for-go/sdk/azcore" - "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" - "github.com/Azure/azure-sdk-for-go/sdk/azidentity" -) - -const ( - EmptyGuid = "00000000-0000-0000-0000-000000000000" //nolint:revive //FIXME(var-naming) -) - -type TokenProvider interface { - GetToken(scope string) (string, error) -} - -type WorkloadIdentityTokenProvider struct { - tokenCredential azcore.TokenCredential -} - -// Used to propagate initialization error if any -var initError error - -func NewWorkloadIdentityTokenProvider() TokenProvider { - cred, err := azidentity.NewDefaultAzureCredential(&azidentity.DefaultAzureCredentialOptions{}) - initError = err - return WorkloadIdentityTokenProvider{tokenCredential: cred} -} - -func (c WorkloadIdentityTokenProvider) GetToken(scope string) (string, error) { - if initError != nil { - return "", initError - } - - token, err := c.tokenCredential.GetToken(context.Background(), policy.TokenRequestOptions{ - Scopes: []string{scope}, - }) - if err != nil { - return "", err - } - - return token.Token, nil -} diff --git a/util/workloadidentity/workloadidentity_test.go b/util/workloadidentity/workloadidentity_test.go deleted file mode 100644 index 6e16f8d829..0000000000 --- a/util/workloadidentity/workloadidentity_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package workloadidentity - -import ( - "context" - "errors" - "testing" - - "github.com/Azure/azure-sdk-for-go/sdk/azcore" - "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -type MockTokenCredential struct { - mockedToken string - mockedError error -} - -func (c MockTokenCredential) GetToken(_ context.Context, _ policy.TokenRequestOptions) (azcore.AccessToken, error) { - return azcore.AccessToken{Token: c.mockedToken}, c.mockedError -} - -func TestNewWorkloadIdentityTokenProvider_Success(t *testing.T) { - // Replace the initialization with the mock - initError = nil - provider := WorkloadIdentityTokenProvider{tokenCredential: MockTokenCredential{}} - - // Test the NewWorkloadIdentityTokenProvider function - _, err := provider.GetToken("https://management.core.windows.net/.default") - require.NoError(t, err, "Expected no error from GetToken") -} - -func TestGetToken_Success(t *testing.T) { - initError = nil - provider := WorkloadIdentityTokenProvider{tokenCredential: MockTokenCredential{mockedToken: "mocked_token"}} - scope := "https://management.core.windows.net/.default" - - token, err := provider.GetToken(scope) - require.NoError(t, err, "Expected no error from GetToken") - assert.Equal(t, "mocked_token", token, "Expected token to match") -} - -func TestGetToken_Failure(t *testing.T) { - initError = nil - provider := WorkloadIdentityTokenProvider{tokenCredential: MockTokenCredential{mockedToken: "mocked_token", mockedError: errors.New("Expected error from GetToken")}} - scope := "https://management.core.windows.net/.default" - - token, err := provider.GetToken(scope) - require.Error(t, err, "Expected error from GetToken") - assert.Empty(t, token, "Expected token to be empty on error") -} - -func TestGetToken_InitError(t *testing.T) { - initError = errors.New("initialization error") - provider := WorkloadIdentityTokenProvider{tokenCredential: MockTokenCredential{mockedToken: "mocked_token", mockedError: errors.New("Expected error from GetToken")}} - - token, err := provider.GetToken("https://management.core.windows.net/.default") - require.Error(t, err, "Expected error from GetToken due to initialization error") - assert.Empty(t, token, "Expected token to be empty on initialization error") -}